04 — Versioning and releases¶
Rules: VER-1…5, CI-4, CI-6, CI-7.
The tag is the version¶
pyproject.toml declares dynamic = ["version"], and hatch-vcs reads the version from the
latest vX.Y.Z tag. The package exposes it as __version__, and the editable install refreshes
it when a tag moves ([tool.uv] cache-keys). There is no version string to forget, and no bump
commit on main.
Releases¶
On every green push to main, the release job:
- refuses to run while a
release-blockerissue is open; - computes the next version with
cz bump --get-next, from the Conventional Commits since the last tag (fix/perf→ patch,feat→ minor, breaking → major, minor while0.y.z); - pushes an annotated tag; builds the wheel and sdist; generates a CycloneDX SBOM; attests build provenance; creates the GitHub Release with generated notes;
- asserts the result with
standards check-version --remote origin --released.
standards check-version¶
| Option | Checks |
|---|---|
| (none) | pyproject.toml has no static version and declares it dynamic |
--remote origin |
the latest tag reachable from HEAD is on origin, pointing to the same commit (a moved tag fails) |
--released |
no releasable commit since the latest tag is left untagged |
The version-tag pre-push hook runs it with --remote origin. Before the first release, when no
tag exists yet, it passes.
Fix forward. Tags are immutable (a ruleset forbids moving or deleting them). If a release job
fails after tagging, the fix is a new fix commit, which releases the next patch.