Skip to content

fix(claude-review): skip cleanly when a commit has no unique open PR (stop red 'main' review runs)#90

Merged
crowecawcaw merged 1 commit into
aws-deadline:mainlinefrom
crowecawcaw:claude-review-fail-clean-on-no-pr
Jul 8, 2026
Merged

fix(claude-review): skip cleanly when a commit has no unique open PR (stop red 'main' review runs)#90
crowecawcaw merged 1 commit into
aws-deadline:mainlinefrom
crowecawcaw:claude-review-fail-clean-on-no-pr

Conversation

@crowecawcaw

Copy link
Copy Markdown

Summary

The Claude PR-review reviewer is not running on post-merge/main changes — but its Actions runs look like it is, and that is the problem this fixes.

What's actually happening

  • Reviews are only ever started by the collect workflow, which triggers on pull_request: [opened, synchronize]. There is no push trigger, so a merge to main cannot start a review.
  • The review stage (Stage 2) is a workflow_run workflow. GitHub always runs a workflow_run file from the repo's default branch and labels the run with that branch — so every review run shows up as Claude PR Review · main, regardless of which PR it reviewed. That's cosmetic, not behavioral.
  • The PR-resolution guard requires the trusted head SHA to map to exactly one open PR. When it can't (the PR was merged/closed by the time the workflow_run fired — common with dependabot rebasing several branches onto a freshly-merged tip, or force-push/close races), it exited 1.

The result: a stream of red ❌ "Claude PR Review · main" runs that read as broken post-merge reviews, even though the guard was correctly refusing to review anything and posting nothing. (Concrete example: openjd-rs run #28974565722 failed at "Resolve and validate PR from trusted head SHA" with found 0; every downstream step — checkout, Bedrock auth, agent — was skipped.)

The change

Downgrade only the "0 or >1 open PRs" case — an absence of work, not a forged input — to a clean skip:

  • set resolved=false, emit a ::notice::, and exit 0;
  • gate every downstream step (Collect prior review state, PR-head checkout, symlink strip, base fetch, tooling checkout, Bedrock token install, OIDC creds, token mint, and the agent) on steps.meta.outputs.resolved == 'true'.

The run now finishes green/neutral with nothing posted, instead of red.

Security property unchanged

Nothing is reviewed or posted unless a unique open PR is resolved from the trusted workflow_run payload. This is not a relaxation of the guard:

  • a malformed head_sha, or a resolved PR whose pr_number/base_sha fail validation, is a real integrity problem and still hard-fails (exit 1);
  • only the benign "no unique open PR to review" case becomes a clean skip.

Testing

  • All four branches of the resolution logic simulated locally: count=0 → skip, count=2 → skip, count=1 valid → resolved=true, count=1 with bad base SHA → hard-fail. ✅
  • YAML validated; all 8 downstream steps gated, the resolve step itself ungated. ✅

Note

Follow-up (caller-side, in each consuming repo): the collect trigger churn from dependabot rebases is what generates these no-op review runs in the first place. Narrowing that is a separate change in the caller workflows, not this reusable one.

🤖 Drafted with Claude Code

The review stage (Stage 2) is a workflow_run workflow: GitHub runs it
from the default branch and labels every run with that branch. When the
PR-resolution guard could not map the trusted head SHA to exactly one
open PR, it exited 1 -- painting the Actions tab with red "Claude PR
Review" runs labelled with the default branch, which read as broken
post-merge reviews even though the guard was correctly refusing to
review anything.

This is a common, benign case: a workflow_run fires from a collect run
whose PR was merged/closed by the time this stage resolves it (e.g.
dependabot rebasing several branches onto a freshly-merged tip), or a
force-push/close race.

Downgrade only the "0 or >1 open PRs" case -- an absence of work, not a
forged input -- to a clean skip: set resolved=false, exit 0, and gate
every downstream step (checkout, tooling, Bedrock auth, agent) on
resolved=true. The security property is unchanged: nothing is reviewed
or posted unless a unique open PR is resolved. Malformed head_sha or a
resolved PR failing pr_number/base_sha validation still hard-fails.

Signed-off-by: Stephen Crowe <6042774+crowecawcaw@users.noreply.github.com>
@crowecawcaw
crowecawcaw force-pushed the claude-review-fail-clean-on-no-pr branch from 9a3237a to 039dee9 Compare July 8, 2026 21:51
@crowecawcaw
crowecawcaw marked this pull request as ready for review July 8, 2026 22:36
@crowecawcaw
crowecawcaw requested a review from a team as a code owner July 8, 2026 22:36
@crowecawcaw
crowecawcaw merged commit 234cdac into aws-deadline:mainline Jul 8, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants