fsprojects / FAKE

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

SdkAssemblyResolver does not properly resolve locally installed runtime #2641

Closed mclark1129 closed 2 years ago

mclark1129 commented 2 years ago

Description

After upgrading to 5.21.0, our .NET 6 builds are failing due to the following error:

System.ArgumentException: The option value was None (Parameter 'option')
   at Microsoft.FSharp.Core.OptionModule.GetValue[T](FSharpOption`1 option) in D:\a\_work\1\s\src\fsharp\FSharp.Core\option.fs:line 11
   at Fake.Runtime.SdkAssemblyResolver.SdkAssemblyResolver.ResolveSdkRuntimeVersion() in D:\a\FAKE\FAKE\src\app\Fake.Runtime\SdkAssemblyResolver.fs:line 89
   at <StartupCode$FSI_0002>.$FSI_0002.main@()
Stopped due to error

This appears to be due to the resolver not being able to resolve the correct Runtime version for the locally installed SDK. We are using global.json to specify an SDK version along with rollForward to help manage any minor SDK version differences between development machines and build agents.

Repro steps

The following steps will reproduce the issue outside of the FAKE pipeline by calling the appropriate methods on the SdkAssemblyResolver class:

Setup: In an empty folder create Resolver.fsx with the following code:

#r "nuget: Fake.DotNet.Cli"
#r "nuget: Fake.Runtime"

open Fake.DotNet
open Fake.Runtime

let resolver = SdkAssemblyResolver.SdkAssemblyResolver(Trace.Verbose)
resolver.ResolveSdkRuntimeVersion() |> printfn "%s"

Note the currently installed .NET SDK(s) on your machine. The expected behavior as written assumes 6.0.101, but this is also reproduceable with 6.0.100

Scenario 1: No global.json

  1. run dotnet fsi Resolver.fsx

Expected behavior

Trying to resolve runtime version from network..
resolved runtime version: 6.0.1
6.0.1

Actual behavior

System.ArgumentException: The option value was None (Parameter 'option')
   at Microsoft.FSharp.Core.OptionModule.GetValue[T](FSharpOption`1 option) in D:\a\_work\1\s\src\fsharp\FSharp.Core\option.fs:line 11
   at Fake.Runtime.SdkAssemblyResolver.SdkAssemblyResolver.ResolveSdkRuntimeVersion() in D:\a\FAKE\FAKE\src\app\Fake.Runtime\SdkAssemblyResolver.fs:line 89
   at <StartupCode$FSI_0002>.$FSI_0002.main@()
Stopped due to error

Scenario 2: Unknown SDK version with rollForward option

  1. Add the following global.json to the workspace

    {
    "sdk": {
    "version": "6.0.0",
    "rollForward": "latestFeature"
    }
    }
  2. run dotnet fsi Resolver.fsx

Expected behavior

Trying to resolve runtime version from network..
resolved runtime version: 6.0.1
6.0.1

Actual behavior

System.ArgumentException: The option value was None (Parameter 'option')
   at Microsoft.FSharp.Core.OptionModule.GetValue[T](FSharpOption`1 option) in D:\a\_work\1\s\src\fsharp\FSharp.Core\option.fs:line 11
   at Fake.Runtime.SdkAssemblyResolver.SdkAssemblyResolver.ResolveSdkRuntimeVersion() in D:\a\FAKE\FAKE\src\app\Fake.Runtime\SdkAssemblyResolver.fs:line 89
   at <StartupCode$FSI_0002>.$FSI_0002.main@()

Scenario 3: Valid SDK version, lower than installed version

  1. Add the following global.json to the workspace

    {
    "sdk": {
    "version": "6.0.100",
    "rollForward": "latestFeature"
    }
    }
  2. run dotnet fsi Resolver.fsx

Expected behavior

Trying to resolve runtime version from network..
resolved runtime version: 6.0.1
6.0.1

Actual behavior

Trying to resolve runtime version from network..
resolved runtime version: 6.0.0
6.0.0

During the actual build this leads to a failure due to the fact that 6.0.0 is not installed:

The last restore is still up to date. Nothing left to do.
Performance:
 - Cli parsing: 126 milliseconds
 - Packages: 44 milliseconds
   - Creating Runtime Graph: 43 milliseconds
   - Retrieve Assembly List: 1 second
 - Runtime: 1 second
There was a problem while setting up the environment:
-> Could not find referenced assemblies in path: 'C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.0\ref\net6.0', please check installed SDK and runtime versions
Hint: If you just upgraded the fake-runner you can try to remove the .fake directory and try again.

Known Workarounds

Specify exact installed SDK in global.json ensure that version is installed across all machines building the project

Related information

FAKE 5.21.0

Installed SDKs:

dotnet sdk check
.NET SDKs:
Version      Status
---------------------------------------------------
2.2.207      .NET 2.2 is out of support.
3.1.416      Up to date.
5.0.104      .NET 5.0 is going out of support soon.
5.0.210      .NET 5.0 is going out of support soon.
5.0.404      .NET 5.0 is going out of support soon.
6.0.101      Up to date.

.NET Runtimes:
Name                              Version      Status
-------------------------------------------------------------------------------------
Microsoft.AspNetCore.All          2.2.8        .NET 2.2 is out of support.
Microsoft.AspNetCore.App          2.2.8        .NET 2.2 is out of support.
Microsoft.NETCore.App             2.2.8        .NET 2.2 is out of support.
Microsoft.AspNetCore.App          3.1.22       Up to date.
Microsoft.NETCore.App             3.1.22       Up to date.
Microsoft.WindowsDesktop.App      3.1.22       Up to date.
Microsoft.NETCore.App             5.0.0        .NET 5.0 is going out of support soon.
Microsoft.AspNetCore.App          5.0.4        .NET 5.0 is going out of support soon.
Microsoft.NETCore.App             5.0.4        .NET 5.0 is going out of support soon.
Microsoft.WindowsDesktop.App      5.0.4        .NET 5.0 is going out of support soon.
Microsoft.AspNetCore.App          5.0.13       .NET 5.0 is going out of support soon.
Microsoft.NETCore.App             5.0.13       .NET 5.0 is going out of support soon.
Microsoft.WindowsDesktop.App      5.0.13       .NET 5.0 is going out of support soon.
Microsoft.AspNetCore.App          6.0.1        Up to date.
Microsoft.NETCore.App             6.0.1        Up to date.
Microsoft.WindowsDesktop.App      6.0.1        Up to date.

OS: Win 10

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!

Jooseppi12 commented 2 years ago

Same issue on my end as well, but in my case dotnet --info claims that I have a 6.0.0 runtime installed (but the folders are not there for that one)

raghur commented 2 years ago

Similar issue - however, our default is not to have a global.json. In a gitpod env, even with the SDKs installed, have to have a global.json with the exact version of the sdk 6.0.101 for the build to work. Without global.json, get a cryptic

Script is not valid: unknown (1,0)-(1,0): Error FS0193: The module/namespace 'System' from compilation unit 'netstandard' did not contain the namespace, module or type 'IAsyncDisposable'

which might be resolving to netstandard2.0 instead of net 6.0

amis92 commented 2 years ago

Why is this not yet labelled as a bug?

I can reproduce this with fake-cli v5.22.0, OS Win10, I have .NET SDK v6.0.102 installed and unless my global.json contains exactly this version, it fails with

There was a problem while setting up the environment:
-> Could not find referenced assemblies in path: 'C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.0\ref\net6.0', please check installed SDK and runtime versions

This is with global.json:

{
  "sdk": {
    "version": "6.0.100"
  }
}
TheAngryByrd commented 2 years ago

I'm also encountering this fun bug in FsToolkit.ErrorHandling

There was a problem while setting up the environment:
-> Could not find referenced assemblies in path: '/opt/hostedtoolcache/dncs/x64/packs/Microsoft.NETCore.App.Ref/6.0.0/ref/net6.0', please check installed SDK and runtime versions
   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.FakeRuntime.retrieveInfosUncached@114(String cacheDir, Lazy`1 paketDependenciesFile, VerboseLevel logLevel, GroupName groupName, SdkAssemblyResolver sdkAssemblyResolver, FrameworkIdentifier framework, Rid rid, Rid ridNotVersionSpecific, Lazy`1 lockFile, Lazy`1 cache, Unit unitVar0) in D:\a\FAKE\FAKE\src\app\Fake.Runtime\FakeRuntime.fs:line 202
        at Fake.Runtime.FakeRuntime.getKnownDependencies@312-1.Invoke(Unit unitVar0) in D:\a\FAKE\FAKE\src\app\Fake.Runtime\FakeRuntime.fs:line 312
        at Fake.Runtime.CoreCache.getCached[a](FSharpFunc`2 getUncached, FSharpFunc`2 readFromCache, FSharpFunc`2 writeToCache, FSharpFunc`2 checkCacheUpToDate) in D:\a\FAKE\FAKE\src\app\Fake.Runtime\CoreCache.fs:line 41
        at Fake.Runtime.FakeRuntime.getKnownDependencies@310(String cacheDir, Lazy`1 paketDependenciesFile, VerboseLevel logLevel, GroupName groupName, FileInfo lockFilePath, String dependencyCacheHashFile, String dependencyCacheFile, SdkAssemblyResolver sdkAssemblyResolver, FrameworkIdentifier framework, Rid rid, Rid ridNotVersionSpecific, Lazy`1 lockFile, Lazy`1 cache, Lazy`1 writeIntellisenseTask, FSharpFunc`2 readFromCache, FSharpFunc`2 writeToCache, Unit unitVar0) in D:\a\FAKE\FAKE\src\app\Fake.Runtime\FakeRuntime.fs:line 311
        at Fake.Runtime.FakeRuntime.knownDependencies@320.Invoke(Unit unitVar) in D:\a\FAKE\FAKE\src\app\Fake.Runtime\FakeRuntime.fs:line 320
        at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
        at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
        at System.Lazy`1.CreateValue()
        at Fake.Runtime.FakeRuntime.paketCachingProvider@329-5.Fake.Runtime.CoreCache.ICachingProvider.TryLoadCache(FakeContext context) in D:\a\FAKE\FAKE\src\app\Fake.Runtime\FakeRuntime.fs:line 336
        at Fake.Runtime.CoreCache.prepareContext(FakeConfig config, ICachingProvider cache) in D:\a\FAKE\FAKE\src\app\Fake.Runtime\CoreCache.fs:line 482
        at Fake.Runtime.CoreCache.runScriptWithCacheProviderExt(FakeConfig config, ICachingProvider cache) in D:\a\FAKE\FAKE\src\app\Fake.Runtime\CoreCache.fs:line 508
        at Fake.Runtime.FakeRuntime.runScript(PrepareInfo preparedScript) in D:\a\FAKE\FAKE\src\app\Fake.Runtime\FakeRuntime.fs:line 579
        at Program.runOrBuild(RunArguments args) in D:\a\FAKE\FAKE\src\app\Fake.netcore\Program.fs:line 156
Hint: If you just upgraded the fake-runner you can try to remove the .fake directory and try again.
csmager commented 2 years ago

Was looking to see if I should log this - we use 'Scenario 3' (6.0.100 with roll forward latestFeature), and updating to the latest CLI breaks.

I think the fix is hinted in this review comment: if we change to use dotnet --version then we solve two problems at once: 1. we get a value if global.json is missing and 2. we get the resolved version given what's installed, any global.json and any rollForward value.

InvisibleBacon commented 2 years ago

Hello, do you know when this fix will be released? Our software is running into the issue with rollForward not being honored.

mclark1129 commented 2 years ago

I do not, a PR for the alpha build is here https://github.com/fsprojects/FAKE/pull/2668 but it is blocked because the Mac OS tests are failing for reasons I can't personally reproduce (works on my fork!). That's basically where the fix has died for now, and my team has already started the process for moving to different build tooling.

InvisibleBacon commented 2 years ago

@mclark1129 That's unfortunate. Thank you for your efforts here.. Hopefully progress will be made.

yazeedobaid commented 2 years ago

The build issue is now fixed and a new release is published.

jrk94 commented 1 year ago

Did it work for you @InvisibleBacon ? Seems like it's still not working for me. It still is unable to roll forward