ci(release): push the version bump with a deploy key, and restrict who can release - #75
Merged
Merged
Conversation
…o can release
The 1.19 dispatch failed at "push code to main" with GH013: the ruleset "Main
edits only by PR" requires changes to arrive by pull request, and the workflow
pushes the version bump directly. Nothing was lost -- the reordering means the
build and the upload had not run, so PyPI never saw 1.19 and no tag or release
was created.
The ruleset already lists DeployKey as a bypass actor, so checking out over SSH
with a write deploy key is enough; the ruleset itself needs no change. The key
lives as an environment secret of build_and_publish, and only jobs declaring that
environment can read it, so the bypass is confined to this workflow. Adding
github-actions[bot] to the bypass list would have been simpler and much broader:
every workflow in the repository with contents: write could then push to main
unreviewed.
Note this is a long-lived credential and a write deploy key may push to any
branch here. What is scoped is who can read it, not what it can do.
Dispatch is also restricted to the maintainer. Any collaborator with write access
can start a workflow_dispatch, and this one publishes to PyPI, where a version
number cannot be reused once taken. The check fails rather than skipping the job:
a dispatch that quietly does nothing looks too much like one that worked.
Requires, before the next dispatch:
- a write deploy key registered on the repository
- its private half stored as RELEASE_DEPLOY_KEY in the build_and_publish
environment
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes the failed 1.19 dispatch (run 30177587416).
What happened
push code to mainwas rejected withGH013: the ruleset Main edits only by PR requires changes to arrive via pull request, and the workflow pushes the version bump directly.Nothing was lost. Because the release steps were reordered in #74, the failure landed before anything irreversible: PyPI never saw 1.19 (the version is still free) and no tag or release was created. Under the old ordering this would have left a
v1.19tag advertising a version that does not exist on PyPI.The fix
The ruleset already lists
DeployKeyas a bypass actor, so it needs no change:Checking out over SSH with a write deploy key is therefore sufficient.
actions/checkoutsupports this directly, so the existinggit pushstep is unchanged.Why a deploy key rather than
github-actions[bot]Ruleset bypasses are per actor, not per workflow. Adding
github-actions[bot]would let every workflow in the repo withcontents: writepush to main unreviewed. The deploy key's private half is an environment secret ofbuild_and_publish, and only jobs declaring that environment can read it — so the bypass is confined to this one workflow.github-actions[bot]bypassbuild_and_publishHonest caveat: this is a long-lived credential, and a write deploy key may push to any branch in this repo. What is scoped is who can read it, not what it can do.
Restricting dispatch
Any collaborator with write access can start a
workflow_dispatch, and this one publishes to PyPI where a version number cannot be reused once taken. The run now fails unless dispatched byVonAlphaBisZulu. It fails rather than skips — a dispatch that quietly does nothing looks too much like one that worked.Required before the next dispatch
RELEASE_DEPLOY_KEYin thebuild_and_publishenvironment.🤖 Generated with Claude Code