SemVer
Semantic Versioning defines a package version format and a set of rules that should be used when the package updates.
Under this scheme, version numbers and the way they change convey meaning about the underlying code and what has been modified from one version to the next.
A brief intro to SemVer: you can specify a version of a package using three groups of numbers: major.minor.patch
. When you create a new version of your package, you should:
- Increment
major
if you introduced a breaking change. - Increment
minor
if you added functionality in a backward-compatible manner. - Increment
patch
if you made a backward-compatible bugfix.
This is pretty much it, although in documents you can find more details.
Version ranges
When you work with package managers which rely on semver (e.g. NPM), you can declare specific versions of dependencies or version ranges, which would allow you to update dependencies easier.
For example, you can use the caret(^
) symbol to tell the package manager that all compatible versions are allowed:
// package.json
"dependencies": {
"react": "^16.0.0"
}
The above means that all versions of react
up to (but not including) 17.0.0
are allowed. So when a new version of react
is out, you can run npm update
and it will download an updated version of it, update your package.json
and a lock file.
Magic zero
But there is an exception for packages with major
version equal to zero, e.g. 0.1.2
.
Major version zero (0.y.z) is for initial development. Anything MAY change at any time. The public API SHOULD NOT be considered stable.
Technically, it is legitimate to introduce breaking changes, updating the minor
digit of the package version. So, versions 0.1.2
and 0.2.0
won't be compatible.
To prevent potential breaking changes, when you do a minor update of a dependency, NPM treats versions a bit different:
Allows changes that do not modify the left-most non-zero element in the [major, minor, patch] tuple. In other words, this allows patch and minor updates for versions 1.0.0 and above, patch updates for versions 0.X >=0.1.0, and no updates for versions 0.0.X.
So, if you have a dependency ^0.1.2
, npm update
won't update it to 0.2.0
, because only patch
updates are allowed.
I didn't know this subtlety before and when an automatic update didn't work, I thought that it was due to some bug in NPM CLI :) Even worse, I updated the dependencies manually... Even though we had a lot of tests, how on Earth didn't I break anything?!
Anyways, if you depend directly or transitively on various 0.x.y
versions of the same package, you can't do much. But as a package author, if you introduce a backward-compatible update to 0.x.y
version, you'd better update patch
instead of minor
. That way the update process would be more streamlined for the package consumers.
P.S.
Online semver calculator - https://semver.npmjs.com/
Discussion related to pre-releases and magic zero - https://github.com/semver/semver/issues/221
Top comments (1)
packagemain.tech/p/github-actions-...