In an automated build and deployment pipeline you deal a lot with version numbers. At Flownative, we generally follow the rules of Semantic Versioning, since it's a widely-used standard.

One of the benefits of using such a standard is, that many tools play well together. There are also regular expressions you can use to check your own made up version numbers. So, since there is a standard, and your tool claims to support it, everything should be clear, right?

In practice, there are a few stumbling blocks, which need to be considered. Some of the key tools and platforms we use, don't support the full set of SemVer syntax, or behave in an unexpected way.

Here's a little of overview of what's possible and the scheme we are following:

Semantic Versioning

Here's a typical version number according to the Semantic Versioning standard, explained:


1MajorIncrease when public API changes
21MinorIncrease when a new feature / enhancement is included
4PatchIncrease when a bug was fixed / non-functional change was added
beta1Pre ReleaseUse when pre releases should be provided (we seldomly do that)
9BuildIncrease when non-app code / configuration (for example for a CI pipeline) changes


Github likes to use a "v" prefix for version numbers. You may argue that this is ugly or unnecessary (and we'd probably agree), but it is also a common practice to indicate it as a version number. It's even mentioned in the Semantic Versioning standard as a common way to denote versions.

Following that convention makes life a bit easier, so we are good citizens and do that (from now on). Git tags we might use:

  • v1.21.4+9
  • v1.21.4+10
  • v2.9.3 (if the project doesn't care about build versions)

In some projects, we introduce branches in order to maintain multiple major or even minor versions at a time. We use the dot "." as a delimiter there, so branch names will just look like these:

  • 1
  • 2
  • 7.3


Docker tags don't support the full character set needed for Semantic Versioning. Only letters, numbers and a dash is allowed. That means "+" is an invalid character in Docker image tags. Therefore we usually don't tag builds individually, but overwrite a preceding version:

  • v1.21.4+9 becomes 1.21.4
  • v1.21.4+10 becomes 1.21.4 as well
  • v1.21.5+1 becomes 1.21.5


Version numbers of Helm Charts closely follow the SemVer standard. That's important to know, because when you do a helm install or helm upgrade, by default, only stable versions are considered. That means, a version containing a "-" will not appear in the list of available chart versions, unless you specify the --devel option. This may be a little confusing, if you use a dash for other purposes (for example as a prefix for build numbers).

We need to be a bit careful here, because even though the Helm chart uses the full SemVer syntax, the Docker images it's using internally don't:

  • 1.21.4+9 is a Helm chart version, internally pointing to a Docker image called 1.21.4


Composer works fine with SemVer, too. And, fortunetaly, Composer can also cope with the "v" prefix found in Git tags: In order to determine the actual version, it strips the "v" from the version string.