In this article I will show you a changelog format and a convention for assigning numbers to your software versions.
The boring introduction
During these holidays I renamed one of my side projects, because I was so smart to name it like a registered trademark. 😓 I had to find a way to communicate this to the users, because manual intervention was required in order to update.
The first thing that came to my mind was to place a big announcement at the beginning of the README in which I say that the project was renamed and the instructions required to update it. But then I thought: how much should I leave the message there?
- For 1 month? Users could update also after this time.
- For 1 year? Too many new users will be really annoyed by this big section.
The project we are talking about is intellimacs. Tldr: it is just a bunch of vim configuration files. Since the project is really simple, for a long time I thought that commit messages were enough to document the changes to the project. Turns out it is not, because since commit messages has to be small, there are too many commits with messages like "fixed typo" that create a lot of noise.
After this terrible idea I thought to build a full website with a blog were people can get updates for the project. This would not be so bad, but it is something that requires time to be built and that I'll have to maintain. Furthermore, for the user would be a pain to first read all the github documentation and then go through the website where there will be inevitably duplicated info. For a project of this size, I think that keeping everything inside the github repository is enough for now.
Anyway, now the project counts 130 stars on GitHub, so all these people deserves to get comprehensive and coincise news about the project.
The best solution I have found for my problem is to keep a changelog.
The user, before updating, can see on which version they are by running git tag
and they can see what changed
by reading this nice plain text file, which contains all the notable changes of the project.
It's something I always knew it was necessary, but that I continued to postpone with excuses like "my project is not too big yet" or "the project is very simple, commit messages are enough"
Well, turns out that now I added a changelog to my project and I found a really nice and efficient way to do it! 💪
Keeping a changelog
After some online research I found this really nice website called, in fact, keep a changelog. This website proposes a common format for changelogs which in my opinion is really nice.
This is an example of this changelog format:
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
## [1.0.0] - 2017-06-20
### Added
- "Why keep a changelog?" section.
- "Who needs a changelog?" section.
- "How do I make a changelog?" section.
### Changed
- Start using "changelog" over "change log" since it's the common usage.
- Fix phrasing and spelling in German translation.
### Removed
- Section about "changelog" vs "CHANGELOG".
## [0.1.0] - 2015-10-06
### Added
- Answer "Should you ever rewrite a change log?".
### Changed
- Improve argument against commit logs.
- Start following [SemVer](https://semver.org) properly.
## [0.0.3] - 2014-08-09
### Added
- "Why should I care?" section mentioning The Changelog podcast.
## [0.0.2] - 2014-07-10
### Added
- Explanation of the recommended reverse chronological release ordering.
## [0.0.1] - 2014-05-31
### Added
- This CHANGELOG file to hopefully serve as an evolving example of a
standardized open source project CHANGELOG.
- CNAME file to enable GitHub Pages custom domain
- README now contains answers to common questions about CHANGELOGs
- Good examples and basic guidelines, including proper date formatting.
- Counter-examples: "What makes unicorns cry?"
[Unreleased]: https://github.com/olivierlacan/keep-a-changelog/compare/v1.0.0...HEAD
[1.0.0]: https://github.com/olivierlacan/keep-a-changelog/compare/v0.3.0...v1.0.0
[0.1.0]: https://github.com/olivierlacan/keep-a-changelog/compare/v0.0.8...v0.1.0
[0.0.3]: https://github.com/olivierlacan/keep-a-changelog/compare/v0.0.2...v0.0.3
[0.0.2]: https://github.com/olivierlacan/keep-a-changelog/compare/v0.0.1...v0.0.2
[0.0.1]: https://github.com/olivierlacan/keep-a-changelog/releases/tag/v0.0.1
The changelog starts with a brief introduction and then it lists all the versions of the software.
Basically, when you make a change to your software, you add this change to the Unreleased
section,
in one of the following subsections:
- 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.
- Security
- In case of vulnerabilities.
When a new release is ready, rename the Unreleased
section with the new version number and the current date.
And you are done! You have your changelog.
The Unreleased
section will be empty again, ready to be filled with your new awesome changes! 😃
Version numbers
Now..how to choose version numbers?
Well, for that the Keep a Changelog website indicates Semantic Versioning. This standard indicates that the software version should be in the format MAJOR.MINOR.PATCH. The initial version is 0.0.1. When a new version is released increment the:
- MAJOR version
- When you make incompatible API changes.
- MINOR version
- When you add functionality in a backwards compatible manner.
- PATCH version
- When you make backwards compatible bug fixes.
When you increase the MAJOR version, MINOR and PATCH go to zero, while when you increase the MINOR version, PATCH goes to zero.
A pre-release version may be denoted by appending a hyphen and a series of dot separated identifiers immediately following the patch version. Examples: 1.0.0-alpha, 1.0.0-alpha.1, 1.0.0-0.3.7, 1.0.0-x.7.z.92.
Even if this method is mainly indicated for public APIs, I decided to apply it even if my project has not public APIs. Of course, I started with version 0.0.1, but since my project is now stable and a manual intervention was required for the update, I directly went to version 1.0.0.
For my project, when a new version is released I tag the git repository, for example:
git tag -a v1.0.0
Then I go to releases, and I create a new release for the current tag, where I copy the content of the changelog. I don't know if this is a best practice, but keeping the changelog only on github releases for me it's dangerous, since (as stated on keep a changelog website) it's not portable and I like the concept of having a plain text file with all the changes versioned together with the software.