From 3acb9986d940ed0b3e3289af3e7edc615c78df7e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 1 Jul 2026 19:25:41 +0000 Subject: [PATCH 1/4] Initial plan From 8eca0703200d2c2a28486a3d140a998a259cb6c4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 1 Jul 2026 19:39:22 +0000 Subject: [PATCH 2/4] Use any TFM for pointer tool settings Co-authored-by: baronfel <573979+baronfel@users.noreply.github.com> --- .../targets/Microsoft.NET.PackTool.targets | 8 +++++++- .../EndToEndToolTests.cs | 17 ++++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.PackTool.targets b/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.PackTool.targets index 79d08620cfc6..61eb947ab87c 100644 --- a/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.PackTool.targets +++ b/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.PackTool.targets @@ -205,9 +205,15 @@ NOTE: This file is imported from the following contexts, so be aware when writin <_ToolRidPath Condition="'$(RuntimeIdentifier)' == ''">any <_ToolRidPath Condition="'$(RuntimeIdentifier)' != ''">$(RuntimeIdentifier) + <_ToolSettingsTargetFrameworkPath>$(_ToolPackShortTargetFrameworkName) + <_ToolSettingsTargetFrameworkPath Condition="'$(_ToolPackageShouldIncludeImplementation)' != 'true' and '$(_UserSpecifiedToolPackageRids)' != ''">any - + + tools/$(_ToolSettingsTargetFrameworkPath)/$(_ToolRidPath)/ + + + tools/$(_ToolPackShortTargetFrameworkName)/$(_ToolRidPath)/%(_GeneratedFiles.RecursiveDir) diff --git a/test/Microsoft.DotNet.PackageInstall.Tests/EndToEndToolTests.cs b/test/Microsoft.DotNet.PackageInstall.Tests/EndToEndToolTests.cs index 75786a86c338..353123037c14 100644 --- a/test/Microsoft.DotNet.PackageInstall.Tests/EndToEndToolTests.cs +++ b/test/Microsoft.DotNet.PackageInstall.Tests/EndToEndToolTests.cs @@ -168,6 +168,7 @@ public void PackagesMultipleToolsWithASingleInvocation() // top-level package should declare all of the rids var topLevelPackage = packages.First(p => p.EndsWith($"{packageIdentifier}.{toolSettings.ToolPackageVersion}.nupkg")); + EnsureToolSettingsFileUsesAnyTfmAndRid(topLevelPackage); var foundRids = GetRidsInSettingsFile(topLevelPackage); foundRids.Should().BeEquivalentTo(expectedRids, "The top-level package should declare all of the RIDs for the tools it contains"); } @@ -264,6 +265,7 @@ public void PackageToolWithAnyRid() // top-level package should declare all of the rids var topLevelPackage = packages.FirstOrDefault(p => p.EndsWith($"{packageIdentifier}.{toolSettings.ToolPackageVersion}.nupkg")); topLevelPackage.Should().NotBeNull($"Package {packageIdentifier}.{toolSettings.ToolPackageVersion}.nupkg should be present in the tool packages directory") + .And.Satisfy(EnsureToolSettingsFileUsesAnyTfmAndRid) .And.Satisfy(SupportAllOfTheseRuntimes([.. expectedRids, "any"])); } @@ -554,16 +556,29 @@ static string[] GetRidsInSettingsFile(XElement settingsXml) return nodes; } + static void EnsureToolSettingsFileUsesAnyTfmAndRid(string packagePath) + { + using var zipArchive = ZipFile.OpenRead(packagePath); + GetToolSettingsFileEntry(zipArchive).FullName.Should().Be("tools/any/any/DotnetToolSettings.xml"); + } + static XElement GetToolSettingsFile(string packagePath) { using var zipArchive = ZipFile.OpenRead(packagePath); - var nuspecEntry = zipArchive.Entries.First(e => e.Name == "DotnetToolSettings.xml")!; + var nuspecEntry = GetToolSettingsFileEntry(zipArchive); var stream = nuspecEntry.Open(); var xml = XDocument.Load(stream, LoadOptions.None); return xml.Root!; } + static ZipArchiveEntry GetToolSettingsFileEntry(ZipArchive zipArchive) + { + var settingsEntries = zipArchive.Entries.Where(e => e.Name == "DotnetToolSettings.xml").ToArray(); + settingsEntries.Should().ContainSingle("tool packages should contain exactly one DotnetToolSettings.xml file"); + return settingsEntries[0]; + } + [TestMethod] public void InstallToolWithHigherFrameworkAsGlobalToolShowsAppropriateError() { From e4842008726011ac1198f07cfe839348ea34eccc Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 1 Jul 2026 19:39:56 +0000 Subject: [PATCH 3/4] Address review feedback on tool packaging fix Co-authored-by: baronfel <573979+baronfel@users.noreply.github.com> --- .../targets/Microsoft.NET.PackTool.targets | 1 + .../EndToEndToolTests.cs | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.PackTool.targets b/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.PackTool.targets index 61eb947ab87c..b483c7625ce5 100644 --- a/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.PackTool.targets +++ b/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.PackTool.targets @@ -206,6 +206,7 @@ NOTE: This file is imported from the following contexts, so be aware when writin <_ToolRidPath Condition="'$(RuntimeIdentifier)' == ''">any <_ToolRidPath Condition="'$(RuntimeIdentifier)' != ''">$(RuntimeIdentifier) <_ToolSettingsTargetFrameworkPath>$(_ToolPackShortTargetFrameworkName) + <_ToolSettingsTargetFrameworkPath Condition="'$(_ToolPackageShouldIncludeImplementation)' != 'true' and '$(_UserSpecifiedToolPackageRids)' != ''">any diff --git a/test/Microsoft.DotNet.PackageInstall.Tests/EndToEndToolTests.cs b/test/Microsoft.DotNet.PackageInstall.Tests/EndToEndToolTests.cs index 353123037c14..6ce8f672984f 100644 --- a/test/Microsoft.DotNet.PackageInstall.Tests/EndToEndToolTests.cs +++ b/test/Microsoft.DotNet.PackageInstall.Tests/EndToEndToolTests.cs @@ -565,8 +565,8 @@ static void EnsureToolSettingsFileUsesAnyTfmAndRid(string packagePath) static XElement GetToolSettingsFile(string packagePath) { using var zipArchive = ZipFile.OpenRead(packagePath); - var nuspecEntry = GetToolSettingsFileEntry(zipArchive); - var stream = nuspecEntry.Open(); + var toolSettingsEntry = GetToolSettingsFileEntry(zipArchive); + var stream = toolSettingsEntry.Open(); var xml = XDocument.Load(stream, LoadOptions.None); return xml.Root!; From be84adc9f99610f69455049183732f911be2cc79 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 1 Jul 2026 19:58:49 +0000 Subject: [PATCH 4/4] Simplify pack tool settings handling Co-authored-by: baronfel <573979+baronfel@users.noreply.github.com> --- .../targets/Microsoft.NET.PackTool.targets | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.PackTool.targets b/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.PackTool.targets index b483c7625ce5..8f6f6f14e137 100644 --- a/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.PackTool.targets +++ b/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.PackTool.targets @@ -186,7 +186,6 @@ NOTE: This file is imported from the following contexts, so be aware when writin Condition=" '$(PackAsTool)' == 'true' " Returns="@(TfmSpecificPackageFile)"> - <_GeneratedFiles Include="$(_ToolsSettingsFilePath)"/>