How generating release notes from pull requests saved hours and made them better, plus the small habits that make an automated changelog worth reading.

Release day used to end with the same chore. Someone scrolled through merged work, tried to remember what each change did, and typed a changelog from memory. It took an hour, it was easy to skip when busy, and it always missed something.

We moved to generating the first draft automatically from pull requests. The result is faster to produce and more accurate. Here is how it works and what we learned.

The idea

Every change that reaches your main branch already has a title and a description, written by the person who knows the change best, at the moment they know it best. That is the raw material for release notes. The job is to collect it, group it and tidy it.

Humans write the pull request and polish the final text. A tool does the collecting in between.

What makes it work

Write pull request titles for readers

Because titles become changelog lines, they must make sense to a user. Compare “Fix bug in handler” with “Fix crash when exporting an empty report”. The second can go straight into the notes.

Use labels to group

A small set of labels, such as feature, fix, docs, breaking and internal, lets a tool sort changes into sections automatically.

release-notes config
sections:
  - title: "New features"
    labels: [feature]
  - title: "Fixes"
    labels: [fix]
  - title: "Breaking changes"
    labels: [breaking]
  - title: "Documentation"
    labels: [docs]
exclude_labels: [internal, chore]

Keep a human in the loop

The generated draft is a starting point. A person should read it, merge duplicates, fix awkward wording and move the most important change to the top. This takes minutes instead of an hour.

Before and after

Automation handles the collecting so people can focus on clarity.

Things to watch

  • Garbage in, garbage out. If titles are sloppy, the notes will be too. Mention it in code review.
  • Do not list everything. Users do not care about internal refactors. Filter them out.
  • Call out breaking changes loudly. Put them at the top, with a short migration hint.
  • Write for users, not for engineers. Say what changed for them and why it matters.