Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions Releasing_MSBuildLocator.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ These instructions can only be followed by Microsoft-internal MSBuild maintainer
1. Create a PR in https://github.com/microsoft/MSBuildLocator
2. Have it reviewed.
3. Once approved, merge it.
4. It will automatically start a pipeline build [here](https://dev.azure.com/devdiv/DevDiv/_build?definitionId=11881).
5. Once it succeeds, proceed to [our release page](https://dev.azure.com/devdiv/DevDiv/_release?_a=releases&view=mine&definitionId=408) and create a release (top-right). Specify the build that succeeded.
6. At some point, it will stop to request permission to continue. If you want to publish to NuGet, do so, clicking Approve. It will make a little more progress and push to NuGet! It will then give you the option to "resume" (or cancel) twice. Do so.

4. Start a pipeline build [here](https://dev.azure.com/devdiv/DevDiv/_build?definitionId=11881) for the commited changes.
5. Once it succeeds, proceed to [our release pipeline](https://dev.azure.com/devdiv/DevDiv/_build?definitionId=27492) and queue release. Specify the build that succeeded.
6. On Public NuGet release stage it will stop to request permission to continue. If you want to publish to NuGet, do so, clicking Approve.
### Releasing a non-preview version of MSBuildLocator

The above steps will push a package to NuGet.org, but it is a preview version. To make a final release branded version, merge the latest changes into a release branch like `release/1.5`. Follow the steps as above, and it will publish a release package to NuGet.org.
Expand Down
19 changes: 11 additions & 8 deletions docs/diagnostics/MSBL001.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

## Error Message

> A PackageReference to the package '{PackageId}' at version '{Version}' is present in this project without ExcludeAssets="runtime" set. This can cause errors at run-time due to MSBuild assembly-loading.
> A PackageReference to the package '{PackageId}' at version '{Version}' is present in this project without ExcludeAssets="runtime" and PrivateAssets="all" set. This can cause errors at run-time due to MSBuild assembly-loading.

## Cause

This error occurs when your project references MSBuild NuGet packages (such as `Microsoft.Build`, `Microsoft.Build.Framework`, `Microsoft.Build.Utilities.Core`, etc.) without excluding their runtime assets. When you use Microsoft.Build.Locator, you want MSBuildLocator to load MSBuild assemblies from an installed Visual Studio or .NET SDK instance, not from the NuGet packages in your output directory.
This error occurs when your project references MSBuild NuGet packages (such as `Microsoft.Build`, `Microsoft.Build.Framework`, `Microsoft.Build.Utilities.Core`, etc.) without excluding their runtime assets and marking them as private. When you use Microsoft.Build.Locator, you want MSBuildLocator to load MSBuild assemblies from an installed Visual Studio or .NET SDK instance, not from the NuGet packages in your output directory.

## Why This Is a Problem

Expand All @@ -16,9 +16,11 @@ When MSBuild runtime assemblies are copied to your application's output director
2. **Missing SDKs and build logic**: The MSBuild assemblies in your output directory don't include the SDKs, targets, and build logic needed to build real projects
3. **Inconsistent behavior**: Your application may behave differently than `MSBuild.exe`, `dotnet build`, or Visual Studio when evaluating projects

Additionally, without `PrivateAssets="all"`, downstream projects that reference your project may still get these runtime assets transitively, causing the same issues in consuming projects.

## Example Runtime Error

Without `ExcludeAssets="runtime"`, you may encounter errors like:
Without the proper asset exclusions, you may encounter errors like:

```
System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.Build, Version=15.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies.
Expand All @@ -34,18 +36,19 @@ This happens because your application loads MSBuild assemblies from your bin fol

## Solution

Add `ExcludeAssets="runtime"` to all MSBuild PackageReferences in your project file:
Add `ExcludeAssets="runtime"` and `PrivateAssets="all"` to all MSBuild PackageReferences in your project file:

```xml
<ItemGroup>
<PackageReference Include="Microsoft.Build" ExcludeAssets="runtime" />
<PackageReference Include="Microsoft.Build.Framework" ExcludeAssets="runtime" />
<PackageReference Include="Microsoft.Build.Utilities.Core" ExcludeAssets="runtime" />
<PackageReference Include="Microsoft.Build" ExcludeAssets="runtime" PrivateAssets="all" />
<PackageReference Include="Microsoft.Build.Framework" ExcludeAssets="runtime" PrivateAssets="all" />
<PackageReference Include="Microsoft.Build.Utilities.Core" ExcludeAssets="runtime" PrivateAssets="all" />
...
</ItemGroup>
```

This tells NuGet to use these packages only for compilation, not at runtime. At runtime, MSBuildLocator will load MSBuild assemblies from the registered Visual Studio or .NET SDK installation.
- `ExcludeAssets="runtime"` tells NuGet to use these packages only for compilation, not at runtime. At runtime, MSBuildLocator will load MSBuild assemblies from the registered Visual Studio or .NET SDK installation.
- `PrivateAssets="all"` prevents the package reference metadata from flowing to downstream projects, ensuring that projects referencing your library don't inadvertently get runtime assets from these packages.

## Alternative: Disable the Check (Not Recommended)

Expand Down
11 changes: 0 additions & 11 deletions release-pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,14 +79,3 @@ stages:
https://microsoft.sharepoint.com/teams/toolsforeng/_layouts/OneNote.aspx?id=%2Fteams%2Ftoolsforeng%2FOne%20Note%2FToolsForSoftwareEngineers&wd=target%28Build%20Tools%2FMSBuild%2FGitHub.one%7CFF6DC598-65EC-43D5-AB29-DB38FEB82BC8%2FMyGet%20Feed%7CFAFC6258-899D-48D4-8DB4-892396202C9C%2F%29
onenote:https://microsoft.sharepoint.com/teams/toolsforeng/One%20Note/ToolsForSoftwareEngineers/Build%20Tools/MSBuild/GitHub.one#MyGet%20Feed&section-id={FF6DC598-65EC-43D5-AB29-DB38FEB82BC8}&page-id={FAFC6258-89
onTimeout: 'reject'

- job: GitHubRelease
displayName: 'GitHub release'
dependsOn: PublicNuGetRelease
pool: server
steps:
- task: ManualValidation@0
displayName: 'Create GitHub release'
inputs:
instructions: 'Create the GitHub release manually'
onTimeout: 'reject'
2 changes: 1 addition & 1 deletion src/MSBuildLocator/build/Microsoft.Build.Locator.targets
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<Error
Condition="@(_DistinctMSBuildPackagesReferencedPoorly->Count()) > 0"
Code="MSBL001"
Text="A PackageReference to the package '%(_DistinctMSBuildPackagesReferencedPoorly.NuGetPackageId)' at version '%(_DistinctMSBuildPackagesReferencedPoorly.NuGetPackageVersion)' is present in this project without ExcludeAssets=&quot;runtime&quot; set. This can cause errors at run-time due to MSBuild assembly-loading."
Text="A PackageReference to the package '%(_DistinctMSBuildPackagesReferencedPoorly.NuGetPackageId)' at version '%(_DistinctMSBuildPackagesReferencedPoorly.NuGetPackageVersion)' is present in this project without ExcludeAssets=&quot;runtime&quot; and PrivateAssets=&quot;all&quot; set. This can cause errors at run-time due to MSBuild assembly-loading."
HelpLink="https://aka.ms/msbuild/locator/diagnostics/MSBL001"
/>
</Target>
Expand Down
Loading