Identifying when, how and whom produced a product is important. It is important with physical goods, hence why we have barcodes, expiry dates, model and serial numbers. The same is also true for software. Embedding a version number in files that ship with a product allow support team members to determine what version of the source code went into produce that version of the product and therefore more easily debug its observed behaviour.
Later this week I was working with a fellow team member on automatically applying version numbers to our product each time that it built (continuously integrated). On the surface it is quite a simple task except when you start to consider the sheer number of places that version numbers should be applied within a relatively complex build process. Here are some common examples:
- .NET assemblies
- NuGet packages
- WiX installers
- Documentation files
Each one of these target locations requires a different approach for finding and updating version numbers and it end up getting pretty complicated. But before you start you might want to give some consideration to what your version number actually looks like, and what it means.
I take a lot of inspiration from SemVer.org but it doesn’t really work for all technologies. For example, strongly named assemblies in .NET have four elements (major.minor.build.revision) whereas SemVer defines three elements (major.minor.patch). SemVer also defines trailing elements followed by a dash (for example 1.0.9-rc1) which won’t work for the strong name in a .NET assembly. Of course we can use other informational versioning techniques to pass along SemVer like version information.
If we look at SemVer and apply the first part (major.minor.patch) to version numbers within the package then we could probably adopt a manual version increment technique and just take a centrally defined version number (say in version.xml in the root of the solution) and stamp it in various files during the build process.
Anyway – version numbers, they are important!