Release#

This page is for maintainers cutting a release. Contributors opening a pull request don’t need it.

Versioning#

Versions follow Semantic Versioning 2.0.0. While the major version is 0, a release with new features or with changes that break the public API bumps the minor version, and a release with only fixes bumps the patch version. From 1.0.0 on, a breaking change bumps the major version. A public name that’s renamed or removed keeps working, with a DeprecationWarning, for at least one release first.

calendaring-sync 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_sync/_version.py is generated during the build and isn’t tracked in git.

Cut a release#

  1. Confirm main is up to date and its CI is green.

    git checkout main
    git pull
    
  2. Build the change log from the pending fragments in news/, replacing 1.2.0 with the real version:

    towncrier build --yes --version 1.2.0
    

    This writes the new section into docs/changelog.rst and deletes the fragments it consumed. Review the diff: towncrier orders the entries in each category by issue number, not in the order the fragments were added.

  3. Commit directly to main, the one exception Commits and pull requests makes to going through a pull request: the commit is mechanical, with nothing for a reviewer to review.

    git add docs/changelog.rst news/
    git commit -m "chore: build 1.2.0 changelog"
    git push
    
  4. Tag the commit you 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 through trusted publishing, with 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.

Maintainer access#

Releasing calendaring-sync requires:

Admin access to the GitHub repository

Needed to push directly to main and push tags.

Owner or Maintainer access to the PyPI project

PyPI publishing uses trusted publishing (OIDC), configured against this repository’s release workflow and its pypi environment; no PyPI API token is stored anywhere. A PyPI account with access can revoke or reconfigure this.

Maintainer access to the Read the Docs project

Needed to manage the Read the Docs build configuration itself, though a normal release build needs no manual action there.

Last updated on 2026-10-27.