Skip to main content

Changelog System

Changelog System

Active Generation Flow

Transform repository history and optional pending content into a structured, rendered CHANGELOG.md document.

Commandapp/core/changelog/

Category

Architecture

Quick Command

Git ranges -> providers -> processing -> releases -> Jinja -> Markdown

providersdomain modelsprocessing pipelinerendering

Overview

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

1
Enter through command or pipeline
The changelog command or GenerateChangelogStep delegates eligibility and execution to WorkflowEngine.
completed
2
Check whether generation applies
WorkflowEngine evaluates skip, enablement, release state, and dry-run conditions before calling the generator.
completed
3
Load services and configuration
ChangelogGenerator creates its typed configuration, GitService, processing pipeline, release processor, sorter, and Jinja renderer.
completed
4
Plan release ranges
Existing tags determine unreleased, prerelease, stable, and promoted-prerelease boundaries.
current
5
Collect raw messages
GitProvider reads repository history; PendingCommitProvider may add the latest pending template content.
pending
6
Build the domain model
The processing pipeline creates semantic commit groups, and the generator assembles release metadata and comparisons.
pending
7
Apply release behavior and order
ReleaseBehaviorProcessor handles release-family policy and DefaultReleaseSorter orders the final releases.
pending
8
Render and write
JinjaRenderer produces Markdown; the generator writes only after successful collection, processing, and rendering.
pending

Provider Boundary

Message Sources

MessageProviderFactoryGitProvider

Always supplies committed messages for each planned Git range.


MessageProviderFactoryPendingCommitProvider

Optionally supplies the pending commit template for the latest unreleased range.


Providerslist[str]

Return raw messages in provider order without deciding presentation.


ChangelogProcessingPipelineCommit models

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 HEAD range.
  • 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.
  • ReleaseBehaviorProcessor applies 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.

Continue