Changelog templates
molt renders each changelog entry from a real Jinja2 template, so you can add dates, custom sections, and your own layout instead of one hard-coded shape.
Dates in the changelog have been an open changesets request since 2019 -- seven years, with a pull request that waited six of them. The blocker is structural: changesets assembles every entry from a fixed ## ${version} template welded to three fixed sections, with no seam for a user to change it. molt makes that whole layer a Jinja2 template. Dates, sections, and reordering are configuration, not a code change.
This is separate from changelog plugins, which control the text of each line. A template controls the structure around the lines: the heading, the section titles, their order, and anything extra you want in the entry. Most customization needs only a template and no code at all.
The default structure
Out of the box, molt reproduces the changesets layout that Python users already recognize -- an entry per version, grouped by bump size:
The load-bearing rules molt keeps faithful to changesets:
- One
## <version>heading per release. - Sections render in order: Major, then Minor, then Patch. An empty section is omitted entirely.
- Dependency bumps always render last, and always in the Patch section -- a bump to an internal dependency is treated as a patch to the dependent, regardless of how big the dependency's own change was. (Add a separate changeset for the dependent if it deserves a louder entry.)
- Dev-only dependencies never produce an "Updated dependencies" line.
New entries are inserted at the top of the file, below the # <package> title, so the changelog reads newest-first.
Correct Markdown, the first time
molt writes the changelog as structured Markdown and emits it correctly on the first pass. It does not shell out to Prettier, dprint, or any other formatter to clean up afterward -- a step changesets needs because its text-surgery approach leaves broken blank lines between entries.
Two consequences you can rely on:
- Spacing is right without a formatter. Blank lines between the heading, sections, and bullets are correct as written, on every platform, with no
formattoolchain to install or configure. - Your summaries are preserved literally. A summary that contains a
#heading, a-list, or a$1keeps its text exactly. changesets strips lines beginning with#and once corrupted summaries containing regex replacement patterns; molt treats a summary as literal prose, never as a template. See Design decisions for the upstream bugs molt refuses to inherit.
Customizing the template
Point the [tool.molt] changelog template at a Jinja2 file:
The template receives the release for one package. The most useful fields:
A template that adds a date to the heading and a dedicated section, otherwise matching the default:
That renders:
Because the section order and headings live in the template, you can rename ### Minor Changes to ### Features, split lines into your own categories, or move dependency bumps into their own section -- all without touching molt or writing a plugin. molt still normalizes the final spacing so the output stays valid Markdown no matter how the template is indented.
Templates and generators together
The two layers compose:
- A changelog generator decides what each bullet says --
- a1b2c3d: Fix the crash (#412). - A template decides where those bullets go -- which section, under which heading, with or without a date.
Use a template alone for structural changes; add a generator only when the per-line text needs to change too. See Custom generators to build one.
Where to go next
- Changelog plugins -- the per-line generator contract.
- Custom generators -- write your own line generator.
- The release plan -- the object a template renders.
- Options reference -- the
changelogand template options.