fix(ci): require the released commit to be on main; surface API errors - #44
Conversation
Dropping the `creation` rule from release-tags reopened, through tags, the hole the ref guard closed for branches. The guard allowed dispatch from refs/tags/$TAG, justified by tag creation being restricted to the maintainers team. That restriction is gone — it had to be, since GitHub Actions is a first-party integration and cannot be named as a ruleset bypass actor at all, so the workflow could never create a tag while `creation` was enforced. With creation unrestricted, anyone with write access could tag an unreviewed commit as v9.9.9, stamp it so VERSION matches, dispatch from that tag, and publish a Release from code nobody reviewed. So the guard now checks the commit rather than the ref: GITHUB_SHA must be an ancestor of origin/main. Review is what makes a commit releasable; the ref used to reach it is incidental. Exercised against real refs — origin/main and v0.4.0 allow, a commit off main blocks. Also stop discarding the API error body on tag creation. `>/dev/null` threw away "Cannot create ref due to creations being restricted", leaving only "Reference update failed (HTTP 422)". Recovering a message the call had already been handed cost a round-trip through the rule-suites API. And corrected the comments in release.yml and AGENTS.md, which still claimed the ruleset restricts tag creation. A comment that misstates a security control is worse than none. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
get-resq-software | d3b1b41 | Aug 11 2026, 06:14 AM |
📝 WalkthroughWalkthroughThe release workflow now validates that ChangesRelease controls
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant GitHubActions as GitHub Actions release workflow
participant Main as origin/main
participant TagAPI as GitHub tag API
GitHubActions->>Main: Fetch origin/main
GitHubActions->>Main: Check GITHUB_SHA ancestry
GitHubActions->>TagAPI: Create release tag
TagAPI-->>GitHubActions: Return success or detailed error
Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
.github/workflows/release.yml (1)
128-159: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy liftBind tag dispatch to the intended release commit.
The ancestry check accepts any commit reachable from
origin/main. It does not prove that the tag was created by an earlier release run or thatGITHUB_SHAintroducedVERSION.If a release fails before tag creation, a later
maincommit can retain the sameVERSION. A caller can createv$VERSIONat that later commit and dispatch from the tag. The checks pass, and Lines 290-327 create a new release. This can publish different artifacts under the intended version and violates the recovery-only rule at Line 128.For tag dispatch, require durable workflow provenance or require the tag target to be the
VERSION-introducing commit. If this bootstrap behavior is intentional, update the comment to document it.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/release.yml around lines 128 - 159, Update the tag-dispatch validation around the main-ancestry check to bind the tag to the intended release commit, not merely any commit reachable from origin/main. Require durable provenance from an earlier release workflow or verify that GITHUB_SHA is the commit introducing the current VERSION, while preserving the existing recovery-only behavior; if intentional bootstrap behavior remains supported, document it explicitly in the surrounding comment.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In @.github/workflows/release.yml:
- Around line 128-159: Update the tag-dispatch validation around the
main-ancestry check to bind the tag to the intended release commit, not merely
any commit reachable from origin/main. Require durable provenance from an
earlier release workflow or verify that GITHUB_SHA is the commit introducing the
current VERSION, while preserving the existing recovery-only behavior; if
intentional bootstrap behavior remains supported, document it explicitly in the
surrounding comment.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 19e305ba-2f46-48ff-8f90-487645cbe5c8
📒 Files selected for processing (2)
.github/workflows/release.ymlAGENTS.md
Follow-up to the v0.4.0 release, which succeeded. Two of these are cleanup; the first is a hole I opened.
Dropping
creationreopened the branch hole, through tagsThe ref guard allowed dispatch from
refs/tags/$TAG, and I justified that with "tag creation is itself restricted by the release-tags ruleset, so the ref is already privileged."That restriction is gone — it had to be. GitHub Actions is a first-party integration, not an installable app, so it cannot be named as a ruleset bypass actor at all; the API rejects it. While
creationwas enforced the workflow could never create a tag.With creation unrestricted, anyone with write access could tag an unreviewed commit as
v9.9.9, stamp it soVERSIONmatches, dispatch from that tag, and publish a Release from code nobody reviewed.Fix: check the commit, not the ref.
GITHUB_SHAmust be an ancestor oforigin/main. Review is what makes a commit releasable; the ref used to reach it is incidental.Exercised against real refs:
Stop discarding the API error
>/dev/nullon the tag-creation call threw away GitHub's explanation — "Cannot create ref due to creations being restricted" — leaving onlyReference update failed (HTTP 422). Recovering a message the call had already been handed cost a round-trip through the rule-suites API.Stale comments corrected
release.ymlandAGENTS.mdboth still claimed the ruleset restricts tag creation to the team. It doesn't. A comment that misstates a security control is worse than no comment, since it invites exactly the reasoning I made.Both now record why
creationwas dropped and whyupdate/deletionare the ones that matter: pins resolve a tag to a commit, so a moved or deleted tag silently repoints a published version, whereas an extra tag publishes nothing on its own.🤖 Generated with Claude Code
Summary by CodeRabbit
Bug Fixes
Documentation