Releasing & Publishing¶
This page describes how to build the documentation and how to release a new version of TextDirectory to PyPI.
Building the documentation¶
The documentation lives in docs/ and is built with Sphinx (furo theme, Markdown via myst-parser).
Build it locally:
uv sync --group docs
uv run --group docs sphinx-build -b html docs docs/_build/html
Open docs/_build/html/index.html in a browser to inspect the result. To treat warnings as errors (as a
pre-release check), add -W.
The hosted documentation at https://textdirectory.readthedocs.io is built automatically by Read the Docs on
every push, using .readthedocs.yaml (Python 3.12, pip install . plus docs/requirements.txt). If you change
the docs dependencies in pyproject.toml’s docs group, mirror the change in docs/requirements.txt.
One-time setup for publishing¶
Releases are published to PyPI via Trusted Publishing (OIDC) — no API tokens or passwords are stored anywhere.
On PyPI, open the project’s Manage → Publishing page and add a Trusted Publisher:
Owner:
IngoKl, repository:textdirectoryWorkflow name:
release.ymlEnvironment name:
pypi
On GitHub, create an environment named
pypi(Settings → Environments). Optionally add yourself as a required reviewer — publishing will then wait for your approval.
Release checklist¶
Bump the version in
src/textdirectory/__init__.py(__version__ = 'X.Y.Z'). This is the single source of truth; hatchling reads it at build time.Then refresh the editable install, otherwise
textdirectory --versionkeeps reporting the previous version (it reads the installed metadata, not__version__, anduv syncalone does not rebuild it):uv sync --reinstall-package textdirectory
Update
CHANGELOG.md: give the release a date and make sure all notable changes are listed.Run the full check suite:
uv run pytest # includes the spaCy tests if the model is installed uv run pytest -m network # optional: live-service tests (UCREL USAS) uv run ruff check src tests uv run mypy
Build and verify the distribution.
uv builddoes not cleandist/, so remove it first — otherwise older releases are checked (and, in the manual path below, re-uploaded):rm -rf dist uv build uvx twine check dist/*
Optionally, install the wheel into a scratch environment and smoke-test it:
uv venv /tmp/td-check uv pip install --python /tmp/td-check dist/textdirectory-X.Y.Z-py3-none-any.whl /tmp/td-check/bin/textdirectory --version
Commit, tag, and push. Tags use the
vX.Y.Zformat:git commit -am "Release X.Y.Z" git tag vX.Y.Z git push && git push --tags
The release workflow does the rest: pushing a
v*tag triggers.github/workflows/release.yml, which checks that the tag matches__version__and that the changelog is dated, runs the test suite, builds the sdist and wheel, runstwine check, and publishes to PyPI via Trusted Publishing.Verify the release:
The new version appears on https://pypi.org/project/textdirectory/
pip install textdirectory==X.Y.Zworks in a clean environmentRead the Docs built the new version (check the version switcher)
Create a GitHub Release from the tag and paste the changelog entry
Manual publishing (fallback)¶
If the workflow is unavailable, you can publish manually with an API token:
uv build
uvx twine check dist/*
uvx twine upload dist/*
twine upload will prompt for a PyPI API token (username __token__).
Rehearsing on TestPyPI¶
For risky changes to the packaging itself, rehearse against TestPyPI first:
uv build
uvx twine upload --repository testpypi dist/*
pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ textdirectory