Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Regression in nuget restore for sfproj from sdk31 -> sdk60 #17671

Open
ghost opened this issue May 17, 2021 · 12 comments
Open

Regression in nuget restore for sfproj from sdk31 -> sdk60 #17671

ghost opened this issue May 17, 2021 · 12 comments
Milestone

Comments

@ghost
Copy link

ghost commented May 17, 2021

Doing a trial run of building our repo on dotnetsdk 6.0 preview 3, and getting restore failures in a few projects. Self contained repro attached. Note that we're currently on latest LTS sdk: 3.1.409.

It appears that dotnet restore is not processing TargetFramework correctly in 6.0 inside an old-style project (e.g. sfproj), when that sfproj has been converted to use PackageReference instead of packages.config.

This is a regression from previous (LTS) version.

Minimal repro

  1. git clone https://github.com/aaronla-ms/bug-repros.git
  2. cd repro-dotnetsdk6
  3. setup.cmd
  4. repro.cmd

expected

restore succeeds on both dotnetsdk31 and dotnetsdk60

actual

restore fails on just dotnetsdk60. Error message as follows:

Determining projects to restore...
C:\repos\aaronla-ms\bug-repros\repro-dotnetsdk6\repro-dotnetsdk6.csproj : error NU1202: Package Bond.Core.CSharp 9.0.3 is not compatible with net40 (.NETFramework,Version=v4.0). Package Bond.Core.CSharp 9.0.3 supports:
C:\repos\aaronla-ms\bug-repros\repro-dotnetsdk6\repro-dotnetsdk6.csproj : error NU1202: - net45 (.NETFramework,Version=v4.5)
C:\repos\aaronla-ms\bug-repros\repro-dotnetsdk6\repro-dotnetsdk6.csproj : error NU1202: - net46 (.NETFramework,Version=v4.6)
C:\repos\aaronla-ms\bug-repros\repro-dotnetsdk6\repro-dotnetsdk6.csproj : error NU1202: - netstandard1.0 (.NETStandard,Version=v1.0)
C:\repos\aaronla-ms\bug-repros\repro-dotnetsdk6\repro-dotnetsdk6.csproj : error NU1202: - netstandard1.3 (.NETStandard,Version=v1.3)
C:\repos\aaronla-ms\bug-repros\repro-dotnetsdk6\repro-dotnetsdk6.csproj : error NU1202: - netstandard1.6 (.NETStandard,Version=v1.6)

It appears that nuget.targets is incorrectly determining the project to be net40, when the project does have TargetFramework=net462 set.

versions

[git: main]
aaronla@aaronla-r:repro-dotnetsdk6$ packages\dotnetsdk31\dotnet.exe --version
3.1.409

[git: main]
aaronla@aaronla-r:repro-dotnetsdk6$ packages\dotnetsdk60\dotnet.exe --version
6.0.100-preview.3.21202.5

[git: main]
aaronla@aaronla-r:repro-dotnetsdk6$ ver

Microsoft Windows [Version 10.0.19043.985]

@dotnet-issue-labeler dotnet-issue-labeler bot added the untriaged Request triage from a team member label May 17, 2021
@dotnet-issue-labeler
Copy link

I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.

@rainersigwald
Copy link
Member

rainersigwald commented May 17, 2021

A few notes on this project:

  1. It doesn't use Microsoft.NET.SDK, but it does depend on NuGet functionality (package restore) that's intended to be consumed from there.
  2. https://github.com/aaronla-ms/bug-repros/blob/main/ServiceFabricOnDotnetSdk.props has a bunch of workarounds for that. Presumably something changed to make them insufficient.

In the restore-task invocation I see this diff (left is 3.1, right is 6.0-preview):

-        Restoring packages for .NETFramework,Version=v4.6.2...
+        Restoring packages for .NETFramework,Version=v4.0...

Here's a diff of restore graph items, showing that the net462 TF is not present in the project item on the newer SDK.

--- 
+++ 
@@ -1,17 +1,18 @@
 RestoreTask
-    Assembly = C:\Program Files\dotnet\sdk\3.1.115\NuGet.Build.Tasks.dll
+    Assembly = C:\Program Files\dotnet\sdk\6.0.100-preview.4.21255.9\NuGet.Build.Tasks.dll
     Parameters
         RestoreGraphItems
-            cea5f56c-bbbf-4a39-8574-ac275eb5dfd5
+            eae28bfa-4ee8-4396-a66c-631b9153661e
                 MSBuildSourceProjectFile = S:\work\bug-repros\repro-dotnetsdk6\repro-dotnetsdk6.csproj
                 MSBuildSourceTargetName = _IsProjectRestoreSupported
                 OriginalItemSpec = S:\work\bug-repros\repro-dotnetsdk6\repro-dotnetsdk6.csproj
                 ProjectUniqueName = S:\work\bug-repros\repro-dotnetsdk6\repro-dotnetsdk6.csproj
                 Type = RestoreSpec
-            93543f6a-5023-4678-958c-92c8d1cf111e
+            f8a6c2ba-0dc3-452d-9132-bf850da8376b
+                _CentralPackageVersionsEnabled = 
                 ConfigFilePaths = S:\work\bug-repros\repro-dotnetsdk6\NuGet.Config;C:\Users\raines\AppData\Roaming\NuGet\NuGet.Config;C:\Program Files (x86)\NuGet\Config\Microsoft.VisualStudio.FallbackLocation.config;C:\Program Files (x86)\NuGet\Config\Microsoft.VisualStudio.Offline.config
                 CrossTargeting = 
                 FallbackFolders = C:\Program Files (x86)\Microsoft Visual Studio\Shared\NuGetPackages
                 MSBuildSourceProjectFile = S:\work\bug-repros\repro-dotnetsdk6\repro-dotnetsdk6.csproj
                 MSBuildSourceTargetName = _IsProjectRestoreSupported
                 NoWarn = 
@@ -27,42 +28,50 @@
                 RestoreLockedMode = 
                 RestorePackagesWithLockFile = 
                 RuntimeIdentifiers = ;
                 RuntimeSupports = 
                 SkipContentFileWrite = 
                 Sources = https://api.nuget.org/v3/index.json
-                TargetFrameworks = net462
                 TreatWarningsAsErrors = 
                 Type = ProjectSpec
                 ValidateRuntimeAssets = false
                 Version = 1.0.0
                 WarningsAsErrors = 
-            d045f94f-b4d1-4851-beae-c1509d60e4db
+            98a4f583-0429-4c9e-9df9-1daa100f7f36
                 GeneratePathProperty = true
                 Id = Microsoft.VisualStudio.Azure.Fabric.MSBuild
                 MSBuildSourceProjectFile = S:\work\bug-repros\repro-dotnetsdk6\repro-dotnetsdk6.csproj
                 MSBuildSourceTargetName = _IsProjectRestoreSupported
                 OriginalItemSpec = S:\work\bug-repros\repro-dotnetsdk6\repro-dotnetsdk6.csproj
                 ProjectUniqueName = S:\work\bug-repros\repro-dotnetsdk6\repro-dotnetsdk6.csproj
                 TargetFrameworks = net462
                 Type = Dependency
                 VersionRange = 1.7.3
-            e144e66a-1c49-4caa-9b5f-f1671429a9bf
+            87a170ec-f7c8-4293-b4b8-3f8487b3ab01
                 Id = Bond.Core.CSharp
                 MSBuildSourceProjectFile = S:\work\bug-repros\repro-dotnetsdk6\repro-dotnetsdk6.csproj
                 MSBuildSourceTargetName = _IsProjectRestoreSupported
                 OriginalItemSpec = S:\work\bug-repros\repro-dotnetsdk6\repro-dotnetsdk6.csproj
                 ProjectUniqueName = S:\work\bug-repros\repro-dotnetsdk6\repro-dotnetsdk6.csproj
                 TargetFrameworks = net462
                 Type = Dependency
                 VersionRange = 9.0.3
-            9de9a081-f356-439c-a917-10b82d5993fd
+            fe4e4461-20f0-4fc7-8025-6f8e80a0b965
                 AssetTargetFallback = 
                 MSBuildSourceProjectFile = S:\work\bug-repros\repro-dotnetsdk6\repro-dotnetsdk6.csproj
                 MSBuildSourceTargetName = _IsProjectRestoreSupported
                 OriginalItemSpec = S:\work\bug-repros\repro-dotnetsdk6\repro-dotnetsdk6.csproj
                 PackageTargetFallback = 
                 ProjectUniqueName = S:\work\bug-repros\repro-dotnetsdk6\repro-dotnetsdk6.csproj
+                RuntimeIdentifierGraphPath = 
                 TargetFramework = net462
+                TargetFrameworkIdentifier = .NETFramework
+                TargetFrameworkMoniker = .NETFramework,Version=v4.0
+                TargetFrameworkProfile = 
+                TargetFrameworkVersion = v4.0
+                TargetPlatformIdentifier = Windows
+                TargetPlatformMinVersion = 
+                TargetPlatformMoniker = Windows,Version=7.0
+                TargetPlatformVersion = 7.0
                 Type = TargetFrameworkInformation
         RestoreRecursive = True
         HideWarningsAndErrors = False

@nkolev92, that ring any bells off the top of your head?

@ghost
Copy link
Author

ghost commented May 17, 2021

FYI, this issue also repros on Visual Studio 2019 Developer command prompt, so I don't think this is limited to dotnetsdk, where it worked find in Visual Studio 2017 Developer command prompt. Suspect regression in msbuild.

Notably, msbuild version is newer in both failing combinations.

Vs 2017 command prompt (works):

$ msbuild /version /nologo
15.9.21.664

Vs 2019 command prompt (fails):

msbuild /version /nologo
16.9.0.16703

Under dotnetsdk31 (works):

$ dotnet --version
3.1.409

$ dotnet msbuild -nologo -version
16.7.2.52901

Under dotnetsdk60 (fails):

$ dotnet --version
6.0.100-preview.3.21202.5

$ dotnet msbuild -nologo --version
16.10.0.18107

@rainersigwald
Copy link
Member

NuGet/NuGet.Client#3548 looks related, which is a change in NuGet 5.8.

@nkolev92
Copy link
Contributor

This change is a consequence of NuGet/Home#9756 and NuGet/Home#9895.

To make .NET 5 work, NuGet and the SDK had to fix an inconsistency in what the source of truth for a framework is.

TargetFramework is a property that should be interpreted, so newer NuGet & SDK use TargetFrameworkMoniker as the source of truth.

In SDK based projects, the TargetFramework value gets automatically deconstructed into the monikers

<PropertyGroup Condition="'$(TargetFramework)' != '' and ('$(TargetFrameworkIdentifier)' == '' or '$(TargetFrameworkVersion)' == '')">
<TargetFrameworkIdentifier>$([MSBuild]::GetTargetFrameworkIdentifier('$(TargetFramework)'))</TargetFrameworkIdentifier>
<TargetFrameworkVersion>v$([MSBuild]::GetTargetFrameworkVersion('$(TargetFramework)', 2))</TargetFrameworkVersion>
</PropertyGroup>

@nkolev92
Copy link
Contributor

NuGet/NuGet.Client#3548 looks related, which is a change in NuGet 5.8.

Beat me by 43s :D
You are on spot, that's where the change happened.

@ghost
Copy link
Author

ghost commented May 17, 2021

@nkolev92 Thanks for taking a look! Do you know when the fix will become available? We have a workaround, but curious when we can remove it. net5.0, net6.0?

@nkolev92
Copy link
Contributor

@aaronla-ms

The fix was done in 5.8/.NET SDK 5.0.100 to use TargetFrameworkMoniker and not TargetFramework.
The project must specify TargetFrameworkMoniker and not just TargetFramework.

@ghost
Copy link
Author

ghost commented May 17, 2021

@nkolev92 Thanks for clarifying. If I understand correctly then, this regression is "by design"? We were only using TargetFramework since some existing docs indicated it was required and sufficient for enabling nuget restore.

@nkolev92
Copy link
Contributor

We were only using TargetFramework since some existing docs indicated it was required and sufficient for enabling nuget restore.

Yep, those docs are incorrect unfortunately.
It was an intentional breaking change.

If you still see docs suggesting that, I'd love to know which so we can try to fix them.

@ghost
Copy link
Author

ghost commented May 17, 2021

@nkolev92 Thanks, if I find them, will do.

Can you clarify which settings are required for old-style projects? Do they need to specify TargetFramework and TargetFrameworkVersion? Just TargetFrameworkVersion? Or more settings?

I ask because it looks like TargetFrameworkVersion is the only setting I have to set, but at the same time, in dotnetsdk31, it looked like TargetFramework was the only setting that needed to be set. I just want to get some clarification on how this is supposed to work.

Alternatively, are there any docs for this?

@nkolev92
Copy link
Contributor

Discussed offline:

TargetFrameworkMoniker is what NuGet reads.

All these props have default values, so it's possible that in some situations even setting 1 property such as TargetFrameworkVersion is sufficient to make everything work.

TargetFramework is not a property that NuGet parses, but the SDK can translate it into a valid TFM if the project is SDK based.

I'm not familiar with particular documentation around this topic.

@wli3 wli3 removed the untriaged Request triage from a team member label Jun 1, 2021
@wli3 wli3 added this to the Discussion milestone Jun 1, 2021
@wli3 wli3 removed their assignment Jun 1, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants