Fix TaskHostTask to pass request-level global properties to TaskHost#13443
Conversation
When -mt mode routes tasks to an out-of-process TaskHost, the TaskHostTask was sending BuildParameters.GlobalProperties (build-level) to the TaskHostConfiguration. These build-level properties do not include per-request properties like MSBuildRestoreSessionId that are added by ExecuteRestore(). This caused NuGet's RestoreTaskEx (which lacks MSBuildMultiThreadableTaskAttribute and thus gets routed to TaskHost in -mt mode) to receive empty MSBuildRestoreSessionId via IBuildEngine6.GetGlobalProperties(). The NuGet static graph restore then excluded conditional ProjectReference items that depend on MSBuildRestoreSessionId, breaking restore for projects like externals.csproj in dotnet/runtime. The fix uses BuildEngine.GetGlobalProperties() (which returns the correct request-level properties from RequestConfiguration) instead of BuildParameters.GlobalProperties, with a fallback to the old behavior if IBuildEngine6 is not available. Fixes dotnet#13153 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
JanProvaznik
left a comment
There was a problem hiding this comment.
24-Dimension MSBuild Code Review
Verdict: COMMENT — approve after addressing test coverage; comparer fix is nice-to-have.
The fix is well-targeted and correct. TaskHostTask.Execute() was sending build-level BuildParameters.GlobalProperties instead of request-level properties from RequestConfiguration, causing MSBuildRestoreSessionId to be missing in -mt mode.
Findings
| Severity | Finding |
|---|---|
| 🔴 MAJOR | No regression test for MT + request-level global properties scenario |
| 🟠 MODERATE | Fallback path (line 437) uses case-sensitive comparer instead of OrdinalIgnoreCase |
| 🟡 NIT | Silent fallback should log a diagnostic message |
24-Dimension Checklist
All 24 dimensions pass except:
- Test Coverage (🔴) — No test for the fixed scenario
- String Comparison (🟠) — Fallback comparer inconsistency
- Logging (🟡) — Silent fallback
See inline comments for details.
16a88e8 to
36a130e
Compare
- Gate the fix behind ChangeWave 18.6 so users can opt out via
MSBUILDDISABLEFEATURESFROMVERSION=18.6 to get the old behavior
(build-level BuildParameters.GlobalProperties) exactly as before
- Remove dead IBuildEngine6 fallback path — BuildEngine is always a
TaskHost implementing IBuildEngine6 in this context
- Add GetGlobalPropertiesTask helper and two regression tests:
- GlobalProperties_ForwardedToAutoEjectedTaskInMultiThreadedMode
verifies request-level properties reach auto-ejected tasks (dotnet#13153)
- GlobalProperties_UseBuildLevelWhenChangeWaveDisabled verifies
the old behavior is preserved when the wave is opted out
- Document the change in ChangeWaves.md under 18.6
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
36a130e to
20c08c1
Compare
- Gate the fix behind ChangeWave 18.6 so users can opt out via
MSBUILDDISABLEFEATURESFROMVERSION=18.6 to get the old behavior
(build-level BuildParameters.GlobalProperties) exactly as before
- Remove dead IBuildEngine6 fallback path — BuildEngine is always a
TaskHost implementing IBuildEngine6 in this context
- Add GetGlobalPropertiesTask helper and two regression tests:
- GlobalProperties_ForwardedToAutoEjectedTaskInMultiThreadedMode
verifies request-level properties reach auto-ejected tasks (dotnet#13153)
- GlobalProperties_UseBuildLevelWhenChangeWaveDisabled verifies
the old behavior is preserved when the wave is opted out
- Document the change in ChangeWaves.md under 18.6
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
validation on runtime running https://dev.azure.com/dnceng-public/public/_build?definitionId=334 |
120070c to
cccae85
Compare
With the TaskHostTask fix, runtime builds successfully with -mt mode. Remove it from MSBuildMTExcludedReposOverride so VMR validation exercises runtime with -mt enabled. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
cccae85 to
e3ab1b4
Compare
AR-May
left a comment
There was a problem hiding this comment.
LGTM, but I’d like to double‑check with @rainersigwald in case there are any hidden issues with fixing this behavior.
rainersigwald
left a comment
There was a problem hiding this comment.
One thing I'd like to understand: how did this not break the MSBuild repo? we use static graph restore
|
It didn't break other stuff such as msbuild because it does not use this pattern: |
…otnet#13443) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Summary
Fixes #13153 — -mt mode breaks NuGet static graph restore for conditional ProjectReference items that depend on MSBuildRestoreSessionId.
Root Cause
When -mt mode routes tasks to an out-of-process TaskHost (via TaskRouter.NeedsTaskHostInMultiThreadedMode()), TaskHostTask.Execute() was sending BuildParameters.GlobalProperties (build-level) to the TaskHostConfiguration. These build-level properties do not include per-request properties like MSBuildRestoreSessionId that are added by ExecuteRestore() in XMake.cs.
This caused NuGet's RestoreTaskEx (which lacks MSBuildMultiThreadableTaskAttribute and thus gets routed to TaskHost in -mt mode) to receive an empty MSBuildRestoreSessionId via IBuildEngine6.GetGlobalProperties(). The NuGet static graph restore then excluded conditional ProjectReference items, breaking restore for projects like �xternals.csproj in dotnet/runtime.
Without -mt: TaskHost.GetGlobalProperties() returns _requestEntry.RequestConfiguration.GlobalProperties → ✅ includes MSBuildRestoreSessionId
With -mt: OutOfProcTaskHostNode.GetGlobalProperties() returns _currentConfiguration.GlobalProperties (from TaskHostConfiguration) → ❌ only has build-level properties from BuildParameters.GlobalProperties
Fix
New method
GetGlobalPropertiesForTaskHost()in TaskHostTask that:BuildEngine.GetGlobalProperties()viaIBuildEngine6(returns correct request-level properties from RequestConfiguration)BuildParameters.GlobalPropertiesifIBuildEngine6is not availablenet10.0andnet472targetsValidation
-mt -m -restoreusing fixed MSBuildexternals.csprojcorrectly restored (was excluded before fix)-mtin command line,MSBuildRestoreSessionIdset with GUID,RestoreUseStaticGraphEvaluation=true,RestoreTaskExexecuted