diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index c5c60f3a09b..966aefd7914 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -14,15 +14,19 @@ jobs: build: name: build-${{ matrix.platform }} # TRACE_CI_RUNNERS picks GitHub-hosted runners (unset) or the local fleet (`self-hosted`); see - # docs/self-hosted-runners.md in Trace Arena. Under the flag only the legs the local fleet can host exist: - # there is no Windows machine, and the arm64 Linux pool is a 1.5 GB container that cannot build the native - # runtime. Hosted CI keeps all four legs. - runs-on: ${{ vars.TRACE_CI_RUNNERS == 'self-hosted' && (matrix.platform == 'macos' && fromJSON('["self-hosted","macOS","ARM64"]') || fromJSON('["self-hosted","Linux","X64","yiazmat-linux-x64-native"]')) || (matrix.platform == 'windows' && 'windows-latest' || matrix.platform == 'macos' && 'macos-latest' || matrix.platform == 'linux-arm' && 'ubuntu-24.04-arm' || 'ubuntu-latest') }} + # docs/self-hosted-runners.md in Trace Arena. Under the flag the legs the local fleet can host exist: the Windows VM on the + # Linux server, the native x64 Linux server and the macOS machine. The arm64 Linux pool is a 1.5 GB container that cannot build + # the native runtime, so that leg stays hosted-only. Hosted CI keeps all four legs. + runs-on: ${{ vars.TRACE_CI_RUNNERS == 'self-hosted' && (matrix.platform == 'windows' && fromJSON('["self-hosted","Windows","X64"]') || matrix.platform == 'macos' && fromJSON('["self-hosted","macOS","ARM64"]') || fromJSON('["self-hosted","Linux","X64","yiazmat-linux-x64-native"]')) || (matrix.platform == 'windows' && 'windows-latest' || matrix.platform == 'macos' && 'macos-latest' || matrix.platform == 'linux-arm' && 'ubuntu-24.04-arm' || 'ubuntu-latest') }} env: - MONOGAME_WINDOWS_PLATFORM_TOOLSET: ${{ matrix.platform == 'windows' && 'v145' || '' }} + # The VSIX templates project needs the full Visual Studio IDE SDK, which the fleet's VM (Build Tools) does not have. The hosted + # legs keep building it. + MONOGAME_SKIP_VS_TEMPLATES: ${{ vars.TRACE_CI_RUNNERS == 'self-hosted' && matrix.platform == 'windows' && '1' || '' }} + # v145 ships with the newest Visual Studio; the fleet's Windows VM has VS 2022 Build Tools, whose toolset is v143. + MONOGAME_WINDOWS_PLATFORM_TOOLSET: ${{ matrix.platform == 'windows' && (vars.TRACE_CI_RUNNERS == 'self-hosted' && 'v143' || 'v145') || '' }} strategy: matrix: - platform: ${{ fromJSON(vars.TRACE_CI_RUNNERS == 'self-hosted' && '["macos","linux"]' || '["windows","macos","linux","linux-arm"]') }} + platform: ${{ fromJSON(vars.TRACE_CI_RUNNERS == 'self-hosted' && '["windows","macos","linux"]' || '["windows","macos","linux","linux-arm"]') }} fail-fast: false defaults: run: diff --git a/MonoGame.Framework.Content.Pipeline/MonoGame.Framework.Content.Pipeline.csproj b/MonoGame.Framework.Content.Pipeline/MonoGame.Framework.Content.Pipeline.csproj index 0b70c82ff3e..f2cf1637b29 100644 --- a/MonoGame.Framework.Content.Pipeline/MonoGame.Framework.Content.Pipeline.csproj +++ b/MonoGame.Framework.Content.Pipeline/MonoGame.Framework.Content.Pipeline.csproj @@ -141,7 +141,8 @@ /p:PlatformToolset=$(MONOGAME_WINDOWS_PLATFORM_TOOLSET) - + + diff --git a/Tools/MonoGame.Tools.Tests/BuilderTests.cs b/Tools/MonoGame.Tools.Tests/BuilderTests.cs index 0bd604714e6..4f1bf444304 100644 --- a/Tools/MonoGame.Tools.Tests/BuilderTests.cs +++ b/Tools/MonoGame.Tools.Tests/BuilderTests.cs @@ -45,7 +45,10 @@ public void CommandLineParserTests() Assert.AreEqual(MakePath(Directory.GetCurrentDirectory(), "obj\\Content"), args.RootedIntermediateDirectory); args = ContentBuilderParams.Parse("build", "-s", "C:/This/Does/Not/Exist"); - Assert.AreEqual(MakePath("C:/This/Does/Not/Exist"), args.SourceDirectory); + // The parser stores the directory relative to the working directory. On a different drive it cannot, and the path stays + // absolute (the hosted runners work on D:); on the same drive it relativizes (the fleet's VM works on C:). Assert the + // round trip, not the hosted image's drive layout. + Assert.AreEqual(MakePath(Path.GetRelativePath(Directory.GetCurrentDirectory(), "C:/This/Does/Not/Exist")), args.SourceDirectory); args = ContentBuilderParams.Parse( "build", diff --git a/build/BuildTemplatesTasks/BuildVSTemplatesTask.cs b/build/BuildTemplatesTasks/BuildVSTemplatesTask.cs index 83f801ae24b..5749150295b 100644 --- a/build/BuildTemplatesTasks/BuildVSTemplatesTask.cs +++ b/build/BuildTemplatesTasks/BuildVSTemplatesTask.cs @@ -6,7 +6,10 @@ namespace BuildScripts; [IsDependentOn(typeof(BuildDotNetTemplatesTask))] public sealed class BuildVSTemplatesTask : FrostingTask { - public override bool ShouldRun(BuildContext context) => context.IsRunningOnWindows(); + // The VSIX project needs the full Visual Studio IDE SDK (VSSDK1077: no extensions directory on a Build Tools-only machine). + // The workflow sets the variable for the self-hosted Windows VM, which has the Build Tools; the hosted legs keep building it. + public override bool ShouldRun(BuildContext context) => + context.IsRunningOnWindows() && Environment.GetEnvironmentVariable("MONOGAME_SKIP_VS_TEMPLATES") != "1"; public override void Run(BuildContext context) { diff --git a/build/TestNuGetsTasks/TestMonoGameTemplateTaskBase.cs b/build/TestNuGetsTasks/TestMonoGameTemplateTaskBase.cs index 6a462c1cfd3..bde48fbb40b 100644 --- a/build/TestNuGetsTasks/TestMonoGameTemplateTaskBase.cs +++ b/build/TestNuGetsTasks/TestMonoGameTemplateTaskBase.cs @@ -190,6 +190,25 @@ private void UninstallExistingTemplates(BuildContext context) private void InstallTemplates(BuildContext context, string templateVersion, string nugetSourcePath) { + // `dotnet new uninstall` removes the template but leaves its package in ~/.templateengine/packages, and the next + // `dotnet new install` of the same version fails with "File ... already exists" (templating exit code 106) instead of + // reinstalling. Clear the cached package so a rerun on the same machine starts from a clean template store. + var templateCache = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".templateengine", "packages"); + if (Directory.Exists(templateCache)) + { + foreach (var cached in Directory.GetFiles(templateCache, "MonoGame.Templates.CSharp.*.nupkg")) + { + try + { + File.Delete(cached); + } + catch (IOException) + { + // A package held open by another dotnet process: the install below will report it if it matters. + } + } + } + context.Information($"Installing MonoGame templates version {templateVersion}..."); context.StartProcess("dotnet", new ProcessSettings { diff --git a/build/Utils/StaticLibCheck.cs b/build/Utils/StaticLibCheck.cs index 5eb0f408daf..ac656a3b1a2 100644 --- a/build/Utils/StaticLibCheck.cs +++ b/build/Utils/StaticLibCheck.cs @@ -48,7 +48,8 @@ public static class StaticLibCheck public static void CheckWindows(BuildContext context, string filePath) { var vswhere = new VSWhereLatest(context.FileSystem, context.Environment, context.ProcessRunner, context.Tools); - var devcmdPath = vswhere.Latest(new VSWhereLatestSettings()).FullPath + @"\Common7\Tools\vsdevcmd.bat"; + // Products = "*" so a Build Tools-only machine (the fleet's Windows VM) is found: the default product filter skips it. + var devcmdPath = vswhere.Latest(new VSWhereLatestSettings { Products = "*" }).FullPath + @"\Common7\Tools\vsdevcmd.bat"; context.StartProcess( devcmdPath,