Do you know those projects that have a cool version number like 3.23.12? And they have a nice changelog that shows the changes in each version? If you're like me, you love the idea of being that organized, but you don't love the idea of doing more busywork when you want to focus on coding. Well, you're in luck, because with a few tools we can automate the whole thing!
There are three tools that we can use to accomplish this:
- Conventional Commits (A convention for how to write commit messages)
- SemVer (Semantic Versioning - the nice X.X.X version number system)
- Standard Version (A node module that automatically updates a changelog with version numbers and commit info)
The best part of all of this is that you can slowly transition into using these tools. You don't have to make any big changes or commit to making a permanent change to your workflow or repository.
Conventional Commits is a standardized way to write your commit messages - as well as the driver of this whole operation. Basically, when writing your commit messages all you have to do is follow a standard format. It may seem complicated at first, but with a little bit of time and the Commitizen VS Code Extension, you will quickly find it feeling natural. Firstly, it would be best to familiarize yourself with the convention, you can read up on it here.
Using Commitizen in VS Code will do the heavy lifting for you. Instead of committing via command line or VS Code's built-in Source Control, you can just open the command palette (ctrl-shift-p) and type select Commitizen. It will prompt you for all of the necessary information and format your commit message according to the standard. Then you can just push your code up as you normally would!
Conventional Commits alone will make an awesome addition to your development arsenal - if a whole team transitions to Conventional Commits, you will notice all changes to the repo are far more readable.
Semantic Versioning is far simpler to understand. You can read up on it at the site, but it's simple enough to quickly explain here.
The version number is split into three sections with .'s like so: 2.5.11 - and each number has its own distinct meaning. I'll explain from the bottom up.
- 1.1.Z Z = Patch version. This starts at zero and increases with every backward-compatible bugfix or patch that is implemented.
- 1.Y.1 Y = Minor version. This starts at zero and increases with every backward-compatible new feature or functionality that is implemented. Every time this goes up, reset the patch version to 0.
- X.1.1 X = Major version. This starts at zero and increases with every major change or addition of functionality that is not backward-compatible.
- Note: If you reach number 9 for any of the versions the next increase is 10. This can even get into the triple digits, ie 1.2.99 => 1.2.100.
In your projects, you can feel free to apply these versions in whatever way makes the most sense to the project. For instance, in some projects, I might increase the major version at each milestone instead of waiting until a breaking change.
Finally, you can use the node package Standard Version to automate the process of creating and updating a changelog. It uses your conventional commits to understand the changes you've made and updates your version number accordingly. The changelog that it generates also succinctly lists the changes in each version.
To use it, you can install it to your project as a developer dependency with this command:
npm i --save-dev standard-version.
To run it for the first time:
npm run release -- --first-release.
To run it for your normal releases:
npm run release.
If you want to release a major or minor version regardless of what your commits indicate you can run:
npm run release -- --release-as CHANGE - replacing CHANGE with either major or minor. Also, you can release to any version you define with
npm run release -- --release-as VERSION - replacing VERSION with any number you like such as 1.2.0.
Running the release command will generate a changelog and you can push your code to your repo.
If you are working in a repository that utilizes multiple branches and merges. You can explore using squash merges so the versioning and changelog only apply to the branch you want them to.
All three of these tools are powerful in their own right, but once you are comfortable using them you can explore some of their more advanced features and make your project organization even better.