ci(claude-review): shallow checkout + harden dispatch input + failure diagnostics#2393
Conversation
… diagnostics Cuts most of the cold-checkout time on this large repo by switching the review job from `fetch-depth: 0` to a depth-1 clone with on-demand deepening (both default branch and HEAD by SHA, since fetch-depth:1 leaves HEAD as a grafted root). The same pattern is applied in the prefetch step for the PR's actual baseRefName. Hardens workflow_dispatch: - New `Validate PR number` step rejects ^[1-9][0-9]*$ failures (any whitespace, leading zeros, non-digits) before the value reaches a refspec or API call. - The validated value is exported as a job output so `post` and `cleanup` consume the same value across job boundaries ($GITHUB_ENV is job-local). - Strict rejection also closes a concurrency-group race where whitespace variants of the same PR could land in different buckets. Adds an `if: failure()` diagnostic step that walks `steps.*.outcome`, identifies the earliest failed step, and writes a structured Step Summary with retry guidance per failure mode. A symmetric diagnostic in the cleanup job surfaces the "label is stuck" condition with the exact recovery command. Bumps actions/checkout, upload-artifact, and download-artifact to Node-24-compatible pinned SHAs (was Node 20). The sanitizer-tests workflow gains a sparse-checkout for .github/scripts, implicitly enabling partial-clone (--filter=blob:none). Docs (CLAUDE_AUTO_REVIEW.md) updated: §8 step table reflects the new validate / deepen / diagnose steps, and a new §8.2 subsection documents the failure-mode classification and the rationale for diagnostic-only (no programmatic retry). Co-authored-by: Cursor <cursoragent@cursor.com>
|
Per review on #2393: the rows duplicated implementation-level detail already in the YAML comments. Trimmed each to one short paragraph in line with the surrounding rows -- intent + cross-references, not regex syntax or invariants. No behavior change. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
Verdict: APPROVE -- submitted as COMMENT (automated reviews are advisory) · Findings: 0 (0 Critical, 0 Major, 0 Minor)
Scope
CI-only change to the claude-review pipeline. Three files:
.github/workflows/claude_auto_review.yml— depth-1 checkout + on-demand deepen of both default branch andHEADSHA; strict-regexpr-validatestep exported as job output;if: failure()diagnostic step in bothreviewandcleanupjobs; action SHAs bumped to v6/v7 (Node-24 compatible)..github/workflows/claude_auto_review_sanitizer_tests.yml— sparse-checkout.github/scripts(partial clone)..github/workflows/CLAUDE_AUTO_REVIEW.md— refreshed §8 step table; new §8.2 failure-classification subsection.
Findings
No blocking issues found.
Notes
- Step-id wiring in the diagnostic block all resolves:
pr-validate,checkout,deepen,perimeter-block,snapshot,overlay,app-token,prefetch,claude-code,materialize,sanitizeeach have matchingid:declarations. - The doc cross-reference
[§8.2](#82-failure-handling)targets the pre-existing### 8.2 Failure handlingheading; correct anchor. concurrency.groupdeliberately stays on rawinputs.pr_number(Actions expressions have no trim); the strict^[1-9][0-9]*$regex inpr-validateis what guarantees only the canonical form ever produces a real run, so distinct buckets for the same PR cannot occur.cleanup'sPR_NUMBER: ${{ needs.review.outputs.pr_number || env.PR_NUMBER }}fallback is safe: the cleanup job'sif:restricts it to thepull_requestlabel path, whereenv.PR_NUMBERis the typed event integer (never the unvalidated dispatch input).- The
deepenstep fetches both$DEFAULT_BRANCH(by name) and$HEAD_SHA(by SHA) becauseactions/checkoutwithfetch-depth: 1leaves HEAD as a grafted root with no local parents; deepening only the default branch would never un-shallow HEAD andmerge-basewould stay empty. The 50 + 10×500 = ~5050-commit cap then hard-fails rather than letting the perimeter gate fail-open on an empty three-dot diff. Correct, and the same pattern is reused (correctly) inprefetchfor the PR's actualbaseRefName. - Sanitizer-tests workflow's
sparse-checkout: .github/scriptscovers everything the suite touches (sanitize_claude_actions.sh,secret_patterns.sh,tests/test_sanitize.shand its fixtures all live under that path). Pre-mergesanitizer-fixture-suitecheck is green.
CI status
All four pre-merge checks pass (Python performance script tests, Python format and lint checks, sanitizer-fixture-suite, detect). No failed or cancelled checks.
Summary
fetch-depth: 0→ depth-1 + on-demand deepen of both default branch andHEADby SHA (avoids a full clone of a large repo). Same pattern applied in theprefetchstep againstbaseRefName.Validate PR numberstep rejects^[1-9][0-9]*$failures (any whitespace, leading zeros, non-digits) before the value reaches a refspec or API call. Validated value is exported as a job output sopostandcleanupsee the same value across job boundaries; strict rejection also closes aconcurrency.grouprace where whitespace variants of the same PR could land in different buckets.if: failure()step classifies the earliest failed step and writes retry guidance to the Step Summary. Symmetric diagnostic incleanupsurfaces the "label is stuck" condition with the exact recovery command..github/scripts(enables partial clone, no source tree).CLAUDE_AUTO_REVIEW.md): §8 step table refreshed; new §8.2 documents the failure-mode classification and the rationale for diagnostic-only (no programmatic retry).Test plan
claude-reviewonce merged to confirm the label path still works end-to-end.deepenandprefetchresolve merge-base on near- and far-base PR shapes; diagnostic classifies each of the 11 step-failure modes to the expected mode label.Made with Cursor