claude-code-review's workflow_dispatch re-review posts a successful require-review check tied to the wrong commit SHA - #286
Conversation
|
Working on this --- paws off until I'm done. (The Generated by Claude Code |
gh workflow run's default ref (the repo's default branch) means every workflow_dispatch re-review claude.yml/claude-review.yml triggers gets its check-runs attributed to main's tip, not the PR's actual head commit --- so a genuinely clean, current review can post while the PR's own required-status-check view stays red, because the passing check landed on the wrong SHA and never supersedes a stale cancelled run. Pass --ref explicitly at every gh workflow run call site, using the PR branch already resolved by the pr_checkout/issue_branch steps (or a fresh API lookup in the two comment-triggered dispatch jobs that never check out the repo). Addresses #285.
Codecov Report✅ All modified and coverable lines are covered by tests. 🚀 New features to boost your workflow:
|
|
@claude review |
|
👀 Picked up by workflow run #30109028583. Setup runs first; Claude itself responds after that. |
|
💰 Cost: $0.6025288 |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (2)
.github/workflows/claude.yml:928
- This step also runs under
always(), but relies onPR_BRANCHcoming fromsteps.pr_checkout.outputs.branch. If the checkout step failed earlier,PR_BRANCHwill be empty and this dispatch attempt will still run. Guard against an emptyPR_BRANCHbefore callinggh workflow runso the step degrades cleanly when checkout failed.
'[.[] | select((((.created_at // .submitted_at) // "") > $ts) and ((.body // "") | test("@claude review")) and ((.user.type // "") != "Bot"))] | length' ) || late=0
if [ "${late:-0}" -gt 0 ]; then
echo "Found $late late @claude review request(s) newer than $TRIGGER_TS; dispatching review."
# --ref: see the comment on the earlier dispatch step above (#285).
gh workflow run "$REVIEW_WF" --ref "$PR_BRANCH" -f pr_number="$PR_NUMBER" \
|| echo "::warning::Could not dispatch $REVIEW_WF for the late review request."
.github/workflows/claude.yml:959
- Because this step is
always()it may run even when the PR checkout failed; in that casePR_BRANCHis empty but the workflow still attempts a dispatch with--ref "$PR_BRANCH". Add a guard to skip the dispatch whenPR_BRANCHis empty so the review re-dispatch can’t run against an unintended ref.
PR_NUMBER="${{ github.event.pull_request.number || github.event.issue.number }}"
echo "before=$SHA_BEFORE after=$SHA_AFTER"
if [ -n "$SHA_AFTER" ] && [ "$SHA_AFTER" != "$SHA_BEFORE" ]; then
echo "Claude pushed new commits; re-requesting reviewer and dispatching code review."
if [ -n "$REVIEWER" ]; then
gh api -X POST "repos/${{ github.repository }}/pulls/$PR_NUMBER/requested_reviewers" -f "reviewers[]=$REVIEWER" \
|| echo "::warning::Could not re-request $REVIEWER as reviewer."
fi
# --ref: see the comment on the earlier dispatch step above (#285).
gh workflow run "$REVIEW_WF" --ref "$PR_BRANCH" -f pr_number="$PR_NUMBER" \
|| echo "::warning::Could not dispatch $REVIEW_WF."
Copilot review on #286: the three PR-context dispatch steps read PR_BRANCH from steps.pr_checkout.outputs.branch but run under always(), so a failed "Checkout PR branch" step leaves PR_BRANCH empty while the step still executes. Guard each dispatch so an empty PR_BRANCH skips with a warning instead of calling `gh workflow run --ref ""`.
…' into claude/issue-285-20260724-011755
Self-review finding: the new changelog.d fragment used a raw em-dash (U+2014), which this repo's ascii-punctuation-in-source convention bans in all tracked source files, .md included, regardless of CI coverage.
|
Self-review (the automated Findings:
Verified the Generated by Claude Code |
…' into claude/issue-285-20260724-011755
The @claude agent's own attempt at this fix (workflow run 30110560206) implemented the change but failed to push -- GitHub rejected a GitHub-App token update to .github/workflows/claude-review.yml without the workflows permission. Re-implementing and pushing from a session with adequate credentials, per the same recovery pattern used for #286. Addresses #289: .head.ref has no owner prefix, so for a fork-originated PR it names a branch that doesn't exist in this repo. gh workflow run --ref would fail to resolve it there, hard-failing claude-review.yml's /review dispatch job (no warning fallback on that call site) and degrading the other three claude.yml call sites to a lost dispatch. Each dispatch site now compares the PR's head repo against the base repo and omits --ref for a fork PR, falling back to the pre-#285 wrong-SHA-attribution behavior rather than failing the dispatch.
…edoing Learned on Morrison-Lab/gha#286, 2026-07-24: a webhook-delivered review reply claimed a fix was already pushed, in a session that hadn't made it. Verified real (a second live session, not injection) by cross-checking the PR's actual commit list before either trusting the claim or duplicating the work.
…290) * Start @claude work on #289 * fix: skip --ref for fork-originated PRs in review dispatch The @claude agent's own attempt at this fix (workflow run 30110560206) implemented the change but failed to push -- GitHub rejected a GitHub-App token update to .github/workflows/claude-review.yml without the workflows permission. Re-implementing and pushing from a session with adequate credentials, per the same recovery pattern used for #286. Addresses #289: .head.ref has no owner prefix, so for a fork-originated PR it names a branch that doesn't exist in this repo. gh workflow run --ref would fail to resolve it there, hard-failing claude-review.yml's /review dispatch job (no warning fallback on that call site) and degrading the other three claude.yml call sites to a lost dispatch. Each dispatch site now compares the PR's head repo against the base repo and omits --ref for a fork PR, falling back to the pre-#285 wrong-SHA-attribution behavior rather than failing the dispatch. --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com>
…edoing (#676) Learned on Morrison-Lab/gha#286, 2026-07-24: a webhook-delivered review reply claimed a fix was already pushed, in a session that hadn't made it. Verified real (a second live session, not injection) by cross-checking the PR's actual commit list before either trusting the claim or duplicating the work.
…cause (#294) * docs: note the in-workflow self-mod guard as a third self-verify-gap cause Complements #291's @v2-floating-tag explanation with the mechanism this session actually hit on #286: claude-code-review.yml's own 'Skip self-review when the PR edits this workflow' step, which skips every downstream step (not just runs a stale pre-fix version) when the PR touches the caller review workflow's own file. Both claude-review / require-review report success with no verdict ever posted -- easy to mistake for a real review unless the job's step list (not just its conclusion) is checked. * Fix overstated file list in self-mod-guard note Review finding on #294: the guard checks exactly one path (github.workflow_ref, the caller's own stub -- claude-review.yml in this repo's dogfooding setup), not all three files previously listed. claude.yml has no analogous self-mod check at all; examples/claude- code-review.yml never executes as a workflow here, so github.workflow_ref can't resolve to it either. Clarify scope and correct the trigger condition. --------- Co-authored-by: Claude <noreply@anthropic.com>
PR opened by
@claudeto address #285.Triggered by workflow run.
Addresses #285.