Two artifacts get confused constantly. The changelog answers “what changed, exactly” for developers - keep a changelog from git tags covers generating one honestly. Release notes answer a different question for a different reader: “what can I do now that I could not before, and did anything I rely on change?” Users, not maintainers. The mistake is shipping the ledger to the letter’s audience.
Lead with what the reader gets#
Not “Fixed bug in invoice retry logic” but “Failed invoice payments now retry automatically - no more manual re-runs.” Same change, different subject. The test for each line: can a user tell whether to care in five seconds? If the change is invisible to them - refactors, dependency bumps, internal cleanup - it does not belong in release notes at all. It belongs in the changelog, which is exactly why having both frees you.
The shape that works#
Three groups, in this order, skipping any that are empty:
- New - capabilities, with a sentence on when you would reach for each.
- Improved and fixed - changes to things people already use, phrased from their side (“exports are faster”, not “optimized query”).
- Breaking and action needed - the section everyone reads first even though it is last. Anything requiring a config change, a migration, or a new minimum version goes here, with the exact step to take. Hiding a breaking change in the fixed list is how release notes lose trust permanently.
The habits behind good notes#
Write the note with the PR, not at release time. One line in the pull request description - “release note: …” - while the context is fresh beats reconstructing twenty changes from commit messages on release day. Your PR template can carry the prompt.
Tie notes to the tag. Notes ship when the version ships - see deploy with tags, not branches - so “what is in production” and “what do the notes say” can never drift.
Keep a human pass. Generated drafts are a fine start; a generated final is a ledger wearing the letter’s clothes. Ten minutes of editing per release is the whole cost.
Users who trust your release notes read them. That trust is built line by line, and spent in one “everything changed, nothing says why.”
Share this post
Keep reading
Conventional Commits for a Small Team
A prefix on every commit message - feat, fix, chore - makes the log scannable and the changelog half-written. Keep the rules short or the team routes around them.
Keeping a Changelog From Git Tags
Tags mark what shipped; the log between them writes the changelog. A small habit that pays off every release.
Deploying a Laravel App With Git Push
A bare repo and a post-receive hook are enough for a honest small-team deploy: checkout, composer, migrate, cache.