Creating A Release¶
This guide covers the full vaxflux release process, from preparing the
changelog to running the manual GitHub Actions release workflow.
Prerequisites¶
- You have write access to the
ACCIDDA/vaxfluxrepository. - The version has already been updated in
pyproject.tomlandsrc/vaxflux/__init__.py. - The release notes for that version have already been added to
CHANGELOG.md. - Your local environment is synced with a supported Python version via
uv sync --locked --python 3.12 --group dev.
1. Format The Changelog¶
The release workflow validates CHANGELOG.md using scripts/release.py, so the
changelog format must match what that script expects.
For a release, the top section of CHANGELOG.md must:
- Not contain a
## [Unreleased]heading. - Start with a heading in the form
## [X.Y.Z] - YYYY-MM-DD. - Use the current release version and the current date.
- Contain at least one non-empty bullet point.
Example:
## [0.3.0] - 2026-04-06
Added:
- Added manual release workflow dispatch with package preflight validation.
- Added clean-room wheel installation tests for release preparation.
Changed:
...
If the top heading, date, or bullet formatting is wrong, just release-check
and the release workflow will fail before anything is published.
2. Run The Local Release Preflight¶
Use the just release-validate recipe to run the following checks locally:
build-check: Build the source distribution and wheel, then runtwine check --stricton the generated artifacts.build-test: Build the wheel, install it into a clean virtual environment, installs the pinned development test dependencies exported fromuv.lock, and run the test suite against the installed wheel.release-check: Runuv run python scripts/release.pywithout--createto ensure theCHANGELOG.mdis formatted correctly.
3. Run The Release Workflow¶
Releases are created through the manual GitHub Actions workflow in
.github/workflows/release.yaml. You can trigger it from the GitHub UI, but it
is preferred that the gh CLI is used to trigger it so appropriate options can
be provided.
If you are testing the workflow before the pull request is merged, add
--ref <branch-name> to the gh workflow run command. Without --ref, GitHub
dispatches the workflow definition from the repository's default branch, so any
unmerged workflow_dispatch inputs will not exist yet. Using
--ref <branch-name> means the workflow validates, builds, and publishes
artifacts from that branch, not from main. That is appropriate for dry runs
and TestPyPI testing before merge, but it should not be used for a real PyPI
release. Real releases should be triggered from main after the pull request
has been merged.
Dry Run¶
Use this to validate the release end to end without publishing to TestPyPI or PyPI, creating a GitHub release, or deploying docs:
gh workflow run release.yaml \
--repo ACCIDDA/vaxflux \
--ref <branch-name> \
--field publish-target=none \
--field create-github-release=false \
--field deploy-docs=false
This runs the validate job only. It will still enforce the changelog and
release metadata checks through just release-validate.
This is the recommended way to test the workflow before merge.
TestPyPI¶
Use this to publish the built artifacts to TestPyPI without creating the GitHub release or deploying docs:
gh workflow run release.yaml \
--repo ACCIDDA/vaxflux \
--ref <branch-name> \
--field publish-target=testpypi \
--field create-github-release=false \
--field deploy-docs=false
This is the safest way to test the release workflow against a real package index before publishing to PyPI. To check that the package can be successfully installed after uploading to TestPyPI you can run:
uv venv --python 3.12 /tmp/vaxflux-testpypi
uv pip install \
--python /tmp/vaxflux-testpypi/bin/python \
--index-url https://test.pypi.org/simple/ \
--extra-index-url https://pypi.org/simple \
vaxflux
The extra index is needed so dependencies can still be resolved from PyPI.
When testing from a branch, keep create-github-release=false and
deploy-docs=false. The documentation deployment workflow checks out main, so
it is not intended for pre-merge branch testing.
Full PyPI Release¶
Use this to run the full release flow:
gh workflow run release.yaml \
--repo ACCIDDA/vaxflux \
--field publish-target=pypi \
--field create-github-release=true \
--field deploy-docs=true
This workflow runs, in order:
just release-validate.- Publish the built artifacts to PyPI.
- Create the GitHub release.
- Deploy the versioned documentation.
Run the full PyPI release flow only from main. Do not use --ref with a
feature branch for a real release.
4. Trusted Publishing Setup¶
The release workflow uses PyPI Trusted Publishing rather than a stored API token. To enable publishing, configure the trusted publisher entry on TestPyPI and PyPI for:
- Owner:
ACCIDDA. - Repository:
vaxflux. - Workflow file:
release.yaml.
If that configuration is missing, the publish job will fail even if validation passes.