I’m working on some code to sort software versions and it’s tricky.
Maven
Software that releases to Maven Central should follow Maven’s versioning scheme. This list is sorted by Maven’s scheme:
- 1.0.0-alpha
- 1.0.0-beta
- 1.0.0-rc1
- 1.0.0-RC2
- 1.0.0
- 1.0.0-final
- 1.0.0-delta
- 1.0.0-preview
In this scheme certain strings like “alpha”, “beta”, and “final” are special and that impacts where they sort. Strings like “delta” and “preview” are not special. Maven versions are case-insensitive.
SemVer
There’s a spec for semantic versioning at semver.org. It formalizes using version strings to express major, minor, and patch-level changes. This list is sorted by SemVer:
- 1.0.0-RC2
- 1.0.0-alpha
- 1.0.0-beta
- 1.0.0-delta
- 1.0.0-final
- 1.0.0-preview
- 1.0.0-rc1
- 1.0.0
In this scheme a version is either pre-release (with a dash) or release (without a dash). Pre-release strings use case-sensitive sorting so “RC2” comes before “rc1”!
Recommendations
Maven and SemVer schemes are surprising in their own ways, and also mutually incompatible. For the JVM ecosystem, Maven is what matters most. SemVer is handy because it specifies major/minor/patch semantics.
I use release candidates to give early-access to eager users. For these I recommend this pattern:
- 1.0.0-rc.1
- 1.0.0-rc.2
- ...
- 1.0.0
The dot after “rc” helps with sorting. Otherwise “rc10” sorts before “rc2” in SemVer because it uses string order when characters and numbers mix.
I use internal-only releases when cutting custom builds of open source projects. Here’s a version naming pattern for those:
- 1.0.0-alpha.jesse.1
- 1.0.0-alpha.jesse.2
- ...
- 1.0.0
The “alpha” string helps with sorting. Otherwise Maven believes the internal build follows the released version.
Versions are tricky because they serve competing use cases. They communicate semantics; signaling both stability and compatibility. They’re used by our tools for dependency resolution. And they’re marketing!