-
Notifications
You must be signed in to change notification settings - Fork 0
151 lines (135 loc) · 6.18 KB
/
Copy pathcompat-check.yml
File metadata and controls
151 lines (135 loc) · 6.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
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