From 1730c78a0db8cc41730ae364d2b7a364ae55f2f8 Mon Sep 17 00:00:00 2001 From: Claude Code Bot Date: Sat, 18 Apr 2026 14:58:00 -0700 Subject: [PATCH] fix: short-circuit review when PR modifies .github/workflows/*.yml (v2.0.1) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The anthropics/claude-code-action refuses to run on PRs that modify any workflow file in the caller repo — this is its by-design security feature (a PR can't modify the reviewer to hide its own issues). The action currently exits with a non-zero status after a ~30s workflow- validation retry loop, which our Check review verdict step interprets as 'exceeded turn limit' and exits 1. Consumer repos hit this on every caller-workflow edit: Dependabot auto-bumps of the @v2 pin, manual version bumps, added new workflows, etc. Observed on PR #1176 (kebab-tax), #70 (dotfiles), #40 (mac-dev-server- setup) during the v1→v2 rollout. Each required a manual bypass marker to merge. Dependabot-driven rollouts would need the bypass on EVERY auto-generated PR, which defeats the point of Dependabot. Detect the condition in the existing Check for doc-only diff step (already enumerates the PR's file list). If ANY .github/workflows/*.yml file is in the UNION of previous_filename and filename, short-circuit with VERDICT: SKIPPED (workflow-self-modification). The real v2 review then runs on the next non-workflow PR. This is a correctness fix, not a security regression: - The claude-code-action already cannot review such PRs (that's the security feature we're accommodating, not defeating). - Humans remain responsible for reviewing workflow changes manually. That was already true under v2.0.0. - A malicious workflow change would skip the review in both v2.0.0 and v2.0.1 — the failure mode is unchanged, only the verdict cleanliness differs. Workflow-self-modification detection runs BEFORE the doc-only check so that a mixed PR (doc + workflow) hits the more-specific workflow skip rather than falling through to non-doc review and then failing. Ship as v2.0.1 (PATCH — narrow bug fix). Consumer migration: none for @v2 floating-tag pinners; explicit-semver pinners who want the fix should bump to @v2.0.1. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/claude-blocking-review.yml | 22 ++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/.github/workflows/claude-blocking-review.yml b/.github/workflows/claude-blocking-review.yml index c1af300..1866d4c 100644 --- a/.github/workflows/claude-blocking-review.yml +++ b/.github/workflows/claude-blocking-review.yml @@ -154,6 +154,28 @@ jobs: exit 0 fi + # PRIORITY SKIP — workflow-self-modification. + # When a PR modifies ANY .github/workflows/*.yml file, the + # anthropics/claude-code-action refuses to run by design (its + # security feature: a PR that modifies the reviewer cannot have the + # reviewer run against itself). Without a skip here, the step fails + # with a misleading "exceeded turn limit" error after 30s. This + # case hits EVERY Dependabot-generated PR that bumps the pin, plus + # any manual caller-workflow edit. Short-circuit cleanly; a real + # review runs on the next non-workflow PR after merge. + while IFS= read -r f; do + [ -z "$f" ] && continue + case "$f" in + .github/workflows/*.yml|.github/workflows/*.yaml) + echo "::notice::PR modifies .github/workflows/ ($f) — claude-code-action refuses to run by design. Skipping; real review will run on the next non-workflow PR after merge." + echo "skip=true" >> "$GITHUB_OUTPUT" + echo "## Claude Code Review" >> "$GITHUB_STEP_SUMMARY" + echo "**Verdict:** SKIPPED (workflow-self-modification)" >> "$GITHUB_STEP_SUMMARY" + exit 0 + ;; + esac + done <<< "$FILES" + ALL_DOCS=true NON_DOC="" while IFS= read -r f; do