Writing better release notes
31st January 2022
Release notes are an important part of the open source process. I’ve been thinking about these a lot recently, and I’ve assembled some thoughts on how to do a better job with them.
Write release notes. Seriously—if you want people to take advantage of the work you have been doing to improve your projects, you need to tell them about it!
Include the date. The date matters a lot, because I want to be able to determine how old a release is—especially important for the dependencies I am using.
It’s much more reasonable to assume people will be running as a minimum a version from 3 years ago than one that came out last week.
Make sure people can link to the release notes for a version. This can be a page-per-release or an anchor target on the releases page, but it needs to be possible and it needs to be discoverable.
There are some projects for which I have to view source on the HTML page to find the anchor links for the version headers—don’t make me do that!
For larger releases, break them up with headers. “New features” v.s. “Bug fixes” is a useful distinction.
Emphasize the highlights. It can be easy for the highlights of a larger release to get lost in a sea of bullet points. I’ll sometimes include an introductory paragraph highlighting the major themes.
Link to relevant documentation from the release notes. If I want to know more about a new feature that should be the best place for me to start.
Flesh them out with examples and screenshots. Most release notes are pretty dry—there’s no space limit on these things, so feel free to use all of the tools at your disposal to best answer the question “what has changed and why does this matter to me?”
Link to the associated issue thread. If I want to know more about a feature, and you’ve been using issues effectively, the issue link can tell me the entire story of the new feature in more detail than anything else.
Credit your contributors! If someone helped build a feature the release notes are a great place to give them a shout out.
When I tweet my release notes (recent example) I include both a link to them and, if they’re short, a screenshot of the release notes with an alt= attribute duplicating their content.
GitHub Releases and GitHub Actions
I really like the GitHub releases feature. You can easily create new release attached to tags, and each release gets its own linkable page. Release notes are written in Markdown and you can edit them later on, expanding them further and fixing any typos or errors.
Releases pages also automatically link to a zip or .tar.gz file of your repository at that tag, and you can attach binary builds to that page too.
Plus they have a good API, and they integrate well with GitHub Actions.
I manage all of my Python package releases using this—I have an actions workflow which triggers on a new GitHub release, builds and packages that tag and then uploads it to PyPI—so all I have to do is click “new release” and fill in the form and my automation does the rest of the work.
Annotated release notes
Something I’ve been trying with my own projects is publishing annotated release notes to accompany the official ones.
The idea here is that while the official release notes succinctly document “what changed”, the annotated ones are a place where I can provide personal notes about the new features—the background on them, what I learned along the way and my own opinions on what they are useful for and why.
I enjoy writing these, but I’ve not yet got a great feel for if people find them useful or not—so I’m not ready to recommend them as a thing that other projects should aim to replicate. I like them though, so if you write them for your project I will look forward to reading them!
I’m a huge fan of Django’s release notes—they’re some of the best I’ve ever seen. It’s worth exploring both minor releases and major releases for an example of what this looks like when it’s done really well.
More recent articles
- Weeknotes: the Datasette Cloud API, a podcast appearance and more - 1st October 2023
- Things I've learned about building CLI tools in Python - 30th September 2023
- Talking Large Language Models with Rooftop Ruby - 29th September 2023
- Weeknotes: Embeddings, more embeddings and Datasette Cloud - 17th September 2023
- Build an image search engine with llm-clip, chat with models with llm chat - 12th September 2023
- LLM now provides tools for working with embeddings - 4th September 2023
- Datasette 1.0a4 and 1.0a5, plus weeknotes - 30th August 2023
- Making Large Language Models work for you - 27th August 2023
- Datasette Cloud, Datasette 1.0a3, llm-mlc and more - 16th August 2023
- How I make annotated presentations - 6th August 2023