ngx-semantic-version: enhance your git and release workflow
In this article I will introduce the new tool
This new Angular Schematic allows you to set up all necessary tooling for consistent git commit messages and publishing new versions.
It will help you to keep your
CHANGELOG.md file up to date and to release new tagged versions. All this is done by leveraging great existing tools like
Table of contents:
- What does it do?
- How to use ngx-semantic-version
ngx-semantic-version is an Angular Schematic that will add and configure commitlint, commitizen, husky and standard-version to enforce commit messages in the conventional commit format and to automate your release and Changelog generation by respecting semver. All you have to do for the setup is to execute this command in your Angular CLI project:
ng add ngx-semantic-version
Surviving in the stressful day-to-day life of a developer is not easy. One feature follows the other, bug fixes and breaking changes come in on a regular basis. With all the hustle and bustle, there's literally no time to write proper commit messages.
If we don't take this job serious, at the end of the day our git history will look like this:
* 65f597a (HEAD -> master) adjust readme
* f874d16 forgot to bump up version
* 3fa9f1e release
* d09e4ee now it's fixed!
* 70c7a9b this should really fix the build
* 5f91dab let the build work (hopefully)
* 44c45b7 adds some file
* 7ac82d3 lots of stuff
* 1e34db6 initial commit
When you see such a history you know almost nothing: neither what features have been integrated nor if there was a bugfix or a breaking change. There is almost no meaningful context.
Wouldn't it be nice to have a cleaner git history that will follow a de facto standard which is commonly used?
But more than this: having a clean and well-formatted git history can help us releasing new software versions respecting semantic versioning and generating a changelog that includes all the changes we made and references to the commits.
No more struggle with forgotten version increasements in your
package.json. No more manual changes in the
CHANGELOG.md and missing references to necessary git commits. Wouldn't it be nice to automate the release process and generate the changelog and the package version by just checking and building it from a clean git history? And wouldn't it be nice to add all this stuff with one very simple single line command to your Angular project?
ngx-semantic-version will give you all that.
ngx-semantic-version will add and configure the following packages for you. We will take a look at each tool in this article.
- commitlint: check commit messages to follow the conventional commit pattern
- husky: hook into git events and run code at specific points (e.g. at commit or push)
- commitizen: helper for writing conventional commit messages
- standard-version: generate conventional changelogs from the git history
Commitlint will give you the ability to check your commit messages for a common pattern. A very prominent project following this pattern is the Angular repository itself. The conventional-commit pattern requires us to follow this simple syntax:
<type>[optional scope]: <description>
Let's see what is the meaning of these parameters:
typecan be one of the following codes:
scopeis optional and can be used to reference a specific part of your application, e.g.
fix(dashboard): add fallback for older browsers
descriptionis mandatory and describes the commit in a very short form (also called
- If necessary, a
footerwith further information can be added which may contain:
- The keyword
BREAKING CHANGESfollowed by a description of the breaking changes
- A reference to a GitHub issue (or any other references, such as JIRA ticket number)
- The keyword
An example message could look like that:
refactor(footer): move footer widget into separate module
The footer widget needs to be imported from `widgets/FootWidgetModule` instead of `common` now.
Following this pattern allows us to extract valuable information from the git history later. We can generate a well-formatted changelog file without any manual effort. It can easily be determined what version part will be increased and much more.
You may think now: "Wow, that style looks complicated and hard to remember." But don't worry: you will get used to it soon! In a second you will see how creating these messages can be simplified using commitizen.
If you want to try you commitlint separately, you can even try it out using
ngx-semantic-version will add the configuration file
commitlint.config.js which can be adjusted later by your personal needs.
Husky allows us to hook into the git lifecycle using Node.js.
We can use husky in combination with commitlint to check a commit message right before actually commiting it.
This is what ngx-semantic-version configures in our application.
It will add this part to your
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
Husky uses the environment variable
HUSKY_GIT_PARAMS containing the current git message you entered and it will pass this through commitlint so it can be evaluated.
Whenever you commit, commitlint will now automatically check your message.
Defining a well-formed message text can be quite hard when you are not used to the conventional-changelog style. The tool commitizen is there to help beginners and to prevent your own negligence. It introduces a lots of restrictions for our commit messages so that it's easier for developers to follow the pattern. Commitizen will help you to always define a commit message in the appropriate format using an interactive CLI:
When adding ngx-semantic-version it will configure commitizen to use the conventional changelog style as well:
If you are using Visual Studio Code, you can also use the extension Visual Studio Code Commitizen Support which will let you type the commit message directly in the editor:
Standard-version is the cherry on the cake and takes advantage of a well-formed git history.
It will extract the commit message information like
BREAKING CHANGES and use this information to automatically create a
The tool will also determine the next version number for the project, according to the rules of semantic versioning.
ngx-semantic-version will configure a new script in your
package.json that can be used for releasing a new version:
Whenever you want to release a version, you should use standard-version to keep your versioning clean and the
Furthermore, it references both commits and closed issues in your
CHANGELOG.md, so that it's easier to understand what is part of in the release.
The tool will also tag the version in the git repo so that all versions will be available as releases via GitHub, Gitlab or whatever you are using.
Are you excited, too? Then let's get started! Configuring all mentioned tools manually can be quite tedious. Here is where ngx-semantic-version enters the game: It is an Angular schematic that will add and configure all the tools for you.
All we need it to run the following command:
ng add ngx-semantic-version
After installation, your
package.json file will be updated.
You will also find a new file
commitlint.config.js which includes the basic rule set for conventional commits.
You can adjust the configuration to satisfy your needs even more.
Try it out and make some changes to your project! Commitlint will now check the commit message and tell you if it is valid or not. It prevents you from commiting with a "bad" message. To make things easier, commitizen will support you by building the message in the right format and it even explicitly asks you for issue references and breaking changes.
If you typically use
npm version to cut a new release, now you do this instead:
npm run release
You should also consider using one of the following commands:
npm run release -- --first-release # create the initial release and create the `CHANGELOG.md`
npm run release -- --prerelease # create a pre-release instead of a regular one
standard-version will now do the following:
- "Bump" the version in
- Update the
- Commit the
- Tag a new release in the git history
Check out the official documentation of standard-version for further information.
I hope that
ngx-semantic-version will make your daily work easier!
If you have a problem, please feel free to open an issue.
And if you have any improvements, I'm particularly happy about a pull request.
Happy coding, committing and releasing!
Suggestions? Feedback? Bugs? Please