Python Towncrier Changelogs — Core Concepts

What Towncrier Does

Towncrier is a changelog management tool that uses a fragment-per-change approach. Instead of editing a single CHANGELOG.md directly, each change gets its own tiny text file. At release time, towncrier collects all fragments, groups them by type, and renders a formatted changelog section.

Install it:

pip install towncrier

The Fragment System

Each fragment is a text file in a changes/ directory (configurable). The filename encodes metadata:

changes/
├── 142.feature.md     ← Issue #142, a new feature
├── 157.bugfix.md      ← Issue #157, a bug fix
├── 163.removal.md     ← Issue #163, a deprecation
└── no-issue.misc.md   ← No issue number, misc change

The filename format is <identifier>.<type>.md:

PartMeaning
IdentifierIssue/PR number, or any unique name
TypeCategory of change (feature, bugfix, etc.)

Fragment contents are simple — one or two sentences:

Added retry logic to the HTTP client with configurable backoff.

Configuration

Add to pyproject.toml:

[tool.towncrier]
package = "mypackage"
directory = "changes"
filename = "CHANGELOG.md"

[[tool.towncrier.type]]
directory = "feature"
name = "Features"
showcontent = true

[[tool.towncrier.type]]
directory = "bugfix"
name = "Bug Fixes"
showcontent = true

[[tool.towncrier.type]]
directory = "removal"
name = "Removals & Deprecations"
showcontent = true

[[tool.towncrier.type]]
directory = "misc"
name = "Miscellaneous"
showcontent = false

The showcontent = false for misc means those entries show only the issue number, not the description.

Building the Changelog

When you’re ready to release:

towncrier build --version 2.4.0

This:

  1. Reads all fragment files from the changes/ directory
  2. Groups them by type
  3. Renders them into a new section in CHANGELOG.md
  4. Deletes the consumed fragment files
  5. Creates a Git commit with the changes

The resulting changelog section:

## 2.4.0 (2026-03-28)

### Features
- Added retry logic to the HTTP client with configurable backoff. (#142)
- New `--json` output format for CLI commands. (#156)

### Bug Fixes
- Fixed connection pool exhaustion under high concurrency. (#157)

### Removals & Deprecations
- Deprecated `sync_client` in favor of `async_client`. (#163)

Why Fragments Eliminate Merge Conflicts

With a traditional changelog, if two developers add entries to CHANGELOG.md on separate branches, they’ll conflict when merged because both edited the same section of the same file.

With towncrier, each developer adds a different file to the changes/ directory. Two new files never conflict. The changelog is assembled only at release time, after all branches are merged.

Previewing Before Release

towncrier build --draft --version 2.4.0

The --draft flag renders the changelog to stdout without modifying any files — useful for reviewing before committing.

Enforcing Fragment Creation in CI

Add a CI check that verifies every PR includes a changelog fragment:

- name: Check changelog fragment
  run: |
    FRAGMENTS=$(git diff --name-only origin/main... -- changes/)
    if [ -z "$FRAGMENTS" ]; then
      echo "No changelog fragment found. Add one to changes/"
      exit 1
    fi

Common Misconception

“Towncrier is only for open-source projects.” Corporate teams benefit even more because they often have larger teams where changelog discipline is harder to maintain. Towncrier’s fragment approach scales to any team size and integrates with any issue tracker (the identifier can be a Jira ticket, a PR number, or a custom ID).

One thing to remember: Towncrier shifts changelog writing from “one big update at release time” to “one sentence per change as you go” — spreading the effort makes it painless.

pythonrelease-managementdeveloper-tools

See Also

  • Python Black Formatter Understand Black Formatter through a practical analogy so your Python decisions become faster and clearer.
  • Python Bumpversion Release Change your software's version number in every file at once with a single command — no more find-and-replace mistakes.
  • Python Changelog Automation Let your git commits write the changelog so you never forget what changed in a release.
  • Python Ci Cd Python Understand CI CD Python through a practical analogy so your Python decisions become faster and clearer.
  • Python Cicd Pipelines Use Python CI/CD pipelines to remove setup chaos so Python projects stay predictable for every teammate.