Skip to content


Subversion checkout URL

You can clone with
Download ZIP


adding the '.' character as a valid first character if the special version number #33

wants to merge 1 commit into from

7 participants


pull request in association with issue #32 at #32

rkh commented



Hey stoicflame,
the format you specify in your suggested modification would allow version strings like or, where the 4 or the 4abc respectively would make up the special part. I think this is not what you meant.

Perhaps you should speak of the dot as a separator rather than the first character of the special part.

BTW, I still prefer the dash over the dot for separating the special version part (see also issue #15).


Actually I was fully aware of what the versions would look like. Certainly the dot is a visual separator, but I intentionally left anything after the patch number being defined as part of the "special version part".

I don't have any problem with the dash, either, but I'd like to see the dot there so as to conform to the suggested OSGi semantic versioning scheme.



As for allowing the special part to begin numeric, that's probably no problem. The reason why the first character is currently restricted to alphabetic in semver is certainly to tell patch number and special version apart. With now having the dot there, that reason is gone.

As for making the dot part of the special version part (as opposed to a separator), that appears a little strange to me. Have I understood "anything after the patch number being defined as part of ..." correctly so?

As for the dash/dot issue, surely both of them could be allowed (mutually exclusive, obviously).

I don't know what OSGi mandates. Do you have a pointer?


Yes, I think you understand what I'm saying about having the the dot part of the special version. I guess I thought that was the least-disruptive way to enhance the current spec while preserving backwards-compatibility, but I can see your point about the dot being a specially-interpreted separator character in the spec.

The OSGi document is here:

It defines a 4-part semantic version with the last part being named a "qualifier". Maybe the proposal I'm making should be adjusted to propose an optional "qualifier" part, like in the OSGi doc. But the "qualifier" would need to not be restricted to a numeric value.

And then there's the issue of distinguishing between the qualifier and the "special string". I think I'd say that if there's a qualifier (identified by the presence of a dot), then there can be no special string or something like that.



I cannot figure out qualifier precedence from the OSGi Semantic Versioning document. However, given that a main use case for qualifier is "build number", I infer that SemVer and OSGi may have incompatible precedence:

SemVer: < < 1.0.0

OSGi: 1.0.0 < <

SemVer spells it out succinctly:

Special versions satisfy but have a lower precedence than the associated normal version

Is my inference of OSGi precedence correct? The most I could find was that an unspecified qualifier is assumed to be empty. For SemVer and OSGi to agree on precedence this must be true:

OSGi: < 1.0.0.{empty qualifier}

I think qualifiers should be a separate issue, since they do not relate to prereleases.


You make a good point about the precedence incompatibilities.

To be honest, I don't really care whether 1.0.0 is ordered before or after because if I choose to use the qualifier, all of my artifacts will use the qualifier. So if SemVer states that < < 1.0.0, that would satisfy me.


I don't see value in altering SemVer to support versions that look like OSGi versions but potentially have conflicting meaning. SemVer appeals to me because it eliminates ambiguities. This feels like it's introducing an ambiguity.


I agree. I don't want to introduce ambiguity. I'm suggesting we make a statement as to the meaning of the qualifier. Let's say that < < 1.0.0, to be consistent with the patch version.


@stoicflame are you suggesting modifying OSGi's document to make that statement?


@toolbear74 no I'm suggesting we add the notion of a qualifier to SemVer and make a clear, unambiguous statement as to what it means and how it's sorted.


My current line of thinking regarding special versions is this:

  1. A pre-release version number MAY be denoted by appending an arbitrary string immediately following the patch version and a dash. The string MUST be comprised of only alphanumerics plus dash [0-9A-Za-z-]. Pre-release versions satisfy but have a lower precedence than the associated normal version. Precedence SHOULD be determined by lexicographic ASCII sort order. For instance: 1.0.0-alpha1 < 1.0.0-beta1 < 1.0.0-beta2 < 1.0.0-rc1 < 1.0.0.

The dash is a better separator than nothing (obviously) and denotes it as being a specially treated part of the version. As for qualifier versions, I think by adding that SemVer would become too complex. Three version parts + a pre-release version is about as complex as I want to go. Specific implementors of SemVer could easily say "we follow SemVer except we add a qualifier version number Q in x.y.z.Q that acts as a build number. And that would be totally fine.


I started a related discussion here: #46

we follow SemVer except we add a qualifier version number Q in x.y.z.Q that acts as a build number.
And that would be totally fine.

It might be nice to make a comment to that effect in the spec. My team is particularly careful these days not to try and fork open standards (my company has been slapped for that in the past). So if the spec mentioned as a note that a fourth version number is out-of-scope for SemVer, but is fine for others to use as their own extended version to SemVer, that'd be helpful. :)

I know, realistically nobody needs anyone's permission to do so. But to have it mentioned as a "known practice" is helpful. Thank!


For what it's worth, we're leaning towards what Debian does with it's versioning system:

First the initial part of each string consisting entirely of non-digit
characters is determined. These two parts (one of which may be empty)
are compared lexically. If a difference is found it is returned. The
lexical comparison is a comparison of ASCII values modified so that all
the letters sort earlier than all the non-letters and so that a tilde
sorts before anything, even the end of a part. For example, the fol-
lowing parts are in sorted order: '', 'a', '~', the empty part,

We'll call it the "Debian flavored SemVer". ;)

This allows us to have the following version precedence (from lowest to highest)

  • 1.0.0beta~001
  • 1.0.0beta~002
  • 1.0.0beta~003
  • 1.0.0beta
  • 1.0.0

That is a nightmarishly complex sorting scheme. What if it was simplified to state:

Special versions MUST take the form LEX[~NUM] where the LEX part is sorted lexically, and the optional NUM part is sorted numerically. If the NUM part is present, it MUST be separated from the LEX part by a tilde. A maximum of one tilde is allowed in the special version string.

Also note that SemVer 1.0.0 will use dashes to separate the special version e.g. 1.0.0-beta~001.


Heh. :) We came to the same conclusion over in another discussion forum.

This discussion is spilling into multiple forums and it's hard to keep them all straight!


BTW, I didn't realize SemVer wasn't already 1.0.0. What version is it now? It wasn't clear to me from or here.


Sorry to be a bother, but any ETA on when the "dash" change will be made to SemVer? We're getting close to release our next version of NuGet and we want to adapt to it before we release. We don't want to be out-of-sync with what's published at because we'd get a lot of flack for that. :)


I'll have an RC1 out hopefully tonight. The current version is 0.9.0, but you are right, I don't say that anywhere on the spec page. That was an oversight. New versions will state their version number when published.


Thanks! Any other changes anticipated? We decided to go ahead and trust that the "dash" will be a separator in our implementation and checked that code in last night. We figured, if you changed your mind, we could still call ours a SemVer infused variant. ;)

Some folks on my team wondered if we should prevent dashes in the version part because they thought this was confusing:


Personally, I don't see the problem. It seems that it's clear that the first dash is a special separator, and "foo-bar" is the special version part. But I could go either way.


Yes, SemVer 1.0 will use the dash separator. I think dashes in the special part are fine. The latest version of the spec can be found at and I will add the specifics for the prerelease version number sorting and ~ stuff soon.


Here is the latest from the spec. It covers this situation cleanly:

  1. A pre-release version number MAY be denoted by appending a dash and a qualifying string immediately following the patch version. The qualifying string is comprised of a mandatory identifier and an optional sequence number. If the sequence number is used, it MUST be separated from the identifier by a tilde. Identifiers MUST be comprised of only alphanumerics plus dash [0-9A-Za-z-]. Sequence numbers MUST be comprised of only digits [0-9]. Pre-release versions satisfy but have a lower precedence than the associated normal version. Precedence SHOULD be determined by lexicographic ASCII sort order of the identifier followed by numeric sort order of the sequence number. If the sequence number is absent, it MUST be considered to be zero. For example: 1.0.0-alpha < 1.0.0-alpha~1 < 1.0.0-beta~2 < 1.0.0-beta~11 < 1.0.0-rc~1 < 1.0.0.
@mojombo mojombo closed this

Sorry for the late response. Just thinking out loud here: If someone sets up continuous integration, they might have the following builds of the 1.0.0-beta release internally.

  • 1.0.0-beta~1
  • 1.0.0-beta~2 ...
  • 1.0.0-beta~N (where N is a large number)

At some point they are ready to cut and ship a release of 1.0.0-beta.

However, if anyone internally has one of these interim builds, according to the rule of precedence stated, 1.0.0-beta < 1.0.0-beta~123. So upgrade scenarios in a package manager would not see 1.0.0-beta as an upgrade of 1.0.0-beta~123.

In much the same way that 1.0.0 > 1.0.0-beta, I thought that 1.0.0-beta > 1.0.0-beta~123 would be the right behavior.

Is there something I'm missing?


Man: Doctor, my arm hurts when I move it like this holds arm upright, flexes elbow
Doctor: Then don't move it like that. drum beat, high hat

A few alternatives to your scenario that fit within current SemVer:

1.0.0-alpha~1 → 1.0.0-alpha~42  → 1.0.0-beta
1.0.0-beta~1 → 1.0.0-beta~2857 → 1.0.1-beta

I prefer implicit (~0) over implicit (~INF); the latter would require 1.0.0-beta~N < 1.0.0-beta and require special logic as opposed to the simple rule of lexicographic sort oder.


Heh heh. Sounds good. I think we only need to tweak our thinking slightly about what the ~build number means and we're all set. Thanks. :)


I just had a revelation. It involves use a dot instead of a tilde as the pre-release part separator:


Because why use a tilde when a dot will suffice? Thoughts?


And so it comes full circle. :) We had thought of using a dot a while ago, but dismissed it because we had a skewed understanding of how the 4th number would work (see my previous comment).

But given the semantics described, using a dot makes total sense.

`1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.2 < 1.0.0-beta'

In .NET, we already have 4 part version numbers as the norm. So would I be correct to assume that this fourth part could be applied to a stable version number, or would this only apply to prerelease versions?


The idea is that it would be used for pre-release versions. SemVer already has rules for dealing with modifications to stable releases. But what you really want is the ability to deal with nightly builds. What about this crazy idea:

Since pre-releases are designated with a dash or minus sign, builds are denoted with a plus sign.

Crazy? Maybe, but it has some logic to it.


Semantics of the build part could be the same as the pre-release part. What do you think?


I think I like the previous proposal better. :) I don't think of it as a minus sign but a dash separator. Also, it keeps it consistent.

If you have: 1.0.0-alpha and start doing multiple builds of that, you simply tack on the build number: 1.0.0-alpha.1

No need to also change the separator. I like to think of the version meanings building up from left to right. Start with Major. Then Minor. Then so on... Also, it's clearer how it sorts compared to other versions.


That doesn't really work though. Imagine this scenario.

  • You release version 1.3.4.
  • You now want to have nightly builds done.
  • What do you call that build? 1.3.5-alpha.1 or 1.4.0-alpha.1?

Without knowing what the next version is going to be, how can you use pre-release versions as build versions?

@mojombo mojombo reopened this

Good question. If you go back to the tilde syntax, you could simply omit the prerelease part.

1.3.4 > 1.3.4~1 > 1.3.4~2

The downside to the tilde character is it's reminiscent of the Debian versioning scheme, but that scheme implies that tilde comes before anything. I believe in that scheme:

1.3.4~1 > 1.3.4~2 > 1.3.4

I suppose you don't even need the tilde syntax. 4 part version numbers are pretty commonplace and have the same semantics, so why not just use a dot!?

Works for release nightlies

1.3.4 > >

as well as pre-release nightlies

 1.3.5-alpha > 1.3.5-alpha.1 > 1.3.5-alpha.2

Alternatively, you could use the + to denote the build number.

1.3.5-alpha > 1.3.5-alpha+1 > 1.3.5-alpha+2

One thing I like about that is it's evocative of what we're trying to communicate: 1.3.5-alpha+2 == "The 1.3.5 alpha release plus two builds.

Works for stable releases too: 1.3.5+10 == "The 10th build of the 1.3.5 stable release"

Now I'm wondering if this is exactly what you meant all along. ;)


One thing to consider (not sure if this is really important to anyone), but the OSGi semantic versioning scheme uses a 4 part version where the last part is simply a build identity.

Kind of like what we're describing here.

Using a dot character for SemVer's build # would make its non-prerelease versions pretty compatible to OSGi. SemVer could be described as being like OSGi but with support for prerelease, which is nice. :)


My biggest problem with doing build versions as a 4th primary value is that build versions are not generally meant for wide distribution. My second biggest problem is that build versions often are done as timestamps like "20111119" and so do not increase numerically like the other parts do. My third biggest problem is that many people do not need or want to use build versions and it would suck to saddle them with the extra complexity of a 4th primary version element.

I see builds very much the same as pre-releases: neither are meant for wide distribution, but both are useful for cutting edge testing. The only different between the two is that builds come after the version they are bound to and pre-releases come before the version they are bound to. Which is why I thought it quite elegant that a dash (or minus) could mean pre-release and a plus could mean build. It matches the semantics of the two very nicely.


How do you compose a pre-release version with a build number? Would it work like this?

You can have builds of a release version:

1.0.0 > 1.0.0+1 > 1.0.0+2

As well as builds of a prerelease.

1.0.0-alpha > 1.0.0-alpha+1 > 1.0.0-alpha+2 > 1.0.0

But you can't have preleases of a build...

1.0.0+3-alpha // VERBOTEN!

Is that what you had in mind?


Yeah, that would work nicely. To keep things consistent, I'd still want the build version to be a two part string like:


This way you could be more specific if you wanted to:

1.3.5+nightly.20111120 -or- 1.3.5+hourly.2011112009

Then consumers only have to write a single parser for the special version parts.

And if you wanted to do builds of pre-releases, you could indeed combo them up:


Most people won't have to care about that, but the people that do will have a simple, easy to understand system for tagging dev releases. Is this starting to make sense and feel elegant?


I know this might not really be solvable, but here's a thought: How would I do build versions from say git then, where I don't have an increasing number but an arbitrary string instead?

Yeah, just use a date, but nah, that feels so un-git.


@rkh You could just put the SHA1 (or a short version of it) in the first position:


This would make the sorting of build versions useless, but it would at least get you what you want. Alternatively, and something I've been thinking about, is making the pre-release and build versions more flexible. Instead of having a two part structure, they could have an arbitrary number of dot separated parts:


Each part would be treated either numerically (if only digits are present) or lexically (if any non-digits are present). This would allow you to construct whatever crazy scheme you wanted and would still preserve sort order. Indeed, if you wanted to have a separate versioning namespace for pre-releases you could even do this:


Now you have an entire SemVer playground within a 2.0 pre-release namespace.


Here is an example of how the more flexible build spec could be written:

  1. A build version MAY be denoted by appending a plus sign and a series of dot separated identifiers immediately following the patch version or pre-release version. Identifiers MUST be comprised of only ASCII alphanumerics and dash [0-9A-Za-z-]. Build versions satisfy and have a higher precedence than the associated normal version. Precedence SHOULD be determined by comparing each dot separated identifier as follows: identifiers consisting of only digits are compared numerically and identifiers with letters or dashes are compared lexically in ASCII sort order. Numeric identifiers always have higher precedence than non-numeric identifiers. For example: 1.3.7+build < 1.3.7+build.2.b8f12d7 < 1.3.7+build.11.e0f985a < 1.3.7+1.0.0.

I'm just about to setup up our alpha build for NServiceBus, is it safe to assume that:


is the way to go?

And our CI to be:



@andreasohlund Yes, it is safe to assume that.


The latest spec with the proposed more flexible pre-release and build version parts is now at:

And I aim to release this as an rc.1 today. If you have any feedback on this, speak now by opening a new ticket on

@mojombo mojombo closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
Showing with 6 additions and 5 deletions.
  1. +6 −5
@@ -54,10 +54,11 @@ version. Each element MUST increase numerically. For instance: 1.9.0 < 1.10.0
1. A special version number MAY be denoted by appending an arbitrary string
immediately following the patch version. The string MUST be comprised of only
-alphanumerics plus dash [0-9A-Za-z-] and MUST begin with an alpha character
-[A-Za-z]. Special versions satisfy but have a lower precedence than the
-associated normal version. Precedence SHOULD be determined by lexicographic
-ASCII sort order. For instance: 1.0.0beta1 < 1.0.0beta2 < 1.0.0.
+alphanumerics plus dash [0-9A-Za-z-] and MUST begin with either an alpha
+character [A-Za-z] or the '.' character. Special versions satisfy but have
+a lower precedence than the associated normal version. Precedence SHOULD be
+determined by lexicographic ASCII sort order. For instance:
+1.0.0beta1 < 1.0.0beta2 < 1.0.0.
1. Once a versioned package has been released, the contents of that version
MUST NOT be modified. Any modifications must be released as a new version.
@@ -191,4 +192,4 @@ About
The Semantic Versioning specification is authored by [Tom Preston-Werner](, inventor of Gravatars and cofounder of GitHub.
-If you'd like to leave feedback, please [open an issue on GitHub](
+If you'd like to leave feedback, please [open an issue on GitHub](
Something went wrong with that request. Please try again.