Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Migrate ComputeEndpointsForReferenceStaticWebAssetst to IMultiThreadableTask - #54767

#54767
Merged
OvesN merged 3 commits into
maindotnet/sdk:mainfrom
dev/veronikao/migrate-ComputeEndpointsForReferenceStaticWebAssetst-to-mtdotnet/sdk:dev/veronikao/migrate-ComputeEndpointsForReferenceStaticWebAssetst-to-mtCopy head branch name to clipboard
Jun 15, 2026
Merged

Migrate ComputeEndpointsForReferenceStaticWebAssetst to IMultiThreadableTask#54767
OvesN merged 3 commits into
maindotnet/sdk:mainfrom
dev/veronikao/migrate-ComputeEndpointsForReferenceStaticWebAssetst-to-mtdotnet/sdk:dev/veronikao/migrate-ComputeEndpointsForReferenceStaticWebAssetst-to-mtCopy head branch name to clipboard

Conversation

@OvesN

@OvesN OvesN commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Fixes dotnet/msbuild#14039

Migrate ComputeEndpointsForReferenceStaticWebAssetst to IMultiThreadableTask

Copilot AI review requested due to automatic review settings June 15, 2026 10:08

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

This PR updates the Static Web Assets MSBuild task ComputeEndpointsForReferenceStaticWebAssets to participate in MSBuild’s multi-threaded task execution model, addressing dotnet/msbuild#11835 by making the task explicitly multi-threadable and environment-aware for path resolution.

Changes:

  • Marked ComputeEndpointsForReferenceStaticWebAssets as [MSBuildMultiThreadableTask] and implemented IMultiThreadableTask.
  • Added TaskEnvironment support and forwarded it into StaticWebAsset.ToAssetDictionary(...) so asset parsing/path handling uses the MSBuild-provided environment when available.

OvesN and others added 2 commits June 15, 2026 12:37
… migration

- Add <inheritdoc/> on TaskEnvironment property to match the ApplyCompressionNegotiation precedent.

- Add ComputeEndpointsForReferenceStaticWebAssetsMultiThreadingTest.cs: a focused smoke test that runs the task with TaskEnvironment.ProjectDirectory pointing into <testRoot>/project while the process CWD is set to <testRoot>/decoy/spawn. The asset item is constructed with a relative ContentRoot and Normalize() is deliberately skipped so the env-driven branch in StaticWebAsset.ToAssetDictionary(Assets, TaskEnvironment) actually runs. Deeper env-resolution semantics remain covered by StaticWebAssetTaskEnvironmentTests.

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

@OvesN OvesN left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Review

Headline

Production change is correct and MT-safe, but the new test does not exercise the migration — it passes identically whether Execute() calls ToAssetDictionary(Assets, TaskEnvironment) or the pre-PR ToAssetDictionary(Assets). The test gives false regression coverage.

Major: new test does not pin the migration behavior

test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/ComputeEndpointsForReferenceStaticWebAssetsMultiThreadingTest.cs

The only production diff is at src/StaticWebAssetsSdk/Tasks/ComputeEndpointsForReferenceStaticWebAssets.cs:27 — passing TaskEnvironment into ToAssetDictionary. The env is plumbed solely into StaticWebAsset.Normalize(env) (StaticWebAsset.cs:1086-1092), which mutates four fields:

ContentRoot  = !string.IsNullOrEmpty(ContentRoot) ? NormalizeContentRootPath(ContentRoot, env) : ContentRoot;
BasePath     = Normalize(BasePath);                       // env-independent: pure string Replace+Trim
RelativePath = Normalize(RelativePath, allowEmpyPath:true); // env-independent
RelatedAsset = !string.IsNullOrEmpty(RelatedAsset) ? Path.GetFullPath(env.GetAbsolutePath(RelatedAsset)) : RelatedAsset;

In this test, RelatedAsset = "", so only ContentRoot is env-sensitive. But in Execute() (lines 34–76) the dictionary value is consumed for asset.BasePath only (and asset.Identity for a log message). ContentRoot is never observed. The dictionary key is Identity, and the test pre-absolutizes it (projectAbsoluteContentRoot/candidate.js) and uses the same string for candidateEndpoint.AssetFile — so the lookup succeeds regardless of env.

Concrete demonstration. Revert line 27 to var assets = StaticWebAsset.ToAssetDictionary(Assets); and trace:

  1. FromTaskItem(item, TaskEnvironment.Fallback) is called.
  2. Normalize(Fallback) sets ContentRoot to <spawnDir>/wwwroot/ (wrong) instead of <projectDir>/wwwroot/.
  3. dictionary.Add(asset.Identity, asset) adds the same key the test fixed (absolute).
  4. assets.TryGetValue(assetIdentity, out asset) → hit.
  5. RouteHasPathPrefix("candidate.js", "base", …) → false (pure string).
  6. CombineNormalizedPaths("", "base", "candidate.js", '/')"base/candidate.js".
  7. Endpoints[0].ItemSpec == "base/candidate.js" ✅ — test still passes.

The wrong ContentRoot is silently materialized in the dictionary value and discarded.

Contrast with MergeConfigurationPropertiesMultiThreadingTest: it feeds a relative MSBuildSourceProjectFile and asserts on task.ProjectConfigurations[0].GetMetadata("Source") == "myRcl", which only succeeds if the env-aware Path.GetFullPath(env.GetAbsolutePath(...)) rooted the path under projectDir. Reverting the env wiring there does flip the test. The new test has no analogous env-dependent assertion.

Suggested test improvement

ComputeEndpointsForReferenceStaticWebAssets.Execute() does not consume any env-sensitive property of the matched asset, so there is no input shape that makes the task's Endpoints[] output depend on env. Any task-level test must therefore assert on intermediate state or be honest about being a smoke test.

Two reasonable options:

  1. Move the regression to StaticWebAsset.ToAssetDictionary(items, env) — that's the actual migration surface and a clean unit. One assertion covers every task that gets migrated this way:

    var dict = StaticWebAsset.ToAssetDictionary(items, env);
    dict[absId].ContentRoot.Should().StartWith(projectDir); // not spawnDir

    This fails immediately if any caller drops the env argument, and it would also fail if the production change here were reverted.

  2. Keep this test as a smoke test and rename the method + comment to reflect that ("task runs to completion with a non-Fallback env and produces the expected route shape"), so future readers don't mistake it for a regression test for the env plumbing.

I'd lean (1).

Minor

  • MergeConfigurationPropertiesMultiThreadingTest.cs:13-16 documents that CWD mutation is safe because [assembly:CollectionBehavior(DisableTestParallelization = true)] is set in LegacyStaticWebAssetsV1IntegrationTest.cs. The new file relies on the same invariant but omits the comment. Not a bug (the attribute is still in place), just makes the safety contract less discoverable.
  • The trailing "st" in ComputeEndpointsForReferenceStaticWebAsset**st** (PR title, branch, test class) is a typo carried through. Cosmetic.

Verified

  • Normalize(env) (StaticWebAsset.cs:1086) touches only ContentRoot/BasePath/RelativePath/RelatedAsset. Identity is untouched.
  • Identity getter (StaticWebAsset.cs:86-102) is env-independent for in-memory StaticWebAsset items.
  • Execute() body reads only asset.BasePath and asset.Identity from the dictionary value.
  • CombineNormalizedPaths, RouteHasPathPrefix, StaticWebAssetEndpoint.FromTaskItem are pure — no CWD reads.
  • MT-safety of Execute(): locals only, no static cache writes, no Environment.CurrentDirectory or unscoped Path.GetFullPath. Looks correct.
  • [assembly:CollectionBehavior(DisableTestParallelization = true)] is still present.

@OvesN
OvesN merged commit 3d609d8 into main Jun 15, 2026
25 checks passed
@OvesN
OvesN deleted the dev/veronikao/migrate-ComputeEndpointsForReferenceStaticWebAssetst-to-mt branch June 15, 2026 14:05
@dotnet-milestone-bot dotnet-milestone-bot Bot added this to the 11.0-preview6 milestone Jun 23, 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 ComputeEndpointsForReferenceStaticWebAssets in SDK

3 participants

Morty Proxy This is a proxified and sanitized view of the page, visit original site.