Run through this list before creating a new tag. Skipping a step has burned us before (see v7.1.1 badge hotfix).
- Bump version in
pyproject.toml(single source of truth). - Verify
install.shVERSION — it readspyproject.tomldynamically; runbash install.sh --helpand confirm. - Update
CHANGELOG.md— use Keep-a-Changelog format, include date. - Bump README PyPI badge cache-bust — update
?v=X.Y.Zquery param in the PyPI version badge URL (GitHub camo caches for 3h). - Run full test suite locally:
pytest -q— all tests green. - Run build locally:
python3 -m build && twine check dist/*. - Commit on a release branch (
chore/release-X.Y.Z), open PR, merge tomain. - Create the GitHub Release (tag
vX.Y.Z, e.g.gh release create vX.Y.Z) —publish.ymlfires onrelease: published, NOT on a bare tag push. - Verify PyPI release — check
pip install schliff==X.Y.Zworks. - Redeploy the web surfaces — their bundles carry engine/seed state:
playground (bump
playground/pyproject.tomlpin +uv lock --upgrade-package schliff, thenvercel --prod+ dispatchplayground-pin-drift.yml) AND leaderboard (vercel --prodfromweb/leaderboard/— its bundled seed shows the self-entry version; skipping this left the live row on 8.1.0 until 2026-07-07). - Re-point the
v1float tag to the release commit (git tag -f v1 <sha> && git push origin v1 --force). - Post-release: close milestone, update memory entries that reference version.
Use git tag -a vX.Y.Z-rc1 ... to test the publish workflow without a real release.
Publishing uses OIDC Trusted Publishing via pypa/gh-action-pypi-publish. No API tokens in the repo. If this breaks: check PyPI Trusted Publisher config at https://pypi.org/manage/project/schliff/settings/publishing/.