While it may seem that versioning assemblies in .NET can be a black art, it really isn’t. The difficulty lies in the lack of guidance in this area. In fact, I had to read many blogs to put together an approach on a project I was working on a few years (see Suzanne Cook’s excellent blog post “When to Change File/Assembly Versions“).
I recently moved to a new project and found that this guidance is still helpful. As a result, I decided to share it because it is still something that is not discussed much, yet it plays an important part of the configuration management of a .NET application.
The .NET framework makes available three (3) separate version attributes:
- AssemblyVersion. As discussed in Assembly Versioning, the .NET runtime uses the assembly version number for binding purposes. It is used for .NET internal purposes only and should not be correlated to the product version.
- AssemblyFileVersion. Instructs a compiler to use a specific version number for the Win32 file version resource. The Win32 file version is not required to be the same as the assembly’s version number.
- AssemblyInformationalVersion. “The attribute defined by this class attaches additional version information to an assembly” for documentation purposes only. It is text-based informational version and typically corresponds to the product’s marketing literature, packaging, or product name. This data is never used at runtime.
Version formats are suggested for the assembly version (AssemblyVersionAttribute), the file version (AssemblyFileVersionAttribute), and the “product number” (AssemblyInformationalVersionAttribute).
Assembly Version Format
Version information for an assembly (set by using the AssemblyVersion attribute) consists of the following four values, as described in the Version Class in the .NET framework documentation.
- Major Version. “Assemblies with the same name but different major versions are not interchangeable. This would be appropriate, for example, for a major rewrite of a product where backward compatibility cannot be assumed.”
- Minor Version. “If the name and major number on two assemblies are the same, but the minor number is different, this indicates significant enhancement with the intention of backward compatibility. This would be appropriate, for example, on a point release of a product or a fully backward compatible new version of a product.”
- Build Number. “A difference in build number represents a recompilation of the same source. This would be appropriate because of processor, platform, or compiler changes.”
- Revision. “Assemblies with the same name, major, and minor version numbers but different revisions are intended to be fully interchangeable. This would be appropriate to fix a security hole in a previously released assembly.”
The assembly version number is used internally by .NET and should not matter to anyone outside of the development team.
File Version Format
This is the actual file version (set by using the AssemblyFileVersionAttribute attribute) and it satisfies the following goals:
- It correlates the product binaries to the source files from which they were compiled (as long as labeling is performed in the source code control database)
- It allows for the re-creation of older builds.
- It clearly identifies upgrade and bug fix releases.
- It clearly identifies which version of the source code is in production.
The File Version could follow this format:
- Major Version. This is the internal version of the product and is assigned by the application team. It should not change during the development cycle of a product release.
- Minor Version. This is normally used when an incremental release of the product is planned rather than a full feature upgrade. It is assigned by the application team, and it should not be changed during the development cycle of a product release.
- Build Number. The build process usually generates this number. Keep in mind that the numbers cannot be more than 5 digits. One scheme for generating this number is what I call the ‘YearDaysCounter.’ The first 1-3 digits pertain to the day of the year on which the build is being performed. It has the advantage of being sequential, going from 001 to 365 as time progresses through the year. The last 2 digits pertain to the iteration of the build for a particular day and thus allow a range of 01 through 99.
- Revision. This could be assigned by the build team and could contain the reference number of the migration to the production environment. When it is not known yet, a 0 is used until the number is issued.
Product Number Format
This is the product number that is communicated to stakeholders outside the development and build teams (e.g. Application XYZ is on release “3.0.1”). It follows the simpler 3-part format <major>.<minor>.<maintenance>. The following guidelines are useful in changing the product version number:
- Major Release. Increment this number when major functionality is being released.
- Minor Release. Increment this number when alterations or enhancements to existing functionality is made and changes the end user experience.
- Maintenance Release: Increment this number when bug fixes are released or performance enhancements are made that exclude functionality changes or material ‘look and feel’ changes to the user interface.
Like the assembly version number, the product version number should be changed after going to production. It is set by using the AssemblyInformationalVersion attribute.