ci(release): automate versioning and changelog with python-semantic-release - #99
Merged
Conversation
Contributor
Release previewNo version bump from the current commits (stays at Changelog preview (truncated)Computed by python-semantic-release from the conventional commits on this branch. |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Contributor
📊 Benchmark ResultsClick to see benchmark comparisonThreshold: 1.3x (30% slower triggers a regression warning) Note: Benchmarks are informational only and won't fail the build. 💡 Tip: Download the |
3 tasks
simontaurus
approved these changes
Jul 26, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Replaces the manual, tag-driven release process with fully automated Conventional
Commits driven releases via python-semantic-release (PSR). On merge to
main, CIderives the version bump from the commits, updates the version and changelog,
tags the release, publishes to PyPI via OIDC, and deploys the docs. Contributors
no longer tag or bump versions by hand.
Why a static version
The project used
hatch-vcs(version from the git tag). This PR switches to astatic
versioninpyproject.toml, owned by PSR:hatch-vcswas a permanentbuild-time
.gitdependency for an unused feature.pyproject.toml,CITATION.cff, andCHANGELOG.mdin one atomiccommit, so the "version in two places" drift concern does not survive
automation.
.git(Docker, sdist);hatch-vcscould not.Seed is
0.16.2(last PSR-parseable stable tag). The earlierv0.17.0alpha1isnot a valid PSR version and is skipped; a
featsince then yieldsv0.17.0.What changed
hatch-vcs; the package version isnow a static string in
pyproject.toml(seeded at0.16.2), owned bypython-semantic-release.
[tool.semantic_release]: conventional parser,tag_format = "v{version}",version_tomlandversion_variables(forpyproject.tomlandCITATION.cff),build_command = "uv lock",assets = ["uv.lock"], and changelogupdatemode with an insertion flag.version:key toCITATION.cff; replacedthe
CHANGELOG.mdstub with a PSR-compatible seed carrying<!-- version list -->.on-release-main.ymlnow triggers on push tomaininsteadof a tag: PSR computes and tags the release, then the job builds, runs
twine check, and publishes to PyPI via OIDC trusted publishing; docs deployis gated on a release.
main.ymlgained a PR-only job that comments thepredicted next version and changelog.
conventional-pre-commitcommit-msghook plusdefault_install_hook_types, so a plainpre-commit installwires both stages.CONTRIBUTING.mddocuments Conventional Commitsand the merge-to-main release flow;
make installusesuv sync --all-extras.uv.lockupdated for the new dependency and the static version pin.Maintainer action required
ooldas a PyPI Trusted Publisher (OIDC) foron-release-main.yml,then the
PYPI_TOKENsecret can be retired if not used anywhere else.github-actions[bot]release commit and tag push undermainbranch protection.
Notes
ci,chore,docstypes); the firstautomated release waits for a
feat:/fix:onmain.It addresses, should meet all acceptance criteria and can close issue Release automation (PyPI, changelog) #49 after merge
.githygiene (.dockerignore) is split to a separate branch(
deployment-docker-cicd), to be verified with a realdocker build,was local test for decision of static versioning mechanism (pre-step for Deployment/installation guide, Dockerfile, CI/CD patterns #78)
Implemented Post-steps
PyPI trusted publisher configured
using new created pypi environment
Added branch protection ruleset "release" -> settings -> rules -> ruleset
active on branch main and requires PR for merge with bypass for actions bot