If you’ve been following the recent Angular release canidates you can’t help but admire the changelog they are able to produce. Each version published has a nicely formated list of bugs, features, and breaking changes. How they were able to generate this type of changelog really interested me into digging deeper into their process and conventions. It turns out, implementing something like this into your workflow is actually quite simple.
The first step is to start utilizing a convention when commiting changes to your codebase. The easiest way is to use the conventions created by the AngularJS team.
A more readable form of this can be found from Angular Material team’s Code Convention Guidelines. At a minimum, each commit message contains a type, scope and subject. In the following format:
Making sure we commit changes using this format can be teadius at first. To make life easier add Commitizen as a development dependency. This provides a command line utlity that will walk you through each portion of the commit message.
First add a new script named commit which executes
Then add an additional block called config
Stage your changes by running
git add . followed by
npm run commit.
Having this tooling is great, but what about that one developer that just doesn’t seem to get it and is stuck in their ways? Thankfully, preventing commits that do not meet the convention is simple to do by installing a git hook. But to be honest, I’ve never configured a Git hook. Thankfully, Husky makes configuration painless.
First install Husky:
Next install validate-commit-msg
Now any commit messages that do not follow the convention will error to the developer.
Now that our project is setup lets see the added benefits this provides. To kick off the next step we are going to install
standard-version. This plugin not only will generate the proper version for our project, but it will also create a change log with proper commit hashes, and issue numbers.
npm run release. This will examine your Git history and based off your commits generate the proper version and a CHANGELOG.md.
To help demo how this would work in the real world, I’ve setup a repository with everything configured. First fork this repository.
With the newly forked project lets enable Issue tracking. This will give us a feel for how this would work when we collaborate on a real project.
- Open the project’s settings in GitHub and enable Features > Issues
- Create a new issue called feat: Implement Footer
- Clone your forked repository
- Verify you’re in the newly created directory and run
- Create a new branch by running
git branch feat/footer
./src/index.htmland add a
- Save your changes
- From the CLI run
git add .followed by
npm run commit
Follow the prompts adding, using the following information:
- Push your changes to GitHub with
- Next open a pull request and merge your changes in
package.json version are unchanged. The reason they haven’t been updated is because we need to first cut a release. Let’s do that now.
- From your command line switch back to master by running
git checkout master
- Pull in your latest changes by running
npm run release
This runs standard-version which examines your commit history to properly update the
CHANGELOG.md, version in
package.json, and tags a branch in your repository.
git push --follow-tags origin master to push your version changes and tag your repository with this version.
Checkout this great plugin for VSCode. It integrates with commitizen and provides a wizard like experience.
I haven’t actually tried this out yet, but to take things to the next level you could look into semantic-release. It promises fully automated packaging and releasing. Basically, what standard-version does, with the added benefit of integrations with GitHub and Travis CI.