Automatic CHANGELOG.md or commitizer and standard-version family

Automatic CHANGELOG.md or commitizer and standard-version family

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.

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

Commitizen

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 ;).

Installation:

npx commitizen init cz-conventional-changelog --save-dev --save-exact

Also add a script to package.json:

JSON
package.json

Other options for installation are described in the documentation.

Usage:

(make changes)
git add .
npm run commit

You will be bombarded with a set of helpful questions that will format your commit message:

Commit names

The specification expects that you:

  • name the commits as follows: <prefix><scope>: <message>
  • 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: feat(admin);
  • include information about breaking changes in a separate line: BREAKING CHANGES: removed method foo or 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. Fixes #4;

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:

feat
A new feature
fix
A bug fix
docs
Documentation only changes
style
Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc.)
refactor
A code change that neither fixes a bug nor adds a feature
perf
A code change that improves performance
test
Adding missing tests or correcting existing tests
build
Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)
ci
Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)
chore
Other changes that don’t modify src or test files
revert
Reverts a previous commit

Standard version

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
  • updates CHANGELOG.md file with the new version and list of changes
  • commits both changes and tags them with the new version

Advice

You can use Standard Version without Commitizen and Commitizen without Standard Version. They are independent.

Installation:

npm install -D standard-version

Again, add a script to package.json:

JSON
package.json

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:

JSON
package.json

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.

Fine-tuning

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 feat and 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.

package.json

JSON
package.json

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 ;)).

.versionrc, .veresionrc.json, .veresionrc.js

JSON
.versionrc

Complete configuration

For a comprehensive changelog, add all sections visible to the .versionrc file:

JSON
.versionrc

Further reading

Leave a Reply

avatar
  Subscribe  
Notify of