############################# Render GitHub Release notes ############################# ``notes`` turns one reviewed changelog section into a GitHub Release body. Run it from the tagged checkout so the description matches the source that was published. It reads the changelog and prints Markdown to standard output; it does not edit the changelog or create the GitHub Release. A complete Markdown example =========================== Suppose ``docs/changelog.md`` contains these two releases: .. code-block:: markdown # Changelog ## 1.2.3 (2026-10-18) ### Fixed - Avoid stale cache reads ([#42](https://github.com/owner/project/pull/42)) by [@alice](https://github.com/alice). ## 1.2.2 (2026-09-20) ### Fixed - Reject invalid cache keys by [@alice](https://github.com/alice). Render only ``1.2.3``: .. code-block:: bash uvx --from release-creator release-creator notes \ --changelog docs/changelog.md \ --tag 1.2.3 \ --repository owner/project \ --previous 1.2.2 \ --artifact-url https://pypi.org/project/project/1.2.3/ \ > release-notes.md ``--tag`` selects one section. ``--repository`` builds GitHub links. ``--previous`` selects the start of the comparison; the :doc:`tags command ` can find it. ``--artifact-url`` adds the published package link. ``release-notes.md`` contains the complete GitHub description: .. code-block:: markdown ### Bug fixes - Avoid stale cache reads ([#42](https://github.com/owner/project/pull/42)) by @alice. [PyPI release](https://pypi.org/project/project/1.2.3/) **Full Changelog**: https://github.com/owner/project/compare/1.2.2...1.2.3 Review that file before passing it to ``gh release create --notes-file release-notes.md``. The ``by`` credit stays in the changelog; the GitHub body uses an ``@alice`` mention. Rules and failure cases ======================= The tagged changelog decides which changes appear, their order, their categories, and their authors. ``notes`` does not infer changes or people from commits. Add only user-visible changes to the changelog. Credit verified human authors there; do not credit bots or reviewers for work they did not author. ``notes`` requires exactly one section for ``--tag`` and rejects unknown categories. It renames ``Fixed`` to ``Bug fixes`` and ``Added`` to ``Features`` while keeping each release bullet on one line. For Markdown, leave empty headings out of the tagged changelog; the supplied Towncrier template does this. The reStructuredText reader omits empty categories. If the source section already has a ``Full Changelog`` line, ``notes`` replaces it with one link built from ``--previous`` and ``--tag``. The source's category anchors remain stable. See :doc:`the format reference <../reference/formats>` for every category name. Omit ``--artifact-url`` if there is no external artifact. Use ``--artifact-label`` to name another ecosystem's package link. If ``--previous`` is absent, the final link points to the commits at this tag instead of a comparison. Artifact links must use HTTPS. Shared changelog with separate packages ======================================= When packages have separate histories in one Markdown file, name the package section explicitly. For example, ``toml-fmt`` has ``## pyproject-fmt`` above ``### 2.30.4 (date)`` and ``#### Fixed``. Its Git tag is ``pyproject-fmt/2.30.4``: .. code-block:: bash uvx --from release-creator release-creator notes \ --changelog CHANGELOG.md --package pyproject-fmt \ --tag pyproject-fmt/2.30.4 --repository tox-dev/toml-fmt \ --previous pyproject-fmt/2.30.3 > release-notes.md The package selector prevents a matching version in another package's history from entering the output. It does not change the repository used for GitHub links. First-time contributors ======================= GitHub's generated notes may identify first-time contributors. Save its body and pass it as a second input: .. code-block:: bash gh api -X POST repos/owner/project/releases/generate-notes \ -f tag_name=1.2.3 --jq .body > generated-notes.md uvx --from release-creator release-creator notes \ --changelog docs/changelog.md --tag 1.2.3 --repository owner/project \ --generated-notes generated-notes.md > release-notes.md Human ``New Contributors`` lines remain even when their PR did not need a changelog entry. Generated change lists and the ```` banner are discarded. This input never decides which changes or changelog authors belong in the release. If GitHub omits a referenced PR from its generated notes, the tagged changelog entry must already credit its author. reStructuredText changelogs =========================== Use a ``.rst`` changelog path to select the reStructuredText reader: .. code-block:: bash uvx --from release-creator release-creator notes \ --changelog docs/changelog.rst --tag 1.2.3 \ --repository owner/project > release-notes.md ``:issue:`` links target issues; ``:pr:`` and ``:pull:`` target pull requests. ``:user:`` becomes an ``@handle`` mention. Nested lists stay nested. ``.. code-block::`` directives become fenced Markdown blocks inside their release items. Top-level ``.. warning::`` directives become separate warning blocks after the preceding item.