Requiring Semantic Versions in NuGet 3.0

Topics: General
Jan 30, 2014 at 6:02 PM
The NuGet team is designing out what NuGet 3.0 is going to be. One thing that we know for sure is that we'll support Semantic Version 2.0.0-based version numbers (with build metadata). We are trying to be as true to the www.semver.org spec as possible.

We're considering actually requiring Semantic Version versions in NuGet 3.0. This would make the client produce errors for non-semver versions, and the gallery would also block uploads of non-semver versions in packages.

Of course, the gallery and client would handle existing legacy packages, and the client would work fine if talking to a repository (or folder) that contains legacy versions.

Are we bonkers or would this restriction be reasonable?
Developer
Jan 30, 2014 at 6:05 PM
It would not only be reasonable, it would be splendid!
Jan 30, 2014 at 6:11 PM
love it
Jan 30, 2014 at 6:16 PM
I think this is a great idea to move the community forward and respects older projects by grandfathering them in. But I know some members will be less than thrilled by the 'requirement' being imposed on them for new packages and I think there should be a plan to provide a walkthrough resource explaining SemVer and why (and how) to adopt it to make it frictionless.
Jan 30, 2014 at 6:17 PM
I personally like the semantic versioning and use it for my packages on NuGet, but is there an advantage to requiring everyone to use it? Unless there is something gained functionally by using semantic versioning (e.g. NuGet can now make certain assumptions about your package based on the requested version of the package vs the latest version of your package), then I don't see the value forcing everyone to use it.
Developer
Jan 30, 2014 at 6:37 PM
Yes please! Sounds great!
Jan 30, 2014 at 6:49 PM
I know the Semantic Version 2.0 spec suggests ignoring the build metadata, so how would deal with a package being uploaded with the same version number but different build numbers?

A scenario where this could happen is where you automatically build a project that contains a number of nuget packages, some which have updated version numbers due to code changed and some which have no codes changes, therefore don't require a version number change. When building, the build server isn't clever enough to work out which packages already have that version, so to get round this a new package is created, but with the build number added to the end, taking the version number from a 3 digit number to a 4 digit number.

By following semantic versioning 2.0 guidelines I'd add the build number to the end after a +. However, it also states that this should be ignored when determining precedence, which is fine, but then could cause issues with the scenario outlined above. Would you allow for two packages with the same version numbers and different build numbers, or replace the existing package?
Jan 30, 2014 at 8:56 PM
I guess I second @cbrianball's thought: What is the gain in limiting to only semantic version strings?
Jan 30, 2014 at 9:22 PM
Yes, please!

Advantages are plenty; first and foremost that it would enable you to decide whether to pull in an update entirely based on the version number: it a package's major version is the same as the one you're currently using, it's safe to upgrade.

Ultimately, it's still the package owner's responsibility to make sure this is the case, it becomes much easier to reason about differences in packages, and whether or not you should update a package. I assume that you could probably even build automated tools that do that (backed by automated testing, obviously).
Jan 30, 2014 at 9:30 PM
Echoing @wwahammy, what is the motivation? SemVer is very bright and shiny but what attributes of it are the reasons NuGet should eschew the ancient Windows #.#.#.# syntax? Looking for a understanding.
Developer
Jan 31, 2014 at 5:28 AM
Edited Jan 31, 2014 at 5:31 AM
@JeffHandley, what does this mean for pre-release packages? Will we sill have the -pre-release-label syntax?

Update: Ignore. Tried to find it on semver.org but was too stupid to type it correctly. Found it mentioned so we should be good.
Jan 31, 2014 at 5:31 AM
@terrajobst - Yes, absolutely. That's part of SemVer.

The primary motivation for this thought is to bring more consistency to the world of NuGet. We're working on a new SemVer 2.0.0-compliant implementation of our versioning. But it will be poisoned with legacy support for 4-part (1.2.3.4), System.Version style version numbers too. Sorting those among SemVer versions is odd. We want to promote SemVer and make the world a little more sane.
Developer
Jan 31, 2014 at 5:41 AM
This would make the client produce errors for non-semver versions
This would happen during NuGet pack time not installs, is that correct?
Jan 31, 2014 at 5:43 AM
@pranavkm - Correct! Errors would occur in 2 places:
  1. NuGet.exe Pack
  2. Uploading to NuGet.org
All consumption scenarios would continue to work for backwards compatibility (forever). We would just stop new packages from being published using legacy versions.
Jan 31, 2014 at 5:55 AM
I like this idea. The tool encouraging a particular versioning scheme simply removes the argument altogether and lets people get back to productive work.
Jan 31, 2014 at 10:07 AM
What would happen to automatic assembly versions (e.g. "1.2.*")? Would the revision number (seconds since midnight / 2) just get stripped?
Jan 31, 2014 at 4:16 PM
@JeffHandley Would new packages still be able to depend on old packages invalid semver versions?
Jan 31, 2014 at 6:46 PM
@tilovell - Yes, packages could take dependencies on old packages that don't use semver.

@mganss - Don't know. It could get moved into the build metadata field on the version (after the + sign) by default, but not sure.
Jan 31, 2014 at 8:11 PM
In principle, I like promoting semantic versioning through NuGet. I make an effort to use semantic versioning myself because it makes the version more meaningful. I do have a few concerns though.

One of them is that four part versions are a little funky. The second is that we have to remember that the version of a package and the version of a piece of software may be different. Semantic versioning is to explain to the user of a library what kind of compatibility to expect from a new version. It is fundamentally about the software itself, not it's packaging. That can lead to strange issues.

Let's consider the situation where you we have LibA which is semantically versioned as 1.2.3 and a NuGet package to distribute it that is also version 1.2.3. After a release, the packager realizes they forgot to put in their install.ps1 script. They need to create a new package version which must be larger than 1.2.3 if they want people to be able to update. The problem is that LibA's hasn't changed at all. This is fine in cases where the packager and project owner are the same people and their main focus is NuGet usage because they'd probably just rev the build number. What happens though if the packager is not the project owner? The packager can't rev the build number on the project so the package version and the build version won't match. In the case of LibA we'd have a library 1.2.3 and the NuGet package of 1.2.4. But that's not the only situation! What if there's another package management system, like say APT? The package on NuGet is 1.2.4, while the official library is 1.2.3 and the APT version is 1.2.3.

So while I like the idea in theory, I think this is a really bad idea in practice.
Jan 31, 2014 at 8:14 PM
My 2 cents on package version vs. library version: Don't even try to make them the same. Just give up, and this manufactured problem goes away. Package versions are different from the library versions, and that's okay.

I understand that sometimes it's nice for them to be the same, but the actual tangible reasons are few in my opinion.
Jan 31, 2014 at 8:17 PM
I think that's a fair point but semantic versions are about APIs, not packages.
Jan 31, 2014 at 9:46 PM
I agree with @wwahammy. The whole point of SemVer is to communicate to the consumer the compatibility guarantees of a given API. The fact that it's wrapped up in a package is immaterial. If NuGet forces you to make arbitrary version changes because you forgot to include a file in your package, it's going to cause more problems that it solves.

@JeffHandley I really don't understand your contention here:
My 2 cents on package version vs. library version: Don't even try to make them the same. Just give up, and this manufactured problem goes away. Package versions are different from the library versions, and that's okay.
Why wouldn't you want them to be the same? At least with the 4-part version number, you can still follow SemVer for your library and package, and at least reserve the 4th number for cases where you have to update the package to a packaging error and not a change in the library. The new direction for NuGet 3 won't allow for that and this will definitely force library and package versions to drift. This will just end up causing confusion.

Don't get me wrong, I'm all for enforcing SemVer on packages. Just that there has to be some mechanism to support updating packages without having to arbitrarily bump the patch version, when the underlying library didn't change.
Jan 31, 2014 at 10:04 PM
Kiliman wrote:
I agree with @wwahammy. The whole point of SemVer is to communicate to the consumer the compatibility guarantees of a given API. The fact that it's wrapped up in a package is immaterial. If NuGet forces you to make arbitrary version changes because you forgot to include a file in your package, it's going to cause more problems that it solves.
Well said. Much better than my attempts.
Why wouldn't you want them to be the same? At least with the 4-part version number, you can still follow SemVer for your library and package, and at least reserve the 4th number for cases where you have to update the package to a packaging error and not a change in the library.
Yes, exactly what I was saying here: https://twitter.com/robmen/status/429020359786905600
Don't get me wrong, I'm all for enforcing SemVer on packages. Just that there has to be some mechanism to support updating packages without having to arbitrarily bump the patch version, when the underlying library didn't change.
I think this comes back to your first point about SemVer defining API compatibility over packaging versioning. Maybe there is something in SemVer that I've missed but I think you've hit upon a very important issue to address here.
Developer
Feb 1, 2014 at 7:17 AM
The spec is not restrictive to "the software". It's just too easy to project its applicability to code only.. See the following excerpt:

"For this system to work, you first need to declare a public API. This may consist of documentation or be enforced by the code itself. Regardless, it is important that this API be clear and precise. Once you identify your public API, you communicate changes to it with specific increments to your version number."

If you consider the "public" API consumed by NuGet clients to be the package metadata, then you can consider its contents as internals (from the nuget client point of view).

Thus, SemVer on pkg level IMHO is independent from whatever versioning used on the pkg internals and can evolve separately.

My two cents
Feb 1, 2014 at 8:10 AM
Edited Feb 1, 2014 at 8:17 AM
@JeffHandley:
Does your proposal also change which version a SemVer package is updated to when no explicit version is specified ?
Meaning, will you update SemVer packages to the highest minor & patch version for the currently installed major version (if no version number is specified explicitly) ?

Is NuGet already doing this ?
If NuGet is not already doing this, then I think it should first implement this (before actually requiring SemVer).
Package authors should have the opportunity to learn the benefits of SemVer, while still allowing them move away from it if it does not fit their needs (for whatever reason). You should allow it to grow upon them.

I've only very recently begun using NuGet, but I have a strong Maven background.
Sorry if I asking questions for which the answer is obvious :p

According to me, imposing SemVer will ultimately be a good thing for all:

package consumers
  1. Makes it clear in a glimpse whether a given version of a package introduces breaking changes.
  2. The history of a given package provides a good indication to its level of stability (eg. a package which jumped from v1.0.0 to v32.0.0 in a year tells you what ? :p).
package authors / publishers
  1. The rules for versioning packages are clearly defined.
  2. Packages authors can easily showcase their track record for maintaining backward compatibility (distinguishing them from "competing" packages).
Note:
Personally, I think the package consumer should ALWAYS be in control.
I'm not a big fan of automagically updating to the latest compatible version (imagine coming back from your lunch break, and finding your pc has automatically upgraded from Windows XP to Windows 8. "But your programs still work, right ?").
Whenever updating packages interactively, the proposed version should be the latest compatible version but you should have the possibility to explicitly update to another (compatible) version.
In a scripted update (command-line, Package Manager Console or API), you should only update to the latest compatible version if no version was specified explicitly.
Developer
Feb 1, 2014 at 9:44 AM
Edited Feb 1, 2014 at 9:44 AM
drieseng wrote:
Does your proposal also change which version a SemVer package is updated to when no explicit version is specified ?
Meaning, will you update SemVer packages to the highest minor & patch version for the currently installed major version (if no version number is specified explicitly) ?

Is NuGet already doing this ?
Just as an FYI, there are NuGet features closely related to this topic:
NuGet clients can pick a good default when installing/updating packages and guide pkg consumers into the pit of success, but that's only possible when imposing SemVer on the package authoring side. (and beyond that it's ultimately the package author's responsibility not to mess up)

Note: This functionality is only exposed in the Package Manager Console. Perhaps this should be more prominently present in the UI as many people don't seem to be aware that these cmdlet switches exist (many package consumers are just clicking around in the dialogs).
Feb 1, 2014 at 3:16 PM
The SemVer spec says "Build metadata SHOULD be ignored when determining version precedence." This means when you move the revision number of an automatic assembly version into the build metadata two builds during the same day will have the same precedence (build number is days since 1/1/2000).

I can think of at least two other ways to deal with this if you must impose a "major.minor.patch" format:
  • Make a single 32bit number out of the build and revision numbers (both 16bit) and use that as the "patch" number. Downside: You can no longer visually compare NuGet package version and assembly version.
  • Concat both build and revision numbers filling up the revision number on the left with zeros up to 5 digits, e.g. "1.2.345.678" becomes "1.2.34500678". Downside: Resulting patch number exceeds 32bits.
Nov 15, 2014 at 5:57 PM
Can someone list what the effective change here is? As I understand it, semantic versioning is more of a technique than an actual numbering system. Is this all just talking about whether the z in w.x.y.z is ignored or not?

If so, that seems like a meaningless change that offers no real value. Currently those that that want to version with x.y.z.* can, and those that want to version with w.x.y.z can as well. What real value add is there in limiting whether people utilize the last number or not?

Unless I misunderstand, all we are talking about is going from n numbers in a version to n-1 numbers in a version. Nothing will really change by forcing 3 numbers instead of 4. This won't force people to give special meaning to the first 3 version numbers. In fact, I would argue that it will imply that semantic versioning is being used when there is no enforcement of that in place. Those that were doing 4 before will just cram the fourth number into the third, or shift everything to the left a place and drop the first. With 4 numbers, there is at least the hint that when someone only uses 3 of the numbers there is an increased chance that they are following the semantic versioning guidelines.

As an alternative, I think it would provide much more value if an additional metadata flag was added to the nuspec file (or assembly info) that allowed the developer to assert that they follow SemVer. Then NuGet could validate that only 3 numbers were used and mark the package as such on NuGet.org.
Nov 18, 2014 at 5:41 PM
We decided NOT to require semantic versions. We'll maintain support for 4-part version numbers.