Release process¶
This project releases from main. Create a version bump on a feature branch,
merge its PR, then annotate the reviewed merge and push that tag to create the
GitHub Release.
The sequence is identical for patch, minor and major bumps.
Versioning policy¶
We follow Semantic Versioning 2.0. Run make version to read
the application version. Template maintenance does not itself bump or reset
the application version. During 0.x,
minor bumps may include breaking changes, as SemVer permits for initial development.
Tooling¶
Use make changelog to generate CHANGELOG.md from Conventional Commits with
Commitizen. The explicit changelog_start_rev under [tool.commitizen] starts at
the standalone application commit 3f302105a980ac7a7ae00935907aadc87a2cfcf6, excluding
earlier monorepo history. It overrides the first-Copier-answers default even after
enrollment. Preserve this boundary during development updates; changing this
metadata follows the normal approval policy.
Each make bump-{patch,minor,major} target:
- Requires a clean working tree on a feature branch, not
main,masteror a detached checkout. - Calls
uv version --bump <segment>to updatepyproject.tomlanduv.lock. - Generates the changelog with Commitizen and formats
CHANGELOG.mdwith mdformat. - Updates this project's installation references in tracked
README.mdand Markdown files beneathdocs/, matchinggit+<Repository>[.git]@v<version>. The full URL comes from[project.urls].Repository; other repositories, branch/SHA refs, changelog pages, symlinks and untracked files stay unchanged. Older installation pins also move to the new version; no manual per-file version update is needed. - Commits the metadata, changelog and updated installation examples with the normal Git hooks enabled, so the pin changes are included in PR review.
The bump prepares the release for review without creating a tag. After the PR
merges, make release-tag creates v<new-version> at the reviewed merge commit
on an updated, clean main. It rejects feature branches, stale local main,
non-merge commits and existing tags.
Every failed step stops the command. Inspect the reported error and working tree before retrying; formatting and hook changes are not silently discarded. Neither command pushes tags or publishes to PyPI.
For coding agents, ordinary uv-managed version changes remain allowed. The complete release operation also commits and tags, so it requires release authorization and is not an automatic dependency-management exemption.
Step-by-step flow¶
Start with a clean working tree and an up-to-date main.
1. Create the release branch¶
git switch main
git pull --ff-only
git switch -c chore/bump-v<new-version>
Choose <new-version> from the current version (make version) and intended
segment. Codex uses codex/bump-v<new-version> for its feature branch.
The repository retains a historical v0.2.0 tag from its monorepo history.
A minor bump from any 0.1.x version would collide with that tag and stop before
changing files. Choose an unused version consistent with the release scope;
do not delete or move the historical tag to bypass the guard.
2. Bump¶
make bump-patch # or bump-minor, or bump-major
Review the resulting metadata, lockfile and changelog. The command creates the bump commit locally. If you chose the wrong segment, inspect the unpushed commit and agree on a correction before changing history.
3. Push the branch only¶
git push -u origin chore/bump-v<new-version>
Use the branch name you created. Finish PR review before creating the tag so the release includes corrections made after the bump commit.
4. Open and merge the PR¶
- Title:
chore: bump version to v<new-version>. - Complete the PR checklist; the pre-push hook runs
make checkandmake docs-build, so no duplicate manual run is required. - Review the changelog as the exact notes that will accompany this release.
- Merge with a regular merge commit, never squash. The finalization command
requires a merge commit on
main.
5. Create and push the reviewed tag¶
Once the PR is merged, update main and review that its latest merge is the
release you intend to publish:
git switch main
git pull --ff-only
make release-tag
git push origin v<new-version>
The tag points at the merged contents, including changes made during review. Never move or overwrite an existing published tag. If a historical branch tag omits changes included when its PR merged, release validation rejects it; an old branch tag with identical merged contents remains valid.
6. Automatic GitHub Release¶
The tag-triggered workflow runs validation code from main with read-only
permissions. It verifies that the tag is annotated, matches the tagged
pyproject.toml, belongs to origin/main, and includes its reviewed merge
contents. It extracts the corresponding section from the tagged CHANGELOG.md.
Only the separate publication job has write permission; it receives those notes
as data and creates the GitHub Release. A rerun keeps an already-created release
instead of duplicating it.
Inspect the workflow result in Actions and the release notes in GitHub Releases. This automation creates the GitHub Release only; package-index publishing is not configured.