Semantic Versioning (also known as SemVer) is a widely-used method of versioning software releases. It uses a version number in the format of X.Y.Z (Major.Minor.Patch), where:
- The major version number (X) is incremented when there are breaking changes in the software's API or functionality.
- The minor version number (Y) is incremented when new, backwards-compatible features are added.
- The patch version number (Z) is incremented for backwards-compatible bug fixes.
Semantic versioning simplifies the work of developers by providing a clear and consistent method for identifying the level of changes in software releases, allowing them to easily assess the potential impact of updating their dependencies and plan accordingly.
In this article I present tools that I use to assist me in managing the versions, publication, and updates of libraries.
Conventional Commits is a method of writing commit messages that is also machine-readable. The goal is to make it easier to automate the release process, generate changelogs, etc.
Commit messages written in this format follow a specific structure and contain a prefix (e.g. feat, fix, chore, etc.) that indicates the type of change made. The prefix is followed by a colon and a space, then a short description of the change. An exclamation mark can be used to indicate a breaking change.
This format allows for easy identification of the type of change and its purpose, making it easier for developers to understand the context of a commit and the impact it may have on the codebase.
Another popular commit format is Gitmoji.
Semantic Release is a tool that automates the process of versioning and publishing of libraries. The versioning follows the principles of Semantic Versioning.
The tool works by analyzing the commit messages in a project's repository, determining the type of changes made (e.g. bug fixes, new features, breaking changes), and automatically generating a new version number and release notes. This is often used in conjunction with Conventional Commits (or the very similar Angular Commit Convention).
It also allows for automated publishing of the release to various package managers such as npm, pypi and maven central. I've mainly used it with npm libraries: every time a PR or MR is merged on Github or Gitlab, Semantic Release creates a changelog, a new release with the new version, publishes the library to the registry, etc. I highly recommend it.
When using Semantic Release, you might be faced by an annoying issue: your commit messages weren't following the convention and they were ignored. It could be because of a typo, a missing colon, an unknown type, etc. And this can be very frustrating because the commit won't appear in the changelog, if you can't wait for the next release and you will have to create a dummy commit to force Semantic Release to create a new release.
If you are using the command line to create your commits, one solution is to use Commitizen. Commitizen will provide you with a nice prompt to ask you the type of change, the scope and the message. This way the commit will be well-formatted and this will also help the developers to adopt the convention. Indeed, at the beginning it could be difficult to decide of the correct type for a change (eg. between chore, libs and refactor).
Commitlint is tool that takes commit messages and check that they follow the commit convention that your project uses.
You can configure your CI or your git hooks to check the commit messages.
Renovate is a tool that automatically creates pull requests / merge requests to update dependencies to their latest version, it can work with the main package managers. Semantic Versioning will be very helpful here because we can decide to automatically update (and merge if we want) patches, but keep a code review for minor and major updates for example.
The most popular alternative to Renovate is Dependabot. They are very similar in their objectives but I tend to prefer Renovate that I find more flexible.