It’s been a long time since I wanted to include a variation of conventional commits to one of my projects – mostly for automated changelogs, but also often to standardize naming commits. The available packages were confusing to me until I finally started to include them in a project.
Table of contents
What’s it about
What are conventional commits? As the name suggests, they are the commits with some convention ;). That convention provides both human and machines ability to recognize the type of change provided in the commit, like: fix of bug, new feature, refactor, documentation, and many more.
Thanks to being readable by a machine, conventional commits simplify two processes related to software development:
- listing changes in a changelog file
- automatically bumping correct version: major, minor or patch.
According to semantic versioning, there are three major parts of a version number:
- major number – changing it means a breaking change was introduced, usually as new API incompatible with the previous one;
- minor number – changing it means a feature was added to the software, but still being backward compatible;
- patch number – changing it means a bug fix or non-relevant change (e.g. refactor) was introduced
Before conventional commits
My workflow before looked as follows:
- Make changes
- Manually update the changelog by reviewing what changed from the last version
- Manually bump version
npm version patch(or minor)
git push --follow-tags && npm publish
This package will help to create commit messages by providing prompts and options. It may be helpful in the beginning, but I think it’s annoying in the long run because creating commits (filling in the form) takes forever now ;).
npx commitizen init cz-conventional-changelog --save-dev --save-exact
Also add a script to
Other options for installation are described in the documentation.
(make changes) git add . npm run commit
You will be bombarded with a set of helpful questions that will format your commit message:
The specification expects that you:
- name the commits as follows:
- start the commit message with a prefix:
fix(bug fix) or
feat(new feature). The former will bump the patch version and the latter will bump the minor version;
- optionally provide the scope of changes in parenthesis:
- include information about breaking changes in a separate line:
BREAKING CHANGES: removed method fooor by just adding the exclamation mark after the prefix:
feat!: changed settings. It will bump the major version;
- list fixed issues in the last line, separated with a blank line from the rest, e.g.
More information and some examples can be found in the docs.
For examples of the prefixes (you can also use own), refer to conventional-commit-types:
A new feature
A bug fix
Documentation only changes
Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc.)
A code change that neither fixes a bug nor adds a feature
A code change that improves performance
Adding missing tests or correcting existing tests
Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)
Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)
Other changes that don’t modify src or test files
Reverts a previous commit
Once you have conventional commits, you can make use of them with the next tool. Standard-version will usually do the following things:
- updates semantic version according to the scope of changes described in the commits
CHANGELOG.mdfile with the new version and list of changes
- commits both changes and tags them with the new version
You can use Standard Version without Commitizen and Commitizen without Standard Version. They are independent.
npm install -D standard-version
Again, add a script to
Now, instead of running
npm version <scope>, you have to run
npm run release.
Note: it is still possible to override the next version by using e.g.
npm run release -- --release-as minor.
The last thing left, as the message suggests, is publishing the git tag and the npm package:
git push --follow-tags && npm publish
An alternative is the set of scripts:
Because the set
pre- scripts are automatically called before, and
post- scripts – after, it is enough to run
npm run release to run tests, bump versions in case all tests pass, and publish the package in case bumping succeeded.
Alternatively, use a much more complicated and configurable package semantic-release.
By default, not much will be included in the
CHANGELOG.md file, because most types of changes will be hidden for clarity. As noted, only
fix will be printed by default.
This can be easily changed. You can force show them or merge into sections by editing any of the files described in the following sections.
The format is straightforward:
hidden hides the type in the changelog, and
section allows naming the section containing commits of that type. More about it and other options in the documentation.
The problem with storing the configuration in
package.json is automatic reformatting, at least in my npm/IDE. It looks horrible afterward (at least to my eyes ;)).
For a comprehensive changelog, add all sections visible to the