Release¶
Releases follow semantic versioning and use automated workflows to handle version bumping, changelog building, commit creation, and publishing. Maintainers trigger releases through GitHub Actions or run the release script locally for testing.
Changelog Fragments¶
Contributors add changelog fragments that get collected during releases. Create a file in docs/changelog/ named
<pr_number>.<type>.rst where type is feature for new functionality, bugfix for fixes, doc for
documentation changes, removal for deprecations, or misc for internal changes. The file should contain a single
line describing the change, optionally crediting the author with :user:`username` syntax. For example,
123.feature.rst might contain Add support for custom backends - by :user:`contributor`. These fragments are
collected during releases to build the changelog automatically.
Automated Release¶
Navigate to the pre-release workflow and click Run
workflow. Select a version bump type: auto for patch bumps, major for X+1.0.0, minor for X.Y+1.0, or
patch for X.Y.Z+1.
The workflow updates the version in src/build/__init__.py, runs towncrier build to collect changelog fragments
from docs/changelog/ and incorporate them into CHANGELOG.rst, creates a release commit with message chore:
prepare for X.Y.Z, creates an annotated tag, and pushes both to trigger the CD workflow.
The tag push triggers the continuous deployment pipeline which builds the source distribution and wheel, creates a GitHub release with auto-generated notes, generates build attestations for supply chain security, and publishes to PyPI via trusted publishing. The process takes approximately five minutes from workflow trigger to published package.
Local Release¶
Run the release script locally for testing or manual control. Ensure tox is installed and git identity is configured:
$ pip install tox
$ git config user.name "Your Name"
$ git config user.email "your@email.com"
The script creates annotated git tags without GPG signing. Package authenticity is guaranteed by PyPI attestations, not git tag signatures.
Dry run without pushing¶
Test the release process locally:
$ tox -e release -- --version auto --no-push
This updates the version file, builds the changelog from fragments, creates the commit and tag locally, but does not push to the remote repository.
Full local release¶
Specify an explicit version or bump type:
$ tox -e release -- --version 1.5.0
$ tox -e release -- --version patch # 1.4.0 → 1.4.1
$ tox -e release -- --version minor # 1.4.0 → 1.5.0
$ tox -e release -- --version major # 1.4.0 → 2.0.0
The script updates src/build/__init__.py, runs towncrier build to collect changelog fragments, runs pre-commit
hooks, creates a commit with message chore: prepare for X.Y.Z, creates an annotated tag, and pushes both to origin.
The GitHub Actions CD workflow takes over to build and publish.
See also¶
PyPI removed PGP signature support in May 2023. Package authenticity is guaranteed through PyPI attestations per PEP 740, which cryptographically link packages to their source repository and build process.
Troubleshooting¶
Workflow timeout¶
If the pre-release workflow times out, run the release script locally with --no-push, then manually push with git
push && git push --tags. The CD workflow triggers automatically on tag push.
Publishing conflicts¶
If a version is already published to PyPI, the publish job fails safely. The CD workflow is idempotent except for PyPI
publishing. For corrections, create a post-release like X.Y.Z.post1.
Implementation¶
The automation consists of the pre-release workflow at .github/workflows/pre-release.yml for manual triggering, the
CD workflow at .github/workflows/cd.yml that triggers on tag pushes, the release script at tasks/release.py for
version bumping and tag creation, and the [env.release] environment in tox.toml providing dependencies.