At Mozilla we share a lot of open source libraries. When you’re using someone else’s library, you might find that an upgrade breaks something in your application — but why? Glancing at the library’s changelog can help. However, manually maintaining a changelog when building features for a library can be a challenge.
First, you need to write commit messages in a way that allows you to extract metadata for a changelog. We use the Angular conventions which specify simple prefixes like
feat: for new features and
fix: for bug fixes. Here’s an example of a commit message that adds a new feature:
feat: Added a `--timeout` option to the `run` command
Here’s an example of a bug fix:
fix: Fixed `TypeError: runner is undefined` in the `run` command
The nice thing about this convention is that tools such as Greenkeeper, which sends pull requests for dependency updates, already support it.
The first problem with this is a social one; all your contributors need to follow the convention. We chose to solve this with automation by making the tests fail if they don’t follow the conventions 🙂 It’s also documented in our
CONTRIBUTING.md file. We use the conventional-changelog-lint command as part of our continuous integration to trigger a test failure:
conventional-changelog-lint --from master
There was one gotcha in that TravisCI only does a shallow clone which doesn’t create a master branch. This will probably be fixed in the linter soon but until then we had to add this to our
Alright, everybody is writing semantic commits now! We can generate a changelog before each release using the conventional-changelog tool. Since we adopted the Angular conventions, we run it like this before tagging to get the unreleased changes:
conventional-changelog -p angular -u
This scrapes our commit log, ignores merges, ignores chores (such as dependency updates), ignores documentation updates, and makes a Markdown list of features and fixes linked to their git commit. Example:
### Bug fixes * Fixed `TypeError: runner is undefined` in the `run` command ([abc1abcd](https://github.com/.../)) ### Features * Added a `--timeout` option to the `run` command ([abc1abcd](https://github.com/.../))
As you can see, we also make sure to write commit messages in past tense so that it reads more naturally as a historic changelog. You can always edit the auto-generated changelog to make it more readable though.
conventional-changelog tool can update a README.md file but, for us, we just paste the Markdown into our github releases so that it shows up next to each release tag.
That’s it! There are a lot of options in the tools to customize linting commits or changelog generation.