Repository navigation
fix(scorecard): fire the reusable's pull-request job on PRs - #108
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Advanced Run ID: 📒 Files selected for processing (1)
Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review. 📜 Recent review details⏰ Context from checks skipped due to timeout. (4)
📝 SummarySummary by CodeRabbit
WalkthroughThe Scorecard workflow now runs for pull requests targeting ChangesScorecard workflow execution
Priority: ➖ Normal Estimated code review effort: 1 (Trivial) | ~5 minutes Change: Bug fix Merge Risk: ⚪ Minimal · up to The workflow can upload Scorecard results for pull-request runs as intended. No actionable merge-blocking risk remains. 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. A rabbit checks the workflow trail Comment |
ochrance requires the `code_scanning` ruleset rule with Scorecard among its tools, but no pull_request event ever produced Scorecard SARIF, so the rule waited forever and every PR sat BLOCKED with all checks green. Two independent reasons the cure never fired, both fixed here: 1. `on:` had no `pull_request:`. The reusable in hyperpolymath/standards already contains a `pull-request:` job gated on `if: github.event_name == 'pull_request'`, but the caller never raised that event, so the job could not run. 2. The pin was @81dbf2dd (2026-07-21), which predates the `pull-request:` job entirely. That job entered the reusable at d200ddca on 2026-09-08. Pinned to da2c748a rather than to main. Measured: `standards` main tip is NOT usable by any caller. Dependabot's 2cea69eb (2026-09-12) bumped github/codeql-action cdf488f5 -> b96794f0 inside scorecard-reusable.yml without regenerating .github/workflows/actions.lock, so every caller pinning 2cea69eb or later dies before any job starts with "references actions not present in the lockfile". da2c748a (2026-09-10) is the newest commit that both carries the `pull-request:` job and whose lockfile is consistent with its own workflow. Workflow-level permissions are widened to exactly the superset the callee's jobs request (security-events: write, id-token: write); a called workflow can only narrow the caller's token, and read-all cannot cover a write scope. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HfgwLCdKNd5iZVo6VTiSim
1b07914 to
009692b
Compare
What was broken
scorecard.ymlcalledstandards/.github/workflows/scorecard-reusable.ymlonpushonly. The reusable'spull-request:job — which measures the repo-levelScorecard checks and merges them into the PR-tree SARIF — is gated on
github.event_name == 'pull_request', so it never fired. Thecode_scanningrule on
mainrequires three tools (CodeQL, Hypatia, Scorecard), and two ofthe three Scorecard categories can only come from that job. Result: every PR
waited forever on a check that could not be produced.
Two limbs, both in the caller:
pull_request:added toon:, so the reusable's PR job actually runs.permissions:raised to the superset the callee needs(
security-events: write,id-token: write). A called workflow can onlynarrow the caller's token, and
read-allcannot cover a write scope — sobefore this, the run was a
startup_failure.Why the pin is
da2c748aand notmainmainis unusable by every caller in the estate, and so are the threecommits before it. GitHub validates a called reusable against the callee
repository's own
.github/workflows/actions.lock, which a caller cannot see,fix or override. Dependabot's
2cea69ebbumpedgithub/codeql-actioninsidescorecard-reusable.ymlwithout regeneratingactions.lock, so every callernow dies with:
Capability is therefore not monotonic in time — newer is not safer:
pull-request:job81dbf2ddd200ddca8f2ee508da2c748a2cea69ebc78f9148c27611ff317101e0actionlintreturns rc=0 on both caller and callee at every pin — a linterstructurally cannot catch this class, because the defect is a cross-repo
relation, not a property of either file.
Measured result
Run
34924268842: success in 43s.Run Scorecard PRexecuted for 38s anduploaded SARIF carrying exactly three categories —
supply-chain/localsupply-chain/branch-protectionsupply-chain/online-scmThe
code_scanningrule's own merge-protection check (Scorecard, appgithub-advanced-security) reports success — "No new alerts in code changedby this pull request", alongside
HypatiaandCodeQL.⚠ The SARIF lands on
refs/pull/108/head, not/merge. The job checks outhead.shaand passes noref:toupload-sarif, so the ref is inferred fromthe checked-out tree; Hypatia and CodeQL land on
/merge. A probe querying onlyone ref reads a working cure as dead. The merge-protection check consumes the
head-ref analysis correctly.
Known gap, deliberately accepted
da2c748apredates theSelect SARIF to uploadandFail if reconciliation did not succeedsteps added atc27611ff. Here reconciliation was a no-op —actions-lock-audit.jsonis[]and the reconciled SARIF is byte-identical toits input (73778 B) — which on this pin passes silently rather than failing
loudly. Harmless in this run because the no-op preserved all three runs, but a
reconciler that dropped runs would ship fewer categories past the green
test -eq 3assertion (that assertion runs before reconciliation andasserts on a different file than the one uploaded). Those guards exist only
on lockfile-poisoned commits, so they are not available at any usable pin. The
durable cure belongs in
standards: a CI gate assertinguses ⊆ actions.lock,or adding the lockfile to Dependabot's update scope.
🤖 Generated with Claude Code
https://claude.ai/code/session_01HfgwLCdKNd5iZVo6VTiSim