Fudging required version numbers

Sometimes a build tool requires version numbers. JavaScript tooling generally requires semantic versions. Go modules also require the use of semantic versioning.

This is good, for publicly-used packages.

But the overhead of managing the different types of changes indicated by semantic version increments isn’t always needed for internal projects—even when cross-project dependencies are in use.

One simple strategy you can employ, in place of strict adeherence to semver, is a rolling compatibility window.

Whereas semver dictates that a you “increment the MAJOR version when you make incompatible API changes”, a rollwing compatibility window dictates that all breaking changes are announced a certian time in advance.

The rules are pretty simple:

  1. A compatibility window is defined. This might be 30 days, 3 months, or 1 year.
  2. All breaking changes become deprecations first. The deprecation notice must be clear and unequivocal. Ideally, it can be enforced by a static analysis tool/linter.
  3. After a feature is marked as deprecated, it is removed after the defined compatibility window lapses.

That’s pretty much it.

The key is that the compatibility window must be long enough to allow all sub projects that depend on the feature to migrate away from the old feature prior to removal.

Note that this is not at all incompatible with semantic versioning. In fact, many well-known public projects that use semver also use this concept of compatibility windows (usually with a window of 1-2 years). They just also increment the major version any time functionality is removed.

The advantage to doing this on internal projects is that you don’t need to worry about the difference between a patch, minor, or major version in your versioning scheme, if you have no other reason to.

Share this