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
| Increment | When, per the specification | What 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
inttolongfor readers declared aslong, may not be, while the same change breaks a reader still declared asint, 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.
