Skip to content

Put package assets in TFM-specific folder#58995

Open
wtgodbe wants to merge 3 commits intomainfrom
wtgodbe/BuildFolder
Open

Put package assets in TFM-specific folder#58995
wtgodbe wants to merge 3 commits intomainfrom
wtgodbe/BuildFolder

Conversation

@wtgodbe
Copy link
Copy Markdown
Member

@wtgodbe wtgodbe commented Nov 15, 2024

Fixes #58990
Related: NuGet/Home#6932

When a package has a build or buildmultitargeting folder without a TFM subfolder, NuGet considers it to be compatible with any TFM. This is causing builds that should be failing with restore errors, to instead later hit a less helpful runtime error.

@ghost ghost added the area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates label Nov 15, 2024
@wtgodbe
Copy link
Copy Markdown
Member Author

wtgodbe commented Nov 15, 2024

@wtgodbe wtgodbe mentioned this pull request Nov 15, 2024
1 task
@adityamandaleeka
Copy link
Copy Markdown
Member

Thanks for reporting this @loganmj and thanks @BrennanConroy and @wtgodbe for the quick investigation/fix!

Copy link
Copy Markdown
Contributor

@captainsafia captainsafia left a comment

Choose a reason for hiding this comment

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

Does ApiDescription.Server need a similar treatment?

@wtgodbe
Copy link
Copy Markdown
Member Author

wtgodbe commented Nov 19, 2024

Does ApiDescription.Server need a similar treatment?

It does, nice catch. Plus I need to fix up Microsoft.AspNetCore.Identity.UI. Will do that today

@wtgodbe
Copy link
Copy Markdown
Member Author

wtgodbe commented Nov 19, 2024

Actually, not sure if we can fix APIDescription.Server since it targets netcoreapp2.1, $(DefaultNetCoreTargetFramework), and $(DefaultNetFxTargetFramework), and the files in build/buildMultiTargeting are meant to be used on any of those. @ericstj how has dotnet/runtime solved similar problems (packages with non-TFM'd build folders are considered compatible with any TFM by nuget)

@ericstj
Copy link
Copy Markdown
Member

ericstj commented Nov 19, 2024

We make sure to use TFMs with all assets, including build, buildTransitive.

I don't think an of our packages use buildMultiTargeting -- I can see why you can't use a framework folder there since it's part of the outer build. I think in that case you'd want to make sure your targets raised the appropriate Diagnostics when used in an unsupported project type.

@dotnet-policy-service
Copy link
Copy Markdown
Contributor

Looks like this PR hasn't been active for some time and the codebase could have been changed in the meantime.
To make sure no conflicting changes have occurred, please rerun validation before merging. You can do this by leaving an /azp run comment here (requires commit rights), or by simply closing and reopening.

@dotnet-policy-service dotnet-policy-service Bot added the pending-ci-rerun When assigned to a PR indicates that the CI checks should be rerun label Nov 27, 2024
Copilot AI review requested due to automatic review settings April 30, 2026 18:11
Copy link
Copy Markdown
Contributor

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

Updates NuGet packaging layout so MSBuild build / buildMultiTargeting / buildTransitive assets are placed under TFM-specific subfolders, preventing NuGet from treating them as compatible with any target framework and improving failure behavior for incompatible TFMs.

Changes:

  • Move package build and buildMultiTargeting assets into TFM-specific folders in the ApiDescription.Client nuspec.
  • Pack MSBuild targets/props into build/<tfm>, buildMultiTargeting/<tfm>, and/or buildTransitive/<tfm> across several projects (SpaProxy, Identity.UI, JsonTranscoding, WebView).
  • Update Identity.UI forwarding .targets imports (currently with wildcard paths).

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/Tools/Extensions.ApiDescription.Client/src/Microsoft.Extensions.ApiDescription.Client.nuspec Moves build assets under build/netstandard2.0 and buildMultiTargeting/netstandard2.0.
src/Middleware/Spa/SpaProxy/src/Microsoft.AspNetCore.SpaProxy.csproj Packs SpaProxy targets into build/<tfm>/ to restrict applicability by TFM.
src/Identity/UI/src/buildTransitive/Microsoft.AspNetCore.Identity.UI.targets Adjusts forwarding import to locate build targets under the new layout.
src/Identity/UI/src/buildMultiTargeting/Microsoft.AspNetCore.Identity.UI.targets Adjusts forwarding import to locate buildTransitive targets under the new layout.
src/Identity/UI/src/Microsoft.AspNetCore.Identity.UI.csproj Packs build assets into build* /<tfm>/ folders.
src/Grpc/JsonTranscoding/src/Microsoft.AspNetCore.Grpc.JsonTranscoding/Microsoft.AspNetCore.Grpc.JsonTranscoding.csproj Packs build targets into build/<tfm> and buildTransitive/<tfm>.
src/Components/WebView/WebView/src/Microsoft.AspNetCore.Components.WebView.csproj Packs build props into build* /<tfm>/ folders.

Comment thread src/Identity/UI/src/buildTransitive/Microsoft.AspNetCore.Identity.UI.targets Outdated
Comment thread src/Identity/UI/src/buildMultiTargeting/Microsoft.AspNetCore.Identity.UI.targets Outdated
@wtgodbe wtgodbe force-pushed the wtgodbe/BuildFolder branch 2 times, most recently from a5f0362 to fddde2a Compare April 30, 2026 18:46
@wtgodbe wtgodbe requested review from Copilot and removed request for mgravell April 30, 2026 18:47
Copy link
Copy Markdown
Contributor

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 updates several ASP.NET Core packages to place build/, buildMultiTargeting/, and buildTransitive/ assets under TFM-specific subfolders so NuGet doesn’t treat them as universally compatible, improving restore-time diagnostics and avoiding later runtime failures.

Changes:

  • Pack MSBuild assets into build/<tfm>/, buildMultiTargeting/<tfm>/, and buildTransitive/<tfm>/ folders.
  • Update MSBuild imports/relative paths inside props/targets to account for the new folder depth.
  • Adjust nuspec/csproj packing rules for affected packages (SpaProxy, Identity UI, WebView, gRPC JSON transcoding, ApiDescription client).

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
src/Tools/Extensions.ApiDescription.Client/src/buildMultiTargeting/Microsoft.Extensions.ApiDescription.Client.props Updates import to point at build/netstandard2.0/ from a TFM-scoped buildMultiTargeting/ folder.
src/Tools/Extensions.ApiDescription.Client/src/build/Microsoft.Extensions.ApiDescription.Client.props Fixes relative path to the tasks assembly after moving props under build/<tfm>/.
src/Tools/Extensions.ApiDescription.Client/src/Microsoft.Extensions.ApiDescription.Client.nuspec Packs build/ and buildMultiTargeting/ assets into */netstandard2.0 subfolders.
src/Middleware/Spa/SpaProxy/src/Microsoft.AspNetCore.SpaProxy.csproj Packs the SpaProxy targets file into build/$(DefaultNetCoreTargetFramework)/.
src/Identity/UI/src/buildTransitive/Microsoft.AspNetCore.Identity.UI.targets Adjusts import path for new buildTransitive/<tfm>/ layout.
src/Identity/UI/src/buildMultiTargeting/Microsoft.AspNetCore.Identity.UI.targets Adjusts import path for new buildMultiTargeting/<tfm>/ layout.
src/Identity/UI/src/Microsoft.AspNetCore.Identity.UI.csproj Packs build* assets under TFM-specific directories.
src/Grpc/JsonTranscoding/src/Microsoft.AspNetCore.Grpc.JsonTranscoding/build/Microsoft.AspNetCore.Grpc.JsonTranscoding.targets Fixes content/protos path after targets move under build/<tfm>/.
src/Grpc/JsonTranscoding/src/Microsoft.AspNetCore.Grpc.JsonTranscoding/Microsoft.AspNetCore.Grpc.JsonTranscoding.csproj Packs the targets file into build/<tfm> and buildTransitive/<tfm>.
src/Components/WebView/WebView/src/buildTransitive/Microsoft.AspNetCore.Components.WebView.props Adjusts import path for new buildTransitive/<tfm>/ layout.
src/Components/WebView/WebView/src/buildMultiTargeting/Microsoft.AspNetCore.Components.WebView.props Adjusts import path for new buildMultiTargeting/<tfm>/ layout.
src/Components/WebView/WebView/src/Microsoft.AspNetCore.Components.WebView.csproj Packs WebView props into TFM-specific build* directories.

Comment on lines +2 to +3
<!-- Packed at buildMultiTargeting/<tfm>/. Navigate to package root then into build/<tfm>/. -->
<Import Project="$(MSBuildThisFileDirectory)..\..\build\$(TargetFramework)\Microsoft.AspNetCore.Components.WebView.props"/>
<Project>
<Import Project="$(MSBuildThisFileDirectory)..\build\Microsoft.AspNetCore.Identity.UI.targets"/>
<!-- Packed at buildTransitive/<tfm>/. Navigate to package root (../..) then into build/<tfm>/. -->
<Import Project="$(MSBuildThisFileDirectory)..\..\build\$(TargetFramework)\Microsoft.AspNetCore.Identity.UI.targets"/>
Comment on lines +2 to +3
<!-- Packed at buildMultiTargeting/<tfm>/. Navigate to package root then into buildTransitive/<tfm>/. -->
<Import Project="$(MSBuildThisFileDirectory)..\..\buildTransitive\$(TargetFramework)\Microsoft.AspNetCore.Identity.UI.targets"/>
<None Include="build\Microsoft.AspNetCore.Components.WebView.props" Pack="true" PackagePath="%(Identity)" />
<None Include="buildTransitive\Microsoft.AspNetCore.Components.WebView.props" Pack="true" PackagePath="buildTransitive\$(DefaultNetCoreTargetFramework)\" />
<None Include="buildMultiTargeting\Microsoft.AspNetCore.Components.WebView.props" Pack="true" PackagePath="buildMultiTargeting\$(DefaultNetCoreTargetFramework)\" />
<None Include="build\Microsoft.AspNetCore.Components.WebView.props" Pack="true" PackagePath="build\$(DefaultNetCoreTargetFramework)\" />
Comment on lines +31 to +33
<None Include="build\*" Pack="true" PackagePath="build\$(DefaultNetCoreTargetFramework)\" />
<None Include="buildMultiTargeting\*" Pack="true" PackagePath="buildMultiTargeting\$(DefaultNetCoreTargetFramework)\" />
<None Include="buildTransitive\*" Pack="true" PackagePath="buildTransitive\$(DefaultNetCoreTargetFramework)\" />
Comment on lines +2 to +3
<!-- Packed at buildTransitive/<tfm>/. Navigate to package root then into build/<tfm>/. -->
<Import Project="$(MSBuildThisFileDirectory)..\..\build\$(TargetFramework)\Microsoft.AspNetCore.Components.WebView.props"/>
@wtgodbe wtgodbe force-pushed the wtgodbe/BuildFolder branch 5 times, most recently from 6ea5556 to fa48094 Compare April 30, 2026 21:57
@wtgodbe wtgodbe force-pushed the wtgodbe/BuildFolder branch 2 times, most recently from 421e85e to c68d717 Compare May 1, 2026 15:02
@wtgodbe wtgodbe requested a review from a team as a code owner May 1, 2026 15:02
@wtgodbe wtgodbe force-pushed the wtgodbe/BuildFolder branch from c68d717 to 421e85e Compare May 1, 2026 15:02
When a package has a build/ or buildMultiTargeting/ folder without a
TFM subfolder, NuGet considers it compatible with any TFM. This causes
builds that should fail at restore to instead hit confusing runtime
errors.

Change PackagePath in csproj/nuspec to pack build assets into TFM
subfolders (e.g., build/net11.0/ instead of build/). The source files
themselves keep their original relative paths — NuGet resolves the
TFM subfolder at restore time, and the relative directory structure
within the package mirrors the source layout.

Affected packages:
- Microsoft.AspNetCore.SpaProxy
- Microsoft.AspNetCore.Identity.UI
- Microsoft.AspNetCore.Components.WebView
- Microsoft.AspNetCore.Grpc.JsonTranscoding
- Microsoft.Extensions.ApiDescription.Client

Fixes #58990

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@wtgodbe wtgodbe force-pushed the wtgodbe/BuildFolder branch from 421e85e to b3d1eb6 Compare May 1, 2026 15:03
wtgodbe and others added 2 commits May 1, 2026 10:00
The generated V4/V5 targets reference static web assets via relative
paths from the targets file location. Since the targets are now at
build/<tfm>/, the assets need to be there too. Update PackagePathPrefix
and PathPrefix to place assets at build/<tfm>/staticwebassets/V4|V5/
so they remain siblings of the targets file.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Identity.UI uses the SDK's static web assets pipeline which generates
build/ targets with hardcoded relative paths (../staticwebassets/) to
the asset directory. Moving targets to build/<tfm>/ breaks these paths
and there's no way to override the depth computation in the SDK.

Other packages in the ecosystem all use flat build/ for static web
assets. Revert Identity.UI to match.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates pending-ci-rerun When assigned to a PR indicates that the CI checks should be rerun

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Errors after updating packages

6 participants