It sounds like you are bypassing normal conventions just to avoid process overhead/audits. That... strikes me as concerning.
What you are doing is effectively making an extra version number (your minor PCI digit) somewhat intentionally in order to move your feature/minor version numbers back a place, to no longer trigger your internal audit criteria.
Anyways, getting to your question about semantic versioning, the spec for Semantic Versioning states:
Given a version number MAJOR.MINOR.PATCH, increment the:
- MAJOR version when you make incompatible API changes,
- MINOR version when you add functionality in a backwards-compatible manner, and
- PATCH version when you make backwards-compatible bug fixes.
- Additional labels for pre-release and build metadata are available as extensions to the MAJOR.MINOR.PATCH format.
Emphasis mine.
So the question is, are you using the fourth character for pre-release/build metadata? Or is it basically another version indication that you are releasing?
If "yes" then semantic versioning's spec does allow for it. If "no" then you technically are not following semantic versioning.
And as a higher-level and more arguable side question, does it really even matter?
Whether you want to rigidly follow it or not is a decision you and your team have to make. The purpose of semantic versioning is to help with API compatibility:
Bug fixes not affecting the API increment the patch version, backwards compatible API additions/changes increment the minor version, and backwards incompatible API changes increment the major version.
I call this system "Semantic Versioning." Under this scheme, version numbers and the way they change convey meaning about the underlying code and what has been modified from one version to the next.
It's a system that helps make it more clear when versioning affects downstream users of the API.
As long as your API is similarly clear it's not a huge deal which way you choose. Semantic versioning just happens to be straightforward, for example if I'm using 3.4.2 and need to upgrade to 3.4.10 I know I can do so without breaking anything. If the new version is 3.5.1 I know it's backwards compatible. And I know version 4.0.1 would be a breaking change.
That's all part of what the version numbers mean.
@enderland Yes basically. MAJOR(PCI).MINOR(PCI).FEATURE.HOTFIX+BUILD. We're basically only allowed to change the 3rd and 4th component without getting PCI (and subsequently the PCI overlords at the company) involved. To me it feels like this is a bit contrived, I am not sure they are justified in the way they manage the version number, but I do not know enough about PCI and audit process to say otherwise.
Ok, this is fine. You have a system which works for you and meets your needs. That's the point of versioning.
If your API is private (only internally facing) it really doesn't matter how you version as long as it makes sense to you and everyone using it. Where versioning in a standard format matters is when you have many other consumers of your API that need to know "what does this version mean?"
Having an arbitrary versioning system will confuse people who are used to other systems, such as semantic versioning. But if no-one is really using your versioning system except the people creating it - it doesn't really matter.
It's my understanding that you have to increment the major version number if your code introduces breaking changes.
If Thing
is used strictly for input and you're now accepting a couple of new values, then you won't break any existing code.
However, if you're returning Thing
and I have code like
switch (myThing) {
case PreExistingValue1:
doProcess1(myThing);
break;
case PreExistingValue2:
doSomethingElse();
break;
default:
throw new NotImplementedException();
}
returning new values will break my code. That's something I'd like to know about.
Best Answer
Semver is mostly concerned about versioning libraries and packages in a manner that avoids dependency hell, in it's various incarnations. However, the idea behind Semver can be extended to all kinds of programs – any piece of code has some kind of user interface, or it is pretty useless.
Using the example of consumer software, such as a word processor:
However, many problems which Semver tries to solve do not exist outside of the area of dependency management. In consumer applications, the version is not only a version, but also a marketing asset.
Firefox and Chrome release new versions comparatively frequently, and increment their major version number at each release. This results in ridiculously high version numbers (both are currently in their 30s). A browser with a higher version number must simply be better than a browser with a lower version number, right?
The major version number of Apple's operating system OS X has become part of the name (X is 10 in Roman numerals), making the minor version number the effective major version number.
The Ubuntu operating system uses a year.month.patchlevel versioning scheme. This makes it easy to remember how old your OS is, but makes it much more difficult to figure out which versions are compatible, and how long support for each version lasts.
The Linux kernel bumped the version number from 2.6.39 to 3.0.0, because the
39
was getting a bit large, and to commemorate Linux' 20th anniversary.Donald Knuth's legendary TeX typesetting system uses a version number that, as of version 3, converges to π by adding another digit at each release: 3.14159265…. This signifies how the system is getting closer to perfection. Similarly, the Metafont system converges to e: 2.7182818….
So, many applications are not well served by Semver. Pick a versioning scheme that's good for your users (regardless of whether these users are fellow programmers or consumers), and keep it consistent.