What is semantic versioning (semver) ?
Semantic versioning is simple agreement on how packages should be versioned. It gives developers creating packages a framework to version their software with and consumers of those packages an expectation of how they can use them and upgrade as required.
The versioning format is
major.minor.patch, described as:
- major - Large improvements and breaking-changes.
- minor - New features that are backward compatible.
- patch - Bug fixes that are backward compatible.
The important thing to note here is that any breaking change is only supposed to be published in a major release.
What’s wrong with that?
Well, the reality is any change could theoretically break somebody already using your package. XKCD has a famous comic about it but even not taken to that extreme there are many ways you can unintentionally break existing users.
How can you unintentionally break existing users?
Here are a few examples of how you can break existing users with a seemingly safe bug fix or innocuous new feature:
Create a new class
Seemingly innocent thing to do - just create a new class. The problem is many languages allow you to import entire namespaces - C# for example - and class names must be unique or fully qualified. So if your class name collides with any others in-scope… boom, compiler error.
Add a method to an existing class
Okay, this is our class we can add a method to it. Wait… did we let the customer inherit from this class? If that well-chosen method name collides with one they implemented in the sub-class, boom. Compiler error.
Change a default value
Convention over configuration is a well-established mantra with a liberal use of defaults. What if you need to change the default? The industry guidance before was X and now it’s Y so you want to change the default to match. The problem is you have no idea of knowing if a customer accepted X because they always want your best-intentioned default or if they specifically wanted that value and knew it was the default when they first observed it.
Speed things up
Performance improvements are always good right?! Well, any speed up… or slow down… can cause previously rare deadlocks to increase or decrease. They can also affect back-pressure on other systems and exceed rate limits on API calls.
Upgrade a dependency
You upgraded a dependency… and now the package manager upstream is having difficulty reconciling it with the customers project as they also have this dependency.
Is semver a dream?
Semantic versioning isn’t a dream. It’s an ideal, an intent, something to strive for.
We can never be absolutely sure an update won’t break somebody. There’s no guarantees.
When we intentionally break things though we can make sure to align it with a major release and ideally bundle it up with some other breaks and a big enough set of features and enhancement to make it worth the effort.