Skip to content

Multi-RID tool packages usability tweaks #49288

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 33 commits into from
Jun 13, 2025

Conversation

baronfel
Copy link
Member

@baronfel baronfel commented Jun 7, 2025

This PR:

  • Migrates from an Item-based usage mode (<ToolPackageRuntimeIdentifier Include="linux-x64" Version="A.B.C" />) to a property-based usage mode (<ToolPackageRuntimeIdentifier>linux-x64</ToolPackageRuntimeIdentifier>).
    • This implies the removal of the Version from the RID-specific tool package configuration entries (the versions must always be aligned with the 'parent' RID-less package)
  • Simplifies some of the packaging of the Tool packages
  • Makes it so packaging the 'parent' package via dotnet pack triggers the packaging of the 'inner' per-RID packages as well
    • Caveat - this won't ever work if we're in AOT mode, so we don't do that for PublishAOT packages.

@Copilot Copilot AI review requested due to automatic review settings June 7, 2025 01:00
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adjusts the packaging mechanism for RID-specific tool packages by migrating from an item‐based to a property‐based usage mode, streamlining package creation for both parent and RID‐specific packages.

  • Migrates from using an Item-based RID specification with a Version attribute to a property-based configuration without a version.
  • Updates various build targets to correctly trigger and define inner and outer builds, including adjustments to packaging tasks and property conditions.
  • Removes legacy code (such as the version handling in tool package resolution and associated unit tests) to simplify the overall tool package design.

Reviewed Changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Sdk.targets Updates PackTool import condition to respect PackAsTool usage.
src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Sdk.Common.targets Adjusts condition to reference the new property ToolPackageRuntimeIdentifiers.
src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.PackTool.targets Refactors packaging targets to differentiate inner and outer builds and update package paths.
src/Tasks/Microsoft.NET.Build.Tasks/GenerateToolsSettingsFile.cs Removes version attribute assignment in RID package nodes.
src/Cli/dotnet/ToolPackage/ToolPackageDownloaderBase.cs Updates package version sourcing for installation and asset file creation.
src/Cli/dotnet/ToolPackage/ToolConfigurationDeserializer.cs Eliminates version information when creating PackageIdentity from RID-specific data.
src/Cli/dotnet/ToolPackage/ToolConfigurationDeserialization/DotNetCliToolRuntimeIdentifierPackage.cs Removes the Version attribute in favor of property-based configuration.
(Other files) Removal of legacy test and resolution files in-line with the new design.
Comments suppressed due to low confidence (3)

src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Sdk.Common.targets:57

  • Verify that the new property 'ToolPackageRuntimeIdentifiers' is correctly defined and consistently propagated across the targets to avoid mismatches with legacy item names.
<_ToolPackageType Condition="'$(RuntimeIdentifier)' != '' And '$(ToolPackageRuntimeIdentifiers)' != ''">DotnetToolRidPackage</_ToolPackageType>

src/Cli/dotnet/ToolPackage/ToolConfigurationDeserializer.cs:70

  • Ensure that all consumers of PackageIdentity are updated to handle a null version, as the version is now inherited from the parent package rather than being stored per RID-specific package.
var ridSpecificPackages = dotNetCliTool.RuntimeIdentifierPackages?.ToDictionary(p => p.RuntimeIdentifier, p => new PackageIdentity(p.Id, null))

src/Cli/dotnet/ToolPackage/ToolPackageDownloaderBase.cs:291

  • Confirm that the 'packageVersion' variable is correctly assigned before this check, as replacing resolvedPackage.Version could lead to unintended behavior if packageVersion is not properly derived.
if (!IsPackageInstalled(new PackageId(resolvedPackage.Id), packageVersion, packageDownloadDir.Value))

@baronfel baronfel requested a review from a team June 7, 2025 15:15
@baronfel baronfel requested a review from a team as a code owner June 7, 2025 15:28
@baronfel
Copy link
Member Author

baronfel commented Jun 8, 2025

All of the failing tests are around packaging the shims. After my changes the shims are getting the NuGetRecursiveDir metadata added onto them, which is causing them to be put into additional nested subfolders due to logic in the Pack targets:

NuGet.Build.Tasks.Pack.targets:

  <Target Name="_GetTfmSpecificContentForPackage"
          DependsOnTargets="$(TargetsForTfmSpecificContentInPackage)"
          Returns="@(TfmSpecificPackageFileWithRecursiveDir)">
    <!-- The below workaround needs to be done due to msbuild bug https://github.com/Microsoft/msbuild/issues/3121 -->
    <ItemGroup>
      <TfmSpecificPackageFileWithRecursiveDir Include="@(TfmSpecificPackageFile)">
        <NuGetRecursiveDir>%(TfmSpecificPackageFile.RecursiveDir)</NuGetRecursiveDir>
        <BuildAction>%(TfmSpecificPackageFile.BuildAction)</BuildAction>
      </TfmSpecificPackageFileWithRecursiveDir>
    </ItemGroup>
  </Target>

Bad item:
image

Leads to bad content:
image

@baronfel
Copy link
Member Author

baronfel commented Jun 8, 2025

I think I've got it - since NuGet forces the use of RecursiveDir if it's present, we just lean into that and don't try to be quite as precise with our PackagePath setting. I've pushed up a commit with comments and adjustments for that.

@baronfel
Copy link
Member Author

baronfel commented Jun 9, 2025

Alright - this is super close so is probably ok for review now. The only tests failing don't fail locally, and cover a pretty specific scenario: It_uses_customized_PackagedShimOutputRootDirectory.

@baronfel
Copy link
Member Author

Ok, I have added a test to cover the new multi-packaging feature, and have verified via binlogs locally that the shim output path stuff works. I want helix to try one more time to give me a binlog so I can see what's going on in the CI system, but then I want to skip those tests so we can get the good syntax in for p6.

@baronfel baronfel force-pushed the multi-rid-packages-tweaks branch from 2c15ee9 to 7b701ca Compare June 12, 2025 02:30
@baronfel
Copy link
Member Author

Ok we're good to go now! The test failures are watch and container timeouts, everything else is good.

@baronfel baronfel force-pushed the multi-rid-packages-tweaks branch from bbe108a to 75b4ee6 Compare June 12, 2025 18:36
Copy link
Member

@nagilson nagilson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another PR I wish I had more time to look over but I did what I could with the time we have :) I think using properties vs items is a great improvement and overall the change looks good. Kudos for the clever engineering here...

@baronfel
Copy link
Member Author

I've addressed @nagilson's feedback (thanks!) and this should be good to merge now.

@nagilson
Copy link
Member

mmmmm yes :shipit:

@baronfel
Copy link
Member Author

The only remaining failing test is the completions known issue. Let's merge!

@marcpopMSFT
Copy link
Member

Known completion test issue.

@marcpopMSFT marcpopMSFT merged commit d7a7d93 into dotnet:main Jun 13, 2025
27 of 30 checks passed
@baronfel baronfel deleted the multi-rid-packages-tweaks branch June 13, 2025 17:35
Copy link
Member

@dsplaisted dsplaisted left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@baronfel Late review question about having different versions for RID-specific packages.

@@ -67,7 +67,7 @@ public static ToolConfiguration Deserialize(string pathToXml, IFileSystem fileSy
dotNetCliTool.Commands[0].Runner));
}

var ridSpecificPackages = dotNetCliTool.RuntimeIdentifierPackages?.ToDictionary(p => p.RuntimeIdentifier, p => new PackageIdentity(p.Id, new NuGet.Versioning.NuGetVersion(p.Version)))
var ridSpecificPackages = dotNetCliTool.RuntimeIdentifierPackages?.ToDictionary(p => p.RuntimeIdentifier, p => new PackageIdentity(p.Id, null))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Late review: Does this now mean that it's not possible to have different versions for the RID-specific packages? I thought we weren't going to support different version numbers for package production, but we were still going to support consuming packages where the primary package has a different version from the RID-specific packages if someone creates packages like that through some other means.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct - I refactored that out in this pass. We could add it back (you're right that the production-side only supports making a single version across all tools), but I am not convinced that we'll ever actually see that scenario happen: IMO the only time you have separate packages being made now is related to AOT packaging, and even that should be really aligned version-wise.

akoeplinger added a commit that referenced this pull request Jul 18, 2025
…tory

Follow-up to #49801 and #49288

We were still seeing an error during publish, note the duplicate slashes:

```
error NETSDK1152: Found multiple publish output files with the same relative path: /__w/1/s/artifacts/bin/dotnet-dump/Debug/shims/net8.0/win-x64/dotnet-dump.exe, /__w/1/s/artifacts/bin/dotnet-dump/Debug//shims/net8.0/win-x64/dotnet-dump.exe, /__w/1/s/artifacts/bin/dotnet-dump/Debug/shims/net8.0/win-x86/dotnet-dump.exe, /__w/1/s/artifacts/bin/dotnet-dump/Debug//shims/net8.0/win-x86/dotnet-dump.exe, /__w/1/s/artifacts/bin/dotnet-dump/Debug/shims/net8.0/osx-x64/dotnet-dump
```

Use the [MSBuild]::NormalizePath property function instead of Path.Combine to get a canonicalized path that doesn't contain duplicate slashes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants