Skip to content

chore: move releases onto release-plz like the sibling crates - #11

Merged
P4suta merged 1 commit into
mainfrom
chore/release-plz
Aug 4, 2026
Merged

chore: move releases onto release-plz like the sibling crates#11
P4suta merged 1 commit into
mainfrom
chore/release-plz

Conversation

@P4suta

@P4suta P4suta commented Aug 4, 2026

Copy link
Copy Markdown
Owner

The last repository still releasing by hand. windows-spawn had no release-plz at all: you tagged a commit, dispatched Release with the tag and a publish checkbox, and approved. That worked — 0.1.0 shipped through it — but the version bump, the changelog entry, and the tag were three manual steps nothing checked against each other.

What changes

release-plz.yml runs on every push to main and publishes only when the manifest version is ahead of the registry, so an unrelated merge cannot release. Merging a reviewed release pull request is what authorises a publish.

Two deviations from the upstream template stay, both documented upstream:

  • GitHub App token. The default GITHUB_TOKEN cannot trigger other workflows, so CI would never run on a release pull request.
  • Windows runners. cargo publish verifies the tarball by building it, and this crate does not build on Linux — its windows-sys dependency sits behind cfg(windows) while the modules using it do not. conpty-oxide failed a release on exactly this after adopting the template's ubuntu-latest.

release.yml becomes release-finalize.yml, called from the same run with needs: release. git_release_enable = false leaves the GitHub release to it, so the existing draft-release xtask still applies and the crate, both SBOMs, and checksums are attached before anything is published. It cannot be a release-event handler — GitHub fires no release events for drafts.

One thing the manual flow could not do

The finalizer previously attested an archive it had just built, with nothing establishing that archive was what crates.io served. Because release-plz now publishes first, the finalizer can compare: it requires the rebuilt archive's SHA-256 to equal the published crate before attesting. The provenance is now bound to the artifact consumers actually download.

crates-io-auth-mode is kept and reused rather than reimplemented in YAML — it is already tested, and duplicating the check would have left the xtask dead.

Configuration this needs

Before merging, the release environment needs:

  • RELEASE_PLZ_APP_CLIENT_ID (variable) and RELEASE_PLZ_APP_PRIVATE_KEY (secret) for the installed p4suta-release-plz App, matching the sibling repositories. The App must be installed on this repository.
  • The existing CRATES_IO_BOOTSTRAP_TOKEN can stay until a trusted publisher is registered for .github/workflows/release-plz.yml + the release environment, then be deleted.

Note the environment currently has a required reviewer. With on: push, that makes every merge to main wait for a deployment approval, not just releases. The sibling repositories carry a branch policy without a reviewer gate and rely on the release pull request as the approval point. Removing the reviewer rule here would match them; keeping it means an approval click per merge.

Verification

just ci passes end to end: fmt, clippy, tests, doc, MSRV 1.75, three windows targets plus linux, cargo-deny, REUSE, typos, public-api snapshot, and cargo package + verify. actionlint passes on both new workflows.

🤖 Generated with Claude Code

This was the last repository still driving releases by hand: tag the commit,
dispatch Release with the tag and a publish checkbox, approve. It worked, but
it left the version bump, the changelog entry, and the tag as three manual
steps that nothing checked against each other, and it was the only one of the
four crates not on the pattern.

release-plz.yml now runs on every push to main and publishes only when the
manifest version is ahead of the registry, so merging a reviewed release pull
request is what authorises a publish. Two deviations from the upstream template
stay, both documented upstream: a GitHub App token, because the default
GITHUB_TOKEN cannot trigger the CI a release pull request needs, and windows
runners, because cargo publish verifies the tarball by building it and this
crate does not build on Linux.

release.yml becomes release-finalize.yml, called from the same run.
git_release_enable = false leaves the GitHub release to it, so the existing
draft-release xtask still applies the crate, both SBOMs, and checksums before
anything is published. It cannot be a release-event handler: GitHub fires no
release events for drafts.

The finalizer gains a check the manual flow could not make. It previously
attested an archive it had just built, with no evidence that archive was what
the registry served. It now requires the rebuilt archive's SHA-256 to equal the
published crate before attesting, so the provenance is bound to the artifact
consumers actually download.

crates-io-auth-mode is kept and reused rather than reimplemented in the
workflow: it is already tested, and duplicating the check in YAML would have
left the xtask dead.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@P4suta
P4suta merged commit df43a90 into main Aug 4, 2026
14 checks passed
@P4suta
P4suta deleted the chore/release-plz branch August 4, 2026 10:49
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