Package Versioning – Best Practices with Semantic Versioning (SemVer)

Presenter: Kevin Griffin of SwiftKick Training, and an Inedo-certified Master Trainer

Note: The following text is a transcript of the video, with minor edits for readability.

Most package managers rely on what’s called SemVer, or Semantic Versioning, and SemVer can have three or potentially even four numbers.

Major. Minor. Patch.

Most cases you’re dealing with three numbers and here’s an example: 3.4.2 — we’ve all used this terminology, hopefully. Number three is our major version, four is our minor version and number two is our patch version.

Major

Depending on the project, and really the team that’s responsible for versioning things, the way it is supposed to work is that the major version only increments when you have significant or breaking changes to an application. Going from three point something to four point something should almost be a completely radical change to the application. If all I’m doing is maybe moving a button, renaming a couple utilities on the screen, or I’m changing how some innards of my code might work, that’s not enough to update the major version.

Minor

If I’m making a couple bug fixes and they drastically improve the performance of the code that’s a minor version update.

Patches

Patches again depend on the team. I’ve seen teams that will just abuse the patch version of segments. They’ll update a little piece of code, increment the patch. Update something else, increment the patch. Eventually, you get so many patches where it’s 3.4.112… and you know that’s fine, you just know it’s a newer version than what you had before, but again, it really depends on the tool that you’re using.

Best Practices (In my opinion)

Normally I tell people in software development that you only increment the major version if you’re making API breaking changes. If you’re changing the code significantly enough, that if I were to install that version and I would have to spend time fixing my code in order to support your updates, this is when you increment a major version.

If you’re only updating the minor versions there should be no expectation on me as the developer to change my code. If we’re talking about machine packages or utilities, there are a similar set of constraints. It again, depends on the team. Usually, major version updates are drastically changing the UI or the command line parameters for a tool, and that is when you change the major version. If I’m just fixing a couple bugs, I’m only updating minor or patch.

The Fourth Octet

If you see a number that has a fourth octet on it, let’s say 3.4.2.1, one is usually held for the build number, this again depends on the team. Build number is used when we might be working on a certain problem, but we haven’t fixed that problem yet, so we’re in the process of fixing it and we’re just not quite there yet. That’s why you don’t commonly see it in a lot of these packaged systems.

Pre-release Qualifiers

There’s also a concept of pre-release qualifiers.

If you’re adventurous, you might want to install a package that’s not necessarily, “ready for release.” If you go into a package system, you might see something that has a “dash” with a suffix attached to it. That typically means that it’s been pre-released.

Examples

I have a couple examples here that I’ve seen in different environments:

1.0.0-alpha

1.0.0-beta

1.0.0-rc.1

It doesn’t really matter what comes after the dash, most package management systems will say, “when you have a suffix attached to a version it’s considered a pre-release.” Don’t forget, a pre-release is always slightly newer than the version that came before it.

Here’s an example where I originally had a 1.0 release, but then I released a 1.1-beta. Well that’s slightly newer, but it’s not as new as if I had released 1.1 by itself. All packaging systems will default to not installing a pre-release package unless you specifically tell it that it’s okay. In NuGet development you have to say, “I want the pre-release.” With several command-line package managers you have to designate, “allow a pre-release version.”

Immutability

Packages should be immutable. We should not be able to change a package after a package has been released.

The problem is that they’re just zip files, you can edit a zip file any way that you want to. Some feed management systems will specifically not let you change a package after it’s been published up to the feed system.

Say you have installed Kevin’s package, but then Kevin loses control of the package, someone could go and update Kevin’s package to have malicious code in it, like a Bitcoin miner. This has actually happened in some public cases. Well, you as the user of Kevin’s package, might unknowingly install the bad package into your system. Usually that doesn’t happen as a part of your daily computer system work, what happens is this is part of a build system. Most build systems, when they run a build, won’t have all the dependencies because we’re not putting dependencies into source control. They’ll physically go out to the different feeds and they’ll pull the latest version, or the version dictated in the manifest of a certain package. So, if your code relies on Kevin’s package, and you run a build and it goes out and gets the malicious version of Kevin’s package, and brings it in, well that’s now out in production. Really nothing changed about the package, except the stuff that’s inside of it, and you should be able to trust the packages that you’re installing, immutability is key.

Some package managers don’t enforce mutability, some do, and then you have some packages like Universal Packages. We can still alter these packages without necessarily changing the contents inside. The biggest change is maybe just updating the version. If I have a 1.1-beta and then I want to move that to a 1.1 release, technically those are two different versions of the package, or, I need to update the original package to remove the beta key word. That’s not necessarily what you want to do. We will talk about a term called repackaging in another video, where I can take a pre-release package and just change the version of it without altering any of the contents of the package itself, and it should still be verifiable across the board.

Next Training Snippet   ➔

Customized Training

Our training courses are built modularly, and we can develop a customized training roadmap for your organization, so that everyone gets the training they need, when they need it.