.. SPDX-FileCopyrightText: 2026 calendaring-sync contributors .. SPDX-License-Identifier: AGPL-3.0-or-later ======= Release ======= .. meta:: :description: How calendaring-sync is versioned, how a maintainer cuts a release, and the access a release needs. 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 :exc:`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 ============= #. Confirm ``main`` is up to date and its CI is green. .. code-block:: bash git checkout main git pull #. Build the :ref:`change log ` from the pending fragments in ``news/``, replacing ``1.2.0`` with the real version: .. code-block:: bash 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. #. Commit directly to ``main``, the one exception :ref:`commits-and-prs` makes to going through a pull request: the commit is mechanical, with nothing for a reviewer to review. .. code-block:: bash git add docs/changelog.rst news/ git commit -m "chore: build 1.2.0 changelog" git push #. Tag the commit you pushed, and push the tag: .. code-block:: bash 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.