All posts
Jun 3, 2026 · 4 min read · Nadun

How to automate your changelog from pull requests

A practical guide to generating a changelog from your PRs — from conventional commits to release-please to fully automatic, grounded drafts. With the trade-offs of each.

A changelog is one of those things everyone agrees is valuable and almost nobody keeps current. It starts strong — a tidy ## [1.0.0] with neat bullet points — and three releases later it's either empty or a copy-paste of git log nobody can read.

The good news: a PR is a near-perfect unit to build a changelog from. It has a title, a description, a diff, and a merge event. The question is just how much of the work you want to automate, and how much you're willing to trust. Here's the spectrum, from "still mostly manual" to "fully automatic," with the honest trade-offs of each.

Level 0: hand-written (the baseline)

You keep a CHANGELOG.md and edit it by hand on each release. It produces the best-written changelog when you do it — and that's the whole problem. Under deadline, the changelog is the first thing to get skipped, and once it's a release behind, nobody trusts it enough to fix it. Fine for a side project; fragile for anything shipping weekly.

Level 1: conventional commits

The first real rung. You adopt Conventional Commits — commit messages like feat: add OAuth login or fix: handle empty cart — and a tool parses them into a changelog.

Tools: conventional-changelog, standard-version, commitizen.

The good: deterministic, no AI, version bumps fall out automatically (a feat bumps minor, a fix bumps patch).

The catch: it's only as good as your commit discipline. The moment someone merges wip, fixed it, or a squash-merge that flattens ten messy commits into one, the changelog reflects that mess. You've moved the discipline problem from "write the changelog" to "write perfect commit messages forever" — which is easier, but not free.

Level 2: release-please / release automation

release-please (and similar) watch your conventional commits and open a "release PR" that bumps the version and updates the changelog. Merge it, and it tags the release.

The good: this is genuinely excellent for teams already disciplined about conventional commits. The release PR is reviewable, and versioning is automatic.

The catch: same dependency on commit hygiene, plus it's changelog-and-version focused — it won't touch your README, your API docs, or your guides when the code they describe changes. Your changelog stays current; the rest of your docs still rot.

Level 3: generate from the diff itself

The next step is to stop depending on humans writing structured commit messages at all, and instead read the diff — the actual code that changed — and draft the changelog entry from that.

This is where AI earns its place, and also where it gets dangerous if you're naive about it. Hand a model a diff and ask for a changelog and it will happily write a confident entry about a function you never added. The fix isn't "trust the model more" — it's to constrain it to what's in the diff:

  • The entry may only reference identifiers (functions, files, flags) that actually appear in the change.
  • Anything that mentions code not present in the diff gets rejected, not published.
  • The result is opened as a PR you review — never written straight into your repo.

That constraint — call it a grounding gate — turns the model from a creative writer into a careful summarizer of something real. It can't invent a feature, because the feature has to be in the diff for it to write about it.

Which level should you pick?

  • Small project, infrequent releases: conventional commits + standard-version. Cheap, deterministic, done.
  • Disciplined team, already using conventional commits: release-please. It'll pay for itself.
  • You want the changelog and the rest of your docs current, without enforcing commit-message rules on everyone: generate from the diff, with grounding + a review PR.

There's no shame in Level 1. The point is to pick a level you'll actually sustain — the best changelog is the one that's still accurate at release #50.

The diff-grounded approach, in practice

This is what docs-keeper does: on every merge it reads the diff, drafts the CHANGELOG (and README / docs) update grounded in that diff, runs it through seven validation gates, and opens a PR you approve. No commit-message convention required, because it reads the code, not the commit text.

It's free for public repos, costs about $0.004 per doc PR, and never touches your code directly — it just opens PRs. If you've bounced off conventional-commit tooling because not everyone on the team follows the format, the diff-grounded route sidesteps that entirely.

Install free on GitHub · See a real docs PR it opened

Try it on one repo.

Free for public repos · grounded in your diff · you review every PR.

Install free on GitHub

Keep reading

Liked this? Get the next one.

Occasional posts on docs, AI, and keeping documentation in sync with code. No spam, unsubscribe anytime.