Skip to content

Promote MSBuild server out of Experimental namespace (#12099) - #13964

Merged
JanProvaznik merged 4 commits into
mainfrom
promote-msbuild-server-namespace
Jul 30, 2026
Merged

JanProvaznik merged 4 commits into
mainfrom
promote-msbuild-server-namespace

Conversation

@JanProvaznik

@JanProvaznik JanProvaznik commented Jun 5, 2026 •

Copy link
Copy Markdown
Member

Fixes #12099

Context

The MSBuild server public surface lived in Microsoft.Build.Experimental. If the server is to become a supported, on-by-default feature, these types should not be in the Experimental namespace. This moves them to a new dedicated Microsoft.Build.Server namespace.

This mirrors the ProjectCache promotion (#12051), but as a clean break (no obsolete shim types) because — unlike ProjectCache, which had external plugin assemblies compiled against the old namespace — research found no external consumers of the server types:

  • dotnet/sdk: 0 references
  • dotnet/roslyn: 0 references
  • org:dotnet code search: only dotnet/msbuild, the dotnet/dotnet VMR mirror, msbuild-api-docs, and source-build reference packages
  • VS (DevDiv/VS): no code consumers — only an ApiCompat backward-compatibility baseline lists these types
  • Within MSBuild: only internal consumers + unit tests

Changes

Moved to Microsoft.Build.Server:

  • MSBuildClient
  • MSBuildClientExitResult
  • MSBuildClientExitType
  • OutOfProcServerNode (incl. nested public delegate BuildCallback)

Updated internal consumers and tests:

  • BuildManager.cs, NodeProviderOutOfProcBase.cs (doc cref), MSBuildClientApp.cs, XMake.cs
  • MSBuildClient_Tests.cs, RedirectConsoleWriter_Tests.cs, MSBuildServer_Tests.cs

Compatibility:

  • src/Build/CompatibilitySuppressions.xml: added 16 CP0001 suppressions (4 removed types × {lib,ref} × {net472,net11.0}), auto-generated via ApiCompatGenerateSuppressionFile, with a comment noting they can be removed once the package-validation baseline advances past this change. Package validation reported only type-level CP0001 (no CP0002), confirming no other public API references these types in its signature.

Docs:

  • documentation/MSBuild-Server.md: noted that the public server entry points now live under Microsoft.Build.Server.

Breaking change

This is an intentional binary-breaking change to a previously Experimental surface (a namespace rename within the same assembly cannot be type-forwarded). It should be noted in release/breaking-change notes. api-docs and source-build reference packages regenerate automatically from the shipped assembly.

VS insertion coordination

The VS ApiCompat backward-compatibility test (microsoft.build-suppressions.xml) treats the shipped public surface as a contract and will flag the removed Microsoft.Build.Experimental.* server types. A matching VS-side suppressions update is required on insertion, mirroring how #12051 was coordinated.

Testing

  • Full build.cmd: 0 warnings, 0 errors
  • Package validation passes against baseline 18.10.0-1.26378.2 (regenerated for net11.0 after main moved off net10.0)
  • Targeted tests pass on net472 + net11.0: MSBuildClient unreachable-server fallback, RedirectConsoleWriter, and end-to-end CanShutdownServerProcess (real server start + shutdown via both BuildManager and MSBuildClient)

Out of scope (separate work)

  • Enabling the server by default (would need a Change Wave)
  • The Microsoft.Build.Experimental.FileAccess / BuildCheck / ProjectCache sub-namespaces

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

@JanProvaznik

JanProvaznik commented Jun 8, 2026 •

Copy link
Copy Markdown
Member Author

The restore task requiring the taskhost workaround is ship blocking... It regresses performance.
I'll keep this as draft for now, but I think breaking change of changing is ok given clear indication this is experimental and no known users

Move MSBuildClient, MSBuildClientExitType, MSBuildClientExitResult and OutOfProcServerNode from Microsoft.Build.Experimental to a new Microsoft.Build.Server namespace so the server can become a supported, non-experimental surface.

Clean break (no obsolete shims): research found no external callers in dotnet/sdk, dotnet/roslyn, or the VS repo. Internal consumers (BuildManager, XMake, MSBuildClientApp) and unit tests updated. Added CP0001 package-validation suppressions for the removed Experimental types. VS-side ApiCompat suppressions must be coordinated on insertion.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@JanProvaznik
JanProvaznik force-pushed the promote-msbuild-server-namespace branch from aa40eed to c6b2e81 Compare July 27, 2026 11:05
@JanProvaznik
JanProvaznik marked this pull request as ready for review July 27, 2026 11:39
Copilot AI review requested due to automatic review settings July 27, 2026 11:39

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Promotes the MSBuild server public surface area out of Microsoft.Build.Experimental into a supported Microsoft.Build.Server namespace, and updates CLI, engine, tests, and docs accordingly.

Changes:

  • Moved server-related public types (MSBuildClient, MSBuildClientExitResult, MSBuildClientExitType, OutOfProcServerNode) to Microsoft.Build.Server.
  • Updated internal call sites and unit tests to reference the new namespace.
  • Updated package-validation suppressions and documentation for the namespace move.

Reviewed changes

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

Show a summary per file
File Description
src/MSBuild/XMake.cs Switched CLI usage/imports to Microsoft.Build.Server.
src/MSBuild/MSBuildClientApp.cs Updated client app imports to Microsoft.Build.Server.
src/MSBuild.UnitTests/MSBuildServer_Tests.cs Updated test imports to Microsoft.Build.Server.
src/Build/CompatibilitySuppressions.xml Added CP0001 suppressions for removed Microsoft.Build.Experimental.* server types (note: see review comment about missing net10 suppressions).
src/Build/BackEnd/Node/OutOfProcServerNode.cs Moved OutOfProcServerNode into Microsoft.Build.Server.
src/Build/BackEnd/Components/Communications/NodeProviderOutOfProcBase.cs Updated XML doc cref to the new namespace.
src/Build/BackEnd/Client/MSBuildClientExitType.cs Moved enum into Microsoft.Build.Server and improved doc comment.
src/Build/BackEnd/Client/MSBuildClientExitResult.cs Moved type into Microsoft.Build.Server and updated summary text.
src/Build/BackEnd/Client/MSBuildClient.cs Moved MSBuildClient into Microsoft.Build.Server.
src/Build/BackEnd/BuildManager/BuildManager.cs Updated shutdown call to Microsoft.Build.Server.MSBuildClient.
src/Build.UnitTests/BackEnd/RedirectConsoleWriter_Tests.cs Updated test imports to Microsoft.Build.Server.
src/Build.UnitTests/BackEnd/MSBuildClient_Tests.cs Updated test imports to Microsoft.Build.Server.
documentation/MSBuild-Server.md Documented the new public namespace for server entry points.
Comments suppressed due to low confidence (1)

src/Build/CompatibilitySuppressions.xml:66

  • Compatibility suppressions were added only for the net472 lib/ref assets. If package validation compares the net10.0 assets against the baseline as well, the removed Microsoft.Build.Experimental.* server types will still trigger CP0001 for lib/net10.0 and ref/net10.0. The PR description also mentions 16 suppressions (including net10.0), but the file currently contains only 8.
  </Suppression>
  <Suppression>
    <DiagnosticId>PKV006</DiagnosticId>
    <Target>net10.0</Target>
  </Suppression>

The suppressions were generated when the repo targeted net10.0. main has
since moved to net11.0, so package validation failed with unsuppressed
CP0001 errors for lib/net11.0 and ref/net11.0.

Regenerated from an empty baseline via ApiCompatGenerateSuppressionFile:
16 CP0001 entries (4 types x {lib,ref} x {net472,net11.0}). The stale
PKV006 net10.0 suppression is dropped since the baseline package
18.10.0-1.26378.2 already ships net11.0.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 1cbfd3fd-6e0a-41f7-8597-bd47632705dd
@rainersigwald

Copy link
Copy Markdown
Member

This mirrors the ProjectCache promotion (#12051), but as a clean break (no obsolete shim types) because — unlike ProjectCache, which had external plugin assemblies compiled against the old namespace — research found no external consumers of the server types:

This suggests to me that maybe we shouldn't make it public at all? Rename the namespace but keep it internal?

@JanProvaznik

Copy link
Copy Markdown
Member Author

This suggests to me that maybe we shouldn't make it public at all? Rename the namespace but keep it internal?

@rainersigwald that'd require Microsoft.Build.csproj InternalsVisibleTo MSBuild.csproj, which I don't have enough context about, but I thought it's intentionally not done so that API consumers can achieve all engine functionality without the cli itself.

@rainersigwald

Copy link
Copy Markdown
Member

Ah, that's a good blocking function. We should update the comments to indicate that we don't expect third-party use of these APIs though--they basically only work to wrap the CLI so invoke the CLI instead.

…y use

Per PR feedback: these types are public only because MSBuild.exe lives in a
separate assembly from Microsoft.Build with no InternalsVisibleTo between
them. They only work to wrap the MSBuild CLI and offer nothing beyond it.

- Mark MSBuildClient, MSBuildClientExitResult, MSBuildClientExitType,
  OutOfProcServerNode (and its nested BuildCallback delegate) with
  [EditorBrowsable(EditorBrowsableState.Never)] so they do not surface in
  IntelliSense.
- Add <remarks> to each stating third-party use is not expected or
  supported and to invoke the CLI instead.
- Note the same in documentation/MSBuild-Server.md.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 1cbfd3fd-6e0a-41f7-8597-bd47632705dd
@JanProvaznik

Copy link
Copy Markdown
Member Author

Done in 9a850b7.

All four types (plus the nested OutOfProcServerNode.BuildCallback delegate) are now marked [EditorBrowsable(EditorBrowsableState.Never)] so they don't surface in IntelliSense, and each carries a <remarks> block:

This type is public only so that the MSBuild command-line application can host the MSBuild server; third-party use is not expected or supported. It exists to wrap the MSBuild CLI and offers nothing beyond it, so invoke the CLI instead.

Also noted the same in documentation/MSBuild-Server.md. Verified the attribute survives into the shipped reference assemblies for both ref/net472 and ref/net11.0.

This was referenced Oct 19, 2026
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.

Promote MSBuild server out of Experimental namespace

4 participants