This guide describes how to cut and publish a release. Ensure CI is green before tagging.
- Python 3.11+
- Clean working tree on
main - Maintainer access to TestPyPI/PyPI (and Homebrew tap if used)
- Tools installed in your venv:
pip install -r requirements-dev.txt
pip install build twine
Run the automated release gate before tagging:
scripts/release_check.sh
- Follow SemVer.
- Update
pyproject.tomlversionandCHANGELOG.md. - Prefer Conventional Commits for history; summarize in CHANGELOG.
- Ensure quality gates pass locally:
ruff check .
mypy .
python -m pytest -q
- Build artifacts (sdist + wheel) and verify:
python -m build
python -m twine check dist/*
- Smoke test install in a clean venv:
python3 -m venv .venv-release
source .venv-release/bin/activate
pip install dist/*.whl
limitless --help
- Tag and push:
git tag vX.Y.Z
git push origin vX.Y.Z
- TestPyPI (first‑time or RCs):
python -m twine upload --repository testpypi dist/*
- PyPI (when ready):
python -m twine upload dist/*
- Post‑publish
- Update GitHub release notes; link to CHANGELOG entries
- Verify
pipx install limitless-toolsworks on a clean machine - (Optional) Homebrew: evaluate providing a formula using a Python venv with vendored deps
- Documented support: releases are currently smoke-tested on macOS (Sonoma) and Ubuntu LTS; call out Windows as experimental until tested.
- CI should run ruff/mypy/pytest on PRs and main. See
.github/workflows/ci.yml(added separately).
- Do not publish secrets. Ensure
.envand local data are ignored by git. - Consider releasing to TestPyPI for validation before PyPI.