Skip to content

Commit 8ea4611

Browse files
committed
feat(ci): two-phase update — haiku for deps, sonnet escalation for test fixes
1 parent 694506b commit 8ea4611

File tree

1 file changed

+114
-14
lines changed

1 file changed

+114
-14
lines changed

.github/workflows/weekly-update.yml

Lines changed: 114 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -176,14 +176,14 @@ jobs:
176176
with:
177177
gpg-private-key: ${{ secrets.BOT_GPG_PRIVATE_KEY }}
178178

179-
- name: Run updating skill with Claude Code
180-
id: claude
181-
timeout-minutes: 15
179+
- name: Update dependencies (haiku — fast, cheap)
180+
id: update
181+
timeout-minutes: 10
182+
shell: bash
182183
env:
183184
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
184185
GITHUB_ACTIONS: 'true'
185186
run: |
186-
# Wrap pnpm through Socket firewall for all subprocesses (not just this shell).
187187
if [ -n "$SFW_BIN" ]; then
188188
mkdir -p /tmp/sfw-bin
189189
printf '#!/bin/bash\nexec "%s" pnpm "$@"\n' "$SFW_BIN" > /tmp/sfw-bin/pnpm
@@ -199,9 +199,12 @@ jobs:
199199
200200
set +e
201201
claude --print \
202-
--allowedTools "Bash(pnpm:*)" "Bash(git:*)" "Read" "Write" "Edit" "Glob" "Grep" \
203-
--model sonnet \
204-
--max-turns 25 \
202+
--model haiku \
203+
--max-turns 15 \
204+
--allowedTools \
205+
"Bash(pnpm:*)" \
206+
"Bash(git add:*)" "Bash(git commit:*)" "Bash(git status:*)" "Bash(git diff:*)" "Bash(git log:*)" "Bash(git rev-parse:*)" \
207+
"Read" "Write" "Edit" "Glob" "Grep" \
205208
"$(cat <<'PROMPT'
206209
/updating
207210
@@ -215,7 +218,7 @@ jobs:
215218
Update all dependencies to their latest versions, including npm packages and upstream submodule pins.
216219
Create one atomic commit per dependency update with a conventional commit message.
217220
Leave all changes local — the workflow handles pushing and PR creation.
218-
Skip running builds, tests, and type checks — CI runs those separately.
221+
Do not run builds or tests — the next step handles that.
219222
</instructions>
220223
221224
<success_criteria>
@@ -235,15 +238,109 @@ jobs:
235238
echo "success=false" >> $GITHUB_OUTPUT
236239
fi
237240
241+
- name: Run tests
242+
id: tests
243+
if: steps.update.outputs.success == 'true'
244+
shell: bash
245+
run: |
246+
if [ -n "$SFW_BIN" ]; then
247+
mkdir -p /tmp/sfw-bin
248+
printf '#!/bin/bash\nexec "%s" pnpm "$@"\n' "$SFW_BIN" > /tmp/sfw-bin/pnpm
249+
chmod +x /tmp/sfw-bin/pnpm
250+
export PATH="/tmp/sfw-bin:$PATH"
251+
fi
252+
253+
BUILD_EXIT=0
254+
pnpm run build 2>&1 | tee build-output.log || BUILD_EXIT=$?
255+
256+
TEST_EXIT=0
257+
pnpm test 2>&1 | tee test-output.log || TEST_EXIT=$?
258+
259+
if [ "$BUILD_EXIT" -eq 0 ] && [ "$TEST_EXIT" -eq 0 ]; then
260+
echo "tests-passed=true" >> $GITHUB_OUTPUT
261+
else
262+
echo "tests-passed=false" >> $GITHUB_OUTPUT
263+
fi
264+
265+
- name: Fix test failures (sonnet — smarter, escalated)
266+
id: claude
267+
if: steps.update.outputs.success == 'true' && steps.tests.outputs.tests-passed == 'false'
268+
timeout-minutes: 15
269+
shell: bash
270+
env:
271+
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
272+
GITHUB_ACTIONS: 'true'
273+
run: |
274+
if [ -n "$SFW_BIN" ]; then
275+
mkdir -p /tmp/sfw-bin
276+
printf '#!/bin/bash\nexec "%s" pnpm "$@"\n' "$SFW_BIN" > /tmp/sfw-bin/pnpm
277+
chmod +x /tmp/sfw-bin/pnpm
278+
export PATH="/tmp/sfw-bin:$PATH"
279+
fi
280+
281+
FAILURE_LOG=""
282+
if [ -f build-output.log ]; then
283+
FAILURE_LOG+="=== BUILD OUTPUT (last 50 lines) ==="$'\n'
284+
FAILURE_LOG+="$(tail -50 build-output.log)"$'\n\n'
285+
fi
286+
if [ -f test-output.log ]; then
287+
FAILURE_LOG+="=== TEST OUTPUT (last 100 lines) ==="$'\n'
288+
FAILURE_LOG+="$(tail -100 test-output.log)"$'\n'
289+
fi
290+
291+
set +e
292+
claude --print \
293+
--model sonnet \
294+
--max-turns 25 \
295+
--allowedTools \
296+
"Bash(pnpm:*)" \
297+
"Bash(git add:*)" "Bash(git commit:*)" "Bash(git status:*)" "Bash(git diff:*)" "Bash(git log:*)" "Bash(git rev-parse:*)" \
298+
"Read" "Write" "Edit" "Glob" "Grep" \
299+
"$(cat <<PROMPT
300+
Build or tests failed after dependency updates. Fix them.
301+
302+
<failure_output>
303+
$FAILURE_LOG
304+
</failure_output>
305+
306+
<instructions>
307+
Diagnose the failure from the logs above.
308+
Fix the code — do not revert dependency updates.
309+
Re-run the failing build or tests to confirm the fix.
310+
Commit all fixes with conventional commit messages.
311+
</instructions>
312+
PROMPT
313+
)" \
314+
2>&1 | tee -a claude-output.log
315+
CLAUDE_EXIT=${PIPESTATUS[0]}
316+
set -e
317+
318+
if [ "$CLAUDE_EXIT" -eq 0 ]; then
319+
echo "success=true" >> $GITHUB_OUTPUT
320+
else
321+
echo "success=false" >> $GITHUB_OUTPUT
322+
fi
323+
324+
- name: Set final status
325+
id: final
326+
if: always()
327+
run: |
328+
if [ "${{ steps.update.outputs.success }}" = "true" ] && \
329+
( [ "${{ steps.tests.outputs.tests-passed }}" = "true" ] || [ "${{ steps.claude.outputs.success }}" = "true" ] ); then
330+
echo "success=true" >> $GITHUB_OUTPUT
331+
else
332+
echo "success=false" >> $GITHUB_OUTPUT
333+
fi
334+
238335
- name: Validate changes
239336
id: validate
240-
if: steps.claude.outputs.success == 'true'
337+
if: steps.final.outputs.success == 'true'
241338
run: |
242-
# Only allow changes to dependency-related files.
243339
UNEXPECTED=""
244340
for file in $(git diff --name-only origin/main..HEAD); do
245341
case "$file" in
246342
package.json|*/package.json|pnpm-lock.yaml|*/pnpm-lock.yaml|.npmrc|pnpm-workspace.yaml) ;;
343+
src/*|test/*|*.ts|*.mts|*.js|*.mjs) ;;
247344
*) UNEXPECTED="$UNEXPECTED $file" ;;
248345
esac
249346
done
@@ -264,13 +361,13 @@ jobs:
264361
fi
265362
266363
- name: Push branch
267-
if: steps.claude.outputs.success == 'true' && steps.validate.outputs.valid == 'true' && steps.changes.outputs.has-changes == 'true'
364+
if: steps.final.outputs.success == 'true' && steps.validate.outputs.valid == 'true' && steps.changes.outputs.has-changes == 'true'
268365
env:
269366
BRANCH_NAME: ${{ steps.branch.outputs.branch }}
270367
run: git push origin "$BRANCH_NAME"
271368

272369
- name: Create Pull Request
273-
if: steps.claude.outputs.success == 'true' && steps.validate.outputs.valid == 'true' && steps.changes.outputs.has-changes == 'true'
370+
if: steps.final.outputs.success == 'true' && steps.validate.outputs.valid == 'true' && steps.changes.outputs.has-changes == 'true'
274371
env:
275372
GH_TOKEN: ${{ github.token }}
276373
UPDATE_SUMMARY_B64: ${{ needs.check-updates.outputs.update-summary }}
@@ -312,7 +409,7 @@ jobs:
312409
--base main
313410
314411
- name: Add job summary
315-
if: steps.claude.outputs.success == 'true' && steps.validate.outputs.valid == 'true' && steps.changes.outputs.has-changes == 'true'
412+
if: steps.final.outputs.success == 'true' && steps.validate.outputs.valid == 'true' && steps.changes.outputs.has-changes == 'true'
316413
env:
317414
UPDATE_SUMMARY_B64: ${{ needs.check-updates.outputs.update-summary }}
318415
BRANCH_NAME: ${{ steps.branch.outputs.branch }}
@@ -341,7 +438,10 @@ jobs:
341438
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
342439
with:
343440
name: claude-output-${{ github.run_id }}
344-
path: claude-output.log
441+
path: |
442+
claude-output.log
443+
build-output.log
444+
test-output.log
345445
retention-days: 7
346446

347447
- uses: SocketDev/socket-registry/.github/actions/cleanup-git-signing@6096b06b1790f411714c89c40f72aade2eeaab7c # main

0 commit comments

Comments
 (0)