I was browsing the Twitterscape and saw this tweet:
"SemVer is a false promise that appeals to many developers", https://t.co/4qUW7qP57E — @jashkenas already said it better than I could.
— DHH (@dhh) January 1, 2015
Mercifully I’ve been able to ignore Semver for a long time, but all this bru-ha-ha got me thinking about how we solved it in a previous open-source project (years ago).
APIs/libraries/projects/etc. need two versions. No, wait – don’t go. It’s pretty simple and looks something like 3.2.1-44 (marketing release-API version).
Marketing release: Major.minor.patch
API version: monotonically increasing integer
Whenever you introduce a breaking change, no matter how small, increment the API version to communicate that someone will need to do something to upgrade. At the same time, increase the marketing release to communicate the expected impact. I’ve found these work well:
Major: A really really big release. Likely you will have to change many things. Rails 2 to Rails 3 would be a good example.
Minor: It breaks some things, but should be migrateable in under a few days to a week.
Patch: Something small is broken. Likely you realized that some method had a security hole and now you have to patch it by changing the semantics. Intent is that upgrading to this release is doable in under a day.
Drop-in change? Leave the API ver alone. Adjust marketing however you want to communicate whatever you want.
That’s it! Super simple. Let the marketing version communicate the magnitude of the change and let the API version let someone know if they need to fix anything. Works for both people and machines!
If your project follows this, someone could even write a simple little status page that would give you rough estimates on how long it would take you to upgrade your app.
Maybe even integrate it into something like bundler…
> bundle update --estimate
1 2 3 4 5 6 7 8 9 |
|
Note: if you are concerned about the API version growing annoyingly big and “looking
weird” then you are sort of missing the point. I concede you could reset it when you increment
the major ver, but then you run the risk of automated systems failing to report a
version conflict if they just do a simple check, e.g.
upgrade gem unless my API ver < your API ver
. Better to leave it alone, the API ver
is primarily for machines anyway.