Release Notes Template: 4 Versions, 630 Real Releases
On this page
Version 4.2 goes out on Tuesday. On Wednesday a customer opens a ticket: their payment reminders changed and nobody told them. The release notes did mention it, as “INV-417 fix reminder dedupe (tz)”, in a list of forty ticket titles that nobody outside the team could read.
Release notes fail when they are one list written for everyone. This page takes a single release and writes it four ways, for customers, for support, for developers and for the app stores. Each version comes with a blank template to copy. Behind them is a count of what 630 real release notes contain.
Short answer: a release note tells one reader what changed for them and what they need to do. This template covers most releases:
# [Product] [version] ([YYYY-MM-DD])
[One sentence: the change that matters most, and who it affects.]
## Action needed
- [What the reader must do, by when. Delete this section if nothing.]
## New
- **[Feature]:** [what the reader can now do, in their words]. [Link]
## Fixed
- [What used to go wrong, now fixed.]
## Known issues
- [Problem, workaround, when a fix is expected.]In the latest releases of 630 top GitHub projects, 66% link the pull requests, but only 9% give upgrade steps and 1% list known issues. Those two are the sections readers need most.
What a release note has to answer
Every good release note answers five questions, in this order, for its reader:
- Does this affect me? The version, the date and one sentence on who the release matters to. Caddy opens its 2.11.9 notes this way: it fixes a regression from 2.11.8, and if you are on 2.11.8 and serve PHP, it recommends upgrading.
- Do I have to do anything? Breaking changes, upgrade steps, deprecations with a removal date, a setting to switch on. This goes first because it is the part that costs the reader if they miss it.
- What can I do now that I could not before? New features, described as what the reader can do, not what the team built.
- What stopped going wrong? Fixes, in past tense, described as the symptom the reader saw.
- What is still wrong? Known issues and workarounds. Saying it up front saves support tickets.
Semantic Versioning makes question 2 visible in the number itself: a MAJOR version is for “incompatible API changes”, a MINOR one adds functionality “in a backward compatible manner”, and a PATCH is for “backward compatible bug fixes”. Readers of a 5.0.0 know to look for the action section.
One release, four readers
Here is the release we will write up. Acme Invoices is a made-up invoicing app; version 4.2.0 holds seven work items:
| Work item | What changed | Customers | Support | Developers | Stores |
|---|---|---|---|---|---|
| INV-412 | A recurring invoice can be paused | yes | yes | yes | yes |
| INV-398 | CSV export lets you choose the columns | yes | yes | yes | |
| INV-405 | PDF showed the wrong tax total when a discount came after tax | yes | yes | yes | |
| INV-417 | Some customers got the same payment reminder twice | yes | yes | yes | |
| INV-420 | API: cursor pagination; the page parameter is deprecated | yes | yes | ||
| INV-422 | Webhooks need TLS 1.2 or newer from 15 December 2026 | yes | yes | yes | |
| INV-409 | PDF library upgraded | yes |
Known issue: CSV export stops at 50,000 rows. The same seven facts make four quite different documents.
For customers
Customers read release notes in an email, an in-app panel or a “What’s new” page. They want benefits in their own words and anything that needs their attention. Leave out internal work (INV-409) and API details they never touch.
# What's new in Acme Invoices 4.2 ([date])
[One sentence: the biggest change for the customer.]
## Please check
- [Anything the customer must do, with a date. Delete if nothing.]
## New
- **[Feature name]:** [what you can now do]. [How to find it.] [Help link]
## Improved
- [Existing feature]: [what is easier or faster now].
## Fixed
- [Symptom the customer saw] no longer happens.
## Known issues
- [Problem]. [Workaround until the fix.]
Questions? [Support link]
Filled in:
# What's new in Acme Invoices 4.2 (8 December 2026)
You can now pause a recurring invoice instead of deleting it.
## Please check
- If you send webhooks to your own server, it must accept TLS 1.2 or newer
from 15 December 2026. Most servers already do. How to check: [link]
## New
- **Pause a recurring invoice:** stop it for as long as you need and resume
it later with the same customer, amount and schedule. Open the invoice
and choose Pause.
- **Choose your CSV columns:** pick the fields you want before you export.
## Fixed
- PDF invoices now show the right tax total when a discount is applied
after tax.
- Payment reminders are no longer sent twice to some customers.
## Known issues
- CSV export stops at 50,000 rows. Export a shorter date range until we
lift the limit.
Note what was left out: ticket keys, the library upgrade, the API change. The webhook rule stayed in, under “Please check”, because a customer with an old server would otherwise find out from failed payments.
For support and internal teams
Support, sales and on-call need the opposite: everything, with ticket keys, so they can answer “is this the bug I reported?” and know what might break. This version also carries the rollout plan.
# Release [version]: internal notes ([date])
Owner: [name] | Rollout: [date, % of customers, feature flag] | Rollback: [how]
## Customer-visible changes
| Key | Change | Who notices | Support answer / macro |
|-----|--------|-------------|------------------------|
## Behaviour that may cause tickets
- [Change]: [what customers may ask]. [Suggested reply.]
## Internal only
- [Key] [change] (no customer impact expected)
## Known issues
- [Key] [problem], [workaround], fix planned for [version].
## Links
- Jira version: [link] | Customer notes: [link] | Runbook: [link]
Filled in:
# Release 4.2.0: internal notes (8 December 2026)
Owner: Dana Kim | Rollout: 8 Dec, 10% of accounts, then all on 10 Dec
(flag: recurring-pause) | Rollback: turn the flag off; no data migration
## Customer-visible changes
| Key | Change | Who notices | Support answer |
|---------|------------------------------|------------------------|------------------------|
| INV-412 | Pause a recurring invoice | all recurring users | macro "Pause invoice" |
| INV-398 | CSV export: choose columns | accountants | help article updated |
| INV-405 | PDF tax total, late discount | accounts with discounts| reissue PDFs if asked |
| INV-417 | Duplicate payment reminders | some time zones | apologise, now fixed |
| INV-422 | Webhooks: TLS 1.2+ from 15 Dec | 37 accounts on old TLS | CSM emails each one |
## Behaviour that may cause tickets
- INV-405: customers may ask for corrected PDFs of past invoices. Reissue
from the admin page; totals in the database were always right.
## Internal only
- INV-409 PDF library upgraded. Watch PDF error rate for 48 hours.
## Known issues
- INV-431 CSV export stops at 50,000 rows. Workaround: shorter date range.
Fix planned for 4.3.
## Links
- Jira version 4.2.0 | Customer notes | Runbook: PDF rendering
For developers using your API or library
Developers read release notes before they bump a dependency or an API version. They want to know, in seconds, whether anything breaks. Keep a Changelog’s six headings suit them: “Added for new features”, “Changed for changes in existing functionality”, “Deprecated for soon-to-be removed features”, “Removed for now removed features”, “Fixed for any bug fixes” and “Security in case of vulnerabilities”. Put the action first.
## [version] - YYYY-MM-DD
[One line: what this release is for. Say if it is safe to upgrade.]
### Upgrade notes
- [Required change, with before/after code.]
### Added
### Changed
### Deprecated
- [What], removed in [version or date]. Use [replacement].
### Removed
### Fixed
### Security
- [CVE or advisory link], [who is affected].
[Full diff: link to compare vX...vY]
Filled in:
## [4.2.0] - 2026-12-08
New pagination for the invoices API. One deprecation, one webhook requirement.
### Upgrade notes
- Webhook endpoints must accept TLS 1.2 or newer from 2026-12-15.
### Added
- `GET /v2/invoices` returns `next_cursor`; pass it as `cursor` to get the
next page (#420).
- `paused` status for recurring invoices, and `POST /v2/recurring/{id}/pause`
and `/resume` (#412).
### Deprecated
- The `page` parameter of `GET /v2/invoices`. It keeps working until
2027-06-01, then returns 400. Before and after:
```
GET /v2/invoices?page=3
GET /v2/invoices?cursor=eyJpZCI6MTIzfQ
```
### Fixed
- `tax_total` on generated PDFs when a discount is applied after tax (#405).
[4.2.0]: https://example.com/acme/compare/v4.1.3...v4.2.0
Semantic Versioning’s FAQ is the reason the deprecation keeps working for six months: removing it now would make this a breaking change, which needs a new major version. If one slips out by mistake, the spec’s advice is to “fix the problem and release a new minor version that corrects the problem and restores backward compatibility.”
For the app stores
App stores give you a small box and a fixed limit. Apple’s App Store Connect describes “What’s New in
This Version” as “A description of the changes in this version of the app, such as new features, UI
improvements, or bug fixes. Limited to 4000 characters.” Google Play is far stricter: “You can enter
release notes using up to 500 Unicode characters per language”, each language between tags such as
<en-US>. Only the first lines show before “more”, so lead with the change people will care about.
<en-US>
[Biggest change, as a benefit.]
[Second change.]
Fixed: [symptom people saw].
</en-US>
Filled in, for Google Play (280 characters, well under 500):
<en-US>
Pause a recurring invoice: stop it for as long as you need, then resume it with the same schedule.
Export invoices to CSV with the columns you choose.
Fixed: PDF invoices showed the wrong tax total when a discount came after tax.
Fixed: some customers got the same reminder twice.
</en-US>
For the App Store you have room for a short paragraph per feature and a line thanking people who reported bugs, but the same rule holds: the first two lines decide whether anyone taps “more”. Leave out webhooks and APIs; nobody updating a phone app needs them. “Bug fixes and performance improvements” tells the reader nothing; one concrete fix is better.
What 630 real release notes contain
We read the latest release of each of the 1,000 most-starred repositories on GitHub on 13 November 2026. 253 have never published a GitHub Release. 630 published one in the last 12 months, and those are the notes counted below.
What stands out:
- The bookkeeping is nearly universal. 91% tag a version number, 66% link the pull requests or issues, 47% credit contributors by their GitHub handle. That serves people who read the diff.
- The reader’s questions are rare. A summary or highlights section appears in 10%, upgrade or migration notes in 9%, known issues in 1%. A breaking change is announced in 5% of latest releases; across each project’s last five stable releases, 15% announced one at some point.
- Grouping is the norm, but not a standard. 54% group changes under headings. The most common headings were GitHub’s own “What’s Changed” (116 releases) and “New Contributors” (95), then “Bug fixes” (81), “Fixes” (54), “Highlights” (50) and “Features” (47). Only 4% use Keep a Changelog’s headings.
- Length varies hugely. The median note is 240 words; half fall between 65 and 789. Notes made with GitHub’s generator run longer (median 479 words) than the rest (198), because they list every pull request.
- Releases are frequent. The median gap between a project’s last five stable releases was 14 days. Notes written every two weeks need a template, or they drift.
Three that do the reader’s part well:
- Sunshine starts with an “Attention” section for a high-severity Linux security fix, then “Breaking changes and migration notes”, then highlights. The action comes before the features.
- Caddy opens with a paragraph saying what the release is and who should upgrade, then explains each highlight as the symptom users saw (a directory request that “usually got a 404”).
- Immich puts one human sentence above GitHub’s generated list (“Notably, it also fixes the performance issues with shared links”). One sentence turns a list of pull requests into a release note.
Get a first draft from Jira
Jira Cloud builds release notes from a version. Atlassian’s documentation says you can “generate release notes for all the work items within a version, categorized by work type.” The steps:
- Open your space and select the Releases tab.
- Select the version, then Release notes.
- Select Create release notes in Jira.
- Select Formatting options to choose the fields to include.
- Select Copy to clipboard to paste them as Markdown or HTML, or Save release notes to keep them in the version’s Related work section.
You can also create them in Confluence, as a draft page whose table includes “a smart link, the date, your description, and everyone who worked on one of the work items.” That needs Confluence and Jira on the same site. With Rovo turned on and Confluence active, a Create with Rovo toggle drafts the text for you.
Four details from the same page that save time:
- Add a “Release notes” field. Add a Paragraph field to the work item, call it “Release notes”, and pick it under Formatting options. Then the person who did the work writes the reader’s sentence while the context is fresh, and the generated notes use it instead of the ticket title.
- The notes are live. “Each time you view your release notes, we automatically generate them based on the current state of your version.” Saving keeps the format, not the content, so copy the text out when the release ships.
- Markdown has limits. If the notes include panels, dates, expands or statuses, Jira offers HTML only. Remove those fields to copy Markdown.
- No images. “Media such as images, videos, and other files, are not yet supported.” Add screenshots after you paste.
Jira gives you the support version almost as is. The customer and store versions still need the rewrite shown above.
Check the version before you generate anything. When you release with open work, Jira can move items that already shipped into the next version, and they drop out of these notes. We tested it in Jira fix version.
Get a first draft from GitHub
GitHub’s Generate release notes button fills the release description with “a list of merged pull
requests, a list of contributors to the release, and a link to a full changelog.” A file at
.github/release.yml sorts those pull requests into sections by label. Only 26 of the 1,000 top
repositories have one; of those, 20 also exclude some pull requests (bots, dependency bumps) from the
notes. This one matches the four-question order above:
# .github/release.yml
changelog:
exclude:
labels:
- ignore-for-release
authors:
- dependabot
categories:
- title: Action needed
labels:
- breaking-change
- deprecation
- title: New
labels:
- enhancement
- title: Fixed
labels:
- bug
- title: Other changes
labels:
- "*"
GitHub’s docs explain the "*" label as a catch-all “for pull requests that didn’t match any of the
previous categories.” lazygit uses the same file with
eight sections, from “Features” to “Other Changes”. The generated list is a draft for developers. Add a
summary sentence on top, as Immich does, and rewrite the “Action needed” items as steps.
Rewrite ticket titles into reader sentences
Most of the work is turning the team’s words into the reader’s. Keep a Changelog warns why a raw list fails: “Using commit log diffs as changelogs is a bad idea: they’re full of noise.”
| Ticket or commit title | Release note line |
|---|---|
| INV-417 fix reminder dedupe (tz) | Payment reminders are no longer sent twice to some customers. |
| feat: recurring pause endpoint | You can now pause a recurring invoice and resume it later. |
| Bump pdfkit to 0.15 | (leave out of customer notes; internal notes only) |
| Refactor tax calc | PDF invoices now show the right tax total when a discount comes after tax. |
| Drop TLS 1.0/1.1 for webhooks | From 15 December, your webhook server must accept TLS 1.2 or newer. |
| Misc fixes | (name one real fix, or leave it out) |
Rules that make the difference:
- Present tense for what is new, past tense for what was wrong. “You can now pause”, “showed the wrong total”.
- Describe the symptom, not the cause. Readers recognise “sent twice”, not “dedupe”.
- Give dates for anything that will stop working. “Deprecated” without a date is not actionable.
- Name a number when you have one. “Up to 50,000 rows” beats “large exports”.
- One owner signs off. Support reads the customer version before it goes out.
Release notes, changelog, announcement
The three overlap, so teams often write one and call it all three.
| Document | For | Covers | Lives in |
|---|---|---|---|
| Changelog | developers, anyone auditing | every version, every notable change | CHANGELOG.md, docs site |
| Release notes | one audience | one release, what it means for them | release page, email, app store |
| Announcement | customers, prospects | one big feature, with the why | blog, newsletter, in-app |
Keep a Changelog’s rules fit the first: “The latest version comes first”, “The release date of each
version is displayed”, and “Keep an Unreleased section at the top to track upcoming changes.” Release
notes are what you write from that file when the version ships.
Make “release notes written” part of the release
The common failure is not a bad template. It is the release shipping before anyone wrote the notes. Our Definition of Done study found that 15% of the top projects’ pull-request checklists ask for a changelog or release note entry. That covers single changes; the release itself needs its own check.
If your releases are tracked in Jira, put that check on the release work item:
- A checklist with a gate. Team Checklist, our app, includes a Release checklist starter template: release notes written, version bumped, changelog updated, rollback plan ready, release announced. A project can add it to every new release work item. With the “Team checklist is done” validator on the Done transition, Jira refuses the move while any item is open and says: “Finish the team checklist first: every item must be done (the Team Checklist panel shows what is left).” Edit the template to match your four audiences, for example one item per version of the notes. Team Checklist is free for up to 10 users.
- Due dates you can see. Give the “write release notes” and “announce” tasks a due date the day before the release. Deadline Tracker shows every overdue and due-soon work item across projects on one board and can send you a daily reminder of yours, so a missing release note shows up before release day, not after. It works from the due date field, not the version’s release date.
Why native Jira checklists are not enough for this, tested: Jira checklist.
How we counted
- Sample: the 1,000 most-starred public repositories from the GitHub search API, the same list as our Definition of Done study (read 13 November 2026; the smallest had 34,741 stars).
- Releases: the five newest GitHub Releases of each repository through the GraphQL API, on 13 November 2026. We took the newest that was not a draft or a pre-release (or the newest pre-release for 23 projects whose last five were all pre-releases) and kept it if it was published in the last 365 days. 630 repositories qualified; 253 had no releases at all, 117 none in the last year.
- Parts: keyword rules on the release text, with HTML comments removed. Headings are Markdown headings or lines that are bold only. “Grouped” means at least one heading names a kind of change (features, fixes, breaking, security, performance, docs, dependencies, improvements, changes). “Generated” means GitHub’s “What’s Changed” heading plus its “Full Changelog” compare link. Badges were not counted as images.
- Hand checks: we read samples for each rule. A first “breaking” rule caught phrases like “non-breaking spaces” and “without breaking existing setups”, so the final rule needs “breaking change” or “BC-breaking” and skips “no”, “non-” and “any” before it; 13 of 15 sampled matches were real announcements.
.github/release.yml: read from the default branch of all 1,000 repositories (.ymlor.yaml).- Not counted: notes kept outside GitHub Releases (a CHANGELOG file, a blog, a docs site). Some projects link out instead (22 short notes did), so the share that publishes release notes somewhere is higher than these numbers show.
The scripts and raw data are in our research notes.
Sources
- Olivier Lacan and contributors, Keep a Changelog 1.1.0.
- Tom Preston-Werner, Semantic Versioning 2.0.0, summary and FAQ.
- GitHub Docs, Automatically generated release notes.
- Atlassian Support, Create release notes, Jira Cloud.
- Apple, App Store Connect Help, Platform version information.
- Google, Play Console Help, Prepare and roll out a release.
- Releases of Caddy 2.11.9,
Sunshine and
Immich 3.4.1, and the
.github/release.ymlof lazygit, read through the GitHub API on 13 November 2026.
Frequently asked questions
What is the difference between release notes and a changelog?
A changelog is the full record, every notable change in every version, newest first, usually in a CHANGELOG file. Release notes are written for one release and one audience and pick what that reader needs: what is new for them, what is fixed, and what they must do. Keep a Changelog puts the changelog side simply: “Changelogs are for humans, not machines.”
What should release notes include?
The version and date, one sentence on who the release matters to, what is new, what is fixed, and anything the reader must do: breaking changes, upgrade steps, deprecations with a date. Add known issues and a link to the details. In our count of 630 recent GitHub releases, 66% linked the work but only 9% gave upgrade steps and 1% listed known issues.
Who should write release notes?
One named owner per release, usually the product manager or the tech lead, with a technical writer where there is one. Engineers supply the facts (a release-notes field on each work item helps); support and customer success read the draft before it goes out, because they will answer the questions it raises.
How long should release notes be?
As short as the release allows. The median latest release of the 630 projects we read was 240 words; half were between 65 and 789. GitHub-generated lists ran longer (median 479 words) than hand-written notes (198). Put the one change that matters most in the first sentence and link to the full list.
Can Jira generate release notes automatically?
Yes, for a version. In Jira Cloud open the space’s Releases tab, select the version, then Release notes. You can create them in Jira and copy them as Markdown or HTML, create a draft page in Confluence, or draft them with Rovo. Jira groups the version’s work items by work type; you still rewrite them for your reader.
Do release notes need a version number?
Yes, so readers can tell which notes apply to them. 91% of the recent releases we counted carried a version like 2.11.9 in the tag. If you follow Semantic Versioning, a major number tells developers to look for breaking changes before they upgrade.
Should every release have release notes?
Every release a customer or developer can see, yes, even a one-line patch. Internal-only releases can skip the customer version, but support and on-call still need the internal one. Keep a Changelog states it plainly: “There should be an entry for every single version.”