Semantic versioning

Semantic versioning or SemVer is an approach to API versioning that says roughly the following:

  • Your version number should have the format "MAJOR.MINOR.PATCH" where each of MAJOR, MINOR and PATCH is an integer >= 0.

Once you hit 1.0.0

  • Increment MAJOR when you break compatibility;
  • Increment MINOR when you implement features or deprecate features without breaking them;
  • Increment PATCH when you fix bugs;
  • If you increment MAJOR reset MINOR and PATCH to zero; if you increment MINOR reset PATCH to zero.

There is a specification for semantic versioning that goes into more detail at http://semver.org/ .


There is a proposal to use Semantic Versioning for Tcl in TIP 439 .


bll 2016-7-7: The specs state:

9. A pre-release version MAY be denoted by appending a hyphen and a series of dot separated identifiers immediately following the patch version. Identifiers MUST comprise only ASCII alphanumerics and hyphen 0-9A-Za-z-. Identifiers MUST NOT be empty. Numeric identifiers MUST NOT include leading zeroes. Pre-release versions have a lower precedence than the associated normal version. A pre-release version indicates that the version is unstable and might not satisfy the intended compatibility requirements as denoted by its associated normal version. Examples: 1.0.0-alpha, 1.0.0-alpha.1, 1.0.0-0.3.7, 1.0.0-x.7.z.92.

(and 11. for precedence)

But I have found that normal people assume that 3.1.1a is a later version than 3.1.1. Some software uses 'rc' to indicate a "release candidate", but even so, regular people who are not cognizant of that will assume that it is a later version.

I am thinking that perhaps using the odd numbers as development only versions would work out better. e.g. 4.2.0 (release), 4.2.1a (dev) 4.2.1b (dev), 4.2.1c (dev), 4.2.2 (release), 4.3.0a (dev), 4.3.0b (dev), 4.4.0 (release). Then the version numbers always have a progression from smallest to largest. No strange precedence comparison code to strip off the trailing -dev or other characters in order to do version comparisons (which I have in my code now).

I disagree with changing the major number only when it breaks compatibility, but that's an opinion, and there can always be a separate public version number and internal version number.

EMJ 2016-07-07:

What are normal people and regular people and how do you tell them apart? :-)

More seriously, 3.1.1a does not match the Semantic Versioning specs, it would need to be (at minimum) 3.1.1-a, and the examples in the specs would make it 3.1.1-alpha which is a lot more obvious.

The odd/even thing is fairly common, but not at all obvious to "normal" people. Does everyone who uses it use it the same way round? If not it's even less obvious. You have version comparison code? For what, and why?

For software using Semantic Versioning, "normal" people should be advised never to go anywhere near a version with a "-" of "+" or both in it unless they know exactly why they need that specific version.

I'd like an example of a non-compatibility reason for changing the major number (so that I can try to demolish it of course).

Separate public version and internal version numbers are a very bad idea indeed unless there is zero chance of ever mistaking a occurrence of one for an occurrence of the other, so one of them would have to be of a totally different format from the other. This is why so many unreleased things have code names.

bll 2016-7-7

Well, I'm not normal. I agree with everything I said and you said.

There's package vcompare in Tcl, but it doesn't handle -alpha. I have version comparison code so I can supply the user with a "new version available" check.
EMJ 20160711 - The package man page specifies what formats are handled by package vcompare, and therefore also the format that must be used for package versions. I can't argue with "new version available", but for a lot of software it woud need to do more than is their version < current version.
There's also a lot to be said for plain old incremental version numbers, 1, 2, 3, ... 1511, etc.
EMJ 20160711 - This is OK if the sequence is strictly linear with no alphas, betas, specials, or versions the sensible "normal" user should skip.
I don't break backwards compatibility with my software. But I made a major version change when the internals got a new database rework enabling some much improved functionality and a second time when the UI changed completely.
EMJ 20160711 - What never? Semantic Versioning says that the software MUST declare a public API , but doesn't define "API". It could certainly be interpreted as including the UI. My view is that if the user does the same things with the same data after a version change they should be able to do them in the same way and get the same result, otherwise it's not backwards compatible.
bll 20160711 Good point. With the new UI, any autohotkey (or equivalent scripts) would need to be rewritten, so in that manner, it does break backwards compatibility even though the user can accomplish the same tasks. Even a simple button rename could break an autohotkey script.

But on the occasions when I send someone a test release, they get confused when 2.1.1a is a pre-release and 2.1.1 is later, so I'm going to do something different from now on. Odd/even or even/odd or incremental will work. No training about letters, - or + necessary.

bll 2016-7-11: I think what I will do is increment the minor or patch number in an incremental fashion, no letters or -version. The readme file can document which minor and patch numbers were development only. There can be some slight confusion if the user thought they missed a release, but the version numbers will always go up.

PYK 2016-07-08: It's useful when versions can be consumed and sorted by fairly simple automated mechanisms. ycl package vcomp , for example splits version on punctuation, digits, upper caser letters, lower-case letters, digits, control characters, and whitespace, and compares each component of two versions, numerically if appropriate, and lexicographically otherwise. This simple mechanism is used to automatically select latest versions for a rather large collection, and succeeds in cases where package vcompare doesn't. It works for example, with software from OS distributions that use - or . to add an additional "private" version component to upstream packages. It falls down, however, when a version attempts to signal an "alpha" release by appending 'a", ".a", ".alpha", or "-alpha". Therefore, from my perspective as a maintainer of a large software collection, I prefer that arbitrary descriptive information doesn't creep into a version, and that signals such as "pre-release release" be overloaded into version components such that the system I just described can succesfully sort and compare versions. I like the idea of modifying the base name to make different products of pre-release versions or versions having varying configurations or feature sets.

bll 2016-7-8 See also: php version_compare