Semantic Versioning

Semantic Versioning, often shortened to SemVer, is a specification for version numbers of the form MAJOR.MINOR.PATCH, in which each part communicates what kind of change a release contains. Its purpose is to let users tell from the number alone whether upgrading can break them.

The three rules

IncrementWhen, per the specificationWhat users can expect
MAJOR (2.0.0 โ†’ 3.0.0)“when you make incompatible API changes”Something they rely on may break
MINOR (2.3.0 โ†’ 2.4.0)“when you add functionality in a backward compatible manner”New capabilities; existing use keeps working
PATCH (2.3.1 โ†’ 2.3.2)“when you make backward compatible bug fixes”Corrections; existing use keeps working

A few further rules keep the scheme honest. Once a version has been released, its contents must not be modified; any change is a new version. Major version zero (0.y.z) is for initial development, where anything may change and the public API should not be considered stable; version 1.0.0 defines the public API.

The rule that makes the others work

Before any of this, the specification requires that software using it “MUST declare a public API,” and that the declaration “SHOULD be precise and comprehensive.” That requirement carries the weight. “Incompatible” is judged relative to a stated interface. Without one, users still break โ€” a caller of an undocumented function fails just the same โ€” but there is no agreed basis for deciding which changes count as breaking, or for saying whose responsibility a breakage was. The version number is a summary of a promise, and the promise has to exist first.

Applying it to data

Data models, tables, and datasets can use the same idea, provided the public interface is declared. For a published table that interface is more than column names and types: it includes the grain (what one row represents), the definitions of its measures, and whatever else consumers are told they may rely on โ€” refresh time, retention, access. With that declared:

  • removing or renaming a column, or changing the grain, is MAJOR; so is a type change that the declared interface or a supported reader cannot absorb โ€” a widening that every supported reader resolves, such as Avro’s promotion of int to long for readers declared as long, may not be, while the same change breaks a reader still declared as int, so check the readers and value ranges rather than the label;
  • adding a nullable column is usually MINOR;
  • fixing a load bug so values match the stated definition is PATCH when the fix is backward compatible with the declared public API. Assess affected totals and any restatement or consumer notice separately; a patch label does not mean published numbers are unchanged.

Changing the stated meaning is different from restoring it. If the public definition of revenue includes canceled orders, redefining it to exclude them is an incompatible contract change and requires MAJOR for a stable API, even if structural checks pass. Consumers using that definition for period comparisons need to know when it changed. A consumer relying only on unsupported behavior may also be affected, but that alone does not set the SemVer category.

A version number also does not migrate anyone. Retiring the old major version still needs deprecation with a date. How versioning, compatibility, and meaning changes fit together is worked through in Changing a Data Model Without Breaking the People Using It, and structural compatibility directions are covered in schema evolution and compatibility.

References


Discover more from Insightful Data Lab

Subscribe to get the latest posts sent to your email.

Similar Posts

Questions, corrections, or additional insights?

This site uses Akismet to reduce spam. Learn how your comment data is processed.