Skip to content

docs: keep a changelog, and put it above the generated release notes - #677

Merged
andiwand merged 1 commit into
mainfrom
docs/changelog
Aug 9, 2026
Merged

docs: keep a changelog, and put it above the generated release notes#677
andiwand merged 1 commit into
mainfrom
docs/changelog

Conversation

@andiwand

@andiwand andiwand commented Aug 9, 2026

Copy link
Copy Markdown
Member

🤖 Generated with Claude Code

A release body is git-cliff over the commit subjects — accurate, free, and an
answer to "which pull requests went in", which is not the question a consumer
asks. The consumers are the apps, the bindings and the packages on conan, maven,
PyPI, npm and SwiftPM, and before taking a bump they want to know whether the
API breaks, what renders better, and what changed under them. Droid's changelog
already re-narrates our changes for its own users, written by reading our commit
list; this does that work once, here.

The file

CHANGELOG.md, backfilled to v5.3.0 and covering what is on main as
Unreleased. High level, but written for a developer rather than for an app
store: File::from_memory and HtmlViewportMode are named where naming them is
the point, while the PDF renderer is four bullets instead of sixty pull
requests. Sources were the commit subjects, the diffs where a subject was
ambiguous, and the changelog draft that was written and then dropped from #627,
which is where the v6.0.0 breaking list comes from.

The file's own arrival is not an entry in it — by its own rule, only what a
consumer notices earns one.

The wiring

  • release.py notes writes the section for the version, a rule, then the
    generated list exactly as before.
  • release.py changelog --version prints one section and fails when it is
    missing or empty. release.yml calls it in the version job, so release copy
    nobody wrote costs seconds instead of the apple build. Dry runs included —
    a dry run is the rehearsal for the body.
  • docs(changelog) joins chore(release) in cliff.toml's skip list: the
    heading cut is a version number moving, and would otherwise narrate itself in
    its own release notes.

Verified end to end against a real git-cliff 2.13.1: section on top, rule,
generated groups below; and the missing-section path fails before git-cliff is
reached.

The flow

Entries land under ## Unreleased in the pull request that makes the change.
The heading is cut to the version as the last commit on main before the merge
into releases, so both branches carry the identical cut and the merge stays
clean. AGENTS.md gains that, the amended wording of "main carries no version",
and a maintenance-branch rule: such a branch keeps its own changelog, covering
what it contains, and does not send sections back to main.

It also records a wart this PR does not fix: the next version cannot be
derived from main.
Since the release train, tags sit on chore(release)
commits that only releases carries, so git describe main says
v6.1.0-38-g890c5e6c and scripts/release.py version would answer with an
already-tagged version. Until that changes, take the last release from gh release list -L 1 and bump the minor if a feat: landed, the patch otherwise —
and if the guess is wrong, the new check refuses in the first job.

Separately discussed and deliberately not in this PR: dropping the
releases branch and letting the release run cut the heading itself, which
removes both the manual step and the wart above.

A release body is git-cliff over the commit subjects, which answers which pull
requests went in. The consumers - the apps, the bindings, and the packages on
conan, maven, PyPI, npm and SwiftPM - ask a different question before taking a
bump: does the API break, what renders better, what changed under them. Droid
already narrates our changes for its own users by reading that commit list;
this is that work done once, at the source.

CHANGELOG.md is backfilled to v5.3.0, high level but written for a developer:
`File::from_memory` and `HtmlViewportMode` are named where naming them is the
point, and the PDF renderer is four bullets rather than sixty pull requests.

`release.py notes` now writes the section for the version, a rule, then the
generated list as before, and `release.py changelog` prints one section and
fails when there is none - checked in the `version` job, so release copy nobody
wrote costs seconds rather than the apple build. `docs(changelog)` joins
`chore(release)` in cliff.toml's skip list: the heading cut is a version number
moving and would otherwise narrate itself in its own release.

AGENTS.md carries the flow, and records that the next version cannot be derived
from main - since the release train the tags sit on `chore(release)` commits
only `releases` has, so main's nearest tag is v6.1.0 and drifting.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VFcWjZhdxeWLE5Abg4qUex
@andiwand
andiwand marked this pull request as ready for review August 9, 2026 16:23
@andiwand
andiwand merged commit 0d1148f into main Aug 9, 2026
34 of 36 checks passed
@andiwand
andiwand deleted the docs/changelog branch August 9, 2026 16:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant