[vs17.14] Redistribute net472 dotnet/runtime 10.0.8 servicing wave (Nrbf + HashCode 6.0) - #14127
Conversation
…rbf + HashCode 6.0) Redistribute the net472 dotnet/runtime 10.0.8 servicing wave to line up with the corresponding VS servicing event, without changing what MSBuild compiles or declares against. net472 downloads the 10.0.8 packages and swaps the copy-local assemblies into the application output after RAR, with matching binding redirects. - eng/Versions.props: introduce RuntimePackageVersion_CompileTime (9.0.0) and RuntimePackageVersion_VSDeploy (10.0.8); document the compile-vs-deploy split. - src/Directory.Build.targets: add ReplaceRuntimeAssembliesWithServicingVersions target gated on DeployRuntimeServicingAssemblies for net472. - src/MSBuild/MSBuild.csproj, src/MSBuild.Bootstrap/MSBuild.Bootstrap.csproj: opt in via DeployRuntimeServicingAssemblies. - src/MSBuild/app.config and app.amd64.config: binding redirects to the deployed assembly versions (10.0.0.8, Microsoft.Bcl.HashCode 6.0.0.0, System.Memory 4.0.5.0, System.Runtime.CompilerServices.Unsafe 6.0.3.0, System.Threading.Tasks.Extensions 4.2.4.0, System.Buffers 4.0.5.0, System.Numerics.Vectors 4.1.6.0). - src/Tasks/System.Resources.Extensions.pkgdef: redirect 10.0.0.3 -> 10.0.0.8. Ports internal PR DevDiv/DotNet-msbuild-Trusted!751025. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR updates the net472 build output to redistribute newer dotnet/runtime servicing assemblies (10.0.8 wave) while keeping compile/restore references pinned to the existing versions, aligning MSBuild’s VS-loaded net472 runtime surface with a VS servicing event via post-RAR assembly swapping + binding redirects.
Changes:
- Split runtime package versions into compile-time vs VS-deploy-time (
RuntimePackageVersion_CompileTimevsRuntimePackageVersion_VSDeploy) and bumpedVersionPrefix. - Added a net472-only, opt-in target to download and swap copy-local runtime assemblies after RAR, plus suppress the expected MSB3277 version-conflict warning.
- Updated net472 binding redirects (and pkgdef redirection) to match the deployed assembly versions; opted MSBuild.exe and bootstrap outputs into redistribution.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| eng/Versions.props | Introduces compile-vs-deploy runtime version split and documents the rationale; bumps VersionPrefix. |
| src/Directory.Build.targets | Adds the net472 servicing redistribution mechanism (package downloads + post-RAR swap + warning suppression). |
| src/MSBuild/MSBuild.csproj | Opts the VS-loaded MSBuild.exe output into deploying servicing assemblies. |
| src/MSBuild.Bootstrap/MSBuild.Bootstrap.csproj | Opts bootstrap MSBuild output into deploying servicing assemblies (tests surface). |
| src/MSBuild/app.config | Updates binding redirects to the deployed servicing assembly versions (net472). |
| src/MSBuild/app.amd64.config | Updates binding redirects + codeBase versions to the deployed servicing assembly versions (net472 x64/arm64 config). |
| src/Tasks/System.Resources.Extensions.pkgdef | Updates VS registry binding redirection for System.Resources.Extensions to 10.0.0.8. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Code Review — 24-dimension analysis
| # | Dimension | Verdict |
|---|---|---|
| 6 | Logging & Diagnostics | 🟡 1 NIT |
✅ 23/24 dimensions clean — one NIT noted inline.
- Logging —
ReplaceRuntimeAssembliesWithServicingVersionshas no output at default verbosity; suggest a<Message Importance="Normal">for observability.
Highlights from the clean dimensions:
- Backwards Compatibility: Binding redirects widening from 9.x→10.x are backed by dotnet/runtime's servicing compatibility guarantees. No customer-visible breakage.
- Cross-Platform: The backslash paths in
DeployedPathare correctly gated —net472only appears inRuntimeOutputTargetFrameworkswhen$([MSBuild]::IsOSPlatform('windows'))is true, so the paths never evaluate on Linux/macOS. - Correctness: The
Remove/Includeswap logic is sound. The;-bracketing pattern on_DeployedRuntimeAssemblyIdscorrectly prevents false substring matches. The%(Identity)==%(NuGetPackageId)assumption holds for every listed package. - Dependency Management: The two new redirects (
System.Configuration.ConfigurationManager,System.Threading.Channels) are correctly added to bothapp.configandapp.amd64.configand close a pre-existing gap. - SDK Integration:
PackageDownloaditems in a top-levelItemGroup(conditioned onTargetFramework == 'net472') are collected on the correct per-TF restore pass; no phase-boundary violation. - Build Infrastructure: The manual
eng/Versions.propsedit is justified — the port of DevDiv/DotNet-msbuild-Trusted!751025 with an explicit compile-vs-deploy split rationale satisfies the Darc justification requirement for a servicing branch.
Generated by Expert Code Review (on open) for issue #14127 · 2.6K AIC · ⊞ 30K ambient context
Test projects that re-bundle MSBuild.exe (via ProjectReference to MSBuild.csproj) copy the servicing MSBuild.exe.config but resolve their own copy-local runtime assemblies at the compiled-against versions. The redirects then point at servicing versions (e.g. System.Memory 4.0.5.0) while the on-disk assembly is the compiled-against one (4.0.2.0), so the copied MSBuild.exe fails to start with a TypeInitializationException/FileLoadException. This broke every net472 out-of-proc test and hung tests waiting on a spawned node/server until the CI timeout. Add an AfterTargets="Build" target (net472, non-deploy projects only) that realigns the copied MSBuild.exe.config binding redirects to the runtime assemblies actually present next to it, keeping those bins self-consistent at the compiled-against versions. Deploy surfaces (MSBuild.exe, bootstrap) are excluded since their output already is the servicing build. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Previously the realign target ran for any net472 project without DeployRuntimeServicingAssemblies, which also matched non-test projects that bundle MSBuild.exe for shipping (e.g. the VS.ExternalAPIs.MSBuild / DevDivPackage insertion package). It was harmless today only because that nuspec does not ship MSBuild.exe.config. Make it an explicit opt-in ($(RealignBundledMSBuildExeConfig)) defaulted on only for $(IsTestProject) == 'true', so the copied config is realigned exclusively in test bins and shipping/insertion projects are never touched. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… exe.config Replace the previous approach (rewriting the bundled MSBuild.exe.config binding redirects down to the compiled-against versions) with deploying the servicing assemblies into the test bins, as preferred in review. Test projects that bundle MSBuild.exe and spawn it out-of-proc (Engine, CommandLine, Tasks, Utilities UnitTests) now set DeployRuntimeServicingAssemblies=true, just like MSBuild.csproj and the bootstrap. Their net472 output then carries the servicing runtime assemblies that the copied servicing app.config binding redirects point at, so the bundled MSBuild.exe starts correctly instead of failing with a FileLoadException. Removes the AlignBindingRedirectsToOutputAssemblies task/target added previously. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
JanProvaznik
left a comment
There was a problem hiding this comment.
i approve of the latest commit but can't approve my own PR
Fixes #14404 ## Context `MSBuild.exe.config` redirects `System.Configuration.ConfigurationManager` to `10.0.0.8`, and the amd64/arm64 config adds a `codeBase` pointing at `MSBuild\Current\Bin\System.Configuration.ConfigurationManager.dll`. That assembly is not in `Microsoft.Build.vsix`, so an in-proc task that carries its own ConfigurationManager has its bind hijacked to a file that does not exist and fails with `FileNotFoundException`. Regression from #14127 (17.14.40 -> 17.14.51). The redirect is not needed by MSBuild. On .NET Framework the `System.Configuration.ConfigurationManager` reference assembly only type-forwards into the GAC's `System.Configuration`, so the shipped binaries reference `System.Configuration, Version=4.0.0.0` and never bind to the package assembly: ``` Microsoft.Build.dll -> System.Configuration 4.0.0.0 Microsoft.Build.Framework.dll -> (none) Microsoft.Build.Utilities.Core.dll -> (none) Microsoft.Build.Tasks.Core.dll -> (none) MSBuild.exe -> (none) System.Configuration.ConfigurationManager.dll -> System.Configuration 4.0.0.0 ``` This is the alternative to #14496, which instead added the missing assembly to the VSIX payload. ## Changes Made - Remove the `System.Configuration.ConfigurationManager` `dependentAssembly` entry from `src/MSBuild/app.config` and `src/MSBuild/app.amd64.config` (redirect + `codeBase`), leaving a comment explaining why there is none. - Bump the servicing version to 17.14.54. Task-local `System.Configuration.ConfigurationManager` binds now resolve the way they did before 17.14.51. ## Testing - `./build.cmd -v quiet /p:RunAnalyzers=false` — `ValidateMSBuildPackageDependencyVersions` passes for x86, x64 and arm64. The only failure is the pre-existing local-only arcade OptProf `GenerateTrainingInputFiles` error, which reproduces unchanged on the unmodified base commit. - Verified the generated `MSBuild.exe.config` for all three platforms no longer contains a ConfigurationManager `dependentAssembly` and that the generated `NuGetFrameworkWrapper.redirects.cs` (which mirrors these redirects into the task AppDomain config) no longer contains one either. --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 98ea148f-b805-4636-8f5a-48016ad923d5
Ports internal PR DevDiv/DotNet-msbuild-Trusted!751025 to GitHub, targeting
vs17.14.Summary
Redistribute the net472 dotnet/runtime 10.0.8 servicing wave (Nrbf +
Microsoft.Bcl.HashCode6.0) to line up with the corresponding VS servicing event, without changing what MSBuild compiles or declares against. For net472, the 10.0.8 packages are downloaded and the copy-local assemblies are swapped into the application output after RAR, with matching binding redirects.This mirrors the existing frozen-maintenance-package mechanism in reverse: compile/restore stay at the referenced versions (so there is no package downgrade and the .NET Core build does not pull in new source-build prebuilts), while net472 ships the newer servicing build.
Changes
RuntimePackageVersion_CompileTime(9.0.0) andRuntimePackageVersion_VSDeploy(10.0.8); document the compile-vs-deploy split.ReplaceRuntimeAssembliesWithServicingVersionstarget (gated onDeployRuntimeServicingAssembliesfor net472) plusPackageDownloadof the redistributed wave; suppress the intentional post-RAR MSB3277 version-conflict warning.DeployRuntimeServicingAssemblies.Microsoft.Bcl.HashCode6.0.0.0;System.Memory4.0.5.0;System.Runtime.CompilerServices.Unsafe6.0.3.0;System.Threading.Tasks.Extensions4.2.4.0;System.Buffers4.0.5.0;System.Numerics.Vectors4.1.6.0). Adds redirects forSystem.Configuration.ConfigurationManager/System.Threading.Channels.10.0.0.3->10.0.0.8.VersionPrefixbumped to 17.14.51.Verification (from the source PR)