30

I'm looking for a version numbering scheme that expresses the extent of change, especially compatiblity.

Apache APR, for example, use the well known version numbering scheme

<major>.<minor>.<patch>
example: 4.5.11

Maven suggests a similar but more detailed schema:

<major>.<minor>.<patch>-<qualifier>-<build number>
example: 4.5.11-RC1-3732

Where is the Maven versioning scheme defined? Are there conventions for qualifier and build number? Probably it is a bad idea to use maven but not to follow the Maven version scheme ...

What other version numbering schemes do you know? What scheme would you prefer and why?

deamon
  • 89,107
  • 111
  • 320
  • 448

5 Answers5

26

I would recommend the Semantic Versioning standard, which the Maven versioning system also appears to follow. Please check out,

http://semver.org/

In short it is <major>.<minor>.<patch><anything_else>, and you can add additional rules to the anything else part as seems fit to you. eg. -<qualifier>-<build_number>.

Tobu
  • 24,771
  • 4
  • 91
  • 98
sixohsix
  • 579
  • 4
  • 8
  • 10
    The -- scheme from Maven seems not to match exactly the semver.org recommondation. semver.org: "A special version number MAY be denoted by appending an arbitrary string **immediately following** the patch version. The string MUST be comprised of only alphanumerics plus dash [0-9A-Za-z-] and **MUST begin with an alpha character [A-Za-z]**." – deamon Jan 12 '10 at 19:12
  • 3
    @deamon semver.org probably changed it years ago but for the record it now complies with the maven scheme: "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. " – kapex Nov 30 '14 at 15:26
  • 1
    @kapep: The formats are still not fully compatible, because the comparison algorithm from semver is much more complicated that what Maven uses. But if you stick to just "-RC1", "-RC2" or similar, you should be fine. – sleske Nov 13 '15 at 08:39
24

Here is the current Maven version comparison algorithm, and a discussion of it. As long as versions only grow, and all fields except the build number are updated manually, you're good. Qualifiers work like this: if one is a prefix of the other, longer is older. Otherwise they are compared alphabetically. Use them for pre-releases.

Seconding the use of semantic versioning for expressing compatibility; major is for non-backwards compatible changes, minor for backward-compatible features, patch for backward-compatible bugfixes. Document it so your library users can express dependencies on your library correctly. Your snapshots are automated and don't have to increment these, except the first snapshot after a release because of the way prefixes are compared.

CupawnTae
  • 14,192
  • 3
  • 29
  • 60
Tobu
  • 24,771
  • 4
  • 91
  • 98
6

Purely for completeness, i will mention the old Apple standard for version numbers. This looks like major version. minor version. bug version. stage. non-release revision. Stage is a code drawn from the set d (development), a (alpha), b (beta), or fc (final customer ship - more or less the same as release candidate, i think).

The stage and non-release revision are only used for versions short of proper releases.

So, the first version of something might be 1.0.0. You might have released a bugfix as 1.0.1, a new version (with more features) as 1.1, and a rewrite or major upgrade as 2.0. If you then wanted to work towards 2.0.1, you might start with 2.0.1d1, 2.0.1d2, on to 2.0.1d153 or whatever it took you, then send out 2.0.1a1 to QA, and after they approved 2.0.1a37, send 2.0.1b1 to some willing punters, then after 2.0.1b9 survived a week in the field, burn 2.0.1fc1 and start getting signoffs. When 2.0.1fc17 got enough, it would become 2.0.1, and there would be much rejoicing.

This format was standardised enough that there was a packed binary format for it, and helper routines in the libraries for doing comparisons.

Tom Anderson
  • 46,189
  • 17
  • 92
  • 133
  • Purely for completeness ( :-) ), I'd like to point out that IMHO requiring separate builds for every stage (which this scheme implies) is not a good idea. At least the builds for final QA/testing should work in production unchanged. Any required differences in behavior should be injected via configuration. See e.g. [Separate 'debug' and 'release' builds?](http://stackoverflow.com/questions/420343/separate-debug-and-release-builds). – sleske Nov 13 '15 at 08:44
  • @sleske I don't think it does imply separate builds for each stage. If you are in the beta-testing phase, you would create 1.2.3b4 in dev, put that through CI, get QA to approve it, do UAT, then roll it out to beta-testers, using the same binary all the way. Rather, what it implies is that at any point, you know how far a build might go - so you know when you commit that it will only be used in development, sent to beta testers, released, etc. There is some duplication at transitions, eg if 1.2.3b10 passes beta testing, the same code will probably become 1.2.3fc1, which is not ideal. – Tom Anderson Nov 15 '15 at 10:56
4

After reading a lot of articles/QAs/FAQs/books I become to think that [MAJOR].[MINOR].[REV] is most useful versioning schema to describe compatibility between project version (versioning schema for developer, does not for marketing).

MAJOR changes is backward incompatible and require changing project name, path to files, GUIDs, etc.

MINOR changes is backward compatible. Mark introduction of new features.

REV for security/bug fixes. Backward and forward compatible.

This versioning schema inspired by libtool versioning semantics and by articles:

http://www106.pair.com/rhp/parallel.html

NOTE: I also recommend provide build/date/custom/quality as additional info (build number, build date, customer name, release quality):

Hello app v2.6.34 for National bank, 2011-05-03, beta, build 23545

But this info is not versioning info!

gavenkoa
  • 45,285
  • 19
  • 251
  • 303
1

Note that a version number scheme (like x.y.0 vs. x.y) can be constrained by external factors.

Consider that announcement for Git 1.9 (Januaury 2014):

A release candidate Git v1.9-rc2 is now available for testing at the usual places.

I've heard rumours that various third-party tools do not like the two-digit version numbers (e.g. "Git 2.0") and started barfing left and right when the users install v1.9-rc1.
While it is tempting to laugh at them for their sloppy assumption, I am also practical and do not mind calling the upcoming release v1.9.0 to help them.

If we go that route (and I am inclined to go that route at this moment), the versioning scheme will be:

  • The next release candidate will be v1.9.0-rc3, not v1.9-rc3;
  • The first maintenance release for v1.9.0 will be v1.9.1 (and Nth one be v1.9.N); and
  • The feature release after v1.9.0 will be either v1.10.0 or v2.0.0, depending on how big the feature jump we are looking at.
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250