Our raw changelog was just squashed commit subjects. Customers ignored it because it was 40 lines of refactor(api): ... that meant nothing to them.
I now generate two changelogs from the same merged PR list: one for users grouped by what they can now do, one for developers with the technical detail. Forcing the "what can the user now do differently" framing per entry was the key move.
How do you stop it from over-claiming impact on tiny internal changes?
From the list of merged PRs below (titles + labels), produce a user-facing changelog for version {VERSION}.
Group entries under exactly these headings, omitting any that are empty: "New", "Improved", "Fixed".
For each entry:
- Write it as something the USER can now do or no longer suffers, in plain language. Start with a verb or a benefit, not a component name.
- One line each, no ticket numbers, no internal component names, no 'refactor'/'chore'/'bump' entries at all (skip them silently).
- If a change is purely internal (deps, tests, CI, refactor with no behavior change), exclude it from the user changelog entirely.
Then, separately, output a short 'For developers' section that DOES include the internal changes, terse and technical.
Do not exaggerate: a bug fix is 'Fixed X', not 'Massively improved reliability'.