compat-check #65
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: compat-check | |
| # Monitors upstream ACP wrapper packages (@agentclientprotocol/claude-agent-acp, | |
| # @agentclientprotocol/codex-acp) for breaking changes. Runs daily and on | |
| # manual dispatch. If a wrapper stops producing correct output (spawn + prompt | |
| # smoke test fails), opens or updates a tracking GitHub Issue. | |
| # | |
| # To avoid burning API quota on unchanged versions, the check caches the last | |
| # successfully-tested version of each wrapper (.compat-versions.json, persisted | |
| # across runs via actions/cache). When the npm latest version matches the | |
| # cached version, the expensive spawn+prompt is skipped (reported CACHED). | |
| # | |
| # Two ways to provide credentials (configure under Settings → Secrets → Actions): | |
| # | |
| # Option A — unified router gateway (recommended, single secret pair): | |
| # UNIFIED_ROUTER_BASE_URL — e.g. https://your-router/v1 | |
| # UNIFIED_ROUTER_KEY — router API key | |
| # CLAUDE_GATEWAY_MODEL — (optional) model for claude, e.g. glm-5.2 | |
| # CODEX_GATEWAY_MODEL — (optional) model for codex, defaults to deepseek-chat | |
| # | |
| # Option B — direct provider keys: | |
| # ANTHROPIC_API_KEY — for the claude-agent-acp smoke test | |
| # OPENAI_API_KEY — for the codex-acp smoke test (CODEX_API_KEY also works) | |
| # | |
| # Agents whose key is absent (and no gateway) are SKIPPED (not failed). | |
| on: | |
| schedule: | |
| # Daily at 06:00 UTC (14:00 Beijing time). | |
| - cron: "0 6 * * *" | |
| workflow_dispatch: | |
| permissions: | |
| issues: write | |
| jobs: | |
| check: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-go@v5 | |
| with: | |
| go-version: "1.24.x" | |
| cache: true | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: "lts/*" | |
| # Persist the version cache across runs so unchanged versions are not | |
| # re-tested (saves API quota). The cache key is fixed so each run | |
| # read+writes the same slot; only the file content evolves. | |
| - name: Restore version cache | |
| id: cache-restore | |
| uses: actions/cache/restore@v4 | |
| with: | |
| path: .compat-versions.json | |
| key: compat-versions-cache | |
| - name: Run compat check | |
| id: check | |
| env: | |
| # Option A: unified router gateway (single secret pair covers both agents) | |
| UNIFIED_ROUTER_BASE_URL: ${{ secrets.UNIFIED_ROUTER_BASE_URL }} | |
| UNIFIED_ROUTER_KEY: ${{ secrets.UNIFIED_ROUTER_KEY }} | |
| CLAUDE_GATEWAY_MODEL: ${{ secrets.CLAUDE_GATEWAY_MODEL }} | |
| CODEX_GATEWAY_MODEL: ${{ secrets.CODEX_GATEWAY_MODEL }} | |
| # Option B: direct provider keys (alternative to gateway) | |
| ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} | |
| OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} | |
| run: | | |
| # Capture output to a file so the issue-creation step can embed it. | |
| set +e | |
| go run ./cmd/acp-compat-check > compat-output.txt 2>&1 | |
| code=$? | |
| echo "exit_code=$code" >> "$GITHUB_OUTPUT" | |
| cat compat-output.txt | |
| echo "---" | |
| echo "exit code: $code" | |
| exit 0 # always succeed here; the issue step decides what to do | |
| # Save the (possibly updated) cache. run-always so a cache miss on the | |
| # first run still populates it. save always succeeds even if the restore | |
| # missed, because the file is written by the check when versions change. | |
| - name: Save version cache | |
| if: always() | |
| uses: actions/cache/save@v4 | |
| with: | |
| path: .compat-versions.json | |
| key: compat-versions-cache | |
| - name: Open or update regression Issue | |
| if: steps.check.outputs.exit_code == '1' | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| set -euo pipefail | |
| LABEL="compat-regression" | |
| TITLE="[compat-check] ACP wrapper compatibility regression detected" | |
| # Render the captured output as a fenced code block in the issue body. | |
| BODY=$(cat <<'BODY_EOF' | |
| A scheduled compatibility check detected that at least one ACP wrapper | |
| stopped producing the expected output against this runtime. This usually | |
| means an upstream wrapper release introduced a breaking change. | |
| **Action required:** investigate the failing agent(s), pin or update the | |
| wrapper, and re-run the check. | |
| --- | |
| #### Check output | |
| ```text | |
| BODY_EOF | |
| ) | |
| BODY="${BODY}$(cat compat-output.txt)" | |
| BODY="${BODY}"$'\n```\n\n'"CI run: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" | |
| # Check for an existing open issue with the same title to avoid dupes. | |
| EXISTING=$(gh issue list --state open --search "${TITLE} in:title" --limit 1 --json number --jq '.[0].number' || true) | |
| if [ -n "$EXISTING" ]; then | |
| echo "Updating existing issue #$EXISTING with a new failure comment." | |
| gh issue comment "$EXISTING" --body "## Regression still detected (${{ github.run_id }}) | |
| ${BODY}" | |
| else | |
| echo "Opening new regression issue." | |
| # Create the label if it does not exist (ignore error if it does). | |
| gh label create "$LABEL" --description "Upstream ACP wrapper compatibility regression" --color D73A4A 2>/dev/null || true | |
| gh issue create \ | |
| --title "${TITLE}" \ | |
| --body "${BODY}" \ | |
| --label "$LABEL" | |
| fi | |
| - name: Close stale regression Issue (check passed) | |
| if: steps.check.outputs.exit_code == '0' | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| set -euo pipefail | |
| TITLE="[compat-check] ACP wrapper compatibility regression detected" | |
| EXISTING=$(gh issue list --state open --search "${TITLE} in:title" --limit 1 --json number --jq '.[0].number' || true) | |
| if [ -n "$EXISTING" ]; then | |
| echo "Check passed; closing resolved issue #$EXISTING." | |
| gh issue comment "$EXISTING" --body "✅ Compatibility check passed on run ${{ github.run_id }}. Closing this issue." | |
| gh issue close "$EXISTING" | |
| else | |
| echo "Check passed; no open regression issue to close." | |
| fi |