Why SemVer fails when you patch old versions and what to do instead
10 points by qznc
10 points by qznc
I think this author either does not understand SemVer or modern VCSes or both.
The author seems to think that releasing 1.1.0 precludes later releasing 1.0.1? The fact that some commits are made after others has no bearing on version order, and it's still well defined. Whether the API and social contracts are upheld is another matter, but it's certainly possible with the tools at hand.
That's not how I understood it, and I don't think they misunderstood anything - they showed a real problem.
Short version:
Now you need to fix something very urgent that WILL break 1.0 BC, so it can't be 1.1. This might not be problem for your 2.x users, who will either get 2.x+1 (if the urgent fix does not break BC for 2.x) or a 3.x (if it would also break 2.x)
But this is strictly about your users who depend on 1.0 and cannot use 2.x for whatever reason. Any choice you make is bad now.
Does that make it clearer? I slightly disagree on the authors' points re "CAN" or "CAN NOT" - but the problem is real. If you say "Whether the API and social contracts are upheld " you are ignoring the whole premise of the post, confirming to SemVer.
I guess I'm coming at this from the other end: if SemVer MUST be followed and there's a change needed, one must either backport it, or redo it and honor the API (if there's not an easy or clean backport), or not do it, or mark it as unstable via prerelease labels.
If the author is saying that SemVer makes no affordances for how urgently a change is needed or how difficult it is to make while retaining API, then I suppose I agree. I just never thought that was something SemVer could solve.
Yeah, feels like they're complaining that they can't make a square circle. Obviously if the fix is backwards-incompatible then people who demand compatibility cannot get the fix.
I thought they were saying there were problems if the fix for the minor release necessarily broke things? I do agree that the article seems somewhat confused
The question "whether the API and social contracts are upheld" is the question if you are "SemVer compliant", isn't it?
I think your example of "1.0.1" corresponds to the third paragraph: "A more intuitive version would be v1.1.0, but then we cannot claim to use SemVer".
I think the “semver dilemma” you are drawing up makes sense - if you needed to make a breaking change to fix an old-version bug, you are stuck.
But in practice, does this matter? If users are going to need to pull in a new version with changes that break their code anyway, why not just ask them to upgrade to the actual latest version (2.0.0 in your example)?
I don't know how common this problem is. My job is in automotive and it is a common problem here. Customers even insist to only get their bugfix and no other bigfix (let alone breaking changes). This is an especially conservative niche, for sure.
We had this issue with very large enterprises when building databases, I suspect it’s similar - there would be multi-million-dollar single accounts that wanted to dictate exactly which fixes and new features would go into the ancient version they had decided they would never migrate off of.. very hard balance.
We ended up doing, for large accounts, either “free” consulting engagements to move them onto new versions, and if that failed either fire the customer or if they were big enough that they paid for multiple full time engineers we would maintain dedicated product branches for them, effectively. The complexity cost of doing that is enormous because your entire support, docs and engineering layers need to understand the cartesian product of all your supported versions (“what happens when Giant Corp Xs ancient fork of the product is combined with the most recent admin tool they just downloaded from our website” kinda things)
SemVer is for APIs, for when the version number is your main way of communicating, when you're talking mostly to a package manager looking at a number in a dependencies file.
Your problem is very common, and SemVer is not the solution for it. SemVer is only a solution to a particular problem, not some kind of virtue.
Fork v1 line to a new name and let them use it.
Though really, if users use v1 because they don't want their code breaking, why would they move to the fixed line if that breaks their code too?
Yeah this is something I've heard before from extremely conservative organizations, where they ask for (somewhat crazy) commitments in a contract about SemVer. Specifically where they say "we only allow members of our team to upgrade dependencies with minor or patch, so you need to commit to us that every breaking change is a major and then we will plan a ticket around that upgrade".
The biggest customer I had with these kinds of requirements was a US airline that also put into place an OSS depreciation schedule for 3rd party libraries. Basically every time you wanted to upgrade a third-party dependency to a major version release you had to re-justify why the dependency existed in the first place and write up a justification for why you couldn't just use the standard library of whatever language.
An article that completely cements my confidence in semver as an abstraction for my own use cases, as it shows that its limits are firmly in territory I thankfully don't have to worry about (releasing API-breaking patches for old versions)