Engineering

Keep a Changelog, actually implemented

· changeloop

Olivier Lacan published Keep a Changelog in 2014 with a line that has aged better than most software writing: don’t let your friends dump git logs into changelogs. Ten years on it is the closest thing this corner of software has to a standard, which mostly means people cite it and then implement about two thirds of it.

It is worth reading the source rather than a summary of it. This is about the third that gets dropped.

What the spec actually asks for

A CHANGELOG.md at the repo root, newest first, with one section per version. Each version carries a number and an ISO date, and groups its entries under six types:

TypeFor
Addednew features
Changedchanges in existing behaviour
Deprecatedfeatures about to be removed
Removedfeatures removed in this release
Fixedbug fixes
Securityvulnerabilities

Plus an Unreleased section at the top, so there is somewhere to put an entry the moment it is merged, and so anyone can see what is coming.

That is nearly all of it. The rest is the reasoning: entries are for humans, one entry per change, and the file is a document rather than a log.

The three parts that get dropped

Unreleased disappears first. It is the section with no deadline, so it is the one that stops being maintained, and once it is gone entries get written at release time from commit history. That is precisely the git-log dump the spec opens by warning about, arrived at gradually.

The six types collapse into two. Most real changelogs end up with Added and Fixed, because Changed and Deprecated require a judgement about what someone relied on. That judgement is the valuable part. Deprecated in particular is the only type that is a promise about the future, and dropping it is how a removal turns into an incident.

Security stops being separate. A security fix filed under Fixed is invisible to the one reader who was scanning for it. Keep it distinct even when the fix is trivial, and especially when you would rather not draw attention to it.

What the spec deliberately does not answer

It is a file format. It says nothing about the questions you hit immediately after adopting it:

Common Changelog, a stricter fork of the idea, tightens some of this: it bans certain entry phrasings, requires a link to the change, and is opinionated about who the reader is. It is worth reading if the loose parts of Keep a Changelog are what your team keeps arguing about.

Automating it without dumping git logs

The spec’s warning is about output, not about tooling. Deriving a draft from structured commits is fine. Publishing that draft unedited is the thing it objects to.

A shape that holds up: derive candidate entries from commits automatically, put them in Unreleased with their type prefilled, and require a human to edit the wording before a release can be cut. The machine handles collection and formatting, which it is good at. The human handles selection and phrasing, which it is not. Our changelog tools roundup covers what exists for the collection half.

Where it stops being enough

Keep a Changelog is a good answer to “what should this file look like”. It is not an answer to “how do our users learn what changed”, because a Markdown file in a repo is a distribution strategy that only works if your users are contributors.

That is the gap most teams hit second: the file is fine, and nobody outside the team reads it. Solving it means the entries have to become data that can be rendered somewhere else, which is a different problem from formatting a file, and the reason changelog examples collects public changelog pages rather than repo files.

Adopt the spec anyway. It costs an afternoon, it makes the second problem tractable, and it is still the best one page written about this.


The technical claims in this article have not been independently reviewed. If something here is wrong, tell us and we will correct it.

Related on changeloop: Changelog examples, Changelog tools