Publishing releases#
Set the package version in
pyproject.tomland finalize the changelog.Commit the release changes, push the branch, and wait for its CI checks.
Create the matching
v<version>tag on that commit and push that specific tag. In SourceTree, select only the intended release tag.The tag workflow validates the version, tests and builds the package, publishes the distributions to PyPI using trusted publishing, then creates the GitHub release with generated notes and the same distribution files.
Ordinary branch pushes do not publish. Tags must exactly match the package
version. Development and local versions are rejected. Alpha, beta, and release
candidate versions use canonical suffixes such as 0.2.0rc1; their GitHub
releases are marked as prereleases and are not marked Latest. Stable releases
use GitHub’s automatic Latest selection. Existing tags are never moved.
If PyPI succeeds but the github-release job fails, choose Re-run failed
jobs on that workflow run. This retries GitHub release creation without
uploading to PyPI again. The job reuses an existing release and uploads only
missing assets, preserving existing notes and assets. Do not rerun all jobs
or delete and recreate a published tag to retry GitHub release creation.
GitHub limits workflow reruns to 30 days after the original run; recover older
runs manually using the already-published distributions.
The existing PyPI trusted publisher and environment approvals still apply. The publishing job only needs OIDC and read permissions; the separate GitHub release job has repository contents write permission. No personal token is required. A manually created GitHub release does not trigger PyPI publication.