Release#
This page is for maintainers cutting a new release. It isn't something a contributor opening a PR needs to read.
Versioning#
calendaring-jmap has no release branches: every release ships from main. The version number comes entirely from the git tag, read at build time by hatch-vcs; nothing in the source tree stores it. src/calendaring_jmap/_version.py is generated during the build and isn't tracked in git.
Cut a release#
Confirm
mainis up to date and its CI is green.git checkout main git pull
Build the change log from the pending fragments in
news/, replacing1.2.0with the real version:towncrier build --yes --version 1.2.0
This writes the new section into
docs/changelog.rstand deletes the fragments it consumed. Review the diff; towncrier sorts entries alphabetically within each category, not in the order the fragments were added.Commit directly to
main. This one commit is the exception to Commits and pull requests's one-PR-per-change rule: it's a mechanical, maintainer-only step with nothing for a reviewer to meaningfully review.git add docs/changelog.rst news/ git commit -m "chore: build 1.2.0 changelog" git push
Tag the commit you just pushed, and push the tag:
git tag v1.2.0 git push origin v1.2.0
Pushing the tag triggers the release GitHub Actions workflow: it runs the full test suite, builds the package, publishes to PyPI via trusted publishing (no stored token), and creates a GitHub release with autogenerated notes. Nothing past the tag push is manual.
Read the Docs builds the new version automatically from the same tag push; no separate step is needed there.
Dependency maintenance#
Whenever adding or dropping a supported Python version, check which dependencies have newer compatible versions with uv tree:
uv tree --all-groups --depth=2 --python-version 3.11
Run this once per supported Python version (see requires-python in pyproject.toml and the python-version matrix in .github/workflows/tests.yml for the current range). --depth=2 shows each direct dependency and its own first-level dependencies, enough to spot an outdated pin without the full transitive tree. Pay particular attention to icalendar: this project's own public API tracks it, so a new icalendar release is worth checking against the Change log.
Maintainer access#
Releasing calendaring-jmap requires:
Adminaccess to the GitHub repositoryNeeded to push directly to
mainand push tags.OwnerorMaintaineraccess to the PyPI projectPyPI publishing uses trusted publishing (OIDC), configured against this repository's
releaseworkflow and itspypienvironment; no PyPI API token is stored anywhere. A PyPI account with access can revoke or reconfigure this.Maintaineraccess to the Read the Docs projectNeeded to manage the Read the Docs build configuration itself, though a normal release build needs no manual action there.