Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@ name: Release
on:
release:
types: [published]
# A release event does not always dispatch a run, and a failed publish should
# not require recreating the GitHub Release. Both paths use the same guard.
workflow_dispatch:
inputs:
tag:
description: "Tag to publish, e.g. v1.2.0 (must match src/codesnake/_version.py)"
required: true
type: string

# Deny by default; each job grants only what it needs.
permissions: {}
Expand All @@ -15,6 +23,8 @@ jobs:
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
# Build the tag being released, never whatever the default branch is at.
ref: ${{ github.event.release.tag_name || inputs.tag }}
persist-credentials: false
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
Expand All @@ -27,7 +37,7 @@ jobs:

- name: Verify the built version matches the release tag
env:
TAG: ${{ github.event.release.tag_name }}
TAG: ${{ github.event.release.tag_name || inputs.tag }}
run: |
BUILT=$(python -c "import sys; sys.path.insert(0, 'src'); from codesnake._version import __version__; print(__version__)")
echo "tag=$TAG built=$BUILT"
Expand Down
10 changes: 10 additions & 0 deletions docs/RELEASING.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,16 @@ Consider claiming the name with a release to [TestPyPI](https://test.pypi.org) f
4. Publish a GitHub Release on that tag with notes. Publishing is what starts the workflow.
5. Approve the `pypi` deployment when GitHub asks.

If the release event does not start a run, or a publish failed and you want to retry
without recreating the Release, dispatch it manually with the same tag:

```bash
gh workflow run release.yml -f tag=v1.3.0
```

Both paths run the identical build, the identical tag/version guard, and the same
environment approval.

The build job refuses to publish when the release tag and `_version.py` disagree, so a `v1.3.0` tag cannot ship a `1.2.0` artifact.

## What protects the release path
Expand Down
Loading