Skip to content

Commit 3cc149d

Browse files
committed
fix: integrate AG-UI schema drift into auto-remediation pipeline
drift-report-collector clones canonical ag-ui repo via fs.existsSync, runs schema drift test, merges into single report; exits 1 if skipped. test-drift.yml notification distinguishes AG-UI vs HTTP drift; uses jq for safe JSON. fix-drift.yml clones ag-ui, adds continue-on-error on autofix with success() guard on PR creation, fixes Slack messaging. fix-drift.ts: corrected agui-handler.ts references, SDK type in prompt, flexible changelog title, ENOENT-specific catch, reordered badge checks, exit code 4 for no-changes, version bump wrapped in try/catch. Test coverage updated for BUILDER_TO_SKILL_SECTION and SDK type output.
1 parent 11658f1 commit 3cc149d

5 files changed

Lines changed: 343 additions & 51 deletions

File tree

.github/workflows/fix-drift.yml

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,11 @@ jobs:
3030
cache: pnpm
3131
- run: pnpm install --frozen-lockfile
3232

33-
# Step 0: Configure git identity and create fix branch
33+
# Step 0a: Clone ag-ui repo for AG-UI schema drift detection
34+
- name: Clone ag-ui repo
35+
run: git clone --depth 1 https://github.com/ag-ui-protocol/ag-ui.git ../ag-ui
36+
37+
# Step 0b: Configure git identity and create fix branch
3438
- name: Configure git
3539
run: |
3640
git config user.name "aimock-drift-bot"
@@ -83,7 +87,9 @@ jobs:
8387
8488
# Step 3: Invoke Claude Code to fix
8589
- name: Auto-fix drift
90+
id: autofix
8691
if: steps.check.outputs.skip != 'true'
92+
continue-on-error: true
8793
run: npx tsx scripts/fix-drift.ts
8894
env:
8995
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
@@ -118,8 +124,8 @@ jobs:
118124
id: pr
119125
if: success() && steps.check.outputs.skip != 'true'
120126
run: |
121-
npx tsx scripts/fix-drift.ts --create-pr 2>&1 | tee /tmp/pr-output.txt
122-
PR_URL=$(grep -oE 'https://github.com/[^ ]+/pull/[0-9]+' /tmp/pr-output.txt | head -1)
127+
npx tsx scripts/fix-drift.ts --create-pr
128+
PR_URL=$(gh pr list --head "$(git branch --show-current)" --json url --jq '.[0].url')
123129
if [ -z "$PR_URL" ]; then echo "No PR URL found"; exit 1; fi
124130
echo "url=$PR_URL" >> $GITHUB_OUTPUT
125131
env:
@@ -146,9 +152,11 @@ jobs:
146152
if: success() && steps.pr.outputs.url != ''
147153
run: |
148154
if [ -z "$SLACK_WEBHOOK" ]; then echo "SLACK_WEBHOOK not set, skipping"; exit 0; fi
149-
curl -s -X POST "$SLACK_WEBHOOK" \
155+
MSG="✅ *Drift auto-fix PR created with auto-merge enabled*\nPR: ${{ steps.pr.outputs.url }}\nRun: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
156+
PAYLOAD=$(jq -n --arg text "$MSG" '{text: $text}')
157+
curl -sf -X POST "$SLACK_WEBHOOK" \
150158
-H "Content-Type: application/json" \
151-
-d "{\"text\":\"✅ *Drift auto-fixed and merged*\nPR: ${{ steps.pr.outputs.url }}\nRun: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}\"}"
159+
-d "$PAYLOAD"
152160
env:
153161
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
154162

@@ -157,8 +165,10 @@ jobs:
157165
if: failure() && steps.check.outputs.skip != 'true'
158166
run: |
159167
if [ -z "$SLACK_WEBHOOK" ]; then echo "SLACK_WEBHOOK not set, skipping"; exit 0; fi
160-
curl -s -X POST "$SLACK_WEBHOOK" \
168+
MSG="❌ *Drift auto-fix failed* — issue created\nRun: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
169+
PAYLOAD=$(jq -n --arg text "$MSG" '{text: $text}')
170+
curl -sf -X POST "$SLACK_WEBHOOK" \
161171
-H "Content-Type: application/json" \
162-
-d "{\"text\":\"❌ *Drift auto-fix failed* — issue created\nRun: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}\"}"
172+
-d "$PAYLOAD"
163173
env:
164174
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}

.github/workflows/test-drift.yml

Lines changed: 49 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -67,47 +67,79 @@ jobs:
6767
if-no-files-found: warn
6868
retention-days: 30
6969

70+
- name: Fail if critical drift detected
71+
if: steps.drift.outputs.exit_code == '2'
72+
run: exit 1
73+
74+
notify:
75+
if: always() && github.event_name != 'pull_request'
76+
needs: [drift, agui-schema-drift]
77+
runs-on: ubuntu-latest
78+
timeout-minutes: 5
79+
steps:
7080
- name: Check previous run status
7181
id: prev
72-
if: always()
7382
run: |
74-
PREV=$(gh run list --workflow="Drift Tests" --branch=main --limit=2 --json conclusion --jq '.[1].conclusion // "unknown"')
83+
PREV=$(gh run list --workflow="Drift Tests" --repo="${{ github.repository }}" --branch=main --limit=2 --json conclusion --jq '.[1].conclusion // "unknown"')
7584
echo "conclusion=$PREV" >> $GITHUB_OUTPUT
7685
env:
7786
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
7887

7988
- name: Notify Slack
80-
if: always()
8189
run: |
8290
if [ -z "$SLACK_WEBHOOK" ]; then echo "SLACK_WEBHOOK not set, skipping"; exit 0; fi
8391
8492
PREV="${{ steps.prev.outputs.conclusion }}"
85-
NOW="${{ job.status }}"
86-
DRIFT="${{ steps.drift.outputs.exit_code }}"
93+
DRIFT_RESULT="${{ needs.drift.result }}"
94+
AGUI_RESULT="${{ needs.agui-schema-drift.result }}"
8795
88-
# Drift detected — always notify
89-
if [ "$DRIFT" = "2" ]; then
96+
HTTP_DRIFT=false
97+
AGUI_DRIFT=false
98+
INFRA_ERROR=false
99+
100+
# Determine what happened in each job
101+
if [ "$DRIFT_RESULT" = "failure" ]; then
102+
HTTP_DRIFT=true
103+
elif [ "$DRIFT_RESULT" != "success" ] && [ "$DRIFT_RESULT" != "skipped" ]; then
104+
INFRA_ERROR=true
105+
fi
106+
107+
if [ "$AGUI_RESULT" = "failure" ]; then
108+
AGUI_DRIFT=true
109+
elif [ "$AGUI_RESULT" != "success" ] && [ "$AGUI_RESULT" != "skipped" ]; then
110+
INFRA_ERROR=true
111+
fi
112+
113+
RUN_URL="<https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}|View run>"
114+
115+
# Both types of drift
116+
if [ "$HTTP_DRIFT" = "true" ] && [ "$AGUI_DRIFT" = "true" ]; then
117+
EMOJI="🚨"
118+
MSG="*Drift detected* in aimock — HTTP API drift + AG-UI schema drift. ${RUN_URL}"
119+
# HTTP API drift only
120+
elif [ "$HTTP_DRIFT" = "true" ]; then
90121
EMOJI="🚨"
91-
MSG="*Drift detected* in aimock — providers changed response formats. <https://github.com/CopilotKit/aimock/actions/runs/${{ github.run_id }}|View run>"
122+
MSG="*HTTP API drift detected* in aimock — providers changed response formats. ${RUN_URL}"
123+
# AG-UI schema drift only
124+
elif [ "$AGUI_DRIFT" = "true" ]; then
125+
EMOJI="🚨"
126+
MSG="*AG-UI schema drift detected* in aimock — canonical ag-ui types changed. ${RUN_URL}"
92127
# Infra failure — always notify
93-
elif [ "$NOW" != "success" ]; then
128+
elif [ "$INFRA_ERROR" = "true" ]; then
94129
EMOJI="❌"
95-
MSG="*Drift tests failed* (infra error). <https://github.com/CopilotKit/aimock/actions/runs/${{ github.run_id }}|View run>"
130+
MSG="*Drift tests failed* (infra error). ${RUN_URL}"
96131
# Recovery: previous was bad, now good — notify once
97132
elif [ "$PREV" = "failure" ]; then
98133
EMOJI="✅"
99-
MSG="Drift tests passing again — all providers match."
134+
MSG="Drift tests passing again — all providers and AG-UI schema match."
100135
# Good → good — stay quiet
101136
else
102137
exit 0
103138
fi
104139
105-
curl -s -X POST "$SLACK_WEBHOOK" \
140+
PAYLOAD=$(jq -n --arg text "${EMOJI} ${MSG}" '{text: $text}')
141+
curl -sf -X POST "$SLACK_WEBHOOK" \
106142
-H "Content-Type: application/json" \
107-
-d "{\"text\": \"${EMOJI} ${MSG}\"}"
143+
-d "$PAYLOAD"
108144
env:
109145
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
110-
111-
- name: Fail if critical drift detected
112-
if: steps.drift.outputs.exit_code == '2'
113-
run: exit 1

0 commit comments

Comments
 (0)