fsprojects / FAKE

FAKE - F# Make
https://fake.build
Other
1.29k stars 587 forks source link

DotNet.publish fails attempting to load Microsoft.Build.Framework, Version=15.1.0.0 #2722

Open circusboy opened 2 years ago

circusboy commented 2 years ago

Description

FAKE throws a BuildFailedException when running DotNet.publish. An inner exception indicates that FAKE is trying to load Microsoft.Build.Framework, Version=15.1.0.0, which doesn't seem to exist on my machine.

I encountered this problem on a colleague's machine. I couldn't reproduce it on my own machine (which has been using this build script for several years now) until I removed the lockfile and the .fake folder before running the build script.

Repro steps

  1. Create a build target containing something like the following:

    Target.create "BuildTestBE" (fun _ ->
    DotNet.publish
    (fun args ->
      { args with
          Configuration = DotNet.BuildConfiguration.Debug
          SelfContained = Some true
          Framework = Some "net6.0-windows"
          Runtime = Some "win-x64"
          OutputPath = Some "build_path" })
     "../wherever/projfile.csproj"
  2. Run the task with something like fake -v run build.fsx -t BuildTestBE

Expected behavior

I expect the task to succeed, and the project to be published to the target folder.

Actual behavior

The build fails at DotNet:publish:

11-17 13:24:12> fake -v run build.fsx -t BuildTestBE
runOrBuild ({ Script = Some "build.fsx"
  ScriptArguments = ["-t"; "BuildTestBE"]
  FsiArgLine = []
  Debug = false
  NoCache = false
  RestoreOnlyGroup = false
  VerboseLevel = Verbose
  IsBuild = false })
FAKE 5 - F# Make (5.23.1) (this line is written to standard error, see https://github.com/fsharp/FAKE/issues/2066)
prepareAndRunScriptRedirect(Script: build.fsx, fsiOptions: "")
Writing 'C:\proj\client\client\.fake\build.fsx\intellisense.fsx'
Restoring with paket...
Lockfile was not found. We will update the dependencies and write our own...
Updating group Main in C:\proj\client\client\.fake\build.fsx\paket.dependencies
Resolving dependency graph...
 - Fsharp.Core is pinned to 6.0.0
Could not detect any platforms from 'net7.0' in 'C:\Users\user\.nuget\packages\microsoft.build\17.4.0\Microsoft.Build.17.4.0.nupkg\Microsoft.Build.nuspec', please tell the package authors
Could not detect any platforms from 'net7.0' in 'C:\Users\user\.nuget\packages\microsoft.build.framework\17.4.0\Microsoft.Build.Framework.17.4.0.nupkg\Microsoft.Build.Framework.nuspec', please tell the package authors
Could not detect any platforms from 'net7.0' in 'C:\Users\user\.nuget\packages\microsoft.build.tasks.core\17.4.0\Microsoft.Build.Tasks.Core.17.4.0.nupkg\Microsoft.Build.Tasks.Core.nuspec', please tell the package authors
Could not detect any platforms from 'net7.0' in 'C:\Users\user\.nuget\packages\microsoft.build.utilities.core\17.4.0\Microsoft.Build.Utilities.Core.17.4.0.nupkg\Microsoft.Build.Utilities.Core.nuspec', please tell the package authors
Could not detect any platforms from 'net7.0' in 'C:\Users\user\.nuget\packages\microsoft.net.stringtools\17.4.0\Microsoft.NET.StringTools.17.4.0.nupkg\Microsoft.NET.StringTools.nuspec', please tell the package authors
Could not detect any platforms from 'net7.0' in 'C:\Users\user\.nuget\packages\system.security.cryptography.pkcs\7.0.0\System.Security.Cryptography.Pkcs.7.0.0.nupkg\System.Security.Cryptography.Pkcs.nuspec', please tell the package authors
Could not detect any platforms from 'net7.0' in 'C:\Users\user\.nuget\packages\system.security.permissions\7.0.0\System.Security.Permissions.7.0.0.nupkg\System.Security.Permissions.nuspec', please tell the package authors
Could not detect any platforms from 'net7.0' in 'C:\Users\user\.nuget\packages\system.codedom\7.0.0\System.CodeDom.7.0.0.nupkg\System.CodeDom.nuspec', please tell the package authors
Could not detect any platforms from 'net7.0' in 'C:\Users\user\.nuget\packages\system.collections.immutable\7.0.0\System.Collections.Immutable.7.0.0.nupkg\System.Collections.Immutable.nuspec', please tell the package authors
Could not detect any platforms from 'net7.0' in 'C:\Users\user\.nuget\packages\system.reflection.metadata\7.0.0\System.Reflection.Metadata.7.0.0.nupkg\System.Reflection.Metadata.nuspec', please tell the package authors
Could not detect any platforms from 'net7.0' in 'C:\Users\user\.nuget\packages\system.resources.extensions\7.0.0\System.Resources.Extensions.7.0.0.nupkg\System.Resources.Extensions.nuspec', please tell the package authors
Could not detect any platforms from 'net7.0' in 'C:\Users\user\.nuget\packages\system.security.cryptography.xml\7.0.0\System.Security.Cryptography.Xml.7.0.0.nupkg\System.Security.Cryptography.Xml.nuspec', please tell the package authors
Could not detect any platforms from 'net7.0' in 'C:\Users\user\.nuget\packages\system.threading.tasks.dataflow\7.0.0\System.Threading.Tasks.Dataflow.7.0.0.nupkg\System.Threading.Tasks.Dataflow.nuspec', please tell the package authors
Could not detect any platforms from 'net7.0' in 'C:\Users\user\.nuget\packages\system.formats.asn1\7.0.0\System.Formats.Asn1.7.0.0.nupkg\System.Formats.Asn1.nuspec', please tell the package authors
Could not detect any platforms from 'net7.0' in 'C:\Users\user\.nuget\packages\system.windows.extensions\7.0.0\System.Windows.Extensions.7.0.0.nupkg\System.Windows.Extensions.nuspec', please tell the package authors
Could not detect any platforms from 'net7.0' in 'C:\Users\user\.nuget\packages\system.configuration.configurationmanager\7.0.0\System.Configuration.ConfigurationManager.7.0.0.nupkg\System.Configuration.ConfigurationManager.nuspec', please tell the package authors
Could not detect any platforms from 'net7.0' in 'C:\Users\user\.nuget\packages\system.text.encoding.codepages\7.0.0\System.Text.Encoding.CodePages.7.0.0.nupkg\System.Text.Encoding.CodePages.nuspec', please tell the package authors
Could not detect any platforms from 'net7.0' in 'C:\Users\user\.nuget\packages\system.security.cryptography.protecteddata\7.0.0\System.Security.Cryptography.ProtectedData.7.0.0.nupkg\System.Security.Cryptography.ProtectedData.nuspec', please tell the package authors
Could not detect any platforms from 'net7.0' in 'C:\Users\user\.nuget\packages\system.drawing.common\7.0.0\System.Drawing.Common.7.0.0.nupkg\System.Drawing.Common.nuspec', please tell the package authors
Could not detect any platforms from 'net7.0' in 'C:\Users\user\.nuget\packages\microsoft.win32.systemevents\7.0.0\Microsoft.Win32.SystemEvents.7.0.0.nupkg\Microsoft.Win32.SystemEvents.nuspec', please tell the package authors
The last restore is still up to date. Nothing left to do.

... snip ...

C:\proj\client\client> "C:\Program Files\dotnet\dotnet.exe"  publish ../widgetApi/widgetApi2/widgetApi2.csproj --configuration Debug --framework net6.0-windows --runtime win-x64 --output "c:\Build\client" --self-contained=true /nodeReuse:False "/bl:C:\Users\user\AppData\Local\Temp\tmpEC0B.tmp.binlog" (In: false, Out: false, Err: false)
MSBuild version 17.3.1+2badb37d1 for .NET
C:\Program Files\dotnet\sdk\6.0.401\MSBuild.dll -distributedlogger:Microsoft.DotNet.Tools.MSBuild.MSBuildLogger,C:\Program Files\dotnet\sdk\6.0.401\dotnet.dll*Microsoft.DotNet.Tools.MSBuild.MSBuildForwardingLogger,C:\Program Files\dotnet\sdk\6.0.401\dotnet.dll -maxcpucount -property:PublishDir=c:\Build\client -property:SelfContained=True -property:_CommandLineDefinedSelfContained=true -property:RuntimeIdentifier=win-x64 -property:_CommandLineDefinedRuntimeIdentifier=true -property:Configuration=Debug -target:Restore -verbosity:m /bl:C:\Users\user\AppData\Local\Temp\tmpEC0B.tmp.binlog /nodeReuse:False ../widgetApi/widgetApi2/widgetApi2.csproj
  Determining projects to restore...
  All projects are up-to-date for restore.
C:\Program Files\dotnet\sdk\6.0.401\MSBuild.dll -nologo -distributedlogger:Microsoft.DotNet.Tools.MSBuild.MSBuildLogger,C:\Program Files\dotnet\sdk\6.0.401\dotnet.dll*Microsoft.DotNet.Tools.MSBuild.MSBuildForwardingLogger,C:\Program Files\dotnet\sdk\6.0.401\dotnet.dll -maxcpucount -property:PublishDir=c:\Build\client -property:SelfContained=True -property:_CommandLineDefinedSelfContained=true -property:TargetFramework=net6.0-windows -property:RuntimeIdentifier=win-x64 -property:_CommandLineDefinedRuntimeIdentifier=true -property:Configuration=Debug -target:Publish -verbosity:m /bl:C:\Users\user\AppData\Local\Temp\tmpEC0B.tmp.binlog /nodeReuse:False ../widgetApi/widgetApi2/widgetApi2.csproj
  widgetApiTypes -> C:\proj\client\widgetApi\widgetApiTypes\bin\Debug\netstandard2.1\widgetApiTypes.dll
  MailboxApi2 -> C:\proj\client\widgetApi\MailboxApi2\bin\Debug\netstandard2.1\MailboxApi2.dll
  widgetApi2Types -> C:\proj\client\widgetApi\widgetApi2Types\bin\Debug\netstandard2.1\widgetApi2Types.dll
  widgetApi2 -> C:\proj\client\widgetApi\widgetApi2\bin\Debug\net6.0-windows\win-x64\widgetApi2.dll
  widgetApi2 -> c:\Build\client\
Trying to resolve: StructuredLogger, Version=2.1.0.0, Culture=neutral, PublicKeyToken=d4c7181801cb6448
Could not find assembly in the default load-context: StructuredLogger, Version=2.1.0.0, Culture=neutral, PublicKeyToken=d4c7181801cb6448
Redirect assembly load to known assembly: StructuredLogger, Version=2.1.0.0, Culture=neutral, PublicKeyToken=d4c7181801cb6448 (Some
  "C:\Users\user\.nuget\packages\msbuild.structuredlogger\2.1.669\lib\netstandard2.0\StructuredLogger.dll")
Redirect assembly from 'netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' to previous loaded assembly 'netstandard, Version=2.1.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'
Trying to resolve: Microsoft.Build.Framework, Version=15.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
Could not find assembly in the default load-context: Microsoft.Build.Framework, Version=15.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
Could not resolve assembly: Microsoft.Build.Framework, Version=15.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
Finished (Failed) 'DotNet:publish' in 00:00:08.4775116
Finished (Failed) 'BuildTestBE' in 00:00:08.5439809

---------------------------------------------------------------------
Build Time Report
---------------------------------------------------------------------
Target        Duration
------        --------
BuildTestBE   00:00:08.5425478   (Could not load file or assembly 'Microsoft.Build.Framework, Version=15.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. General Exception (0x80131500))
Total:        00:00:08.5918476
Status:       Failure
---------------------------------------------------------------------
saving cache...
Script reported an error, see standard error for details.
Script reported an error:
-> BuildFailedException: Target 'BuildTestBE' failed.
   StackTrace:
        at Fake.Core.TargetModule.raiseIfError(OptionalTargetContext context) in D:\a\FAKE\FAKE\src\app\Fake.Core.Target\Target.fs:line 992
        at Fake.Core.TargetModule.runOrDefault(String defaultTarget) in D:\a\FAKE\FAKE\src\app\Fake.Core.Target\Target.fs:line 1174
        at <StartupCode$build_6462F3749AF7D79C31B8133B4B715F495C9B435FCB1E07DBB83F106AFD699239>.$Build$fsx.main@() in C:\proj\client\client\build.fsx:line 375
-> One or more errors occurred. (Could not load file or assembly 'Microsoft.Build.Framework, Version=15.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. General Exception (0x80131500))
-> FileLoadException: Could not load file or assembly 'Microsoft.Build.Framework, Version=15.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. General Exception (0x80131500)
   StackTrace:
        at Fake.DotNet.MSBuildBinLog.getErrorsAndWarnings(String binLogFilePath)
        at Fake.DotNet.MSBuild.handleAfterRun(String command, FSharpOption`1 binLogPath, Int32 exitCode, String project) in D:\a\FAKE\FAKE\src\app\Fake.DotNet.MSBuild\MSBuild.fs:line 758
        at Fake.DotNet.DotNet.publish(FSharpFunc`2 setParams, String project) in D:\a\FAKE\FAKE\src\app\Fake.DotNet.Cli\DotNet.fs:line 1434
        at Build.clo@209-17.Invoke(TargetParameter _arg11) in C:\proj\client\client\build.fsx:line 210
        at Fake.Core.TargetModule.runSimpleInternal(TargetContext context, Target target) in D:\a\FAKE\FAKE\src\app\Fake.Core.Target\Target.fs:line 300
-> Could not load 'Microsoft.Build.Framework, Version=15.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.
   This can happen for various reasons:
   - You are trying to load full-framework assemblies which is not supported
     -> You might try to load a legacy-script with the new netcore runner.
       Please take a look at the migration guide: https://fake.build/fake-migrate-to-fake-5.html
   - The nuget cache (or packages folder) might be broken.
     -> Please save your state, open an issue and then
     - delete 'Microsoft.Build.Framework' from the '~/.nuget' cache (and the 'packages' folder)
     - delete 'paket-files/paket.restore.cached' if it exists
     - delete '<script.fsx>.lock' if it exists
     - try running fake again
     - the package should be downloaded again
   - Some package introduced a breaking change in their dependencies and .dll files are missing in the resolution
     -> Try to compare the lockfile with a previous working version
     -> Try to lower transitive dependency versions (for example by adding 'strategy: min' to the paket group)
     see https://github.com/fsharp/FAKE/issues/1966 where this happend for 'System.Reactive' version 4

   -> If the above doesn't apply or you need help please open an issue!
   StackTrace:
        at Microsoft.FSharp.Core.PrintfModule.PrintFormatToStringThenFail@1439.Invoke(String message) in D:\workspace\_work\1\s\src\fsharp\FSharp.Core\printf.fs:line 1439
        at Fake.Runtime.CoreCache.findAndLoadInRuntimeDepsCached@315.Invoke(AssemblyLoadContext loadContext, AssemblyName name, VerboseLevel logLevel, FSharpList`1 runtimeDependencies) in D:\a\FAKE\FAKE\src\app\Fake.Runtime\CoreCache.fs:line 321
        at Fake.Runtime.CoreCache.FakeLoadContext.Load(AssemblyName assem) in D:\a\FAKE\FAKE\src\app\Fake.Runtime\CoreCache.fs:line 405
        at System.Runtime.Loader.AssemblyLoadContext.ResolveUsingLoad(AssemblyName assemblyName)
        at System.Runtime.Loader.AssemblyLoadContext.Resolve(IntPtr gchManagedAssemblyLoadContext, AssemblyName assemblyName)
Performance:
 - Cli parsing: 234 milliseconds
 - Packages: 3 seconds
   - Resolver: 3 seconds (1 runs)
      - Runtime: 123 milliseconds
      - Blocked (retrieving package details): 1 second (68 times)
      - Blocked (retrieving package versions): 1 second (10 times)
      - Not Blocked (retrieving package versions): 58 times
   - Disk IO: 128 milliseconds
   - Average Request Time: 38 milliseconds
   - Number of Requests: 74
 - Script analyzing: 78 milliseconds
 - Script running: 8 seconds
 - Script cleanup: 9 milliseconds
 - Runtime: 13 seconds
Paket omitted 37 warnings similar to the ones above. You can see them in verbose mode.

Known workarounds

Following the steps suggested in the error above didn't help, but disabling the internal binlog solved the problem:

Target.create "BuildTestBE" (fun _ ->
  DotNet.publish
    (fun args ->
      { args with
          Configuration = DotNet.BuildConfiguration.Debug
          SelfContained = Some true
          Framework = Some "net6.0-windows"
          Runtime = Some "win-x64"
          OutputPath = Some "build_path"
          MSBuildParams = { MSBuild.CliArguments.Create() with DisableInternalBinLog = true } })
      "../wherever/projfile.csproj"

Related information

OS Name: Microsoft Windows 10 Enterprise OS Version: 10.0.19044 N/A Build 19044

FAKE 5 - F# Make (5.23.1) (this line is written to standard error, see https://github.com/fsharp/FAKE/issues/2066) FakePath: C:\Users\user.dotnet\tools.store\fake-cli\5.23.1\fake-cli\5.23.1\tools\net6.0\any\Fake.Runtime.dll Paket.Core: 6.2.1

Microsoft Visual Studio Enterprise 2022 Version 17.3.5 Installed Version: Enterprise

github-actions[bot] commented 2 years ago

Welcome to the FAKE community! Thank you so much for creating your first issue and therefore improving the project!

yazeedobaid commented 2 years ago

Had the same issue on the GitHub action for the build. It seems due to the release of .NET 7. The dependency resolution in the script uses the newer versions of build packages that are released with .NET 7. We fixed it in FAKE by pinning the packages in the build script:

nuget Microsoft.Build 17.3.2
nuget Microsoft.Build.Framework 17.3.2
nuget Microsoft.Build.Tasks.Core 17.3.2
nuget Microsoft.Build.Utilities.Core 17.3.2
haraldsteinlechner commented 1 year ago

Just ran into it and had a quick workaround thanks to your comments here :)

Should fake.dotnet.msbuild list the nuget dependency to prevent this or did i miss something? at least it it not listed here https://www.nuget.org/packages/Fake.DotNet.MSBuild/5.23.1#dependencies-body-tab

baronfel commented 1 year ago

There's a related part of this - components that want to use the version of MSBuild shipped with the .NET SDK should not actually copy the MSBuild dlls to the application directory. This can be done via the use of ExcludeAssets="runtime" or copy_local: false. Then, MSBuildLocator can be used to discover and load the SDK MSBuild assemblies. This is how projects like Ionide.ProjInfo and Buildalyzer work, and IMO it's how all MSbuild-using utilities should work. Unfortunately, NuGet doesn't allow marking these dependencies in a way that would make the ExcludeAssets="runtime" happen automatically.

hippieZhou commented 1 year ago

when I use dotnet fake build to run run my csharp project, I also got the similar issue as follow:

Resolving dependency graph...
 - FSharp.Core is pinned to 6.0.0
Could not detect any platforms from 'net7.0' in System.Collections.Immutable 7.0.0, please tell the package authors
Could not detect any platforms from 'net7.0' in Microsoft.Build.Framework 17.5.0, please tell the package authors
Could not detect any platforms from 'net7.0' in Microsoft.Build.Utilities.Core 17.5.0, please tell the package authors
Could not detect any platforms from 'net7.0' in Microsoft.NET.StringTools 17.5.0, please tell the package authors
Could not detect any platforms from 'net7.0' in System.Security.Permissions 7.0.0, please tell the package authors
Could not detect any platforms from 'net7.0' in System.Configuration.ConfigurationManager 7.0.0, please tell the package authors
Could not detect any platforms from 'net7.0' in System.Text.Encoding.CodePages 7.0.0, please tell the package authors
Could not detect any platforms from 'net7.0' in System.Security.Cryptography.Pkcs 7.0.1, please tell the package authors
Could not detect any platforms from 'net7.0' in System.Security.Cryptography.ProtectedData 7.0.1, please tell the package authors
Could not detect any platforms from 'net7.0' in System.Formats.Asn1 7.0.0, please tell the package authors
Could not detect any platforms from 'net7.0' in System.Windows.Extensions 7.0.0, please tell the package authors

my local env just installed .net6.0 SDKs and have installed fake-cli with 5.23.1 , but I don't know that it always to find net7.0.

Feel free if you have any idea about this error ?

Thorium commented 3 months ago

Had the same issue on the GitHub action for the build. It seems due to the release of .NET 7. The dependency resolution in the script uses the newer versions of build packages that are released with .NET 7. We fixed it in FAKE by pinning the packages in the build script:

nuget Microsoft.Build 17.3.2
nuget Microsoft.Build.Framework 17.3.2
nuget Microsoft.Build.Tasks.Core 17.3.2
nuget Microsoft.Build.Utilities.Core 17.3.2

Meanwhile this works for this issue, it opens another problem: More recent versions of MSBuild.StructuredLogger have dependency to Microsoft.Build >= 17.5. If you try to use old version of MSBuild.StructuredLogger then you'll get this another error: Unsupported log file format. Latest supported version is 14, the log file has version 18. ...which is listed e.g. here

Thorium commented 3 months ago

Could FAKE do somehow copylocal=true for this dependency to .fake folder?

Numpsy commented 2 months ago

There's a related part of this - components that want to use the version of MSBuild shipped with the .NET SDK should not actually copy the MSBuild dlls to the application directory. This can be done via the use of ExcludeAssets="runtime" or copy_local: false. Then, MSBuildLocator can be used to discover and load the SDK MSBuild assemblies. This is how projects like Ionide.ProjInfo and Buildalyzer work, and IMO it's how all MSbuild-using utilities should work. Unfortunately, NuGet doesn't allow marking these dependencies in a way that would make the ExcludeAssets="runtime" happen automatically.

fwiw I was having a poke about at the build in https://github.com/fsprojects/FAKE/pull/2825 whilst seeing how some things work, and it looks to me like the Microsoft.Build.* dlls being in the build for fake-cli is an artifact of how the libraries are arranged, and that it should be possible to remove the transitive dependencies by shuffling things about a bit.