Skip to content

Migrate GenerateStaticWebAssetsDevelopmentManifest - #54836

Merged
AlesProkop merged 8 commits into
dotnet:mainfrom
AlesProkop:migrate-generate-static-web-assets-development-manifest
Jun 26, 2026
Merged

Migrate GenerateStaticWebAssetsDevelopmentManifest#54836
AlesProkop merged 8 commits into
dotnet:mainfrom
AlesProkop:migrate-generate-static-web-assets-development-manifest

Conversation

@AlesProkop

Copy link
Copy Markdown
Member

Fixes dotnet/msbuild#14059

Context

Migrates GenerateStaticWebAssetsDevelopmentManifest to MSBuild's multithreaded task model. Under multithreaded execution the process current directory is not the project directory, so any path resolved relative to the process CWD is wrong. All file-system paths must be absolutized through TaskEnvironment so they root against the project directory.

Changes Made

  • Annotated the task with [MSBuildMultiThreadableTask] and implemented IMultiThreadableTask, adding TaskEnvironment TaskEnvironment { get; set; } = TaskEnvironment.Fallback;.
  • Absolutized ManifestPath and CacheFilePath via TaskEnvironment.GetAbsolutePath() before the up-to-date check (File.Exists / File.GetLastWriteTimeUtc) and passed the absolutized AbsolutePath into PersistManifest for File.Exists / File.ReadAllBytes / File.WriteAllBytes.
  • Passed TaskEnvironment into StaticWebAsset.FromTaskItemGroup so each asset's ContentRoot / RelatedAsset resolves against the project directory.
  • Threaded TaskEnvironment through CreateManifest into ResolveSubPath and absolutized asset.Identity for the File.Exists probe.
  • Preserved the original File.Exists(null/"")==false semantics by guarding the up-to-date check with !string.IsNullOrEmpty(ManifestPath) and the ResolveSubPath probe with !string.IsNullOrEmpty(asset.Identity), and preserved the && short-circuit so CacheFilePath is only absolutized when the manifest exists.
  • Left all Log.LogMessage calls using the original ManifestPath / asset.Identity strings (no absolutized paths leak into log output); the StartsWith / Substring subpath logic still uses the raw asset.Identity, keeping manifest output byte-identical in single-process mode.

Testing

  • Built Microsoft.NET.Sdk.StaticWebAssets.Tests — 0 warnings, 0 errors.
  • Added GenerateStaticWebAssetsDevelopmentManifestMultiThreadingTest (decoy-CWD pattern):
    • WritesManifestRelativeToTaskEnvironmentProjectDirectory_NotProcessCurrentDirectory — asserts the manifest is written under the project directory, not the process CWD.
    • ResolvesExistingManifestProbeRelativeToProjectDirectory_NotProcessCurrentDirectory — asserts the change-detection probe targets the project directory and leaves a decoy manifest in the CWD unread and unoverwritten.
  • Ran the full GenerateStaticWebAssetsDevelopmentManifest suite (existing + new). Result: 25 passed, 0 failed.

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

Migrates GenerateStaticWebAssetsDevelopmentManifest to MSBuild’s multithreaded task model by resolving all file-system paths via TaskEnvironment (instead of relying on the process current directory), and adds regression tests that validate behavior when process CWD differs from the project directory.

Changes:

  • Marked the task as [MSBuildMultiThreadableTask] / IMultiThreadableTask and introduced TaskEnvironment-rooted path resolution for manifest/cache paths and per-asset resolution.
  • Updated manifest persistence and change-detection probes to operate on TaskEnvironment-absolutized paths.
  • Added tests that mutate process CWD and assert manifests are created/probed relative to the project directory, not the process CWD.

Reviewed changes

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

File Description
src/StaticWebAssetsSdk/Tasks/GenerateStaticWebAssetsDevelopmentManifest.cs Implements multithread-safe path resolution via TaskEnvironment and updates manifest probing/writing to use absolutized paths.
test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/GenerateStaticWebAssetsDevelopmentManifestMultiThreadingTest.cs Adds CWD-decoy regression tests ensuring the task resolves and writes manifests relative to TaskEnvironment.ProjectDirectory.

Comment thread src/StaticWebAssetsSdk/Tasks/GenerateStaticWebAssetsDevelopmentManifest.cs Outdated
Comment thread src/StaticWebAssetsSdk/Tasks/GenerateStaticWebAssetsDevelopmentManifest.cs Outdated
Comment thread src/StaticWebAssetsSdk/Tasks/GenerateStaticWebAssetsDevelopmentManifest.cs Outdated
Comment thread src/StaticWebAssetsSdk/Tasks/GenerateStaticWebAssetsDevelopmentManifest.cs Outdated
AlesProkop and others added 2 commits June 24, 2026 08:38
Microsoft.NET.Sdk.StaticWebAssets.Tests was migrated to MSTest.Sdk on main. The new test file still used xUnit [Fact], so after merging main it failed to compile (CS0246: Fact/FactAttribute not found) on every CI Build leg. Convert it to [TestClass]/[TestMethod] with [DoNotParallelize] to match the migrated project.

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

The multithreaded migration changed Execute() to call TaskEnvironment.GetAbsolutePath(ManifestPath) unconditionally. The test left the [Required] ManifestPath/CacheFilePath unset, so GetAbsolutePath(null) threw ArgumentNullException where File.Exists(null) previously returned false. Provide non-null paths so the no-assets early-out is exercised.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@AlesProkop
AlesProkop merged commit 7a75610 into dotnet:main Jun 26, 2026
25 checks passed
@dotnet-milestone-bot dotnet-milestone-bot Bot added this to the 11.0-preview7 milestone Jun 29, 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.

[Multithreaded] Migrate GenerateStaticWebAssetsDevelopmentManifest in SDK

4 participants