Release Workflow
This workflow describes how to create a Buffalo Wings release as a maintainer. It covers the version bump, changelog generation, release commit, release tag, and the follow-up publication steps.
Goal
The goal is to produce:
one release commit containing the version updates and changelog,
one git tag in the form
vX.Y.Z,and one releasable project state that can then be published to PyPI and the documentation site.
This workflow uses Towncrier to build CHANGELOG.md from newsfragments/, and Bump My Version to update the project version.
Prerequisites
Before starting, make sure:
you are working in the canonical project repository rather than a fork,
you have permission to push branches and tags,
the working tree is clean,
the repository is up to date with
main,you know whether this release is
patch,minor, ormajor,the news fragments are present and readable,
and the release environment has
uv,towncrier, andbump-my-versionavailable.
Pre-Release Checks
Before beginning the formal release steps, confirm:
tests are passing,
the documentation builds successfully,
examples still run correctly,
and any breaking changes are clearly described in the release notes and fragments.
1. Sync And Create A Release Branch
Start from an up-to-date main branch and create a release branch:
git checkout main
git pull --ff-only
git checkout -b release/next
2. Verify The News Fragments
Check that the Towncrier fragments are valid:
uv run towncrier check
This should report no problems.
If it does, add or fix fragments in newsfragments/ before continuing.
3. Confirm A Clean Repository State
Make sure the repository is clean before changing the version:
git status --porcelain
If this prints anything, resolve it before continuing.
4. Bump The Version
Choose the appropriate release type and update the version without creating a commit or tag yet:
major release:
uv run bump-my-version bump major --no-commit --no-tagminor release:
uv run bump-my-version bump minor --no-commit --no-tagpatch release:
uv run bump-my-version bump patch --no-commit --no-tag
This updates the configured version files, such as pyproject.toml and sphinx/source/conf.py.
5. Read The New Version
Read the updated version from pyproject.toml:
VERSION="$(uv run python - <<'PY'
import tomllib
with open("pyproject.toml", "rb") as f:
print(tomllib.load(f)["project"]["version"])
PY
)"
VERSION_TAG="v${VERSION}"
echo "Releasing ${VERSION_TAG}"
6. Preview The Changelog
Preview the changelog without modifying files:
uv run towncrier build --draft --version "${VERSION}"
Review the generated text for wording, grouping, and missing items. If needed, edit the fragments before continuing. For externally consumed releases, confirm the preview communicates:
what changed in user-visible terms,
what is considered stable now,
and what remains actively evolving.
7. Build The Changelog
Write the final changelog and remove the consumed fragments:
uv run towncrier build --version "${VERSION}" --yes
If you need to set the changelog date explicitly, use:
uv run towncrier build --version "${VERSION}" --date 2026-02-13 --yes
Towncrier must write to the canonical root CHANGELOG.md.
8. Run The Full Project Checks
Run the standard full check suite before committing the release:
./scripts/run_checks.sh
This should pass cleanly before you continue.
9. Commit The Release Changes
Stage the expected release-related files and create the release commit:
git add .copier-answers.yml CITATION.cff src/buffalo_wings/__init__.py \
pyproject.toml CHANGELOG.md newsfragments/ sphinx/source/conf.py uv.lock
git commit -m "Bump to new version -> ${VERSION_TAG}"
Review the staged files before committing to make sure no unrelated changes are included.
10. Push The Release Branch
Push the release branch to the remote:
git push -u origin HEAD
11. Open And Merge The Release PR
On Codeberg, open a pull request from the release branch into main.
Use the CHANGELOG.md section for ${VERSION} as the release notes, and merge the PR once CI is green.
For first external releases, include a short release summary in the PR body that highlights current subsystem maturity and known limitations.
12. Tag The Release
After the release PR has been merged, create and push the release tag:
git checkout main
git pull --ff-only
git tag -a "${VERSION_TAG}" -m "Release ${VERSION_TAG}"
git push origin "${VERSION_TAG}"
13. Publish The Package
If package publication does not happen automatically, follow the PyPI Release Workflow.
14. Publish The Documentation
If documentation publication does not happen automatically, follow the Documentation Release Workflow.