I'm working on a small, open-source project in my free time and trying to figure out a reasonable way to number releases. There are about 10 of us working on the project right now, and there seem to be 10 different opinions about when we should roll out the major and minor numbers for our project. Since the software is only in the alpha stage, I thought it was premature to come up with a numbering scheme; but once someone else posted it on our mailing list we decided we should tackle the problem now so we don't have to think about it again later. When you're working on software, when do you roll out a new version number?
Averse to Aversion
You have 10 developers and you have only 10 opinions? I was expecting you to say you had 20 opinions, so right from the start it looks like you're not in as bad a shape as you might think. Choosing a versioning scheme is more important than most programmers really understand, in part because a versioning scheme is a form of human communication, and human communication...well, let's just say that many programmers don't get that at all.
A good version-numbering system can be used to track the change in functionality of a piece of software.
A versioning scheme serves a few important purposes. The most obvious is allowing users to know where they are in the evolution of your software, but version numbers also communicate a good deal more information.
A good version-numbering system can be used to track the change in functionality of a piece of software. A new feature, or a major change to a feature, should always result in a new version number being assigned. I've always been happiest, or perhaps least miserable, with three-number versioningMajor.Minor.BugFixwhere the major version changes for large features, the minor version changes for small features, and the last number is a bug-fix release. The bug-fix number is perhaps the easiest to understand. After a number of bugs are fixed, you want to release new software into the field so that users can benefit from the work your team has done. Increase the last number and release a new version. Bug fixes should never change an API in a library or introduce or significantly change a feature.
The difference between a major and a minor version change can be tricky depending on the software you are writing. Minor versions can be rolled out so long as there are no backward-incompatible changes to the system. What this means is that if you have a change to your software that will break another piece of software that depends on your code, or that breaks a user assumption about how your system works, that requires a major version change. Additive changes, such as new APIs, or new features that do not break backward compatibility can be rolled into minor version updates.
The slippery slope is figuring out how many minor changes add up to a major change. If your software has 30 features and you add 10 new ones, even if none of them touches the original 30, shouldn't that necessitate a major version change? I think it should, but not everyone agrees. Of course those who don't agreewell, let's just leave that alone, shall we?
One thing that software versions communicate is the rate of change in your software. If your software goes from 1.0 to 2.0 in a month, then either your team is performing miracles, which I find highly suspect, or they're claiming major changes when none has really occurred. A very high rate of minor or bug releases can also indicate problems in a projectin particular, that it is buggy. Although there is no perfect rate for releases, they should definitely slow down a bit as a product matures. Too-frequent releases often mean that a piece of software is immature and perhaps lacks staying power.
Another pattern, in some projects, is never to release a 1.0, but to release a lot of 0.x's. A particularly egregious version of this, pun intended, was the Ethereal project, which, after more than 10 years of development, got to the point of releasing a 0.99.5. This was just a way, as far as I could tell, of moving the version number to the right. The software itself is quite good and widely used, but its versioning system was quite odd. Now that the project has been renamed Wireshark, it seems to have moved to a more traditional Major.Minor style of versioning.
The difference between a major and a minor version change can be tricky depending on the software you are writing.
Version numbers should also be able to correlate related pieces of software. One of the banes of my existence is the Linux versioning system, although I believe this has more to do with the way Linux itself is developed. The fact that there are now many different operating-system kernels that I might have to choose from to use a piece of related software is simply maddening. A recent example involves having to find the correct bits so I could use a driver for a new piece of hardware. The standard release was 2.6.18-194.3.1.el5, but the version I needed was, 2.6.18-164.el. And just what do those numbers mean? Of course I could work them out with some Web searches, but still, the fact that kernel APIs have changed enough within those minor releases that a driver couldn't work is madness. Even looking at kernel.org, the source of all things Linux kernel, isn't much help. At the time this column was written these are the kernels that are listed as stable for the 2.6 version of the kernel:
Now, I ask you, how does 2.6.34 come out 10 days before 126.96.36.199, and how can all of these be stable? How do they even relate to each other?
Of course, it's not just open-source projects that have problems with versioning. The biggest software company of them all seems to have one of the most ridiculous versioning schemes of all. Based on the names alone, how does one figure the difference between Windows 95, Windows 98, Windows ME, Windows NT, Windows XP, Windows XP Service Pack 2, and Vista? I can list them in order only because I have watched them all come and go, and, happily, never installed any of them on my own machines. Perhaps if you hash the names just right, then they turn into monotonically increasing version numbers.
One last thing to note is that you should not tie yourself down with your versioning scheme; remember that you may have to be flexible. I once worked on a product with a 1.0.1b release. The b release was necessitated by a not-so-amusing mistake, wherein a developer decided that if a user saved a file without an extension, the developer would provide one. The extension was a four-letter word that is included in George Carlin's list of seven things you can never say on TV, and which one should never really have as a file extension either. I think you get the idea. The developer had meant to remove that particular feature before the code was released but forgot, and so, we had 1.0.1 and 1.0.1b releases. We could have made a 1.0.2 release, but, really, there was just one changethough I do believe we should have made the release 1.0.1f.
A Conversation with Steve Bourne, Eric Allman, and Bryan Cantrill
Making Sense of Revision-Control Systems
The Digital Library is published by the Association for Computing Machinery. Copyright © 2010 ACM, Inc.
Whatever version scheme you have, I recommend it be written down and published for your team and customers. In some of our projects, we followed the major.minor.bug.build naming and it worked fine. In others, we used a sprint.major.minor.build pattern. Or was that sprint.major.bug.build? Oh well. That is why we document it - my memory is so bad and the possible schemes are endless.
Displaying 1 comment