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
5 changes: 4 additions & 1 deletion Directory.Build.targets
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
<Import Project="Sdk.targets" Sdk="Microsoft.DotNet.Arcade.Sdk" />

<PropertyGroup>
<IsPackable Condition="$(TargetFramework.Contains('netstandard'))">false</IsPackable>
<!-- Don't ship .NET Standard packages by default, EXCEPT when a project explicitly opts in via
<IsPackable>true</IsPackable> (e.g. the workload manifest and SDK packs, which are netstandard-only
but must ship). The '$(IsPackable)' == '' guard preserves that explicit opt-in. -->
<IsPackable Condition="$(TargetFramework.Contains('netstandard')) and '$(IsPackable)' == ''">false</IsPackable>

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.

💡 💡 Discussion (non-blocking) — two follow-ups on this guard

The guard itself is correct: Directory.Build.targets is auto-imported at the end of every project, so $(IsPackable) is already populated when this condition evaluates — an explicit <IsPackable>true</IsPackable> set earlier survives, while netstandard libraries that never set it still default to non-packable. 👍

Two things worth confirming for the record:

  1. Blast radius is wider than the description's "2 workload packs." A repo-wide grep for explicit <IsPackable>true</IsPackable> on single-TFM netstandard projects shows this guard restores packability for ~6 projects — Microsoft.Maui.Sdk and Microsoft.NET.Sdk.Maui.Manifest (described), plus Resizetizer, Controls.Build.Tasks, Controls.SourceGen, and Graphics.Text.Markdig. This matches main's behavior (which is green), so it's almost certainly intended — but worth an explicit confirmation since they'll now ship again.

  2. Forward-port. PR Don't pack .NET Standard #32203 (the blanket netstandard → IsPackable=false rule, commit 543b1ebeb7) is on inflight/current only and is not an ancestor of main/net10.0. When Don't pack .NET Standard #32203 forward-ports, this and '$(IsPackable)' == '' guard must travel with it, or the same MSB4019 nightly break reappears.

— 3-model consensus (Opus 4.8 / GPT-5.5 / Gemini 3.1 Pro).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Confirmed — the wider blast radius is intended. The guard restores packability for the 6 netstandard-only opt-in projects (the 2 workload packs + Resizetizer, Controls.Build.Tasks, Controls.SourceGen, Graphics.Text.Markdig), which exactly matches main, where #32203's blanket rule never existed. So this is a main-parity restore, not new shipping behavior.

Good catch that #32203 was over-broad: the workload/MSI leg just failed loudest (the missing-file import is fatal at evaluation → MSB4019), while the other four would have silently stopped packing on inflight/current.

Updated the PR description with a Scope / blast radius table reflecting all 6 projects. Forward-port acknowledged — the '$(IsPackable)' == '' guard must travel with #32203 when it lands on net10.0/main, or the break reappears.

</PropertyGroup>

<ItemGroup>
Expand Down
23 changes: 21 additions & 2 deletions src/Workload/workloads.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,14 @@
<SwixTargetsPath>$(PkgMicroBuild_Plugins_SwixBuild_Dotnet)\build\MicroBuild.Plugins.SwixBuild.targets</SwixTargetsPath>
</PropertyGroup>

<Import Project="$(WorkloadMsiGenProps)" />
<!--
vs-workload.props is generated by _GenerateVSWorkloadProps in Microsoft.NET.Sdk.Maui.Manifest.csproj
(AfterTargets="Build") during the manifest pack. The import is conditional on Exists(...) so that a
missing file does NOT fail at evaluation time with a cryptic MSB4019 that points at this line; instead
_EnsureWorkloadMsiGenProps (a dependency of the MSI-generation target below) fails fast at the point the
file is actually consumed, with an actionable message naming the root cause. When the file exists, this
import behaves exactly as before. -->
<Import Project="$(WorkloadMsiGenProps)" Condition="Exists('$(WorkloadMsiGenProps)')" />

<!-- Provide default values for properties that can be set in vs-workload.props -->
<PropertyGroup>
Expand Down Expand Up @@ -109,8 +116,20 @@
<Message Text="Generated MSI version: %(WorkloadPackages.Filename) - %(WorkloadPackages.MsiVersion)" Importance="High" />
</Target>

<!--
Fail fast (with an actionable, self-routing message) if vs-workload.props was not generated by the time
the workload MSIs are actually built. This is wired as a dependency of _GenerateAndSignMsis - the target
that consumes @(WorkloadPackages) from the props - so it only runs on the build/MSI path. Restore,
design-time builds, and unrelated target invocations never reach this target, so it does not break those.
A full Build of this project does require the props (that is by design - you cannot generate the MSIs
without it), so in that case the error is the intended, accurate failure rather than the cryptic MSB4019. -->
<Target Name="_EnsureWorkloadMsiGenProps">
<Error Condition="!Exists('$(WorkloadMsiGenProps)')"
Text="vs-workload.props was not generated ('$(WorkloadMsiGenProps)'). This usually means the workload manifest pack ran with IsPackable=false (the official 'Pack, Sign' step runs -pack without -build, so _GenerateVSWorkloadProps (AfterTargets=Build) in Microsoft.NET.Sdk.Maui.Manifest.csproj never ran). Ensure the netstandard IsPackable guard in Directory.Build.targets preserves the manifest pack's explicit &lt;IsPackable&gt;true&lt;/IsPackable&gt;. See PR #36089 / #36088." />
</Target>

<Target Name="_GenerateAndSignMsis"
DependsOnTargets="_SetMsiVersionFromNuGetVersion;_CreateManifestMsiVersionsWithDateTime"
DependsOnTargets="_EnsureWorkloadMsiGenProps;_SetMsiVersionFromNuGetVersion;_CreateManifestMsiVersionsWithDateTime"
BeforeTargets="SignFiles" >
<CreateVisualStudioWorkload
AllowMissingPacks="true"
Expand Down
Loading