Skip to content

ci(release): gate release-pr to the main ref (RIG-3813) - #1263

Open
rigel-mintaka wants to merge 1 commit into
mainfrom
compass-native/rig-3813-release-pr-ref-guard
Open

rigel-mintaka wants to merge 1 commit into
mainfrom
compass-native/rig-3813-release-pr-ref-guard

Conversation

@rigel-mintaka

@rigel-mintaka rigel-mintaka commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

Closes RIG-3813.

release.yml accepts workflow_dispatch from any ref, and release-pr was the one sensitive job
in the file with no if: guard. It holds contents: write + pull-requests: write, mints the
installation-scoped release-please App token, and is the sole vX.Y.Z tag minter. Because
release-please defaults target-branch to the repository default branch, the dispatched ref did not
scope what the job acted on: a dispatch from a feature branch would cut a real release from main.

What changed

Two lines of real change in .github/workflows/release.yml:

  1. release-pr gets if: github.ref == 'refs/heads/main', the same guard publish-image,
    release-assets-macos, release-assets, release-image and publish-runner-image already
    carry.
  2. The release-please step pins target-branch: main rather than relying on the action's
    default-branch default, so the release branch is stated rather than inferred.

Why it matters now

The same workflow holds agent-image-arm64-spike, which is if: github.event_name == 'workflow_dispatch' by design. Because release-pr was ungated, any dispatch of this workflow
started release-pr alongside the spike, which is what made that spike job unsafe to dispatch from
a feature branch. With this guard, a non-main dispatch runs the spike and skips release-pr.

Verification

  • Every job's if: enumerated by parsing job line boundaries: all seven jobs now carry a guard, and
    release-pr's new one appears exactly once, inside its own block.
  • target-branch confirmed to be a real input of the action at its pinned SHA
    (5c625bfb5d1ff62eadeeb3772007f7f66fdcf071), by decoding that ref's action.yml.
  • actionlint from the dev shell: 6 findings (3 shellcheck, 3 syntax-check), message sets identical
    between base main and this tree after stripping line and column. The syntax-check findings are
    the unknown queue: max concurrency key at three concurrency blocks and pre-date this change.
    Zero new findings.
  • No behaviour change on the push to main path, which is the only path that previously reached
    this job legitimately.

Open Questions

None load-bearing. One judgment call recorded for the reviewer, stated precisely: target-branch: main is not what closes the dispatch hazard. The ref guard does, and with the guard present no
non-main ref reaches this job at all, so the pin contributes nothing to that attack path.

It is kept because it closes a different, real hazard. Without it, release-please reads the
repository's mutable default_branch over the API on every run, so a branch rename silently
repoints the release lane. It also fixes the standing Release PR's head branch name, which
release-please derives as release-please--branches--<target-branch>: main is the value that
preserves the identity of the existing Release PR, so any other pin would orphan it and open a
second one.

@trunk-io

trunk-io Bot commented Sep 17, 2026

Copy link
Copy Markdown

Merging to main in this repository is managed by Trunk.

  • To merge this pull request, check the box to the left or comment /trunk merge below.

After your PR is submitted to the merge queue, this comment will be automatically updated with its status. If the PR fails, failure details will also be posted here

@linear-code

linear-code Bot commented Sep 17, 2026

Copy link
Copy Markdown

RIG-3813

@github-actions

github-actions Bot commented Sep 17, 2026

Copy link
Copy Markdown

Compass engineering docs preview: https://compass-native-rig-3813-rele.compass-eng-docs.pages.dev

Deployed from compass-native/rig-3813-release-pr-ref-guard at 9918238.

`release.yml` accepts `workflow_dispatch` from any ref, but `release-pr` was
the one sensitive job in the file with no `if:` guard. It holds
`contents: write` + `pull-requests: write`, mints the release-please App token,
and is the sole `vX.Y.Z` tag minter. release-please also defaults its
`target-branch` to the repository default branch, so the dispatched ref did not
scope what the job acted on: a dispatch from a feature branch would cut a real
release from `main`.

Gate it the way `publish-image`, `release-assets`, `release-image` and
`publish-runner-image` already are, and pin `target-branch: main` explicitly so
the release branch is stated rather than inferred. Every job in the file now
carries an explicit guard.

This also makes the dispatch-only `agent-image-arm64-spike` job safe to run
from a non-main ref, which it was not before: the two jobs share the workflow,
so any dispatch previously started `release-pr` alongside the spike.

Scope: this governs future dispatches. Re-running a historical run replays that
run's own workflow definition, so the guard cannot retroactively cover a
pre-existing run.

Co-authored-by: Matt Wilkinson <matt@rigel.build>
@rigel-mintaka
rigel-mintaka force-pushed the compass-native/rig-3813-release-pr-ref-guard branch from 8271144 to 9918238 Compare September 17, 2026 02:27
@rigel-mintaka
rigel-mintaka added this pull request to stack #1272 September 17, 2026 02:32
@rigel-mintaka
rigel-mintaka marked this pull request as ready for review September 17, 2026 02:56
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.

1 participant