Need advice on Nightly Builds, SemVer, and NuGet

Coordinator
Oct 25, 2011 at 8:14 PM

Hi All,

I just posted a blog post with ideas and questions on how to handle nightly builds and semantic versioning of your packages.

I wanted to create this topic as the place for discussion of this post.

Oct 25, 2011 at 8:52 PM

I prefer this one:

1.0.1alpha_0001 – internal build

"The downside of this approach is that it’s not completely clear that these are internal nightly builds of what will be 1.0.1beta. They could be builds of 1.0.1alpha2."

I don't think that this causes any confusion.

Oct 25, 2011 at 9:21 PM
Edited Oct 26, 2011 at 2:27 AM

comment removed due to bad logic

Oct 25, 2011 at 9:40 PM

Hi Phil,

Besides the discussion on versioning, I definitely like the idea of having multiple feeds and a package promotion mechanism. I think it makes a lot of sense to split up feeds for different purposes, such as a Internal Build - feed, a QA feed, a Releases feed etc. Package promotion implies we don't want to mess around changing package versions: the package we want to promote should end up on the next feed in line without touching the package itself.

In terms of the NuGet.org gallery, everything is considered a release right now, so I really welcome support for SemVer patch-number-suffixes such as 'alpha', 'beta', ... I think this is indeed much needed for some packages out there, including some of mine :-) Considering the growth of the public gallery, you might want to consider to filter out 'unreleased' packages by default? Having a separate feed for them might encourage proper versioning and the package promotion model as well I think, although not sure about the technical hassle it could present for the current implementation of the NuGet tooling. What's more, this could facilitate separate versioning models for these feeds, e.g. public gallery doesn't support SemVer pre-releases, the pre-release feed however does, etc. Think about multiple instances of NuGet.Server running, each with their own purpose and matching versioning scheme...

Coming to the nightly builds question: this, in my opinion, is a third kind of package feed, for internal use, with its own versioning scheme. You gave the example of having a datetimestamp + build increment, for some people this would work, others would like to deviate from that. As this is meant to be internal, I believe people should be able to use whatever they prefer (and live with the consequences of their choices).

I personally like the idea of having a sequence of post-alpha builds incremented with a simple build number. I'd use the fourth version number, the build number for that (it's not because SemVer doesn't mention the 4th number, we can't use it, although it's just a matter of semantics). So when working on a beta-build, you'd end up with something like this:

  • 1.0.0alpha <-- the alpha build
  • 1.0.0alpha.1
  • 1.0.0alpha.2
  • ...
  • 1.0.0alpha.n <-- n-th build after alpha (no notion of date/time, file system already has creation date/time, build server hopefully as well)
  • 1.0.0beta <-- the beta build

Promoting the alpha and beta packages from the Internal Build feed to a QA feed (what could be a NuGet.org pre-release feed) does not require any change to the packages: a simple copy of the 1.0.0alpha and the 1.0.0beta feed to the QA feed repository would be sufficient. When releasing v1.0.0, you just drop the patch-number-suffix (and build-number) and publish it onto the release feed for consumption.

I also don't see an issue in the fact that it might not be immediately obvious that a "beta" is coming after the "alpha". If an intermediate milestone "alpha2" is required, you're still flexible enough to hook it in between 'alpha' and 'beta'. 

Anyway, I like the fact that NuGet is moving towards supporting such scenarios as well! Nice work!

Cheers!

Coordinator
Oct 25, 2011 at 10:44 PM

Hi all, I updated my post to replace the underscore character in my sample versions with the dash character because underscore is not allowed in SemVer.

@Eddie Are you sure about that? I think the order of precedence is...

  • 1.0.1alpha
  • 1.0.1alpha-001
  • 1.0.1alpha-002

Which defeats that versioning scheme unless we make the release version "alpha1".

@xavier yes, pre-release packages are filtered out by default. When using the Package Manager Console, you have to opt-in to pre-release packages using the -IncludePrelease flag (or the -pre flag for short).

Oct 26, 2011 at 3:39 AM

Based on SemVer rule#3: 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.

We can still use lexicographic sort, but treat the hyphen as a special subversion indicator where we could get the following precidence:

1.0.1alpha-0001
1.0.1alpha-0002
1.0.1alpha
1.0.1alpha2
1.0.1beta-0003
1.0.1beta-0004
1.0.1beta
1.0.1

If you do this, you still fully support the spec as defined, and make it easy to promote more stable prereleases from internal feeds to public feeds without having to repackage them.

Coordinator
Oct 26, 2011 at 5:03 AM

@Eddie, the problem is, that seems to violate the spec. Notice the following part of the spec:

The string MUST be comprised of only alphanumerics plus dash [0-9A-Za-z-]

Dash is an allowed character (see it at the very end). So to change the meaning of dash to allow for a different sort order seems to violate the spec. If we're going to violate the spec, might as well introduce a new special character not already allowed in the version string by the spec. Say, a dot! :)

I'm planning to propose that to the SemVer folks.

Oct 26, 2011 at 8:38 AM
Edited Oct 26, 2011 at 8:41 AM

Just a comment from Tom Preston-Werner (semver.org author) regarding specific build number :

comment on issue #33 : adding the '.' character as a valid first character if the special version number

He said :

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.

It seems to follow your proposition (using a dash to separate special version number instead of the fourth version part).

Oct 26, 2011 at 9:03 AM
Edited Oct 26, 2011 at 9:03 AM
styx31 wrote:

Just a comment from Tom Preston-Werner (semver.org author) regarding specific build number :

comment on issue #33 : adding the '.' character as a valid first character if the special version number

He said :

...

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.

Thx for pointing out this comment!

At the same time he's saying it would be totally fine to use a fourth Q number to act as a build number. I like this idea for internal builds as explained in my earlier comment. The distinction between patch and build version information is more clear imo.

The only place you'd need and use build information, would be internal, so I wouldn't go as far as to expose such build number information on release-packages, most consumers don't find this information meaningful. So releasing a pre-release would only be a matter of dropping the build number and you're done. The dot-character clearly indicates where build information starts and patch information stops. I kinda like this simplicity.

Notice that SemVer already uses a dash between patch number and pre-release tag, e.g. v1.0.0-alpha (instead of v1.0.0alpha). If we'd consider using a dash for build information, e.g. v1.0.0-alpha-666 (or v1.0.0alpha-666?), thinks can become fuzzy quite fast. What if someone decides to use v1.0.0-alpha-20111026-666 and so on?

Oct 26, 2011 at 9:06 AM

(And haacked just opened another issue on github about this discussion).

Oct 26, 2011 at 12:01 PM
I'm totally digging the idea of

1.0.1-alpha.###

The dash separation is perfectly legal, improves readability a bit, and makes a pretty nice separator between the version and the pre-release parts. It may even help in determining you have a prerelease because you can just scan the version for "-".

Showing an ordering:
1.0.0-alpha.001
1.0.0-apha
1.0.0-alpha1.001
1.0.0-alpha1.002
1.0.0-apha1
1.0.0-beta
1.0.0-rc
1.0.0


Thoughts?

Oct 26, 2011 at 12:28 PM

+1 @ferventcoder :-)

Oct 26, 2011 at 1:10 PM

I think moving in this direction is great, having the ability to have a HEAD/TIP build on NuGet that is not the default package is definitely needed. People are used to NuGet, and want to get nightly builds from it as well.

It would be nice to setup branches/paths/chains/links/whatever to allow for a mechanism of patching bugs in a 1.0.0 release (with a 1.0.1 package) while still having a GA-tagged 2.0.0 release. This would allow people on down-rev versions to be able to get bug fixes without having to jump out-of-band. This would also help everyone (MS-included) since many shops can update to every release due to API changes (such that a 2.0.0 might introduce).

Would be nice to setup auto-purge rules as well (assuming space is limited, if it is unlimited then forget I mentioned it) so that nightly builds could be auto-published via the build server to NuGet.org so people would wanted nightly builds (by pulling from the -branch nightly, etc. -- however it gets done) would get them.

If you do it entirely by version (instead of random branch names) that might be slick as well.

I push 1.0.0beta
I push 1.0.0 (the GA release)
Later, I push 2.0.0beta
I push 2.0.0beta-2
Then, I push 1.0.1beta (bug-fix beta)
 Then, I push 1.0.1 (new 1.0.x GA release)

IT would be nice that somebody who was on the 1.0.x lineage would get an update for the 1.0.1 bug fix but not the 2.0.0 beta. 2.0.0 GA would require a greater level of acceptance than 1.0.1, since it's a major version change and could have breaking API changes (isnt' that the SemVer rule?).

Enough spewing of ideas, but I'm excited to see something like this under development.

Oct 26, 2011 at 2:42 PM

A lot of interesting discussion on this on both your blog and in the comments here.  My 2c FWIW

 

- My preference would be against string additions like 'alpha', 'beta' and friends because they are particularly warty / hideous IMHO. I don't like that aspect of SemVer at all, and its not an obligatory feature that you must opt-in to.

- I think Ken Egozi is on totally the right track with alternating stable (even) and beta (odd) minor version numbers, which alleviates the need for ugly strings munged in with version numbers, and is a well known pattern in other environments. Many *nix applications following this same scheme, as did Ruby.  Node.js source is another example which follows this convention, but if you look around enough you'll find plenty of other examples.  I don't see what a blob of text for 'alpha' / 'beta' etc will buy over this simple convention.  Alpha, beta, gamma, delta ... are really all just synonyms for 'unstable'.

- With that in mind, it should be easy to specify in a packages.config whether you're willing to accept just Patches (1.2.1 -> 1.2.2 but not 1.2.1 -> 1.3.0), Minor functionality (1.2.1 -> 1.3.0 but not 1.2.1 -> 2.0.0) or wholesale potentially breaking Major changes (1.3.0 -> 2.0.0 or anything in between).  I think a sensible default is Minor, but should be overrideable.

 

- Date based build numbers by themselves are an anti-pattern.  They are not totally appropriate w/out additional data as there might be multiple legitimate builds in a single day and a date does not tie directly into a point in a source tree (not to mention other issues with distributed teams / timezones / rolling counters / etc).  A much better approach, if date is important, is to combine it with a 4th revision number that is derived from a check-in number.  I use this approach for CI, modifying a shared AssemblyInfo.cs as part of the build process.  We use hg, so the source servers node # is used as build number, and the assembly is further tagged with the universal hash id in the AsemblyInfo AssemblyConfiguration.  In MSBuild speak

<VersionNumber>$(MajorVersion).$(MinorVersion).$(YearMonth).$(DayNumber)$(Build)</VersionNumber>

One thing to be aware of, however, is that each of the build numbers has a max # of 65535.

http://blogs.msdn.com/b/msbuild/archive/2007/01/03/why-are-build-numbers-limited-to-65535.aspx

For this reason, I've considered dropping date integration with version numbers altogether as, in practice, I don't think it's really that important. 

 

- There is a lot of talk of nightly builds here.  I fall in the camp of believing that nightly builds are an anti-pattern.  In a perfect continuous delivery pipeline, the concept is non-existent.  A set of code should proceed through a build process upon each commit, and if it passes all established quality gates (passing tests / coverage / static analysis / etc), it should be promoted and ultimately published to an internal Nuget feed automatically.  If you're doing it right, you will break things often, and only a small subset of builds meeting your minimum quality will make it as far as your internal Nuget feed.  For more detail on this, check out the great Continuous Delivery book -- http://continuousdelivery.com/ or for the CliffNotes version, check this DZone ref card -- http://refcardz.dzone.com/refcardz/continuous-delivery-patterns

 

- FWIW, I would like to see a facility for automatically rejecting assemblies that improperly fail to update Major / Minor version numbers in accordance with the semantic guidelines.  SemVer requires a lot of discipline and is pretty hard to get right... so it would be nice to reject submission of a bad egg.  I don't think that this would be too difficult to implement by reflecting an asms public API and comparing to last known good in that particular Major / Minor chain.

Oct 26, 2011 at 2:55 PM
Edited Oct 26, 2011 at 3:07 PM

Also... on the separate feeds.  I think this is a good idea, but might be overkill.

Debian / Ubuntu use that concept to great success, providing configurable stable, unstable and experimental package sources for aptitude.

 

Out of curiosity, has anyone looked in detail at the schemes for RVM (yes, I know the SemVer proposal comes from Ruby guru / GitHub cofounder ;0), NPM, Aptitude or even CPAN for that matter?  I feel like these same types of versioning problems have already been solved in other worlds, and Nuget should learn from their successes / failures.

Oct 26, 2011 at 3:50 PM

@Phil This is not violating the spec at all.

According to Request for Comments: 2119
3. SHOULD   This word, or the adjective "RECOMMENDED", mean that there may exist valid reasons in particular circumstances to ignore a particular item, but the full implications must be understood and carefully weighed before choosing a different course.

This means using the dash, as it is a valid character, and adding NuGet flair to it doesn't go against the spec or the intention of the spec. With this in mind you could even use multiple dashes to allow sub-sub ordering, and so on.

Using a date stamp [yyyymmdd] and daily build number for ci builds, yeilds the following precidence:
1.0.1alpha-ci-20111026-1   <-- CI Build
1.0.1alpha-ci-20111026-2   <-- CI Build
1.0.1alpha-ci-20111026      <-- Nightly
1.0.1alpha-ci-20111027-1   <-- CI Build
1.0.1alpha

This also opens up the ability to install packages at certain explicit prerelease levels I.E. '1.0.1alpha-ci' and '1.0.1alpha'. Or '1.0.1-alpha-ci' and '1.0.1-alpha' if you use the dash as an initial seperator.

Coordinator
Oct 26, 2011 at 4:05 PM

@EddieGarmon Ah, true. But I sort of feel that if we adopt the standard, we shouldn't deviate from well established patterns. Supporting a version string and then NOT sorting it lexicographically seems wrong and confusing to those who expected we follow the recommendations of SemVer.

There was an earlier discussion about this on Github here: https://github.com/mojombo/semver.org/pull/33#issuecomment-2026210

The recommendation was:

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'd prefer that approach simply because SemVer has nothing to say about a fourth version part, so we wouldn't be violating any expected behavior. The behavior of that part is full up to us.

Now, regarding the "-ci" part, I wonder if we couldn't just accomplish this all with tags, which NuGet supports. So tag it as a "CI" or "nightly".

Developer
Oct 26, 2011 at 4:57 PM

We definitely shouldn't be using a full stop (dot) as a separator to imply something different from what's already being done. It would lead to a very confusing versioning system where 1.0.0a.1 < 1.0.0a, but 1.0.0.1 > 1.0.0.

One alternative that's been tried and tested would be to look at what Debian does with it's versioning system: http://www.unix.com/man-page/all/5/deb-version/

       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,
       'a'.

So in this case 1.0.0a~1 < 1.0.0a < 1.0.0ab < 1.0.0 etc. I still dislike the idea of assigning more meaning to SemanticVersion than what's already being offered, but this does sound a lot simpler to follow. 

Oct 26, 2011 at 5:41 PM
pranavkm wrote:

We definitely shouldn't be using a full stop (dot) as a separator to imply something different from what's already being done. It would lead to a very confusing versioning system where 1.0.0a.1 < 1.0.0a, but 1.0.0.1 > 1.0.0.

Depends if you'd stick to SemVer for release packages (major.minor.patch), and only allow the 4th (build) number to be used for pre-release and internal packages :-)

Coordinator
Oct 26, 2011 at 6:39 PM

Well the problem is that we have all these existing 4-part versioned packages in the feed that don't use SemVer today. We don't want to break them all overnight. So the SemVer semantics we want to adopt should be backwards compatible.

I like the tilde approach for two reasons:

1. It's a well established pattern so it makes it easier for us to communicate it.

2. Tilde is not a valid SemVer character, so for the purposes of SemVer, we would ignore that segment

Thus, going back to the CI builds, in order of precedence (lowest to highest):

  • 1.0.1alpha~001
  • 1.0.1alpha~002
  • 1.0.1alpha~003
  • 1.0.1alpha
Oct 26, 2011 at 6:53 PM

Hmm, looking at the listed example, makes a lot of sense. Could live with that :-)

Just a question on the lexical comparison, because you use leading zeros, as in 1.0.1alpha~001..

You don't know up front how many CI builds you will get between two changes in SemVer version. Which leads to the question: how many leading zeros would be enough?

Let's say I don't use leading zeros (which I'd prefer), will the ordering be able to find out that v1.0.1alpha~9 < v1.0.1alpha~10 for instance?

This would result in something like this, in order of precedence (lowest to highest)

  • 1.0.1alpha~1
  • ...
  • 1.0.1alpha~9
  • 1.0.1alpha~10
  • ...
  • 1.0.1alpha
Oct 26, 2011 at 8:18 PM
I still am leaning towards a prefix of "-" prior to any prerelease just due to providing a clean separation for readability and maybe ease of figuring out what version comparison algorithm to use.

1.0.1-alpha~1
1.0.1-alpha~2
1.0.1-alpha
1.0.1

Gems does the dot separation by the way.
Oct 26, 2011 at 8:19 PM
A curiosity - What happens if I submit a package with 1.0.0 and then submit the next version as 1.0.0.1?
Oct 26, 2011 at 8:33 PM
And to follow up, with packages I do not author the library, what do I do when I mess up the 1.0.0 package and need to update it? In the past the idea has been to append something to the package to show that it is a package "fix" and not a new package.

  1. To illustrate, say I am working on log4net's package.
  2. I have log4net version 1.2.10
  3. log4net.1.2.10.nupkg gets uploaded.
  4. I realize I messed up a dependency on foo in the nuspec
  5. I need to fix the package and reupload log4net 1.2.10.
  6. Do I:
  • add the last dot with a fix date?
  • add the last dot with a fix number?
  • increment the last number?
  • just tell people not to use the package b/c it's messed up?
Since I cannot reupload the same package number by design, the only option to continue SemVer is to increment the last number. So I upload log4net.1.2.11.nupkg with log4net 1.2.10 in it.

Now a few weeks later, log4net 1.2.11 is released. Shoot. Now what do I do?

This is a good illustration of something that really happens. And has happened to me a few times. With the new nuget gallery implementation that doesn't allow you to change package details once you've uploaded a package, this will become more commonplace for others as well. IME I've found that I add a package fix number to the end.

But I am curious what the thought is and how SemVer will be supported?

A possible precedence order:
1.0.0alpha~001
1.0.0alpha
whoops - 1.0.0alpha.1
Oct 26, 2011 at 8:48 PM

@fervent Your last example sounds like a case of not testing before publishing. Otherwise I would say 1.2.10.1. If the 4 digit versioning is kept along with SemVer, and I believe it should be for this exact reason, then 4 digit versions would use the existing version comparison where 1.2.10[.0] < 1.2.10.1. Here the assumption would be that 4 digit versions are not prerelease, and as such would disallow the use of the dot as a prerelease indicator.

Oct 26, 2011 at 8:57 PM

@eddiegarmon: I am almost on board with you on the testing before publishing.  But let me throw this out for you. How do I test the image or link for my package prior to publishing?

Oct 26, 2011 at 9:02 PM

@eddiegarmon: I know my example was kind of crappy in what point I was trying to get across. I test all of my packages prior to release and have still run into terse little things that have to do with package information that you only find out about once it ends up on nuget.org (icon urls, links, bad grammar or misspellings in the package information being the big ones).

I think instead we should be able to upload (push) the same package multiple times. Until we publish it. Then no longer allow it to be uploaded (but that's a different discussion entirely).

Oct 26, 2011 at 9:07 PM
Edited Oct 26, 2011 at 9:08 PM

Definitely on board for kicking the dot (".") out of prerelease indications (in any form).

I would definitely say (leaving my "-" preference out):

1.2.10alpha~001
1.2.10alpha~001.1 (fix of build 001 alpha package, not contents)
1.2.10alpha
1.2.10alpha.1 (fix of alpha package, not contents) 
1.2.10
1.2.10.1 (fix of 1.2.10 package, not contents) 

 

Updated: clarified it a bit.

Coordinator
Oct 26, 2011 at 9:32 PM

Wow, lots of comments! I'll take them in order.

@xavierdecoster - Since the part after the ~ is not part of SemVer, perhaps we could interpret it the way you mentioned. Maybe we take a strict subset of Debian here.

Thus the sort would be:

  • 1.0.1alpha~1
  • 1.0.1alpha~3
  • 1.0.1alpha~10
  • 1.0.1alpha~20

@ferventcoder - I think using the dash looks great and it's allowed by SemVer. I don't think we should require it. But anyone is free to use it if they want to, as long as they are consistent with their own packages.

@ferventcoder If you use four part version numbers without any version string part, we keep to the old behavior. For example:

  • 1.0.0
  • 1.0.0.1
  • 1.0.0.10
  • 1.0.0.2

Otherwise we'd break a huge number of packages! :)

So going to your log4net case, it's always safe to increment the fourth version part. I would release it as Log4Net 1.2.11.1.

Perhaps the NuGet clients could even strip out the last part and show it as a separate "build number". Nah, that's just confusing.

Oct 26, 2011 at 9:33 PM

I personally dont like the dot anywhere in a prerelease.

1.2.10alpha~001
1.2.10alpha~002 (fix of build 001 alpha package metadata, not contents)
1.2.10alpha~003 (same package metadata, new contents)
1.2.10alpha (ideally this is a repackage of alpha~003 with just package metadata edits, same contents)
1.2.10
1.2.10.1 (fix of 1.2.10 package or contents)

@fervent As for testing, I'm sure you do. I have my own server set up as I'm sure you do as well. I always test from that several times before I publish. Not trying to make any issue out of testing here.

I do believe that having the ability to do prereleases will help reduce/eliminate the number of times you would want to make package edits after publish.

Oct 26, 2011 at 9:33 PM
ferventcoder wrote:
I still am leaning towards a prefix of "-" prior to any prerelease just due to providing a clean separation for readability and maybe ease of figuring out what version comparison algorithm to use.
1.0.1-alpha~1
1.0.1-alpha~2
1.0.1-alpha
1.0.1
Gems does the dot separation by the way.

If you look at the SemVer specification though, it says the special version number must immediately follow the patch version AND must start with an alpha character. So unfortunately, you can't have the separation you want (which I agree is more readable).

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.
Oct 26, 2011 at 9:39 PM

@kiliman: take a look at what they are taking about on that github thread. The guy behind semver says "-" is legal.

Coordinator
Oct 26, 2011 at 9:47 PM

@ferventcoder that's not how I read that. - is legal, but not to start the part of the string that denotes the "special version number". I think the spec is pretty clear on that, as kiliman points out. :)

Oct 26, 2011 at 9:47 PM
@eddiegarmon: the last dot isn't actually part of the prerelease at all. The prerelease information is all contained completely in that 3rd version number.

Major.Minor.PatchPrerelease.PackageFixNumber

So 1.0.0[.1] or 1.0.0alpha~1[.1]. The last .1 in both cases here is only applicable to packagefixes and not the prerelease version at all.

Oct 26, 2011 at 9:51 PM
I don't think we are reading the same thing -

https://github.com/mojombo/semver.org/pull/33#issuecomment-2026210

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.

Coordinator
Oct 26, 2011 at 9:55 PM

Right, thus the dash as a separator would separate the SemVer (X.Y.Z) part from the build number part.

Thus looking at what you proposed:

1.0.0-alpha.001

The SemVer part is 1.0.0 (aka a release of 1.0.0 and not 1.0.0alpha from the SemVer perspective)

The custom build part is "alpha.001"

That's not exactly what I'm looking for as I want the SemVer part to match what we'll actually release. The final goal is:

1.0.0alpha

Thus I want all builds of this release to start with "1.0.0alpha"

I think using the dash as a separator is an odd choice in this case because it's a valid SemVer character. That's why I like the tilde. It provides a nice separation.

Oct 26, 2011 at 10:01 PM
I like the tilde. I changed my mind on that a few threads ago. ;)

Here, to reduce confusion.

  • There is no dot in the special versioning at all. All dots relate to the normal versioning.
  • The special versioning is contained ONLY within the 3rd version number.

Thus breaking apart : 1.2.3alpha~4.5
Major: 1
Minor: 2
Patch: 3
Special: alpha~4
Fix: 5

Oct 26, 2011 at 10:05 PM
My argument for the "-" is for separating the patch from the special versioning to increase readability and to provide a nice context for knowing you are on a special version. One could argue you can get that without it there and that is valid. One could also argue that this is technically not part of SemVer (yet) and that is also valid if you go by the official released spec and not what Tom was saying on the thread.

So adding that part back in and remembering that there is no dots in special versions,
1.2.3-alpha~4.5
is still
Major: 1
Minor: 2
Patch: 3
Special: alpha~4 where 4 is the custom build
Fix: 5
Oct 26, 2011 at 10:07 PM
I'm good either way, as long as you can still have the fix version number at the end (the fourth version number), even after a special version.

Coordinator
Oct 26, 2011 at 10:18 PM

Nothing like software developers to spend hours arguing minute details. This is great though! :)

My proposal is slightly different from yours. 

Breaking apart: 1.2.3alpha~4

SemVer Part: 1.2.3alpha

Build Number: 4

More detailed breakdown

Major 1
Minor 2
Patch 3
Prerelease annotation alpha
Build Number 4

So in a CI scenario, every commit increments the build number. In reality, it's up to you how you label it, but we would sort it numerically when determining precedence.

Oct 26, 2011 at 10:27 PM

I think we are saying the same thing for build number.
I'm technically arguing for a fifth number. ;)

____
Rob
"Be passionate in all you do"

http://devlicio.us/blogs/rob_reynolds
http://ferventcoder.com
http://twitter.com/ferventcoder

On Oct 26, 2011 5:18 PM, "haacked" <notifications@codeplex.com> wrote:
Coordinator
Oct 26, 2011 at 10:34 PM

Why do we need a fifth number?

Oct 27, 2011 at 12:37 AM

I don't think a 5th number is needed. I also do not think that the BuildNumber should be used for touching-up your package metadata. The fact that the server doesn't allow you to verify all aspects of your package seems to be a problem with the server and should be addressed there (and you could already use the prerelease mechanism to verify that your package looks good on the server)

I would like to steer the conversation back towards the concept of the extra Build Number for CI purposes. The idea here is that most users would not be consuming CI packages. That's because while a project is in development the APIs could keep changing and consumers would have to keep adjusting. If they want to do that and suffer through that pain - their choice. In fact, I don't think that nuget.org should even support CI builds of packages (in part due to storage constraints and in part because it's meant for consumers developing applications).

The idea behind this feature is (in my mind): I'm developing a not-yet-released component X that depends on a not-yet-released component Y. I want to be able to have a verification process (another CI machine) that ensures that as Y changes i can respond appropriately by fixing up X. But if Y breaks me I can decide to snap to the last-known-good build of Y, ask that project's members what their plan is for addressing the break and either adapt to it or decide to keep working against an older version of Y until it gets fixed. That's why the BuildNumber is required: to be able to unambiguously identify the LKG build of a particular package.

Note that if you don't like SemVer you can use the odd/even approach. But not everyone likes that, hence the idea for semver+buildnumber.

Also note that package versions don't have to match .NET assembly versions or file versions. It would be nice if there was some unambiguous connection between the assembly version/package version as well as file version/build number that you adopt but that's not always possible due to the general mismatch between SemVer, .NET GAC and .NET assembly binding semantics.

Coordinator
Oct 27, 2011 at 2:55 AM

Agreed. This will not be a feature of the public nuget.org gallery, but it may become a feature of the software that the Gallery runs on https://github.com/NuGet/NuGetGallery/.

BTW, Rob, looks like you are going to get your wish after all. Tom just commented that SemVer 1.0.0 will use the dash as the special version separator: https://github.com/mojombo/semver.org/pull/33#issuecomment-2538713 

So eventually, we can support:

1.0.0-alpha~1

Oct 27, 2011 at 6:02 AM
Edited Oct 27, 2011 at 6:04 AM
haacked wrote:

So eventually, we can support: 1.0.0-alpha~1

I'm all settled with that approach! If I understood correctly, you'll find a summary below of what has been discussed so far.

 

Prerelease semantics [major].[minor].[patch-prereleaseTag~buildAnnotation]

for instance 1.0.0-alpha~1

where [major].[minor].[patch-prereleaseTag] (or 1.0.0-alpha) is fully compliant with SemVer,

with prereleaseTag (-alpha) sorted lexicographically in ASCII order, and buildAnnotiation (~1) in numerical order (no recommendation or need for leading zeros, although supported).

 

Release semantics [major].[minor].[patch].[build] 

for instance 1.2.10.1 or 1.2.10 or 1.2

where [major].[minor].[patch] ideally is used fully compliant with SemVer versioning rules (although that's up to package producer)

Build number still taken into account because of backwards-compatibility with existing four-version-number packages.

 

On a sidenote

For release semantics, I'd love to see [major].[minor] as required and [patch].[build] as optional (if not specified, 0 is assumed, e.g. 1.2 maps to 1.2.0 and 1.2.0.0).

Going further, [major].[minor].[patch] as required would even be better :-)

I've used required and optional here as a desire for good practice, although it is not enfored by NuGet in anyway as far as I know.

Oct 27, 2011 at 1:46 PM

This sounds great. One remaining question is how would we support date-time based build annotations (yyyymmdd used in example below)?

1.2.10-alpha~1~20111017 (CI Build)
1.2.10-alpha~2~20111017 (CI Build)
1.2.10-alpha~3
1.2.10-alpha~4~20111018 (CI Build)
1.2.10-alpha~5
1.2.10-alpha

Would we want to allow an additional ~ and anything after it? What other simple options could there be for build annotation format?

Oct 27, 2011 at 4:20 PM
EddieGarmon wrote:

This sounds great. One remaining question is how would we support date-time based build annotations (yyyymmdd used in example below)?

1.2.10-alpha~1~20111017 (CI Build)
1.2.10-alpha~2~20111017 (CI Build)
1.2.10-alpha~3
1.2.10-alpha~4~20111018 (CI Build)
1.2.10-alpha~5
1.2.10-alpha

Would we want to allow an additional ~ and anything after it? What other simple options could there be for build annotation format?

Then the numerical sort starts to get complicated. There should be one build number. Either go with the sequential CI build number (in which case you can look at the CI machine to see when the thing was built) or a date/time combo. But not both.

Oct 27, 2011 at 4:31 PM
Edited Oct 27, 2011 at 4:31 PM

Also, i'm not sure what's the difference between "1.2.10-alpha~2~20111017 (CI Build)" and "1.2.10-alpha~3". They should both be CI builds.

Oct 27, 2011 at 5:20 PM

The thought was that there are organizations where the blessed build shall not come from a CI server, and what would be a simple way to coordinate the two.

Oct 27, 2011 at 7:05 PM
EddieGarmon wrote:

The thought was that there are organizations where the blessed build shall not come from a CI server, and what would be a simple way to coordinate the two.


I see CI vs. Nightly vs. Stable as being served through different feeds, not the same feed. Otherwise there's too much work on the consumer side of configuring options for how to pull the package. Now there's the problem that NuGet does not store an association between the package and the feed that it came from and I think that's a seperate issue that should be addressed to better support CI build feeds.

Oct 29, 2011 at 10:22 AM
Edited Oct 29, 2011 at 10:22 AM

Hi,

interesting discussion you have here, guys :)
In my opinion @Iristyle was right when talking about *unix way, it works perfectly well. Adding 'alpha' or 'beta' is already too much. And simple odd-even convention should solve all your problems.

In my company we have an internal NuGet feed and we use it in the following way:
1) all packages get deployed by CI server when somebody makes a commit
2) all assemblies and packages are versioned like: 2.1.45.5673
Where '2' is a product version, '1' is a branch version, '45' is a tag version and '5673' is a revision from SVN.
All packages from trunk have revision 0.0.0.5673.
3) when some project needs a package it can specify required version like:
- HEAD - means 'give me latest from trunk'
- 4.* - means 'give me latest available package from any branch or tag for product version #4'
- 4.1.* - will get latest package only from branch #1 or from any tag that was created from that branch
- 4.1.0.* - returns latest available package only from branch #1
4) release-ready packages must have versions without zeros (i.e., they were created from tags)
5) thanks to NAnt tasks all this revisions-related stuff is very easy to follow :) Until now we didn't have any major problems

The only disadvantage I see in our approach is that we tied to SVN revisions, in GIT case, for example, it is not available. But it shouldn't be a problem to create an alternative solution.

So, my vote is for simple convention without 'alpha'-s and 'beta'-s.

Oct 29, 2011 at 10:39 AM

@usarskyy: you might run against the AssemblyVersionInfo Build-number limitation, as explained here: http://michaelsync.net/2007/01/12/assemblyversion-buildno-limitation

On a related note: having a changeset/revision number appearing in a build number is not really a good practice.

The link between the compiled output, the date/time, the changeset/revision number, should not be stored in the version number itself in my opinion. That's why TFS keeps track of builds, changesets, and date/time information in the first place. I'm sure other build systems do the same (or at least they should).

Not to mention the amount of 'build numbers' you skip by relying on the changeset/revision number (another project can have multiple revisions/changesets committed to your VCS, before the next build of your project's next revision/changeset, thus going from a build number 5673 to the "next one" being 5681 for instance.

Oct 29, 2011 at 4:51 PM

@xavierdecoster: I'm aware of this limitation but that's the most pragmatic way in our case. It doesn't require too much effort to follow, it's always clear to which revision package is related to (easy to check log history) and we won't run into a version-overflow problem in the next 4-5 years for sure. Also I don't see anything bad in having a few versions skipped.

Oct 29, 2011 at 5:37 PM

@usarskyy don't get me wrong, it might be a perfectly valable solution in your case, but it might be insufficient to extrapolate this solution to everyone using NuGet

Oct 29, 2011 at 10:59 PM

@xavierdecoster: I don't say that my solution is perfect and should be used by everyone. All I'm trying to show is that all these alphas&betas can be easily achieved by having a simple convention + very little implementation. "Keep it simple" :)

Like @Iristyle already mentioned, *unix world lives without complicated versioning systems just because long time ago they agreed on what odd/even versions mean for them. Why this approach can't be copied (with appropriate changes if needed)?

Dec 30, 2011 at 12:32 PM

Phil

I like idea of using timestamp for nightly builds.

For example:

X.Y.Zalpha(-._)201112300509

Using ISO 8601 timestamp at the end has some benefits:

  • It's standard (ISO 8601)
  • its obvious
  • it tells exactly when the build occurred
  • works for multiple builds within a 24 hour period

 

 

Jan 3, 2012 at 7:07 AM

I'm quite partial to the odd and even versioning scheme since it's quite well known in the open source community and it's worked out well so far for everyone.

Jan 11, 2012 at 3:03 PM

Any conclusions yet?

This discussion started when semver was at version 1.0.0.
I think some important changes were made in 2.0.0-rc1 in regards to this.

  • Include the "-" before the pre-release version.
  • Use the "+" sign the build number
Coordinator
Jan 11, 2012 at 5:31 PM

Many of the changes to SemVer were inspired by this discussion. We're going to follow whatever SemVer closes on. Might be good to have a discussion there if you see any problems with their versioning scheme.

https://github.com/mojombo/semver/issues

Jun 22, 2012 at 7:11 PM

The build number issue is really something that deserves some attention. Fingers crossed for RTM version of SemVer soonish...

This issue http://nuget.codeplex.com/workitem/2346 relates to this discussion.

Coordinator
Oct 23, 2012 at 6:18 PM

I've been talking with @haacked about SemVer and getting the spec to RTM.  There's some debate on the Build numbers and how they are spec'd now.  I created an issue that outlines my thoughts on it and references this thread and the examples that have been illustrated here.

https://github.com/mojombo/semver/issues/51