Skip to content

Expand optimized publish support beyond Native AOT in .NET 12 #55911

Description

@marcpopMSFT

Is your feature request related to a problem?

.NET 11 introduces an optimized publish path for Native AOT that runs the compile prerequisites instead of a full Build. The public UseOptimizedPublish property and internal extension points are intentionally generic, but support is currently limited to PublishAot=true because skipping Build changes MSBuild extension-point behavior.

Other transformed publish modes can also produce outputs that differ substantially from build output. For example, trimming rewrites and removes assemblies, ReadyToRun rewrites assemblies, and single-file publish bundles most deployment files. Their publish pipelines consume intermediate and resolved items rather than the completed bin output, so running a full Build may be unnecessary. However, broadening the optimization can break project or NuGet targets attached to Build, BeforeBuild, AfterBuild, PreBuildEvent, or PostBuildEvent.

Known compatibility examples include Microsoft.Extensions.ApiDescription.Server, which generates OpenAPI documents before Build, and Microsoft.XmlSerializer.Generator, which generates serializers after Build and copies them during publish.

Describe the solution you'd like

Early in .NET 12, investigate and incrementally expand UseOptimizedPublish beyond Native AOT where it is safe and valuable. Evaluate at least:

  • PublishTrimmed
  • PublishReadyToRun
  • PublishSingleFile
  • Combined publish modes
  • Ordinary framework-dependent and self-contained publish as controls

For each mode:

  1. Verify that publish does not consume completed build output.
  2. Compare build and publish layouts to establish customer value.
  3. Scan popular NuGet packages and GitHub projects for affected MSBuild hooks and data flow into publish.
  4. Define any additional targets needed by the optimized publish extension point.
  5. Add tests for output correctness, project references, web/static assets, common Build hooks, explicit opt-in/opt-out, and combined modes.
  6. Decide whether optimization should be the default or opt-in for that mode.
  7. Document compatibility impact and migration guidance.

Keep UseOptimizedPublish=false as the general opt-out and make explicitly setting UseOptimizedPublish=true affect only modes whose support has been validated.

Alternatives you've considered

  • Keep optimization permanently limited to Native AOT. This minimizes compatibility risk but retains unnecessary builds for other transformed publish modes.
  • Add one public property per mode, such as UseTrimmingOptimizedPublish. This makes support explicit but fragments the UX and makes combined modes harder to reason about.
  • Apply the optimization to all publishes at once. This has the largest potential performance benefit but an unacceptable compatibility surface without mode-by-mode investigation.

Additional context

PR #54515 establishes the Native AOT implementation, the generic UseOptimizedPublish property, and generic internal extension points. The original motivation was correctness and customer clarity: Native AOT's managed self-contained build output is not the intended publish artifact and can be mistaken for the native result. Performance savings are secondary.

A preliminary top-100 NuGet scan found a small number of direct Build hooks, but broader ecosystem analysis should include BuildDependsOn/CoreBuildDependsOn, BeforeTargets="Build", AfterTargets="Build", BeforeBuild, AfterBuild, and skipped target hooks whose outputs flow into ResolvedFileToPublish, PrepareForPublish, or PublishDir.

Metadata

Metadata

Assignees

No one assigned

    Labels

    untriagedRequest triage from a team member

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions