Skip to content

ci: release only from a signed tag and an approved deployment - #27

Merged
P4suta merged 3 commits into
mainfrom
ci/release-on-approval
Sep 25, 2026
Merged

P4suta merged 3 commits into
mainfrom
ci/release-on-approval

Conversation

@P4suta

@P4suta P4suta commented Sep 25, 2026 •

Copy link
Copy Markdown
Owner

Releases now follow the shape OComment uses: a machine proposes, and the maintainer signs and approves.

  • release-plz.yml only keeps a draft release pull request, bumping the version and updating CHANGELOG.md; it never tags and never publishes.
  • The maintainer's signed vX.Y.Z tag starts the new release.yml:
    1. candidate requires an annotated tag GitHub verified as signed, verifies that it names a commit on main whose Cargo version it matches, builds the reproducible release candidate, and attests SLSA v1 provenance and the CycloneDX SBOM.
    2. publish waits in the crates-io environment for the maintainer's approval, and takes a crates.io token through trusted publishing only.
      It publishes only if cargo package makes the attested archive, and then requires crates.io to serve that archive.
    3. github-release attaches the crate, SBOMs, and checksums to a draft release and publishes it, as release-finalize.yml did.
  • cargo xtask crates-io-auth-mode and the bootstrap-token fallback go: 0.1.0 is out, so trusted publishing is the only credential.
  • docs/releasing.md describes the new flow.

Settings this needs

Already done:

  • the crates-io environment: the maintainer is its required reviewer, and it deploys from v* tags only;
  • the release environment deploys from main only;
  • no administrator may bypass crates-io.

Left for the maintainer:

  • the trusted publisher on crates.io for P4suta/windows-spawn, workflow release.yml, environment crates-io, with trusted publishing required;
  • revoking the bootstrap token, and deleting the CRATES_IO_BOOTSTRAP_TOKEN secret;
  • two v* tag rulesets, because a bypass actor skips every rule of its ruleset: one where only the maintainer may bypass creation, and one with update, deletion and required_signatures that nobody bypasses.

Verification

  • actionlint and zizmor report nothing on either workflow.
  • cargo xtask gates, the xtask tests, typos and reuse lint pass.

release-plz now only keeps a draft release pull request; it never tags and never publishes.
The maintainer's signed `vX.Y.Z` tag starts release.yml, which verifies that the tag names a commit on main whose Cargo version it matches, and attests the release candidate.
Publishing waits in the `crates-io` environment for the maintainer's approval, then takes a crates.io token through trusted publishing alone.
It publishes only if `cargo package` makes the attested archive, and then requires crates.io to serve it.
The GitHub release follows, as release-finalize.yml did.

0.1.0 went out with a bootstrap token, so `crates-io-auth-mode` and its fallback go.
The `release` environment now serves only the release pull request, from main.
@coderabbitai

coderabbitai Bot commented Sep 25, 2026 •

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: 6381960a-0f06-4f92-8505-7746a1063495


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

release.yml runs as the tagged commit has it, so this check is defence in depth: the creation rule and the approval remain the gates, and the approver now checks the run before approving.
The tag protection is described as two rulesets, because a bypass actor skips every rule of its ruleset, signatures and the ban on moving tags included.
actions/attest moves to v4.2.2, which `v4` now names.
@P4suta
P4suta enabled auto-merge (squash) September 25, 2026 16:05
@P4suta
P4suta merged commit 2629552 into main Sep 25, 2026
15 checks passed
@P4suta
P4suta deleted the ci/release-on-approval branch September 25, 2026 18:22
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