my software versioning policy

My old versioning policy was to assign just a release code and a patchlevel, in the form of RELEASE.PATCHLEVEL. This was enough for my projects, but when I started to write libraries it was very difficult to tell if an increment in the PATCHLEVEL meant just a bugfix or a change deep enough to make impossible to use the new version as a drop in replacement for the old version (e.g. some API change). This would force an increment in the RELEASE number for medium importance changes, and probably will confuse the users.

Right now I have TWO different versioning policies, one for projects that export some kind of API/ABI, like libraries, whose intended audience is developers, and another for general projects like applications, etc. where the intended audience is the end users.



I'll explain the shorter, simpler policy first, the one for projects intended for end users. Before, I used version numbers like RELEASE.PATCHLEVEL, later RELEASE.MINOR.PATCHLEVEL, and both worked quite good for me. The problem behind this kind of version numbers is that they no longer mean anything for end users. They are not standardized, so depending on the particular project, the MINOR may mean "odd number for development branch, even number for stable branch", or something equally arbitrary. In my opinion, end users just look at the version number and if it is higher than the version number they have currently installed, they may upgrade. Or, if installing for the first time, they will choose probably the the version with the highest number.

So I think it's much easier for me to distribute my end user projects using a single number as the version number. The higher the number, the newer the version. Yes, an increase in the version number doesn't indicate if the change is just a bugfix, a minor change or an entire rewrite, but current practice doesn't provide that kind of information most of the time and it's unnecesarily complex.

I'm pretty sure that end users are way too familiar with version numbers following the X.Y or X.Y.Z scheme, but nonetheless I'm going to break with it. From now on, only single numbers. This works for Apple, right?



When the project is a library, or any other kind of software that needs to export a public API or ABI, a different scheme is needed. For a start, the intended audience is other programmers and they will correctly interpret (most of the time...) what the version number means, so it's a very good idea to provide as much information as possible in the version number.

In this case, I chose the schema of using a major release code, a minor release code and a patchlevel, in the form of MAJOR.MINOR.PATCHLEVEL. A change in the version code will show more exactly how deep is the update in the software. Here is a reference about the meaning of a code change (I use the term library to refer to anything with a public API or ABI):
  • A change in the PATCHLEVEL will indicate a bugfix or a very minor code change that doesn't make the library binary incompatible with the previous version. You can use the new library as a drop-in replacement for the old one.
  • A change in the MINOR code will indicate a more or less important change in the code, meaning that some entry point has been added to the API, or some entry point has been deprecated (but not removed). Depending on the platform, this kind of change may render the library binary incompatible with the old one, but that's not common: most of the time the new version will still be usable as a drop in replacement. In any case, the list of changes should be read just in case the project using this library has to be changed in some near future, but NO CHANGE is needed now. The library still maintains it's old API, deprecating some entry points (but not removing them) and adding new ones in preparation for future major releases.
  • A change in the MAJOR code will indicate a very large, deep or important change in the code, probably a major rewrite or even a change in the behaviour: the library may have some entry points removed, other entry points may have their behaviour changed, etc. The new version CANNOT be used as a drop-in replacement anymore  because it CANNOT be binary compatible with the old one.
To summarize: a PATCHLEVEL increment just means "don't worry, I just fixed a bug", a MINOR increment means "I'm on my way of redesigning the library, but you can use this version instead of the previous one without problems" and a MAJOR increment means "read the docs, this library is not the one you used to know soooooo well, sorry".