diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f987c515..c105b151 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -33,34 +33,16 @@ defaults: jobs: build: - runs-on: windows-latest + runs-on: ubuntu-latest steps: - name: 🤘 checkout uses: actions/checkout@v4 - - name: ⚙ msbuild - uses: microsoft/setup-msbuild@v1.1 - - - name: 🙏 build - shell: pwsh - working-directory: src/NuGetizer.Tests - run: | - dotnet restore Scenarios/given_a_packaging_project/a.nuproj - # THIS IS IMPORTANT: WE NEED TO BUILD WITH DESKTOP MSBUILD - msbuild -r - - - name: 🐛 logs - uses: actions/upload-artifact@v4 - if: runner.debug && always() - with: - name: binlog-build-${{ github.run_number }} - path: src/NuGetizer.Tests/msbuild.binlog - - name: 🧪 test run: | dotnet tool update -g dotnet-retest - # THIS IS IMPORTANT: WE TEST BUT NEVER BUILD (to keep desktop-built artifacts) - dotnet retest -- --no-build + # Build and test in one command - no longer need Desktop MSBuild + dotnet retest -- src/NuGetizer.Tests/NuGetizer.Tests.csproj - name: 📦 pack run: dotnet pack -m:1 -c:${{ env.Configuration }} diff --git a/global.json b/global.json new file mode 100644 index 00000000..40584df3 --- /dev/null +++ b/global.json @@ -0,0 +1,7 @@ +{ + "sdk": { + "version": "9.0.100", + "rollForward": "latestMinor", + "allowPrerelease": false + } +} diff --git a/src/NuGetizer.Tests/ModuleInitializer.cs b/src/NuGetizer.Tests/ModuleInitializer.cs index 87244372..70da2ed7 100644 --- a/src/NuGetizer.Tests/ModuleInitializer.cs +++ b/src/NuGetizer.Tests/ModuleInitializer.cs @@ -1,51 +1,120 @@ using System; +using System.Diagnostics; using System.IO; +using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; +using System.Runtime.Loader; namespace NuGetizer.Tests { static class ModuleInitializer { - static readonly string logFile = Environment.ExpandEnvironmentVariables(@"%TEMP%\NuGetizer.txt"); + static readonly string logFile = Path.Combine(Path.GetTempPath(), "NuGetizer.txt"); + static string sdkPath; [ModuleInitializer] internal static void Run() { - AppDomain.CurrentDomain.AssemblyResolve += OnAssemblyResolve; + // Get the .NET SDK path by running 'dotnet --info' + sdkPath = GetDotNetSdkPath(); - File.AppendAllText(logFile, $"Initializing MSBuild to {ThisAssembly.Project.MSBuildBinPath}\r\n"); + File.AppendAllText(logFile, $"Initializing MSBuild from SDK at {sdkPath}\r\n"); - var binPath = ThisAssembly.Project.MSBuildBinPath; - Microsoft.Build.Locator.MSBuildLocator.RegisterMSBuildPath(binPath); + // Set up assembly resolution to prefer SDK assemblies + AssemblyLoadContext.Default.Resolving += OnAssemblyResolving; - // Set environment variables so SDKs can be resolved. - Environment.SetEnvironmentVariable("MSBUILD_EXE_PATH", Path.Combine(binPath, "MSBuild.exe"), EnvironmentVariableTarget.Process); + // Set environment variables so SDKs can be resolved + var msbuildExe = Path.Combine(sdkPath, "MSBuild.dll"); + Environment.SetEnvironmentVariable("MSBUILD_EXE_PATH", msbuildExe, EnvironmentVariableTarget.Process); } - static Assembly OnAssemblyResolve(object sender, ResolveEventArgs args) + static Assembly OnAssemblyResolving(AssemblyLoadContext context, AssemblyName assemblyName) { - var name = new AssemblyName(args.Name).Name; - var file = Path.Combine(ThisAssembly.Project.MSBuildBinPath, name + ".dll"); - - File.AppendAllText(logFile, $"Resolving {name}\r\n"); - - if (name.StartsWith("Microsoft.Build") && File.Exists(file)) - { - File.AppendAllText(logFile, $"Found {file}\r\n"); - return Assembly.LoadFrom(file); - } - else + // Resolve MSBuild, NuGet and related assemblies from the SDK directory + if (assemblyName.Name != null && + (assemblyName.Name.StartsWith("Microsoft.Build") || + assemblyName.Name.StartsWith("Microsoft.CodeAnalysis") || + assemblyName.Name.StartsWith("NuGet.") || + assemblyName.Name.StartsWith("System.Collections.Immutable") || + assemblyName.Name.StartsWith("System.Reflection.Metadata") || + assemblyName.Name.StartsWith("System.Security.Cryptography"))) { - file = Path.Combine(ThisAssembly.Project.MSBuildProjectDirectory, ThisAssembly.Project.OutputPath, name + ".dll"); - if (File.Exists(file)) + var assemblyPath = Path.Combine(sdkPath, assemblyName.Name + ".dll"); + if (File.Exists(assemblyPath)) { - File.AppendAllText(logFile, $"Found {file}\r\n"); - return Assembly.LoadFrom(file); + File.AppendAllText(logFile, $"Loading {assemblyName.Name} from SDK at {assemblyPath}\r\n"); + return context.LoadFromAssemblyPath(assemblyPath); } } return null; } + + static string GetDotNetSdkPath() + { + try + { + // Use 'dotnet --list-sdks' to find the SDK path + var process = new Process + { + StartInfo = new ProcessStartInfo + { + FileName = "dotnet", + Arguments = "--list-sdks", + RedirectStandardOutput = true, + RedirectStandardError = true, + UseShellExecute = false, + CreateNoWindow = true + } + }; + + process.Start(); + var output = process.StandardOutput.ReadToEnd(); + process.WaitForExit(); + + // Parse the output to get SDK paths, use the latest SDK + // Output format: "9.0.100 [/usr/share/dotnet/sdk]" + var lines = output.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); + + // Use the latest SDK (last line) + if (lines.Length > 0) + { + var lastLine = lines.Last(); + var startIndex = lastLine.IndexOf('['); + var endIndex = lastLine.IndexOf(']'); + if (startIndex >= 0 && endIndex > startIndex) + { + var sdkBase = lastLine.Substring(startIndex + 1, endIndex - startIndex - 1); + var version = lastLine.Substring(0, startIndex).Trim(); + var sdkPath = Path.Combine(sdkBase, version); + File.AppendAllText(logFile, $"Using latest SDK at {sdkPath}\r\n"); + return sdkPath; + } + } + + // Fallback: try to use DOTNET_ROOT or common paths + var dotnetRoot = Environment.GetEnvironmentVariable("DOTNET_ROOT"); + if (!string.IsNullOrEmpty(dotnetRoot)) + { + var sdkDir = Path.Combine(dotnetRoot, "sdk"); + if (Directory.Exists(sdkDir)) + { + var versions = Directory.GetDirectories(sdkDir) + .OrderByDescending(d => d) + .FirstOrDefault(); + if (versions != null) + return versions; + } + } + + throw new InvalidOperationException("Could not locate .NET SDK path"); + } + catch (Exception ex) + { + File.AppendAllText(logFile, $"Error finding SDK path: {ex}\r\n"); + throw; + } + } } } diff --git a/src/NuGetizer.Tests/NuGetizer.Tests.csproj b/src/NuGetizer.Tests/NuGetizer.Tests.csproj index 44268018..0538f2f1 100644 --- a/src/NuGetizer.Tests/NuGetizer.Tests.csproj +++ b/src/NuGetizer.Tests/NuGetizer.Tests.csproj @@ -1,7 +1,7 @@ - net472 + net9.0 $(DefaultItemExcludes);Scenarios\**\* Preview @@ -19,9 +19,12 @@ + + + - + @@ -29,7 +32,7 @@ - + @@ -39,10 +42,6 @@ - - - - @@ -56,15 +55,7 @@ - - - - - - - - - +