Changelog System
Changelog System
Transform repository history and optional pending content into a structured, rendered CHANGELOG.md document.
app/core/changelog/Category
Quick Command
Git ranges -> providers -> processing -> releases -> Jinja -> MarkdownOverview
The active generator coordinates several focused components. It plans Git ranges, creates message providers, converts raw messages into semantic commit models, groups them into releases, applies release-family behavior, sorts the result, builds a template context, and renders the complete Markdown document.
Writing the file is a final boundary. Most of the subsystem works with domain
objects or an in-memory string before the requested CHANGELOG.md path is
replaced.
Subsystem Responsibilities
Configuration
config/
ChangelogConfigResolver reads the project-owned changelog tables into typed
dataclasses used by providers, processors, links, metadata, and rendering.
Providers
providers/
MessageProviderFactory always creates the Git provider and conditionally
adds the pending-commit provider when that active configuration is enabled.
Processing
processing/
ChangelogProcessingPipeline cleans, parses, expands, filters, ignores,
deduplicates, and groups messages into semantic commit structures.
Release Planning
generator.py and sorting/
The generator chooses stable or prerelease range boundaries, records promoted prerelease tags, applies release behavior, and sorts release objects.
Domain Models
models/
Commit, group, scope, section, release, metadata, contributor, statistics, and template models carry data without embedding Git or file-writing behavior.
Rendering
rendering/
JinjaRenderer turns the final Changelog model and rendering configuration
into one Markdown string using the initialized project template.
Active Generation Flow
Workflow Timeline
Provider Boundary
Message Sources
Always supplies committed messages for each planned Git range.
Optionally supplies the pending commit template for the latest unreleased range.
Return raw messages in provider order without deciding presentation.
Owns normalization, semantic parsing, filtering, deduplication, and grouping.
The provider protocol keeps collection separate from interpretation. This makes it possible to add another source without teaching the renderer how that source stores messages.
Release and Range Model
- The newest tag is the lower boundary for the unreleased
HEADrange. - A prerelease uses the adjacent older tag as its lower boundary.
- A stable release searches for the previous stable tag so its range covers the full prerelease family promoted into that stable version.
- Release objects can carry dates, comparison links, promoted tags, metadata, contributors, statistics, and grouped semantic changes.
ReleaseBehaviorProcessorapplies configured stable, prerelease, and unreleased presentation policy before final sorting.
This planning belongs to the generator because it depends on relationships between several tags and releases, not on a single message provider.
Configuration and Integration Status
Backup-looking generator copies, debug checkpoints, and files under old/ are
not part of this documented path. The architecture describes the active
app/core/changelog/generator.py implementation.
Failure and Write Boundaries
- Git range or provider failures stop generation before the final write.
- Parsing and rendering happen before the destination file is replaced.
- The flow is not a transaction across the larger release pipeline; an earlier workflow step may already have changed project files.
- Dry-run prevents the changelog file write, but callers should still expect configuration resolution, repository reads, and planning work.
- A rendering or template error is surfaced rather than producing a partial Markdown document.