Question

Are different version naming conventions suited to different projects? What do you use and why?

Personally, I prefer a build number in hexadecimal (e.g 11BCF), this should be incremented very regularly. And then for customers a simple 3 digit version number, i.e. 1.1.3.

1.2.3 (11BCF) <- Build number, should correspond with a revision in source control
^ ^ ^
| | |
| | +--- Minor bugs, spelling mistakes, etc.
| +----- Minor features, major bug fixes, etc.
+------- Major version, UX changes, file format changes, etc.
Was it helpful?

Solution

I find myself rarely agreeing completely with Jeff Atwood, but I tend to follow his opinion of the .NET convention of version numbering.

(Major version).(Minor version).(Revision number).(Build number)

More often than not, for personal projects, I find this to be overkill. The few times where I have worked on substantial projects like search engines in C# I've stuck to this convention and have been able to use it as an internal tracker effectively.

OTHER TIPS

Semantic Versioning (http://semver.org/) deserves a mention here. It is a public specification for a versioning scheme, in the form of [Major].[Minor].[Patch]. The motivation for this scheme is to communicate meaning with the version number.

I don't use it but I have seen and it's an interesting structure:

Year.Month.Day.Build

Self explained.

I try to use the RubyGems Rational Versioning policy in which:

  • The Major version number is incremented when binary compatibility is broken
  • The minor version number is incremented when new functionality is added
  • The build number changes for bug fixes.

Here is very fine-grained approach to version numbering:

  • N.x.K, where N and K are integers. Examples: 1.x.0, 5.x.1, 10.x.33. Used for intermediate builds.
  • N.M.K, where N, M and K are integers. Examples: 1.0.0, 5.3.1, 10.22.33. Used for releases.
  • N.x.x, where N is integer. Example: 1.x.x. Used for support branches.
  • N.M.x, where N and M are integers. Example: 1.0.x. Used for release branches.

Here is the picture for simple illustration of version numbering approach:

Agile version numbering

PA means pre-alpha A means alpha B means beta AR means alpha-release BR means beta-release RC means release candidate ST means stable

Advantages of such version numbering approach are following:

  • It represents specifics of agile software development lifecycle.
  • It takes into account specifics of source code repository structure.
  • It is self explaining for those who got used to the patterns. Every pattern represents different artifact. Such patterns can be easily parsed and used for other purposes, such as issue tracking.
  • Versioning patterns set, which basic for the described versioning approach can be used for gathering metrics and planning.
  • It is focused on the concepts of maturity and level of quality. Very often such version numbers as 1.0.0 are assigned without much necessity (when software is in deep alpha). Presented version numbering approach allows to establish several levels of maturity. In the simplest case it will have only two levels: intermediate build (N.x.K) and release (N.M.K). Release means that piece of software with full version number (N.M.K) has gone through some kind of quality management process within the supplier company/organization/team.
  • It is an evidence of agile nature of both development and testing.
  • Encourages modular approach to the software structure and architecture.

There is also more complex diagram representing versioning approach in details. Also you might find useful presentation slides describing transition to the versioning approach and SCMFViz application illustrating basic principles of version numbering approach. Presentation slides also explain why it is important to stick to the same versioning approach throughout the whole life of the software project.

Personally my attitude towards using date version instead of real version numbers assumes that developers of the software with dated versions:

  • Know nothing about software development lifecycle. Development is usually agile and iterative. Version numbering approach should represent iterative nature of software development process.
  • Do not care about software quality. Quality control and assurance are agile and iterative. Just like development. And version number should be the evidence of agile and iterative nature of both development and quality control/assurance.
  • Do not care about architecture or idea of their application. Major version number (N in N.M.K) is responsible for both architectural solution and underlying principle of the application. Major version number N is to be changed accordingly to the changes in architecture or changes of major ideas and principles of its working/functioning.
  • Do not have control over their codebase. There is probably only one branch (trunk) and it is used for everything. Which personally I do not think is right as it encourages codebase to become one large garbage dump.

This approach might seem a little bit controversial, but I believe this to be most straightforward way of giving software appropriate version numbers.

For every major version you release, it's not uncommon to have a working version you call it internally. For instance, at my last job, we referred to a major version with the following Ubuntu-inspired naming convention:

[sickly condition] [alliterative animal name]

Which gave such names as "Limp Lamprey", "Wounded Wombat" and "Asthmatic Anteater".

Make sure unless it's a truly cool name that it doesn't leak to your customers.

Generation.Version.Revision.Build (9.99.999.9999)

Generation rarely changes. Only a big turn on product: DOS -> Windows, complete reengineering.

Version is for big incompatible changes, new functionality, changes on some specific paradigms on software, etc.

Revision is often done (minor features and bug fix).

Build is internal information.

git describe provides a nice extension to whatever numbering convention you've chosen. It's easy enough to embed this in your build/packaging/deployment process.

Suppose you name your tagged release versions A.B.C (major.minor.maintenance). git describe on a given commit will find the most recent tagged ancestor of the commit, then tack on the number of commits since then, and the abbreviated SHA1 of the commit:

1.2.3-164-g6f10c

If you're actually at one of the versions, of course, you'll just get the tag (1.2.3).

This has the nice benefit of letting you know exactly what source you built from, while not having to number every single build yourself.

Major.Minor.Public (build) [alpha/beta/trial], such as "4.08c (1290)"

  • With Major being the major version number (1, 2, 3...)
  • Minor being a 2 digit minor version (01, 02, 03...). Typically the tens digit is incremented when significant new functionality is added, the ones for bug fixes only.
  • Public being the public release of the build (a, b, c, d, e), which is often different from the minor version if a minor version is never released as a public update
  • build, being the actual build number that the compiler keeps track of.
  • with TRIAL, ALPHA, BETA X, or RC X appended for those special cases.

I prefer version numbers that assign some semantic meaning. As long as you can use the version number to track bugs reported with a particular version to changes that occurred in the source code (and in your activity management system) then you're probably using the right method.

I use .NET so I'm stuck with the .NET version numbering system but I try to give semantic meaning to the numbers so with

major.minor.build.revision

  • major = (up to the project)
  • minor = (up to the project)
  • build = build number from Hudson (you could use TeamCity or TeamBuild, etc. here)
  • revision = subversion or bazaar revision (depending on the project and what its using)

We always make sure thatt he version number is visible in some way (with our batch console-based programs its printed to console and a log file, with web apps its on the menu bar at the top usually)

This way if clients report problems we can use the version number to track if they are using the latest version and how many problems we have had with particular versions.

It's all about traceability!

We use Major.Minor.Build#.YYMMDD[suffix], as we usually only do one production build on any particular day (but use a b/c/d suffix if there's more than one) and the YYMMDD gives users/customers/management an indication of the age of the build, where 6.3.1389 does not.

Major numbers increase with significant product features (paid-for).

Minor numbers increase with fixes/improvements (free update).

Build always increases; not all builds ship, so it's not a linear progression.

Version numbers should have enough information that you avoid conflicts and fixing a bug in the wrong release type problems, but shouldn't convey additional information that isn't relevant.

For instance if you use the date customers can tell that they have an older version, and patches against old versions can have confusing versions.

I personally like semantic versioning:

  • Releases are Major.Minor.Patch
  • Patch increments every time you release a build.
  • Minor increments every time backwards compatible functionality is added.
  • Major increments when new functionality is not backwards compatible.
  • When Major == 0 you're in alpha/pre-release. Major >= 1 are your public releases.
  • Lower numbers reset to 0 every time you increment, so

    1.5.3 -> 1.5.4 (bug fix) -> 1.6.0 (minor feature) -> 2.0.0 (breaking change)

This way if someone is using, say, version 1.5.3 they could tell at a glance that they could upgrade to 1.5.4 to get the patches, that 1.6.0 would add functionality and that they shouldn't upgrade to 2.0.0 (at least without handling the change).

              1.0.0
                |
              1.0.1
                |
(public 1.0)  1.0.2-----
                |       \
              2.0.0    1.1.0
                |        |
              2.0.1    1.1.1 (public 1.1)
                |
(public 2.0)  2.0.2-----
                |       \
              3.0.0    2.1.0
                         |
                       2.1.1 (public 2.1)
                         |
                       2.2.0
                         |
                       2.2.1

X.Y.Z is our internal version number. X.Y is the public version number, the one that has a meaning to our clients. When a X.Y.Z version becomes public, there will never be a X.Y.(Z+1) version : the public version is always the last of the serie.

X is incremented when a major version is released.

Y is used for the maintenance branches of those major releases, only for bug fixes.

Z is used internally, and has no fixed meaning. Until now, I create a new Z version when I think that the application has a set of features that are interesting to show to non developers, and is relatively stable. This way, I can show a demo of the "last known good version" of the application when someone ask one. In a near future, I plan to use the Z number versions for naming a "target" of features, in our bugtracker.

As a side note, we use maven (with the release command) to increment the version number. So, there are X.Y.Z-SNAPSHOT versions, too (which indicates any version between X.Y.(Z-1) and X.Y.Z).

Licensed under: CC-BY-SA with attribution
scroll top