Home: SemVer 2.0

Created on 9 Sep 2015  Â·  42Comments  Â·  Source: NuGet/Home

It seems like using a SemVer2 versionnumber is not possible with NuGet 3.2.0 CLI.

NuGet.exe pack -minClientVersion 3.2.0
MSBuild auto-detection: using msbuild version '14.0' from 'C:\Program Files (x86)\MSBuild\14.0\bin'.
Attempting to build package from 'MyProject.nuspec'.
'4.0.0+45' is not a valid version string.
Parameter name: version

Wasn't the support for semver2 planned for NuGet 3.x? It's also interesting that the NuGet.Versioning Assembly seems to support semver2. The CLI sill uses the NuGet.Core (2.8.6) SemanticVersion implementation, would it be possible to support semver2 for packaging e.g. by specifying the minClientVersion 3.2.0?

2 DCR

Most helpful comment

The lack of support for SemVer 2 is a bummer for those of us using Octopus Deploy who want to deploy pre-release packages named after our feature branches.

Any updates on this?

All 42 comments

There is no way to get full semver 2.0.0 support yet, but we are working on it. As you pointed out the parts of the code still relying on NuGet.Core are blocking this, but those will be replaced in a future release.

Is there some timeframe known when this will be available?

There is currently no timeframe for this. Semver 2 is a breaking change, and we are not sure we can actually take it all the way.

Regarding http://blog.nuget.org/20140924/supporting-semver-2.0.0.html

Projects that consume packages using these new versioning features will require NuGet 3.0 to be able to install/uninstall/restore packages

The third point under "Downstream Implications" is a non-issue, and here's why:

• Only NEW packages will carry SemVer 2 versions; existing projects are guaranteed to not break by themself
• It's perfectly reasonable to require people to update their NuGet client tools if a package update requires it
• There are two kinds of people: those who update their NuGet client software and those who don't
• If you belong to the second group of people then you probably don't ever check for package updates either
• It's UNreasonable to expect that a project will still work with older versions of the tools once it has been edited with a newer version

Therefore we must implement this in a way that won’t expose these new version numbers to old NuGet clients.

This should be extremely easy to implement with a User-Agent header or query string parameter. Starting with NuGet version 3, all clients should send a user agent string. The server should then check for that user agent string to determine whether to show SemVer 2 packages. If the user agent string is missing then the server should assume that the client does not support SemVer 2

I'd like to echo @StevenLiekens's point. I don't see any issues in packages requiring a newer NuGet client to work. There's already a minClientVersion concept, this just takes it to the next level.

A few things to note:

  • Even if SemVer 2 is used, I believe at worst it'd just mean that downlevel clients couldn't understand pre-release packages. Too bad, they can't use them.
  • However, even with SemVer 2, a stable package would follow a format (2.0.0), that the downlevel client would understand.

In the end, it should hopefully be something that can be filtered out by the server. Down-level clients simply won't see packages that they won't parse.

We can't assume that all clients are using the NuGet.org server. There is a rich ecosystem of 3rd party servers out there in use. It feels like this breaking change that we could pilot in a future release, but wide-acceptance of this should be rolled up with other breaking changes under consideration for a v4 release.

Understanding that there are difficulties around implementing the full SemVer 2.0 spec, what is the plan regarding the 20 character limit on prerelease tags?

The lack of support for SemVer 2 is a bummer for those of us using Octopus Deploy who want to deploy pre-release packages named after our feature branches.

Any updates on this?

No update at the moment, I'm hoping we can get to it in another release or so

@csharpfritz I don't understand the argument of the breaking change, how is this different to the developer dependency released in 2.8, or any other change which was introduced and the server wouldn't validate the nuspec?

Or the group targetFramework which came in 2.5? Can I install a package which uses that feature using nuget 2.2? Or push that package to a 2.2 NuGet Gallery?

Also is there any guidance on how we should do pre-release numbers. I am currently padding with 0's, so beta0001. Is that the recommended way to work around this?

The breaking change is there because old clients first look at id + version and only then on the content of the package. Unlike all the changes you specified above that are in the content of the package that happens after checking for minclient version.

I think the path we are going to take it to enable semver2 on the client but not on nuget,org at least to begin with.

Does that make sense?

That does make sense, once in the client the server could show the client different things though?

For old clients the server could do the padding for us, if it sees 1.0.0-beta.1 then it should expose 1.0.0-beta0001 to the client. Now seems like a good time to start trying to put it in because of all the ecosystem changes, package authors are trying to add support for dnx and such.

It is just the filename, right? Or is it both the filename and the <version> tag in the nuspec?

For checking minversion that is

It is just the filename, right? Or is it both the filename and the tag in the nuspec?
it is actually in the server metadata derived from the version tag.

The server shouldn't do any padding, you can do it yourself and there is nothing new about it.

IMHO the path is to enable semver2 on the client, and on private servers. People using them have to move up for these packages using semver2.

In all seriousness nuget.org is not the place to publish CI builds, so I'm not too concerned about semver2 on the public site, the applicability of that is rather small.

Any movement along this path I think would be nice, from a author point of view this limitation is pretty annoying and trips a lot of people up. One of the pain points I see a lot of GitVersion users have is along the lines of:

  1. GitVersion generates a semver
  2. I use the build number (which is the semver) which blows up
  3. I have installed the Octopack task, which looks at my VersionInformation and that is a SemVer
  4. I now have to edit my .csproj file to override the version numbers.

Maybe we are not the ecosystem you guys are talking about, but we are trying to build tooling which helps people version their stuff and not having this causes friction. The number of people I have had to explain why they need to use NuGetVersion and why it's padded is quite a few. Probably still a vast minority as you say, but those in the community who try to go down the SemVer path hit roadblocks then don't bother. As both a package author and a consumer of packages, having an ecosystem which embraces semver would be nice.

@JakeGinnivan all I'm talking about is publishing to nuget.org. I have no idea why any of these users will publish such packages to nuget.org? can you enlighten me?

For a simple library I can't just use my build server version number. In my build scripts I always have to deal with two version numbers, the SemVer then the NuGetVersion. Not the end of the world, would just simplify as then I can use the same version for everything and don't need to document workarounds for NuGet not sorting pre-release packages property.

I know of many people who build CI packages then push the ones they want into NuGet, this is not publishing all packages, it is just following continuous delivery. Padding is ugly and is a workaround for NuGet not supporting SemVer.

Yes - I see your point.
The above stuff will just work, because you can consume semver2 anywhere you upgraded your clients.

But for putting stuff on nuget.org, this will force client updates on all the community using your package, which wouldn't be easy, because the work to ship new clients to Visual 2013 -> 2010 is just too much for us. Furthermore these clients will not get a reasonable error message.

Filtering these packages out causes even larger pain and hard to track issues like why does the package show for him but not for me.

Also, not saying this is the end of the world. It just seems to be a point of friction, one that is easily worked around but still a point of friction. Also it seems to be hurting the ecosystem around NuGet more than NuGet itself. Maybe if NuGet supported semver properly we would get more packages which actually follow semver from an api point of view etc.

The first steps you suggest sound great. I just wonder if a server workaround would be possible _once_ that client update is out there, so pad the version metadata of the API then min-version for the client. But again, maybe that is a terrible idea :P

Anyways, appreciate the explanations as always. It gives me more context to make my decisions and guide other people (especially in the GitVersion docs).

@emgarten moving under you for 3.4, based on the work to get rid of nuget.core (this will mean adding some tests, and assess where we stand, if we believe the client is solid enough after removing nuget.core then we call victory on the client side and perhaps ammend nuget.server to support it.

If not we look at it in 3.5.

CC @maartenba

Really happy to see movement on this front. As part of this work can the 20 char limit on prerelease tags be removed?

One pattern that GitVersion enables is the use of a branch name as the prerelease tag. With CI builds, it helps keep things accurate and I can add a wildcard on that tag. However, between the branch name, the build number and any new semver support (adding "+"?), it's easy to exceed 20 chars. I have no issue if those packages were filtered from downlevel clients if they'd break. OTOH, are they really being stored in a char[20] or is it a string anyway?

Are we including support for something like 3.3.1-build-meta.1+4 where build-meta is the prerelease tag, 1 is the prerelease version and +4 is the build of that version.

  1. We can consider changing the limit. But note that this is quickly going to hit max path, and it just comes back as nuget bugs.
  2. I don't know about the build number. This is a best effort kind of thing right now. The work above is to add tests to see what actually works. Any work beyond that is optional on how much time we have for the 3.4 release.

Cool. I think the Max_Path bugs might be slightly mitigated by the way NuGet v3 puts them all in the user profile dir. Not that it cannot happen but that it's a fixed path prefix.

Besides, isn't .NET busy fixing max path (@terrajobst)? https://github.com/dotnet/corefx/issues/645

it is worse in that case, because they show up twice (package Ids do)

If it helps, there might be some SemVer parsing/interpreting/comparison code you can use from https://github.com/GitTools/GitVersion/blob/master/src/GitVersionCore/SemanticVersion.cs. It's MIT licensed so should be adaptable. Less code for you to write.

I am also more than happy to pull it out into a source library if that helps.

We already have semver2 parsing in NuGet 3.X, it is a matter of using it consistently everywhere and figuring out the server story. We are thinking about banning it on nuget.org but allowing it on private servers.

The issue is that NuGet 2.X cannot understand packages with Semver 2.0, and will break without a good recourse, we can't go back in the past and make it so. And since nuget.org is mostly about stable releases, and key pre-releases rather than CI builds, we think it will be an acceptable middle ground at least for now.

Is this still the tracking issue for semver 2.0 support or is there a newer or more updated issue? Even just the client side support for use with private package repositories would be good

Because of issues using the dotnet cli's dotnet pack, and advice from that project, I tried moving to using nuget pack using the 3.5.0-rc1-1644 nuget client and found that versioning is differently enforced across versions of the tooling.

The differences are all around the ecosystem as well -- dotnet pack supported semver 2 strings provided they were short enough; myget doesn't seem to care (even with the semver enforcement flag on).

Perhaps when it's settled for NuGet, some assistance tooling could be created to help other projects which really mean to "support the same thing NuGet does"

Sooo, we could build packages with semver 2.0 version numbers in v3.3 but that got broken in v3.4? See AppVeyor issue which is exactly the same I'm facing.

:disappointed:

nuget.exe pack has SemVer 2.0.0 blocked until it is supported everywhere for NuGet. At this point the 3.5.0 client is very close to having full support. For servers, including nuget.org there are still open issues.

I am glad to hear that this is close to becoming a reality (at least for the client). I guess my brief moment of bliss is a bit "downed" by the fact that we run a private NuGet server, and I understand it so that the server needs updating too to make this work as I am hoping for... :disappointed: But, very happy about this making real progress. Keep up the good work. Change is good :smirk:

Now that we have the basics implemented in the 3.5 client, we can start looking into enabling this for heterogeneous environments on servers via https://github.com/NuGet/Home/issues/3610

I'm not sure what is or isn't supposed to work for 3.5.0.1737, I tried to pack using a version with metadata and it just ignored the metadata part.

I can now start a release tag with a number. It still can't exceed 20 characters in total. 1737 doesn't allow . in the release part but 1938 does.

Same in 3.5.0.1938. Which also gave a warning.
3.6.0.1978 (no one said it would work in 3.6 tho) pretty much the same as 3.5

I'm running Nuget.exe pack -Version 1.0.2-1some.release+3hashes .\database.nuspec

@worldspawn would you open an issue to track that? Internally NuGet ignores the metadata labels by default since it does not impact the order or identity of the version, it looks like it is also ignored when writing out the passed in _Version_ from pack.

Putting the full version string directly into the nuspec and packing will keep the metadata labels, you could use that as a workaround for now.

Ok @emgarten. Will do

NuGet.Core 2.14.0-rtm-832 is now available on nuget.org with support for SemVer 2.0.0. Using this with NuGet.Server will give support for private feeds that support SemVer 2.0.0.

So, what is the status of the issue? Will nuget.org support SemVer 2.0?

A quick update on this issue: we're working hard on adding SemVer 2.0 support to nuget.org.
In fact, many semver2 issues are in our current milestone, but please note we'll have a phased deployment approach (so it may require an additional sprint to fully unlock semver2 support).

What is the status?

This went live. See the blog post for details and a link to relevant docs: https://blog.nuget.org/20170815/Whats-nu-in-NuGet-with-VS2017-15-3.html#support-for-semantic-versioning-200

The above link is dead now. Use this instead
https://devblogs.microsoft.com/nuget/whats-nu-in-nuget-with-visual-studio-2017-version-15-3/#support-for-semantic-versioning-200

Was this page helpful?
0 / 5 - 0 ratings