Skip to content

ci: introduce towncrier to generate changelog from fragments#5187

Merged
lzchen merged 12 commits into
open-telemetry:mainfrom
MikeGoldsmith:mike/towncrier-review
May 12, 2026
Merged

ci: introduce towncrier to generate changelog from fragments#5187
lzchen merged 12 commits into
open-telemetry:mainfrom
MikeGoldsmith:mike/towncrier-review

Conversation

@MikeGoldsmith

@MikeGoldsmith MikeGoldsmith commented May 8, 2026

Copy link
Copy Markdown
Member

Description

Replace manual CHANGELOG.md editing with towncrier fragment-based changelog management. Each PR adds a small text file in .changelog/ instead of editing the changelog directly, eliminating merge conflicts.

This supersedes #4382 (PoC by @emdneto) — builds on that foundation with updates for current main, additional features informed by how pip, pytest, attrs, and Twisted use towncrier.

Fixes #4307
Fixes #4309

What changed

Core towncrier setup:

  • pyproject.toml: towncrier config with 5 fragment types (added, changed, deprecated, removed, fixed), pinned towncrier==25.8.0 in CI
  • scripts/changelog_template.j2: custom Jinja2 template matching existing changelog format
  • CHANGELOG.md: <!-- changelog start --> marker added above existing ## Unreleased section; existing entries preserved as-is and can be migrated to fragments at the next release

CI & workflows:

  • .github/workflows/changelog.yml: rejects direct CHANGELOG.md edits, validates fragments exist via git diff, previews rendered changelog with towncrier build --draft
  • .github/workflows/prepare-release-branch.yml: sed replaced with towncrier build
  • .github/workflows/prepare-patch-release.yml: same + adds backport step to sync changelog to main

Documentation:

  • CONTRIBUTING.md: changelog section with style guidance (imperative tone, package prefix, <80 chars)
  • RELEASING.md: updated backporting section

Improvements over #4382

  • Added deprecated and removed categories (original only had added/changed/fixed)
  • Style guidance in CONTRIBUTING.md
  • towncrier added to dev dependency group
  • Updated bot references to otelbot[bot]
  • Based on current main (original PR was months stale)

Type of change

  • New feature (non-breaking change which adds functionality)
  • This change requires a documentation update

How Has This Been Tested?

  • towncrier build --draft --version "Unreleased" — verified fragment parsing and categorized output
  • towncrier build --yes --version "1.42.0/0.63b0" — verified full build inserts into CHANGELOG.md at marker, deletes fragments
  • Verified CI changelog preview step renders correctly

Does This PR Require a Contrib Repo Change?

Checklist:

  • Followed the style guidelines of this project
  • Changelogs have been updated
  • Unit tests have been added
  • Documentation has been updated

@MikeGoldsmith
MikeGoldsmith requested a review from a team as a code owner May 8, 2026 12:05
@MikeGoldsmith MikeGoldsmith added the Skip Changelog PRs that do not require a CHANGELOG.md entry label May 8, 2026
@linux-foundation-easycla

linux-foundation-easycla Bot commented May 8, 2026

Copy link
Copy Markdown

CLA Signed

The committers listed above are authorized under a signed CLA.

Replace manual CHANGELOG.md editing with towncrier fragment-based changelog
management. Each PR adds a small text file in .changelog/ instead of editing
the changelog directly, eliminating merge conflicts.

Changes:
- Add towncrier configuration in pyproject.toml with 5 fragment types
  (added, changed, deprecated, removed, fixed)
- Replace sed-based changelog generation in release workflows with
  towncrier build
- Add changelog backport step to patch release workflow
- Update CI to use towncrier check for fragment validation
- Add pre-commit check via scripts/check_changelog_fragment.py
- Add tox environments: changelog (preview) and new-changelog (create)
- Add contributor documentation in CONTRIBUTING.md
- Convert existing unreleased entries to fragment files
- Add custom Jinja2 template for changelog output

Based on the proof-of-concept in open-telemetry#4382 by @emdneto.

Co-authored-by: Emídio Neto <[email protected]>
Assisted-by: Claude Opus 4.6
@MikeGoldsmith
MikeGoldsmith force-pushed the mike/towncrier-review branch from 6d7185f to f664c36 Compare May 8, 2026 12:09
Existing ## Unreleased entries stay in CHANGELOG.md — the towncrier
marker is placed above them. Fragment migration can happen at the
next release.

Assisted-by: Claude Opus 4.6
- Regenerate misc.yml for new changelog/new-changelog tox envs
- Update uv.lock for towncrier dependency
- Apply ruff formatting to check_changelog_fragment.py

Assisted-by: Claude Opus 4.6

@emdneto emdneto left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome. Thanks for resurrecting this 👍🏻 Left some comments

Comment thread tox.ini Outdated
Comment thread .pre-commit-config.yaml Outdated
@aabmass

aabmass commented May 11, 2026

Copy link
Copy Markdown
Member

Awesome thanks Mike! I think we discussed it on slack but I can't remember the pro/cons of town crier vs chloggen.

Per review feedback from @emdneto:
- Remove changelog/new-changelog tox envs (they generate CI jobs)
- Remove pre-commit hook (not all PRs need changelog, PR number
  unknown at commit time)
- Simplify CONTRIBUTING.md to document direct file creation
- Regenerate misc.yml

Assisted-by: Claude Opus 4.6
@MikeGoldsmith

Copy link
Copy Markdown
Member Author

Awesome thanks Mike! I think we discussed it on slack but I can't remember the pro/cons of town crier vs chloggen.

Both tools solve the same problem in a similar way - they replace a single CHANGELOG.md that causes merge conflicts with per-PR fragment files that get compiled at release time.

towncrier chloggen
Language Python (pip install) Go binary
Fragment format Plain text file Structured YAML (change_type, component, note, issues, subtext)
File naming <PR#>.<type> Auto-generated from git branch name
Validation towncrier check (branch-level) chloggen validate (validates against component list)
Used by pip, pytest, attrs, Twisted OTel Collector, Collector Contrib
Install in CI pip install towncrier Requires Go toolchain or pre-built binary

I suggested Towncrier because it's built for use with with python projects, chloggen is a custom OTel tool used by the collector and requires a go binary.

  • Native to the Python ecosystem — pip install in CI, no Go toolchain needed
  • Simpler contributor experience — create a text file with one line, vs filling out a YAML template with multiple fields
  • Already widely adopted by major Python projects, so many contributors will already be familiar with the workflow
  • chloggen's component validation is valuable for collector-contrib (200+ components) but less useful for core Python where all packages release together

I'm not against chloggen, they are very similar. chloggen would tie back into more OTel and has a stricter fragment strucure which would be nice.

Comment thread .github/workflows/changelog.yml Outdated
Comment thread CHANGELOG.md
Comment thread .github/workflows/prepare-release-branch.yml
Comment thread .github/workflows/prepare-patch-release.yml

@emdneto emdneto left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm really happy to see that we now have an agreement on this!

My suggestion is we wait for the next release and prioritize merging this ASAP so we can start with a very fresh changelog, and you won't need to map every already merged PR to an entry here. Also, I believe we need at least the same setup for -contrib so the contributor experience is the same in both repos.

Comment thread .github/workflows/changelog.yml
Per review feedback from @aabmass.

Assisted-by: Claude Opus 4.6
- Pin towncrier==25.8.0 for repeatability (per @aabmass)
- Add preview step to print rendered changelog in CI (per @emdneto)
- Fix error messages to reference CONTRIBUTING.md

Assisted-by: Claude Opus 4.6
Remove references to manual ## Unreleased header requirements.
Note that towncrier eliminates changelog merge conflicts during backports.

Assisted-by: Claude Opus 4.6
Comment thread RELEASING.md Outdated
Per feedback from @xrmx — no need to explain the old problem
since it's already solved.

Assisted-by: Claude Opus 4.6
@MikeGoldsmith MikeGoldsmith moved this to Ready for merge in Python PR digest May 12, 2026
@lzchen
lzchen merged commit 5ccb54f into open-telemetry:main May 12, 2026
479 of 480 checks passed
@github-project-automation github-project-automation Bot moved this from Ready for merge to Done in Python PR digest May 12, 2026
@MikeGoldsmith
MikeGoldsmith deleted the mike/towncrier-review branch May 13, 2026 11:42
raajheshkannaa added a commit to raajheshkannaa/opentelemetry-python that referenced this pull request May 14, 2026
Address @emdneto's feedback: replace direct CHANGELOG.md edit with a
.changelog/5017.fixed fragment per the new towncrier workflow added in
open-telemetry#5187.
xrmx pushed a commit that referenced this pull request May 15, 2026
* migrate unreleased changelog entries to towncrier fragments

Convert 26 existing entries from the ## Unreleased section of
CHANGELOG.md into towncrier fragment files in .changelog/,
completing the migration started in #5187.

The ## Unreleased section is removed since towncrier now manages
changelog generation from fragment files at release time.

Assisted-by: Claude Opus 4.6

* fix fragment PR numbers and categorization

- 5072.fixed → 5077.fixed (5072 was the issue, 5077 is the PR)
- 4907.added → 4908.added (4907 was the issue, 4908 is the PR)
- 5163.changed → 5163.fixed (recategorize as fix)

Per review from @xrmx.

Assisted-by: Claude Opus 4.6
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Skip Changelog PRs that do not require a CHANGELOG.md entry

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Backport workflow as part of releasing is broken Patch release workflow doesn’t backport the patch changelog entry to main branch

5 participants