Versioning Methodology

In my effort to improve application documentation, I’ve found myself improving my versioning methodology to be more meaningful. I work on a variety of applications on an intranet site serving as an “application farm”, so my apps are constantly having revisions as our needs change or grow. Versioning is complex and should vary based on the needs of the development environment. I’ve found the following approach beneficial for my “application farm”.

Application Versioning

The following recommendation came from Don’t Back Down: New Versioning Guidelines. This methodology is best suited for application development, where versions are most meaningful in relation to the features being developed.

  • Use a three-number, two-dot version number (X.Y.Z, such as 1.0.3).
    • The major version number (”X”, first number) changes when significant extra functionality is added to a release or a large number of smaller functions are added since the last major release so that the product is now vastly different. The latter scenario is obviously subjective; thus, simply using good judgment is required.
    • The minor version number (”Y”, second number) changes upon releasing new features that did not exist in the product before but do not vastly change the appearance or behavior of the application.
    • The release number (”Z”, last number) likely changes the most often, and is incremented any time a bug fix or optimization is released or an extremely small functionality enhancement is added.

Version incrementing. The three version numbers ought to be treated as separate numbers that do not impact their superiors. For instance, 1.1.9 would increment to 1.1.10, not 1.2.0. If the programmer decided that enough minor version changes have occurred to warrant a major version increment (i.e. 1.15.0 -> 2.0.0), that is acceptable and is the programmer’s prerogative. A version increment resets its subordinates to zero (i.e. 1.5.8 -> 1.6.0, or 1.5.8 -> 2.0.0).

Repository check-in versioning. In the case that the application is in a source code repository (and it should be), you may also decide to place the exact repository revision associated with the tagged version. This is superfluous, but leaves no doubt as to the precise version of the code. This number may be delimited differently since it isn’t really part of the tagged version number (i.e. 1.5.8R253 or 1.5.8-253, for “Release 253″).

Library or API Versioning

Versioning for functions, classes, custom tags, libraries, and APIs is better suited by compatibility versioning. That is, you can determine compatibility simply by looking at the difference in version numbers.

The following principles were pulled from ADC: Framework Versions and The Jakarta Site: Versioning Guidelines, which are guidelines for existing public systems, and Brian’s Waste of Time: Versioning at the Airport, a commentary on versioning by an open-source developer.

  • Version numbers are of the form X.Y.Z, but do not have the traditional meaning of major, minor, and bugfix, though it frequently may work out that way. Call them major.minor.point versions; the version numbering serves as a guide for compatibility.
    • Different major (X) versions are not compatible. Thus, apps using v2.5 would break if they switch to v3.0.
    • Different minor (Y) versions are backwards compatible. Thus, apps using v1.4 would continue to function using v1.5 without any changes to code. They either add new interfaces or modify existing interfaces to provide new behavior without changing the old behavior.
    • Different point (Z) versions are forward compatible. Thus, if you are developing against v1.2.17 and find a bug that didn’t exist in v1.2.15, you can drop to the older version without any changes to code.

Major Version Examples. Examples of actions necessitating major version increments: (a) Removing or renaming public interfaces, such as a method in a class. (b) Changing data layouts, such as in a database or file. (c) Changing the signature (the order, type, or number of parameters) of a public function or method.

Avoiding Major Version Changes. Before implementing the library/class/API, consider its implementation carefully. Don’t publish a class, function, or method unless you want your clients to use them. Don’t delete interfaces; instead, leave them in for compatibility purposes, returning a reasonable value. If you need to alter the signature of a function/method, leave it compatible in the old form if possible. This frequently can be done by adding a parameter to the end of the list and assigning it a typical default value.

Minor Version Examples. Minor versions retain compatibility with their linked applications. They don’t change existing interfaces; they add new interfaces or modify the implementation of existing interfaces in ways that provide new behavior without changing the old behavior. (a) Adding a class/function/method. (b) Make enhancements that don’t change your public interfaces.

Point Version Examples. Point versions are typically bug fixes or optimizations implemented in such a way that dropping from a newer version to an older version wouldn’t break an application. (a) Bug fixes not affecting programming interfaces. (b) Optimizations that do not affect programming interfaces.

Development States

It is worth considering a list of defined standardized states an application or library may be in.

  • In Development. Application is new and still relatively unstable.
  • Beta. Application is considered relatively complete but not thoroughly tested. The programmer(s) and client(s) should begin rigorously testing the application, on a test platform or database if necessary.
  • Released. Once an application reaches production quality, it can be set to this state, meaning it is ready to be deployed and used. Even when revisions are made and are individually in a beta state, the application itself, in its current version, remains in a released state.
  • Unsupported. When an application is entirely supplanted by another application or for any other reason it is retired or obsoleted for supported use, it reaches an unsupported state.

Prerelease Versioning

Small projects may not have a tagged version until the final release. While in development, they may be referred to by their repository revision. If a project is large enough, the programmer(s) may opt to implement versioning on the prerelease project. If this is done, they could use a major version of zero (for instance, the first version thus being v0.1.0). The beta release would then also be a zero-version number. Once the development state moves from beta to released, the version can be updated to v1.0.0.


Conclusion.
Again, the approach to versioning will vary from one team to the next, and from one environment to the next. Web app versioning may vary from compiled app versioning. But even web apps should be housed within a repository, with key points in the applications’ lives tagged as versions, to improve documentation and deployment tasks.

Leave a Reply

  Theme Brought to you by Directory Journal and Elegant Directory.