Cut a release¶
The authoritative release checklist lives in RELEASE.md at the repository root. It is included below so the rendered docs always match the repository.
Checklist for cutting a plone.pgthumbor release.
All packaging is automated by
.github/workflows/release.yaml:
Every push to
main(after green CI) is published to test.pypi.org.A published GitHub Release is uploaded to pypi.org.
The package version itself is derived from the git tag via hatch-vcs
(see [tool.hatch.version] in pyproject.toml), so no version field
needs to be edited in pyproject.toml.
Steps¶
Make sure
mainis green and everything you want in the release is merged.Finalize
CHANGES.md. Replace the current## X.Y.Z (unreleased)header with the release version and today’s date, e.g.## 0.6.2 (2026-04-10).Bump
docs/sources/conf.py. Update therelease = "..."line to the new version so the rendered Sphinx site shows the right version in the header.Commit and push.
git add CHANGES.md docs/sources/conf.py git commit -m "Release X.Y.Z" git push
Wait for CI to go green on
main.Tag the release.
git tag -a vX.Y.Z -m "Release X.Y.Z" git push origin vX.Y.Z
Create a GitHub Release from the tag.
gh release create vX.Y.Z --title "X.Y.Z" --notes-from-tagor use the GitHub web UI: Releases → Draft a new release → choose tag
vX.Y.Z. Publishing the release triggers therelease-pypijob which uploads the package to pypi.org via trusted publishing.Verify. Check pypi.org/project/plone.pgthumbor and the GitHub Actions run for the release event.
Open the next development cycle. Add a new
## X.Y.(Z+1) (unreleased)section at the top ofCHANGES.md, commit, push.
Notes¶
hotfixes: same process, just branch off the tag and merge-back via PR.
test.pypi: every
mainpush already ships a dev build there, so you can sanity-check the build pipeline without cutting a real release.Trusted publishing: both
release-test-pypiandrelease-pypienvironments use OIDC viapypa/gh-action-pypi-publish— no API tokens to rotate.