What is semantic versioning (semver) ?
Semantic versioning is a simple agreement on how packages should be versioned. It gives package developers a framework to version their software. It provides consumers of packages an expectation of how they will behave over time that they can consider.
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 thing to note here is that a breaking change should only be found 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 strip 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
A seemingly innocent thing to do - just create a new class. The problem is many languages allow you to import entire namespaces - C#, for example. Class names must be unique or fully qualified, so if your class name collides with any others in-scope and 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—a compiler error.
Change a default value
Convention over configuration is a well-established mantra with 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 desirable, 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 customer's 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 sure an update won't break somebody. There are no guarantees.
When we intentionally break things, we can ensure we align it with a major release and ideally bundle it with other breaks and a set of enhancements or features to make adopting it worth the effort.