Skip to content

Release Checklist

The actual command sequence from version bump to publishing on PyPI. Release Management is written for a general audience and can drift out of date; this page is the source of truth for what to actually run.

0. Before You Start

  • git status is clean (main pulled to latest)
  • Merged MRs contain the intended changes
  • .env has PYPI_API_TOKEN / TESTPYPI_API_TOKEN set

1. Preview the Version Bump

task bump:check

fix-only commits bump PATCH; any feat bumps MINOR. Review the conventional-commit breakdown to confirm it matches expectations.

2. Apply the Version Bump

task bump:auto

This:

  • Updates the version in pyproject.toml / src/fnb/__init__.py
  • Updates CHANGELOG.md
  • Creates a commit (bump: version X.Y.Z → A.B.C)
  • Creates a git tag (local only — not pushed yet)

3. Write the Release Notes

task docs:release -- X.Y.Z

This scaffolds docs/releases/vX.Y.Z.md from the template. Fill it in (in English — release notes for this project are English-only) using the relevant CHANGELOG.md entries as source material.

Commit it:

git add docs/releases/vX.Y.Z.md
git commit -m "docs: add vX.Y.Z release notes"

4. Update the Release Notes Index

⚠️ task docs:release does not update the index automatically. Forgetting this means the new release notes aren't reachable from the site. (zensical.toml's nav.Releases only ever points at releases/index.md, not individual versions, so there's no nav entry to add — just the index page itself.)

  • Add an entry under ## Recent Releases in docs/releases/index.md
  • Confirm uv run zensical build succeeds
git add docs/releases/index.md
git commit -m "docs: add vX.Y.Z to release notes index"

5. Push

git push origin main

The tag was already created locally by task bump:auto. Once GitLab sees the tag, CI automatically triggers deploy-testpypi.

6. Create the GitLab Release

task push:release -- X.Y.Z

Creates a GitLab Release using docs/releases/vX.Y.Z.md as the notes.

7. Confirm the Automatic TestPyPI Deploy

glab ci status --branch X.Y.Z

Confirm deploy-testpypi is success. If it is, there's no need to run task publish:test locally — re-uploading the same version will likely just error out.

8. Install from TestPyPI and Sanity-Check

VERSION=X.Y.Z task verify:testpypi

Installs into a clean venv from TestPyPI and checks fnb version / fnb --help / import fnb.

9. Publish to Production PyPI

⚠️ This is irreversible. A published version can never be replaced.

task publish:prod

⚠️ Check dist/ before publishing. uv build doesn't clean existing files, so leftover .whl/.tar.gz from older versions can get swept up into the same publish call (usually harmless, but noisy).

rm -rf dist/
task publish:prod

10. Post-Publish Verification

pip install fnb==X.Y.Z
fnb version

The full version history on PyPI is visible at https://pypi.org/project/fnb/#history.

Troubleshooting

  • TestPyPI/PyPI rejects the upload as a duplicate version → that version is already published. Cut a new one with task bump:patch (or minor/major)
  • task push:release fails with Release notes not found → step 3 (writing the release notes) was skipped
  • zensical build fails → check docs/releases/index.md for a typo in the linked releases/vX.Y.Z.md filename