From de904aecbf9c6f47993ef85ca6ce09a27eb38afb Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Wed, 8 Apr 2026 18:38:47 +0000 Subject: [PATCH 1/6] Use the paths feature in global.json to point to our local .NET SDK. As C# Dev Kit improves their experience, the fact that we don't have this makes it incresingly frustrating to work with in the runtime repo. Let's use the feature we built for this specific case. --- global.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/global.json b/global.json index bd19f150ac5bcb..4aeb8b3fa0d335 100644 --- a/global.json +++ b/global.json @@ -2,7 +2,12 @@ "sdk": { "version": "11.0.100-preview.3.26170.106", "allowPrerelease": true, - "rollForward": "major" + "rollForward": "major", + "paths": [ + ".dotnet", + "$host$" + ], + "errorMessage": "The required .NET SDK wasn't found. Please run ./eng/common/dotnet.cmd/sh to install it." }, "tools": { "dotnet": "11.0.100-preview.3.26170.106" From 564c0cfeda7eb183159683615eb0d821ae142f42 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Wed, 8 Apr 2026 21:45:34 +0000 Subject: [PATCH 2/6] Write empty global.json in test/workload temp dirs to isolate SDK resolution The global.json paths feature causes the SDK resolver to walk up the directory tree and find the repo root's global.json with relative paths like ".dotnet". When dotnet is invoked from temp directories (workload install, WBT test projects, Blazor test projects), the resolver picks up the wrong SDK from the repo-local .dotnet directory instead of the intended SDK. Fix by writing an empty global.json ({}) in temp directories so the SDK resolver stops there and uses default resolution (DOTNET_ROOT, PATH). This follows the established pattern used in HostTestContext.cs and several CI pipeline scripts. Files changed: - InstallWorkloadFromArtifacts.cs: fixes workload install failures ("wasm-tools isn't supported on this platform") - Wasm.Build.Tests/BuildTestBase.cs: fixes WBT test project builds - Wasm.Build.Tests/Blazor/BlazorWasmTestBase.cs: fixes Blazor WBT builds - Wasi.Build.Tests/BuildTestBase.cs: fixes WASI test project builds Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>" --- src/mono/wasi/Wasi.Build.Tests/BuildTestBase.cs | 6 ++++++ .../wasm/Wasm.Build.Tests/Blazor/BlazorWasmTestBase.cs | 5 +++++ src/mono/wasm/Wasm.Build.Tests/BuildTestBase.cs | 6 ++++++ .../WorkloadBuildTasks/InstallWorkloadFromArtifacts.cs | 7 +++++++ 4 files changed, 24 insertions(+) diff --git a/src/mono/wasi/Wasi.Build.Tests/BuildTestBase.cs b/src/mono/wasi/Wasi.Build.Tests/BuildTestBase.cs index f0963a33b6a241..e884daf8305fdf 100644 --- a/src/mono/wasi/Wasi.Build.Tests/BuildTestBase.cs +++ b/src/mono/wasi/Wasi.Build.Tests/BuildTestBase.cs @@ -148,6 +148,12 @@ protected void InitProjectDir(string dir, bool addNuGetSourceForLocalPackages = { targetFramework ??= DefaultTargetFramework; Directory.CreateDirectory(dir); + + // Create an empty global.json so the SDK resolver doesn't walk up + // to the repo root's global.json which may contain relative "paths" + // entries that don't apply in the test directory. + File.WriteAllText(Path.Combine(dir, "global.json"), "{}"); + File.WriteAllText(Path.Combine(dir, "Directory.Build.props"), s_buildEnv.DirectoryBuildPropsContents); File.WriteAllText(Path.Combine(dir, "Directory.Build.targets"), s_buildEnv.DirectoryBuildTargetsContents); File.Copy(BuildEnvironment.WasmOverridePacksTargetsPath, Path.Combine(dir, Path.GetFileName(BuildEnvironment.WasmOverridePacksTargetsPath)), overwrite: true); diff --git a/src/mono/wasm/Wasm.Build.Tests/Blazor/BlazorWasmTestBase.cs b/src/mono/wasm/Wasm.Build.Tests/Blazor/BlazorWasmTestBase.cs index 9c2ad7dfc8e59f..f60507ef843b29 100644 --- a/src/mono/wasm/Wasm.Build.Tests/Blazor/BlazorWasmTestBase.cs +++ b/src/mono/wasm/Wasm.Build.Tests/Blazor/BlazorWasmTestBase.cs @@ -90,6 +90,11 @@ public void InitBlazorWasmProjectDir(string id) Directory.Delete(_projectDir, recursive: true); Directory.CreateDirectory(_projectDir); + // Create an empty global.json so the SDK resolver doesn't walk up + // to the repo root's global.json which may contain relative "paths" + // entries that don't apply in the test directory. + File.WriteAllText(Path.Combine(_projectDir, "global.json"), "{}"); + File.WriteAllText(Path.Combine(_projectDir, "nuget.config"), GetNuGetConfigWithLocalPackagesPath( GetNuGetConfigPath(), diff --git a/src/mono/wasm/Wasm.Build.Tests/BuildTestBase.cs b/src/mono/wasm/Wasm.Build.Tests/BuildTestBase.cs index 4e993991471be5..cbec148b060fcf 100644 --- a/src/mono/wasm/Wasm.Build.Tests/BuildTestBase.cs +++ b/src/mono/wasm/Wasm.Build.Tests/BuildTestBase.cs @@ -240,6 +240,12 @@ protected void InitProjectDir(string dir, bool addNuGetSourceForLocalPackages = if (Directory.Exists(dir)) Directory.Delete(dir, recursive: true); Directory.CreateDirectory(dir); + + // Create an empty global.json so the SDK resolver doesn't walk up + // to the repo root's global.json which may contain relative "paths" + // entries that don't apply in the test directory. + File.WriteAllText(Path.Combine(dir, "global.json"), "{}"); + File.WriteAllText(Path.Combine(dir, "Directory.Build.props"), s_buildEnv.DirectoryBuildPropsContents); File.WriteAllText(Path.Combine(dir, "Directory.Build.targets"), s_buildEnv.DirectoryBuildTargetsContents); if (UseWBTOverridePackTargets) diff --git a/src/tasks/WorkloadBuildTasks/InstallWorkloadFromArtifacts.cs b/src/tasks/WorkloadBuildTasks/InstallWorkloadFromArtifacts.cs index 097be0d8484045..6457c6277c43a5 100644 --- a/src/tasks/WorkloadBuildTasks/InstallWorkloadFromArtifacts.cs +++ b/src/tasks/WorkloadBuildTasks/InstallWorkloadFromArtifacts.cs @@ -65,6 +65,13 @@ public override bool Execute() if (Directory.Exists(_tempDir)) Directory.Delete(_tempDir, recursive: true); Directory.CreateDirectory(_tempDir); + + // Create an empty global.json so the SDK resolver doesn't walk up to a + // parent global.json that may contain relative "paths" entries (e.g. ".dotnet"). + // Without this, the workload install invokes dotnet from a different SDK directory + // but the resolver picks up the wrong SDK from the repo-local .dotnet directory. + File.WriteAllText(Path.Combine(_tempDir, "global.json"), "{}"); + _nugetCachePath = Path.Combine(_tempDir, "nuget-cache"); if (SkipTempDirectoryCleanup) { From 8c7e260dea1b386db99288d372c40dfa3282fd56 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Fri, 10 Apr 2026 20:47:57 +0000 Subject: [PATCH 3/6] Isolate SDK resolution in workload testing targets from repo global.json The _GetDotNetVersion and _FirstDotNetRun targets run dotnet commands from the dotnet-none SDK directory. Without isolation, the SDK resolver walks up and finds the repo root's global.json with paths: [".dotnet"], resolving to the older preview.3 SDK instead of the preview.4 SDK actually installed in dotnet-none. This causes: - Manifests installed into the wrong version band directory - Workload packs not found at runtime - "multithreading runtime pack not available" test failures Fix by writing an empty global.json into the dotnet-none directory and setting WorkingDirectory on all Exec calls so the SDK resolver stops there and uses the correct SDK. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>" --- .../Sdk/WorkloadTesting.Core.targets | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/mono/nuget/Microsoft.NET.Runtime.WorkloadTesting.Internal/Sdk/WorkloadTesting.Core.targets b/src/mono/nuget/Microsoft.NET.Runtime.WorkloadTesting.Internal/Sdk/WorkloadTesting.Core.targets index aa817442bf6cd9..606809b5378243 100755 --- a/src/mono/nuget/Microsoft.NET.Runtime.WorkloadTesting.Internal/Sdk/WorkloadTesting.Core.targets +++ b/src/mono/nuget/Microsoft.NET.Runtime.WorkloadTesting.Internal/Sdk/WorkloadTesting.Core.targets @@ -99,7 +99,13 @@ <_DotNetVersionCommand>$(_DotNetPath) --version - + + + + @@ -107,7 +113,8 @@ - + $(SdkBandVersion)$([System.Text.RegularExpressions.Regex]::Match($(_DotNetVersionOutput), `-(?!rtm|release)[A-z]*[\.]*\d*`)) @@ -129,7 +136,8 @@ - + From 670e7ce05303cf7d8f8d93384b594cdeb59c5339 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Mon, 13 Apr 2026 11:33:16 -0700 Subject: [PATCH 4/6] Update global.json Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- global.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/global.json b/global.json index 4aeb8b3fa0d335..2d06ddfdaa2349 100644 --- a/global.json +++ b/global.json @@ -7,7 +7,7 @@ ".dotnet", "$host$" ], - "errorMessage": "The required .NET SDK wasn't found. Please run ./eng/common/dotnet.cmd/sh to install it." + "errorMessage": "The required .NET SDK wasn't found. Please run ./eng/common/dotnet.sh (Unix) or eng\\common\\dotnet.cmd (Windows) to install it." }, "tools": { "dotnet": "11.0.100-preview.3.26170.106" From 9355891aa6cc893c4b84fe5dbe1a9fd219fc167f Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Mon, 13 Apr 2026 18:55:18 +0000 Subject: [PATCH 5/6] Address PR review feedback from Copilot - Move global.json write inside try block in InstallWorkloadFromArtifacts so IO exceptions are caught by the existing error handler - Fix comment typo: `dotnet -version` -> `dotnet --version` Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>" --- .../Sdk/WorkloadTesting.Core.targets | 2 +- .../InstallWorkloadFromArtifacts.cs | 13 ++++++------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/mono/nuget/Microsoft.NET.Runtime.WorkloadTesting.Internal/Sdk/WorkloadTesting.Core.targets b/src/mono/nuget/Microsoft.NET.Runtime.WorkloadTesting.Internal/Sdk/WorkloadTesting.Core.targets index 606809b5378243..20de8202beea42 100755 --- a/src/mono/nuget/Microsoft.NET.Runtime.WorkloadTesting.Internal/Sdk/WorkloadTesting.Core.targets +++ b/src/mono/nuget/Microsoft.NET.Runtime.WorkloadTesting.Internal/Sdk/WorkloadTesting.Core.targets @@ -110,7 +110,7 @@ - Date: Mon, 13 Apr 2026 13:41:04 -0700 Subject: [PATCH 6/6] Use the variable instead of the command to avoid -- problems --- .../Sdk/WorkloadTesting.Core.targets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/nuget/Microsoft.NET.Runtime.WorkloadTesting.Internal/Sdk/WorkloadTesting.Core.targets b/src/mono/nuget/Microsoft.NET.Runtime.WorkloadTesting.Internal/Sdk/WorkloadTesting.Core.targets index 20de8202beea42..c8a742387b7183 100755 --- a/src/mono/nuget/Microsoft.NET.Runtime.WorkloadTesting.Internal/Sdk/WorkloadTesting.Core.targets +++ b/src/mono/nuget/Microsoft.NET.Runtime.WorkloadTesting.Internal/Sdk/WorkloadTesting.Core.targets @@ -110,7 +110,7 @@ -