Skip to content

Enable MSBuild server by default in MSBuildForwardingApp#55231

Draft
JanProvaznik wants to merge 2 commits into
dotnet:mainfrom
JanProvaznik:janprovaznik/msbuild-server-default-on
Draft

Enable MSBuild server by default in MSBuildForwardingApp#55231
JanProvaznik wants to merge 2 commits into
dotnet:mainfrom
JanProvaznik:janprovaznik/msbuild-server-default-on

Conversation

@JanProvaznik

@JanProvaznik JanProvaznik commented Jul 10, 2026

Copy link
Copy Markdown
Member

Summary

  1. in MSBuild server dogfooding and release plan msbuild#14311
    Makes the MSBuild server enabled by default in MSBuildForwardingApp. When the user hasn't specified anything about the MSBuild server, it is now turned on.

Changes

  • DOTNET_CLI_USE_MSBUILD_SERVER now defaults to true (was false).
  • MSBUILDUSESERVER=1 is only forced on when the user hasn't already set MSBUILDUSESERVER themselves, so an explicit opt-out (MSBUILDUSESERVER=0) or DOTNET_CLI_USE_MSBUILD_SERVER=false is still respected.
  • Added ItEnablesMSBuildServerByDefault test verifying the default-on behavior.

Behavior change

⚠️ This is a user-visible behavior change: the MSBuild server is now on by default. Opt out via DOTNET_CLI_USE_MSBUILD_SERVER=false or MSBUILDUSESERVER=0.

Testing

Ran GivenMsbuildForwardingApp locally against a full Debug build; the new test passes and existing server-related tests pass.

Change DOTNET_CLI_USE_MSBUILD_SERVER to default to true so the MSBuild server is enabled when the user hasn't specified anything about it. An explicit MSBUILDUSESERVER value (or DOTNET_CLI_USE_MSBUILD_SERVER=false) is still respected as an opt-out.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 499249b7-514f-4ecf-88bc-2466455069c5
@JanProvaznik

Copy link
Copy Markdown
Member Author

Test failure analysis: real bug, already fixed upstream, blocked on an MSBuild version lag

The CI test failures on this PR (e.g. Microsoft.TemplateEngine.Authoring.Tasks.IntegrationTests LocalizeTemplateTests / ValidateTemplatesTests, plus dotnet-watch.Tests) are real, not flaky, and are a direct consequence of enabling the MSBuild server by default in MSBuildForwardingAppWithoutLogging.

Root cause

With MSBUILDUSESERVER=1, TerminalLogger auto-detection runs in the persistent server node and inspects the node's stdout instead of the client's. When the client's stdout is redirected (as it is when tests capture dotnet build output), the server still emits terminal-logger ANSI output. So assertions like HaveStdOutContaining("Build FAILED.") fail because the output is the TL-formatted failed with 1 error(s) instead of the classic console-logger Build FAILED..

This is exactly dotnet/msbuild#14077 ("Fix TerminalLogger auto-detection under MSBuild Server", fixes dotnet/msbuild#13940), merged 2026-06-17, which explicitly calls out the Windows > file.txt (redirected) case.

Reproduction (pure CLI, no test harness)

Using the SDK built from this branch, a redirected dotnet build of a failing project:

Scenario Exit ANSI codes Build FAILED.
MSBUILDUSESERVER=0 (server off) 1 No Yes
server on (this PR's default) 1 Yes No

Deterministic, reproduces without any test framework. Verified end-to-end that the daily .NET 11 SDK (11.0.100-preview.7.26360.102, MSBuild 18.10.0-1.26360.102, post-#14077) makes server-on behave identically to server-off (plain output, no ANSI) — so the fix resolves it.

Why CI still fails (the blocker)

The SDK builds against / redistributes MSBuild via MicrosoftBuildVersion, which resolves from eng/Version.Details.props:

MicrosoftBuildPackageVersion = 18.9.0-preview-26311-113

That MSBuild is source-dated 2026-06-11 — six days before the fix. Note this is out of sync with eng/Version.Details.xml, which was VMR-source-updated to Microsoft.Build 18.9.0-preview-26325-102 (2026-06-25, which does contain #14077). Both files are identical on origin/main, so this is not a stale-branch issue on my side — main's redistributed MSBuild simply predates the fix.

What would unblock it

The SDK needs a post-#14077 MSBuild (>= 18.9.0-preview-26325-102; confirmed the fix is present in 26325 and daily 26360). Either wait for the dependency flow that bumps MicrosoftBuildPackageVersion in eng/Version.Details.props, or bump it manually as part of this PR.

Happy to do whichever the maintainers prefer.

…ild#14077)

The SDK redistributed MSBuild 18.9.0-preview-26311-113 (source-dated 2026-06-11), which predates the TerminalLogger-under-MSBuild-Server fix (dotnet/msbuild#14077, merged 2026-06-17). With the server enabled by default, that bug caused integration tests capturing 'dotnet build' output to fail. Version.Details.props lagged behind Version.Details.xml (already at 26325-102); this aligns them.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 499249b7-514f-4ecf-88bc-2466455069c5
@JanProvaznik

Copy link
Copy Markdown
Member Author

Update: MSBuild bump to 26325 fixed the Windows TL failures; residual failures are a separate Unix server bug

Pushed 31ecd76 bumping the redistributed MSBuild to 18.9.0-preview-26325-102 (which contains dotnet/msbuild#14077). Result on the next CI run (build 1503449): failed work items went 7 → 3, and all Windows legs are now green (TestBuild: windows 214/214, FullFramework: windows 152/152) — confirming the TerminalLogger-under-server fix resolves the Windows failures.

Remaining 3 failures (all Unix)

Test OS Symptom Verdict
TemplateEngine.Authoring.Tasks…CanRunValidateTask_OnInfo linux dotnet build prints Build succeeded. 0 Error(s) but returns exit code 1 real — Unix server bug
dotnet-watch…EvaluationTests.ProjectReferences_OneLevel macOS dotnet msbuild /t:GenerateWatchList restores successfully (no errors) but the process exits with code 1, so watch reports "Error(s) finding watch items" and targetsResult is null real — same Unix server bug
dotnet.Tests…ItReturnsNullWhenCommandNameDoesNotExistInProjectTools linux pure unit test (CommandResolver.Resolve), no MSBuild/server involved unrelated flake (0.06%)

The first two are the same root cause, and it is not the TerminalLogger bug: with the server enabled on Unix, an MSBuild invocation that succeeds (0 errors, Build succeeded.) intermittently returns exit code 1. It hit a different test each run (previously CanRunTask, now CanRunValidateTask_OnInfo), which points to an intermittent exit-code race in the server node on Unix rather than a deterministic failure. I could not find an existing MSBuild fix for it, and it reproduces only on Unix (I'm on Windows, so I can't repro/fix it locally).

Net

  • Windows: green with MSBuild ≥ 26325.
  • Unix: blocked on a separate, still-unfixed MSBuild-server "exit code 1 on successful build" issue that enabling the server by default surfaces.

This looks like it needs an upstream MSBuild fix (or confirmation that these are acceptable/known-flaky) before the server can be defaulted on for Unix. Flagging for maintainer guidance.

@JanProvaznik

Copy link
Copy Markdown
Member Author

Local repro investigation of the residual Unix failures (WSL Ubuntu 24.04)

To determine whether a newer MSBuild would fix the two Unix "exit code 1 on a successful build" failures, I tried to reproduce them locally with the exact SDK CI uses (11.0.100-preview.7.26325.102, MSBuild 18.9.0-preview-26325-102) and the daily (26360, MSBuild 18.10.0):

  • Sequential dotnet build of a message-logging succeeding project under the server: 0 failures.
  • Concurrent (8×6) dotnet build under the shared server: 0 failures.
  • Faithful replication of the dotnet-watch invocation (dotnet msbuild /restore /t:GenerateWatchList /p:DesignTimeBuild=true with the real DotNetWatch.targets + DotNetWatchTasks.dll, 2-project reference graph), sequential and concurrent, on 26325: 0 failures in 130+ invocations.

So the exit-code race is rare and timing/parallelism-dependent — it did not reproduce once locally, yet CI hits ~1 test per run (a different test each time). I therefore can't confirm locally whether bumping MSBuild further (e.g. to 18.10.0-1.26360.102) fixes it, and a 18.9→18.10 skew against the rest of the 26325 dependency set carries its own risk, so I did not make that change.

Summary for maintainers

  • The 26325 MSBuild bump fixes the deterministic Windows TerminalLogger failures (Windows now green).
  • The remaining Unix failures are a rare, intermittent MSBuild-server "exit code 1 on success" race (CanRunValidateTask_OnInfo, dotnet-watch ProjectReferences_OneLevel), plus one unrelated flaky unit test (ItReturnsNullWhenCommandNameDoesNotExistInProjectTools, no MSBuild involved).
  • These look like an upstream MSBuild-server correctness issue surfaced by defaulting the server on, rather than anything fixable in the SDK. Guidance welcome on whether to (a) pursue an upstream fix, (b) treat as known-flaky, or (c) gate the default differently.

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.

1 participant