When people talk about versioning this can be a very broad subject so let’s narrow this down a little bit…

 

There really is only one version number that anyone should care about and that is the ‘file version’ of the files that you ship. I think this topic gets easily confused and convoluted since there are so many different ways of how this file version number (usually a four part number – explained in detail later) gets generated. Furthermore, with the introduction of the Microsoft .Net Framework and .Net assembly versions, this topic gets very confusing as people move from unmanaged to managed code.

 

Now if you are doing some .Net programming you will have to worry about .Net assembly versions but you should Not confuse this with the actual file version.

The two versions should not be linked together. You can use the same format described below for file versioning as for your assembly version (as this is what is recommended with the last field being a little different). Assembly versions are meant for binding purposes only.  They are not meant to keep track of different daily versions – use the file version for that instead. It is recommended to keep the assembly version the same from build to build and only change it after each external release. For more details on how .Net works with these versions I will refer you to the link below:

 

For Assembly versioning info on MSDN look here.

For general win32 versioning info on MSDN look here

 

Why worry about file versioning

I think there are several reasons why having a good version scheme for your software is very important. Of all of the good reasons I think the top five are (in random order):

1) To be able to track product binaries back to the original source files.

2) To recreate a past build.

3) To avoid DLL hell – multiple versions of the same file (library in this case) on a machine.

4) To help your setup program handle upgrades and service packs.

5) So your Product Support and Q/A teams can easily identify the bits they are working with.

So how do we keep track of files in a product and link them back to the owner? How can you tell that you are testing or using the latest version of a released file?

This is a recommendation (taken from “The Build Master” book) of how to best setup the way you apply versioning to your software. There are a lot of different schemes out there and you should feel free to create your own versioning method. What is described here is what I have found to be the most effective and easiest way to do this to satisfy the top five reasons above.

Ultimately, like most of the other topics in the book, the versioning responsibility of the files in a build tends to fall into hands of the build team. The reason why may be because it is usually the build team that has to deal with the headaches that come from having a poor versioning scheme. Therefore it is in their best interest to publish, promote and enforce a good versioning scheme. If the build team does not own this then someone who does not understand the full implications of versioning will make the rules. Needless to say, this would not be very desirable for anybody involved with the product.

 

Microsoft Sidenote: “I’ve been slimed….”

In the old days (early nineties) in the Windows and Small Business Server group we used a very primitive source code control (SCC) tool called Source Library Manager (SLM, affectionately pronounced ‘slime’) and the labeling function was so unreliable (and poor when it did work) that we would not even bother labeling the sources after each build. But how did the developers, testers, and build team look up previous check-ins to previous builds? Well fortunately back then the projects were not as complicated or as large as they are today so this was all manageable through our release and build process. As mentioned in an earlier chapter we kept all of the sources and binaries of each build on a release server and we kept about two weeks worth of those releases. This allowed the developers, testers, and builders quick access to the previous builds without having to rely on the labeling function of the SCC tool. If someone needed files from a build other than what was on our release server we had custom tools that we wrote that would scan the sources on the source trees by date stamp and file version, copy the sources to a share, then we would rebuild those sources on that share. Since we had weekly tape backups of the release servers we could always restore past shares on the rare occasion we had reason to do this.

 

Bringing this forward to today (2005), Microsoft uses a very powerful SCC tool that was developed internally that handles labeling and branching extremely well – this was probably the most compelling reason to move to the new tool several years ago. If you want to adopt this tool take a look at the SCC tool in the Visual Studio Team System. This tool has all of the features of Microsoft’s in-house tool and more.

File versioning

Every file in a product should have a version number. A four part number separated by periods such as the one below seems to be the established best practice. There are a lot of variations of what each part represents so I will explain what I have found to be the best way of defining these parts.

<major version>.<minor version>.<build number>.<revision>

<major version> – usually assigned by the component owner, should be the internal version of the product, rarely changes during the development cycle of a product release

<minor version> – usually assigned by the component owner, this is normally used when an incremental release of the product is planned rather than a full feature upgrade, rarely changes during the development cycle of a product release

<build number> - usually assigned by the build team based on the build that the file was generated with, changes with every build of the code

<revision> - usually assigned by the build team and can have several meanings: bug number, build number of older file being replaced, or service pack number, rarely changes most of the time and mostly used when servicing the file for an external release

NOTE: These numbers range between 0 and 64k and can be enforced by a pre-build test tool or a build verification test.

For example

“5.1.2600.2180” is a typical file version for a Windows XP SP2 binary. Where 5.1 is the major.minor (5.0 was the version for Windows 2000) version of the product and 2600 is the build that this binary was built in and finally 2180 is the build number of the file it is replacing. Now if this was a one-off hotfix rather than a service pack release the <revision=2180> field may have the number of the bug that is being fixed such as 1000 (if this was the bug number).

Product Marketing numbers such as Windows NT 4.0.

WARNING: There seems to be a common misuse of product marketing version numbers for the major and minor numbers in the version string.
Do not use the product marketing version in the file version string since many components can be used by different products. 
Furthermore, sometimes marketing numbers do not follow a sequential order or tend to be random. Now if on the occasional circumstance, the marketing people 
want to use the internal version number of a product, e.g. NT 4.0 for their marketing version, then this would be ok just do not link the two numbers together in a permanent way.
Instead, for major and minor numbers use whatever numbers you use in your bug tracking database.

You should also try to avoid tools that inject version numbers into binaries (as a post-build step). Although the tools may seem reliable, they introduce an instability factor into your released binaries by hacking hexadecimal code. Most Q/A teams would have a cow if this was happening to the binaries they were testing – and justifiably so. The build number should be built into the binary or document files.

 

Comments, insults, or better ideas?

 

PS

More details and info in “The Build Master” book that will be out in July by Addison-Wesley.