Skip to content

Commit a7dcfc3

Browse files
committed
Align PyPI release flow with trusted publishing
1 parent 8d7619b commit a7dcfc3

4 files changed

Lines changed: 87 additions & 45 deletions

File tree

.github/workflows/release.yml

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ on:
66

77
permissions:
88
contents: read
9+
id-token: write
910

1011
jobs:
1112
build:
@@ -70,11 +71,6 @@ jobs:
7071
name: Publish to PyPI
7172
runs-on: ubuntu-latest
7273
needs: build
73-
environment:
74-
name: pypi
75-
url: https://pypi.org/project/wagtail-honeypot/
76-
permissions:
77-
id-token: write
7874

7975
steps:
8076
- name: Download built distributions

CHANGELOG

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ All notable changes to this project will be documented in this file.
1414
- Update contributor and agent documentation for the new development workflow
1515
- Update the honeypot field documentation for the `aria-hidden="true"` accessibility attribute
1616
- Sync the Ruff pre-commit hook version with the locked Ruff release and correct the developer doc Wagtail baseline
17-
- Publish PyPI releases from GitHub Actions with trusted publishing and a protected `pypi` environment
17+
- Publish PyPI releases from GitHub Actions with PyPI Trusted Publishing
1818

1919
## [1.2.1] - 2026-02-05
2020

docs/contributing/releasing.md

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# Releasing wagtail-honeypot
2+
3+
This is the maintainer runbook for publishing package releases to PyPI via GitHub Actions.
4+
5+
## Release Workflow
6+
7+
- Workflow file: `.github/workflows/release.yml`
8+
- Trigger: GitHub Release event `published`
9+
- Authentication: PyPI Trusted Publisher (OIDC), no API token secret
10+
11+
The release workflow:
12+
13+
1. validates GitHub release tag (`vX.Y.Z` or pre-release like `vX.Y.Zrc1`) matches `project.version` in `pyproject.toml`
14+
2. validates the tagged commit is contained in `origin/main`
15+
3. builds `sdist` + `wheel` with `uv build`
16+
4. runs `twine check` on built artifacts
17+
5. publishes artifacts to PyPI using `pypa/gh-action-pypi-publish`
18+
19+
## One-Time Setup (PyPI Trusted Publisher)
20+
21+
In the PyPI project settings for `wagtail-honeypot`, add a Trusted Publisher with:
22+
23+
- Owner or organization: `nm-packages`
24+
- Repository: `wagtail-honeypot`
25+
- Workflow: `release.yml`
26+
- Environment: unset (unless intentionally adding GitHub Environments later)
27+
28+
The GitHub repository and workflow identity must match exactly, or publish will fail.
29+
30+
## Maintainer Release Steps
31+
32+
1. Keep `CHANGELOG` updated under `## Unreleased` for every merged PR landing on `main`.
33+
2. Update `version` in `pyproject.toml` to the intended release version.
34+
3. Convert the current `## Unreleased` notes in `CHANGELOG` into the new release entry, then leave a fresh `## Unreleased` placeholder for future work.
35+
4. Review user-facing docs and examples that intentionally describe the current release, and either:
36+
- update them to the new version where exact release numbers are still useful, or
37+
- remove brittle hardcoded release numbers when the docs work just as well without them.
38+
5. Merge the release-prep changes to `main`.
39+
6. Ensure normal CI on `main` is green (`Tests` workflow).
40+
7. Create a GitHub Release with a tag that matches the package version with `v` prefix.
41+
8. Use the `CHANGELOG` entry as the GitHub Release body.
42+
9. Publish the GitHub Release.
43+
10. Confirm `.github/workflows/release.yml` succeeds and the version appears on PyPI.
44+
45+
For local sandbox/test command workflows before a release, use:
46+
47+
- [developer.md](../developer.md) for canonical developer workflow and quickstart commands
48+
- [AGENTS.md](https://github.com/nm-packages/wagtail-honeypot/blob/release/AGENTS.md) for canonical contributor command/reference guidance
49+
50+
## Changelog Maintenance
51+
52+
- Add or update a `CHANGELOG` entry under `## Unreleased` in every PR.
53+
- During release prep, move or rewrite the `Unreleased` notes into the new versioned release section.
54+
- After release prep, keep an empty `## Unreleased` section in place for subsequent work.
55+
- During release prep, review any docs/examples that intentionally point at the current package release and avoid leaving stale version numbers in user-facing pages.
56+
57+
Examples:
58+
59+
- `pyproject.toml` version `1.3.0` => GitHub tag `v1.3.0`, release title `1.3.0` (or `Release 1.3.0`)
60+
- `pyproject.toml` version `1.4.0rc1` => GitHub tag `v1.4.0rc1`, release title `1.4.0rc1` (or `Release 1.4.0rc1`)
61+
62+
## Local Preflight (Optional but Recommended)
63+
64+
Run these before creating the GitHub Release:
65+
66+
```bash
67+
uv build --sdist --wheel --out-dir /tmp/wagtail-honeypot-dist-check
68+
uvx twine check /tmp/wagtail-honeypot-dist-check/*
69+
```
70+
71+
## Failure Modes and Troubleshooting
72+
73+
- Tag/version mismatch:
74+
- Symptom: workflow fails in "Validate release tag matches package version"
75+
- Fix: align GitHub tag with `pyproject.toml` version and republish release
76+
- Tag commit not on main:
77+
- Symptom: workflow fails in "Validate release commit is on main"
78+
- Fix: retag a commit that is on `main`
79+
- Trusted Publisher identity mismatch:
80+
- Symptom: PyPI publish step reports authorization/trust failure
81+
- Fix: verify owner/repo/workflow values in PyPI Trusted Publisher settings
82+
- Duplicate version:
83+
- Symptom: publish step fails because version already exists on PyPI
84+
- Fix: bump `pyproject.toml` version and publish a new tag/release

docs/developer.md

Lines changed: 1 addition & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -70,45 +70,7 @@ make lint
7070
make format
7171
```
7272

73-
## Release process
74-
75-
PyPI releases are published from GitHub Actions after a GitHub Release is published.
76-
77-
Prepare the release from `main`, not `release`:
78-
79-
```bash
80-
git switch main
81-
git pull origin main
82-
```
83-
84-
Before creating the release:
85-
86-
- Update `project.version` in `pyproject.toml`
87-
- Update `CHANGELOG` for the release
88-
- Ensure the commit you intend to release is on `main`
89-
90-
Create and push the release tag using the `vX.Y.Z` format:
91-
92-
```bash
93-
git tag vX.Y.Z
94-
git push origin vX.Y.Z
95-
```
96-
97-
Then publish the matching GitHub Release for that tag. The `Release` workflow will:
98-
99-
- Verify the GitHub Release tag exactly matches `v{project.version}`
100-
- Verify the tagged commit is contained in `origin/main`
101-
- Build the sdist and wheel
102-
- Run `twine check`
103-
- Wait for approval on the GitHub `pypi` environment before uploading to PyPI
104-
105-
Repository setup required for trusted publishing:
106-
107-
- Add a GitHub environment named `pypi`
108-
- Protect that environment with the required approval rules for your release process
109-
- Register the PyPI trusted publisher for repository `nm-packages/wagtail-honeypot`, workflow `.github/workflows/release.yml`, and environment `pypi`
110-
111-
After approving the `pypi` environment job, confirm both the source distribution and wheel appear on PyPI.
73+
See [Releasing wagtail-honeypot](contributing/releasing.md) for the maintainer release runbook.
11274

11375
## Dependency management
11476

0 commit comments

Comments
 (0)