Nineteen of our Node services book carrier labels through an internal package, label-client. It started at 0.0.1 two years ago and was never given a 1.0.0, because nobody felt it was finished, and by September it had reached 0.0.14. The services depend on it with a caret range, ^0.0.14 in most of them, which is what npm install writes by default.
Once a month a workflow runs npm update in every service repository, opens a pull request with the new lockfile, and merges it when the tests pass. We rely on it to roll out fixes to our shared packages without nineteen hand made pull requests.
In September we found that the client retried a timed out booking without its idempotency key, so a slow carrier response could produce two labels and two charges. The fix went into 0.0.15 on a Tuesday, and we told the warehouse teams it would be everywhere after the monthly refresh. The refresh ran, nineteen pull requests merged green, and three weeks later the carrier's invoice still showed duplicate labels.
npm ls in each repository explained it. Seventeen services were still on 0.0.14, and two older ones were on 0.0.11. A caret range allows changes that do not modify the leftmost non zero part of the version. For 1.4.2 that part is the 1, so ^1.4.2 accepts anything below 2.0.0. For 0.0.14 the leftmost non zero part is the 14, so ^0.0.14 means 0.0.14 and nothing else. That follows the semver specification, under which anything in a 0.y.z version may change at any time, so npm treats every 0.0.x release as potentially breaking. npm update did exactly its job, and npm outdated would have told us so, with 0.0.14 in its Wanted column and 0.0.15 under Latest.
The pull requests had been green because they carried other updates, and nobody checked which packages had moved.
The client is 1.0.0 now, and every service depends on ^1.0.0. The monthly workflow runs npm outdated as well and fails on any internal package whose Wanted and Latest differ. Each service publishes the versions of our shared packages it was built with, and a fix counts as rolled out only when that list says so.
The version number we never wanted to commit to was a commitment after all. It promised that nothing would ever change.
– Sergey Shinder
Top comments (0)