_From @citizenmatt on March 20, 2017 16:56_
Given a PackageReference with a floating version that accepts pre-releases, e.g. 2.3-*, then dotnet restore will always pick the oldest pre-release version. This is contrary to the description of floating versions in NuGet for project.json (as linked to from the PackageReference docs).
Is there an msbuild switch to work around this bug?
_Copied from original issue: dotnet/sdk#1011_
_From @dsplaisted on March 21, 2017 2:47_
@emgarten
This sounds like it might be a NuGet bug, and I don't think there's anyway of changing this behavior.
It might be that the version number is not specified in a way NuGet likes. 2.3.0-* might work better (though you may not want to restrict the patch version).
@citizenmatt I'm not able to repro this, would you share some repro steps or an example csproj and package id?
Sure.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net452</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="JetBrains.ReSharper.SDK" Version="2017.1-*" />
</ItemGroup>
</Project>
I would expect this to install the latest prerelease of JetBrains.ReSharper.SDK 2017.1, currently at 2017.1.20170316.165446-eap05, but it resolves to 2017.1.20170209.154249-eap01 instead.
It actually fails to fully resolve -eap01 due to an error in one of the packages that references a dependency that doesn't exist (so you'll see an error message Unable to resolve 'JetBrains.MahApps.Metro (= 1.3.0)'). This is our error and fixed in packages post -eap01. You can look in project.assets.json to see that it's using -eap01.
The four point version syntax and the fact that the patch level is different also don't matter. I've tried repackaging the last several versions of this package to have three point versions and keep the patch version the same, and it still resolves to the lowest version.
Similarly, setting the version to 2016-* will resolve to 2016.1.20160319.102744-eap7 instead of picking the latest stable of 2016.3.20170126.124206. And 2016.2-* will resolve 2016.2.20160525.124855-eap1 (and fail to restore due to target framework differences, but the resolution is already done) instead of the final 2016.2.20160913.94928.
-* only floats to the highest release label. Leaving out parts of the version does not have an impact, 2016-* is the same as 2016.0.0.0-*.
To get the highest stable version use:
<ItemGroup>
<PackageReference Include="JetBrains.ReSharper.SDK" Version="*" />
</ItemGroup>
or
<ItemGroup>
<PackageReference Include="JetBrains.ReSharper.SDK" Version="2017.*" />
</ItemGroup>
Sorry, can you clarify, please? What does "only floats to the highest release label" mean? I'm not sure I'm seeing the behaviour you're describing - -* is resolving to the oldest pre-release version.
Here are some examples
1.0.0-c is selected for 1.0.0-* because c is the highest release label for 1.0.0
1.0.0-a
1.0.0-b
1.0.0-c
1.1.0-a is selected for 1.0.0-* because 1.1.0-a is nearest to 1.0.0, there were zero release labels that matched the -* for 1.0.0 (this is what you are hitting)
1.1.0-a
1.1.0-b
1.1.0-c
For floating on a minor version with 1.* you will get 1.2.0 since it matches the major version of 1 and has the highest minor.
1.0.0
1.1.0
1.2.0
2.0.0
2.1.0
2.3.0
Alternatively you can think of it like this: 1.0.0-* is the normal range of >= 1.0.0 with a preference for the highest version it can get up to 1.0.0.1. Once you go beyond the preferred range the lowest version/nearest will be preferred.
Ah, ok. It would be so much more intuitive if you had to specify all parts of a version and it was illegal to miss parts out. Then it would be obvious that they matched zero, and would explain the nearest match. Similarly, it's frustrating that you can't make 2016.* match pre-releases as well as stable releases - 2016.*-* would be nice.
But I get it now. To get the behaviour I want (CI build restoring latest pre-release packages) I need to fix my packages to have a stable patch number, and then 2017.1.0-* should work (although I'd need my build number to also be 0).
Thanks for the help!
Glad it helped, we're looking at supporting *-* to handle this. It is a known pain point. That worked is tracked here https://github.com/NuGet/Home/issues/912
Just one last question - is it possible to override this behaviour with a nuget.config? So instead of picking nearest/lowest it would pick highest?
Not currently for project.json/PackageReference. But that is another feature we plan to add.
OK, thanks :thumbsup:
@emgarten You say
we're looking at supporting - to handle this. It is a known pain point. That worked is tracked here #912
However, that ticket is now over 2 years old and as far as I can see it has had absolutely 0 work done, other than all the duplicate or related issues being closed and redirected to this issue.
It would also be really good to be able to specify/override the resolution policy per package reference (e.g. from a metadata value) and/or project as well as to actually obey the configured behaviour specified in nuget.config as requested by @citizenmatt
Most helpful comment
@emgarten You say
However, that ticket is now over 2 years old and as far as I can see it has had absolutely 0 work done, other than all the duplicate or related issues being closed and redirected to this issue.
It would also be really good to be able to specify/override the resolution policy per package reference (e.g. from a metadata value) and/or project as well as to actually obey the configured behaviour specified in nuget.config as requested by @citizenmatt