How do You Version Packages?
This topic seems to come up regularly. And is usually a friction point for teams because many of us do this differently. In an attempt to standardize versioning and to remove this undesired friction I decided to promote Semantic Versioning (http://semver.org/).
Familiarizing Ourselves with Semantic Versioning
This is not a new or revolutionary idea. In fact, you probably do something close to this already. The problem is that “close” isn’t good enough. Without compliance to some sort of formal specification, version numbers are essentially useless for dependency management. By giving a name and clear definition to the above ideas, it becomes easy to communicate your intentions to the users of your package. Once these intentions are clear, flexible (but not too flexible) dependency specifications can finally be made.
Given a version number is composed of the following 4 parts: MAJOR.MINOR.PATCH and INCREMENT. The recommended approach to incrementing each part is as follows:
- MAJOR version when you make incompatible API changes
- MINOR version when you add functionality in a backwards-compatible manner
- PATCH version when you make backwards-compatible bug fixes
- INCREMENT version when you make a build (should be automatically set by the build server)
Additional labels for pre-release and build metadata are available as extensions to this format.
NuGet has wonderful documentation about versioning. The following package versions illustrate the flexibility that we get from using metadata. In this list, we can clearly observe the distinctions created by the use of metadata.
To summarize, the template for a package version is MAJOR.MINOR.PATCH.INCREMENT
optionally we can add -METADATA to denote various stages of preview packages.
Why is this Standard Important?
Having a standard in place simplifies the communication of intent to the consumers of your packages. Seeing that a package has changed MAJOR versions is a clear indicator for consumers to review a packages’s release notes. In turn, helping the consumers save countless hours of troubleshooting because of breaking changes.
Noticing a MINOR, PATCH or INCREMENT version change should not be alarming to the consumers of the package. This type of version change should be welcomed with greater confidence. Release notes remain important, but should not convey any breaking changes.
Should we Produce Release Notes?
The short answer is YES. Release notes should documents fundamental changes to the component. These are especially important for MAJOR versions. MINOR and PATCH versions also deserve to have release notes, but I consider these to be relaxed because these versions should be backward compatible and should be tested accordingly.
Safely Updating Packages Through NuGet
In a blog post by Maxime Rouiller titled NuGet–Upgrading your packages like a boss we get introduced to NuGet’s -Safe flag. If everyone applies Semantic Versioning to their packages, this flag can definitely become your best friend, because it can save you countless hours of refactoring and debugging. By using this flag you are assured that only PATCH versions are applied to your solution. Find out how this work by reading his blog post.
Very good intention and practice but there are a few things you shouldn’t leave unsaid.
How do you plan to move from ‘preview’ to ‘beta’ or ‘stable’? Say, John creates ‘220.127.116.11-preview’ and then Jane creates ‘18.104.22.168-preview’ because her changes are breaking. Can they merge? How will John know if he can assign a stable version if he’s not sure if Jane’s’ changes are good? What if it goes on and on and we are at version 19?
Release notes are great but you have to have a single database which is your only truth. You should not duplicate it in source control. Instead you should establish a procedure to include links to work items in commit comments. And you should have a build time script that is capable of constructing release notes from this information. Do not duplicate your data.
LikeLiked by 1 person
Those are valid concerns and I would love to hear about how you would tackle these challenges.
Can they merge? yes. The thing that’s great about SemVer, it is tells you the expected level of API incompatibility between versions. so if you merge a breaking change and a bob breaking API addition, you still have a net breaking change to apply to the next version number.