Skip to content

Upstream Pi watch

Upstream Pi watch #115

name: Upstream Pi watch
on:
schedule:
- cron: "13 6 * * *"
workflow_dispatch:
permissions:
actions: write
contents: read
issues: write
pull-requests: read
concurrency:
group: upstream-pi-detector
cancel-in-progress: false
jobs:
detect:
name: Detect exact Pi release
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout without credentials
uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
with:
persist-credentials: false
- name: Resolve exact package versions
id: versions
shell: bash
run: |
set -euo pipefail
current=$(jq -r '.piVersion' compatibility/pi.json)
coding=$(npm view @earendil-works/pi-coding-agent version)
ai=$(npm view @earendil-works/pi-ai version)
tui=$(npm view @earendil-works/pi-tui version)
printf 'current=%s\ncoding=%s\nai=%s\ntui=%s\n' "$current" "$coding" "$ai" "$tui" >> "$GITHUB_OUTPUT"
echo "current=$current latest coding=$coding ai=$ai tui=$tui"
- name: Fail closed on upstream version skew
if: steps.versions.outputs.coding != steps.versions.outputs.ai || steps.versions.outputs.coding != steps.versions.outputs.tui
env:
GH_TOKEN: ${{ github.token }}
GH_REPO: ${{ github.repository }}
shell: bash
run: |
set -euo pipefail
title="[pi-lockstep blocked] upstream package version skew"
body="Exact latest versions disagree: coding-agent=${{ steps.versions.outputs.coding }}, pi-ai=${{ steps.versions.outputs.ai }}, pi-tui=${{ steps.versions.outputs.tui }}. No repair was dispatched."
existing=$(gh issue list --state open --search "$title in:title" --json number --jq '.[0].number // empty')
if [ -z "$existing" ]; then gh issue create --title "$title" --body "$body" --label needs-human; fi
exit 1
- name: Check whether repair is needed
id: gate
if: steps.versions.outputs.coding == steps.versions.outputs.ai && steps.versions.outputs.coding == steps.versions.outputs.tui
env:
GH_TOKEN: ${{ github.token }}
GH_REPO: ${{ github.repository }}
shell: bash
run: |
set -euo pipefail
target="${{ steps.versions.outputs.coding }}"
if [ "$target" = "${{ steps.versions.outputs.current }}" ]; then
echo "dispatch=false" >> "$GITHUB_OUTPUT"
echo "Already compatible with Pi $target"
exit 0
fi
open=$(gh pr list --state open --label upstream-pi --search "$target in:title" --json number --jq 'length')
active=$(gh run list --workflow pi-upstream-lockstep.lock.yml --json status --limit 20 --jq '[.[] | select(.status == "queued" or .status == "in_progress")] | length')
if [ "$open" -gt 0 ] || [ "$active" -gt 0 ]; then
echo "dispatch=false" >> "$GITHUB_OUTPUT"
echo "Repair already open or running for Pi $target"
exit 0
fi
echo "dispatch=true" >> "$GITHUB_OUTPUT"
echo "target=$target" >> "$GITHUB_OUTPUT"
- name: Dispatch sandboxed repair
if: steps.gate.outputs.dispatch == 'true'
env:
GH_TOKEN: ${{ github.token }}
GH_REPO: ${{ github.repository }}
shell: bash
run: gh workflow run pi-upstream-lockstep.lock.yml -f target-version="${{ steps.gate.outputs.target }}"