Skip to main content

changelog-fragment-cli

Generate release changelogs from directories of changelog fragments, obeying the laws from Keep-a-Changelog and Semantic Versioning.

Each user-visible change gets its own YAML fragment in a project subdirectory. As an example, per Merge Request / Pull Request a new fragment is placed in the changes.d subdirectory.

When building a release, a CI workflow then collects every fragment, merges them into a new ## [X.Y.Z] - YYYY-MM-DD section at the top of the existing CHANGELOG.md and deletes the consumed files. Additional meta information can be placed in various temporary files, e.g. the calculated version number of the new release or the list of removed files.

Why fragments

  • Avoids merge conflicts on CHANGELOG.md when several branches ship changes concurrently.
  • Tags each change with a severity so the release workflow can pick the correct semver bump automatically (patch < minor < major).

Format

File name: anything ending in .yaml or .yml. Suggested form: <short-slug>.yaml, e.g. signed-urls.yaml or fix-cors.yaml. Prefix with an issue or story identifier when one exists (STORY-005-signoff.yaml) so PRs self-document.

severity: minor    # one of: patch | minor | major
added:             # any subset of Keep a Changelog sections:
  - First bullet.  #   added | changed | deprecated | removed | fixed | security
fixed:
  - Second bullet, possibly multi-line:
  - |-
    Use a `|-` block scalar to preserve line breaks inside a bullet
    verbatim. Continuation lines indent by two spaces relative to the
    scalar's first line.

Rules enforced by poetry run python scripts/changelog.py validate:

  • Top level must be a mapping.
  • severity is required and must be patch, minor, major, or release.
  • At least one section with at least one non-empty string entry.
  • Unknown top-level keys are rejected (prevents silent typos).

Severity — how to pick

The severity decides which place of the version number is incremented. Please refer to the official Semantic Versioning documentation for detailed information.

Severity Use when
patch Bug fix, internal change, or docs change with no user-visible behavior change.
minor New feature or user-visible improvement that is backwards-compatible.
major Breaking change for users (data loss, schema drops, removed endpoints, required re-login).
release The 0.x → 1.0.0 cutover. Only valid while the current version is 0.y.z.

The highest severity present across all fragments decides which place in the version number will be incremented.

Pre-1.0 bump rule

While the project is on 0.y.z, the major digit stays pinned at 0 and the bumps map down one level:

  • major (breaking) → bumps the minor digit (e.g. 0.3.0 → 0.4.0).
  • minor / patch → bumps the patch digit (e.g. 0.3.0 → 0.3.1).

The 0 → 1 transition is gated behind the explicit release severity so it never happens by accident. Once the current version is 1.0.0 or higher the standard SemVer mapping applies (major/minor/patch bump the matching digit) and release is rejected.

Starting a new project

A fresh project has no CHANGELOG.md yet. Scaffold one, plus the fragments directory, with:

changelog-fragment-cli init CHANGELOG.md changes.d

This writes an empty Keep-a-Changelog file (no version entries yet) and a changes.d/ directory containing a .gitkeep placeholder so the empty directory survives in git. An existing CHANGELOG.md is never overwritten unless you pass --force.

Because the scaffolded changelog declares no released version, it parses as 0.0.0 ("nothing released yet"), so the first release is always 0.1.0 regardless of the fragments' severity — the one exception being a release fragment, which cuts straight to 1.0.0.

Creating a fragment

Scaffold a new fragment with a chosen severity and empty placeholders for every Keep-a-Changelog section:

changelog-fragment-cli create --minor changes.d/signed-urls.yml

Exactly one of --patch, --minor, --major, or --release is required. The file is written with the selected severity plus an empty list for each section (added, changed, deprecated, removed, fixed, security) — fill in the ones that apply and delete the rest. Missing parent directories are created; an existing file is never overwritten unless you pass --force.

Validating locally

changelog-fragment-cli validate --fragments-dir changes.d

Exit 0 means the fragments are release-ready; exit 2 prints every offending file to stderr.

Previewing the next release

changelog-fragment-cli preflight \
  --fragments-dir changes.d \
  --changelog CHANGELOG.md \
  --run-number 1 \
  --out-changelog /tmp/CHANGELOG.md.new \
  --out-notes /tmp/release-notes.md \
  --out-consumed /tmp/consumed.txt \
  --out-summary /tmp/summary.md

This writes version=... / build_number=... to the file passed via --github-output and writes the prospective new CHANGELOG.md and per-release notes to the paths above.

Metadata

Release files for changelog-fragment-cli 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for changelog-fragment-cli 0.1.1
File Size Uploaded
changelog_fragment_cli-0.1.1.tar.gz 23.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for changelog-fragment-cli 0.1.1
File Interpreter ABI Platform
changelog_fragment_cli-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 50.4 kB

Release files / changelog_fragment_cli-0.1.1.tar.gz

Download URL changelog_fragment_cli-0.1.1.tar.gz
Size 23.7 kB
Tags Source
SHA-256 checksum
How to use checksums
64869e934bb913e693887143a1c81721e4eb23b0af44ed1fd24d3e702a9fdb87
BLAKE2b-256 checksum
How to use checksums
4b9d986844567f75b671a7d51591a9f7f08e28daf7eb0855bcbffb30ed9eb9d4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 6, 2026.

Transparency log

Release files / changelog_fragment_cli-0.1.1-py3-none-any.whl

Download URL changelog_fragment_cli-0.1.1-py3-none-any.whl
Size 26.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0bf9477107a9904a1dc3912874102115ae6656ebd0754a1892fa386511ebcf81
BLAKE2b-256 checksum
How to use checksums
cec67f62db1f8cdb46b7ef8699363fabd0ccc21becbbfdaa029fd1b8608b1915
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 6, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page