From b8ead4a99db82419fe670b2620f9fcd2cad027a7 Mon Sep 17 00:00:00 2001 From: Jens Geyer Date: Wed, 21 Oct 2026 01:06:14 +0200 Subject: [PATCH] THRIFT-6440: Let the .NET tool run where only .NET 9 or later is installed Client: build Apache.Thrift.Compiler targets net8.0 and set no RollForward, so on a machine with only .NET 9 or 10 the tool installed and then refused to start, asking for .NET 8. With RollForward=Major the launcher uses the next newer .NET when 8 is missing; where 8 is installed, nothing changes. test-dotnet-tool.ps1 now checks the runtimeconfig.json in the package. The CI runners have .NET 8 next to newer versions, so installing and running the tool there could not show the problem. Co-Authored-By: Claude Opus 5.5 (1M context) --- build/windows/README.md | 6 ++++++ .../dotnet-tool/Apache.Thrift.Compiler.csproj | 4 ++++ build/windows/dotnet-tool/test-dotnet-tool.ps1 | 12 ++++++++++++ 3 files changed, 22 insertions(+) diff --git a/build/windows/README.md b/build/windows/README.md index 715a4515fba..26bb12bf907 100644 --- a/build/windows/README.md +++ b/build/windows/README.md @@ -189,6 +189,10 @@ managed code, but a package built that way cannot be installed by the .NET 8 or .NET 9 SDK at all, and the MSBuild properties involved are undocumented. The launcher costs one small assembly and works everywhere. +The launcher targets .NET 8 and rolls forward to a newer major version when +.NET 8 is not installed. Otherwise a machine with only .NET 9 or later would +install the tool and then refuse to start it, asking for .NET 8. + The package carries the Windows compiler only. NuGet installs a tool package on any platform, so the launcher checks and reports that rather than failing to start a Windows executable. @@ -207,6 +211,8 @@ neither shows up before somebody installs it: the payload can be missing, and the layout can be such that the tool installs but does not run. So the test checks the package contents - including that `LICENSE` and `NOTICE` really are in there and are not empty - and then proves the installed command works. +It also checks that the launcher may roll forward to a newer .NET, because +running the tool on a machine that has .NET 8 as well cannot show that. It runs anywhere PowerShell and the .NET SDK do. Off Windows it checks the launcher's refusal instead of the compiler's output, which is the behaviour that diff --git a/build/windows/dotnet-tool/Apache.Thrift.Compiler.csproj b/build/windows/dotnet-tool/Apache.Thrift.Compiler.csproj index 5b8662a45e2..09c2d00628d 100644 --- a/build/windows/dotnet-tool/Apache.Thrift.Compiler.csproj +++ b/build/windows/dotnet-tool/Apache.Thrift.Compiler.csproj @@ -34,6 +34,10 @@ Exe net8.0 + + Major enable disable latest diff --git a/build/windows/dotnet-tool/test-dotnet-tool.ps1 b/build/windows/dotnet-tool/test-dotnet-tool.ps1 index 905ef687b5d..2c27fcb5994 100644 --- a/build/windows/dotnet-tool/test-dotnet-tool.ps1 +++ b/build/windows/dotnet-tool/test-dotnet-tool.ps1 @@ -155,6 +155,18 @@ try { Assert-True 'the tool entry point is the managed launcher' ` ($settings -match "EntryPoint\s*=\s*`"$([regex]::Escape($PackageId)).dll`"") $settings + # The launcher targets the oldest .NET the tool has to install on. Unless it + # may roll forward to a newer major version, a machine with only .NET 9 or + # later installs the tool and then refuses to start it, asking for .NET 8. + # Runners that also have .NET 8 never show that, so check the setting. + $runtimeConfig = Read-Entry "$toolDir/$PackageId.runtimeconfig.json" + $rollForward = '' + if ($runtimeConfig) { + $rollForward = [string](($runtimeConfig | ConvertFrom-Json).runtimeOptions.rollForward) + } + Assert-True 'the launcher may run on a newer major .NET' ` + ($rollForward -in @('Major', 'LatestMajor')) "rollForward '$rollForward'" + $nuspec = Read-Entry "$PackageId.nuspec" Assert-True 'the package is a DotnetTool package' ($nuspec -match 'packageType\s+name="DotnetTool"') Assert-True "the package id is $PackageId" ($nuspec -match "$([regex]::Escape($PackageId))")