-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Fix WASM boot config ContentRoot to use IntermediateOutputPath #124125
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Updates the Blazor WASM SDK targets to define the build boot config static web asset from its actual on-disk generation location (obj/) to prevent stale-asset Identity selection during incremental builds (which can lead to incorrect SRI integrity values at runtime).
Changes:
- Change
DefineStaticWebAssetsContentRootfor the build boot config asset from$(OutDir)wwwrootto$(IntermediateOutputPath).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.
Canceled AzDO jobs (typically from timeouts) still have pipeline artifacts containing binlogs. The SendToHelix.binlog contains Helix job IDs that can be queried directly to recover actual test results. Discovered while investigating PR #124125 where a 3-hour timeout caused a WasmBuildTests job to be canceled, but all 226 Helix work items had actually passed.
Canceled AzDO jobs (typically from timeouts) still have pipeline artifacts containing binlogs. The SendToHelix.binlog contains Helix job IDs that can be queried directly to recover actual test results. Discovered while investigating PR #124125 where a 3-hour timeout caused a WasmBuildTests job to be canceled, but all 226 Helix work items had actually passed.
Canceled WasmBuildTests actually passed ✅The browser-wasm windows Release WasmBuildTests job in build 1284169 was canceled after the 3-hour timeout, but all Helix work items completed successfully. Recovery steps:
The failure was purely the AzDO job wrapper timing out while waiting to collect results, not an actual test failure. |
Canceled AzDO jobs (typically from timeouts) still have pipeline artifacts containing binlogs. The \SendToHelix.binlog\ contains Helix job IDs that can be queried directly to recover actual test results. ## What changed - Added **Recovering Results from Canceled Jobs** section to helix skill SKILL.md - Documents the workflow: download artifacts → load binlog → extract Helix job IDs → query Helix API - Includes concrete example from PR #124125 (226 work items all passed despite 3h timeout cancellation) - Added tip about binlog MCP server for structured binlog analysis ## Context Discovered while investigating #124125 where \�rowser-wasm windows Release WasmBuildTests\ was canceled after 3 hours. The script reported no failures (correct — no *failed* jobs) but also couldn't surface that the tests actually passed. With the documented recovery workflow, the Helix results were fully recoverable.
| CopyToOutputDirectory="PreserveNewest" | ||
| CopyToPublishDirectory="Never" | ||
| ContentRoot="$(OutDir)wwwroot" | ||
| ContentRoot="$(IntermediateOutputPath)" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this needs to happen in other places like the definition of the .wasm files as assets (after webcil conversion).
I believe the important bit here is that ContentRoot + RelativePath must exist for all assets
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. Added a commit that sets per-item ContentRoot metadata on each _WebCilAssetsCandidates item to %(RootDir)%(Directory) (its own directory). This ensures candidateFullPath.StartsWith(normalizedContentRoot) is always true in DefineStaticWebAssets.ComputeCandidateIdentity, so Identity equals the physical file path for all candidates — webcil-converted files in obj/webcil/, runtime pack files in packs/, PDBs from obj/, etc.
The task-level ContentRoot parameter is kept as a fallback but the per-item metadata takes precedence via ComputePropertyValue.
|
Bad base commit? |
b649bd9 to
dc5c351
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.
yup, and then github stopped responding |
## Summary Work around [dotnet/dnceng#6072](dotnet/dnceng#6072) in the CI analysis skill by using the Helix \ListFiles\ endpoint instead of file URIs from the \Details\ endpoint. ## Problem The Helix work item Details API (\GET .../workitems/{id}\) has two bugs in its \Files[].Uri\ values: 1. **Subdirectory flattening**: Files uploaded from subdirectories (e.g. \xharness-output/logs/test/build.binlog\) get URIs with only the base filename (\.../files/build.binlog\), so multiple distinct files with the same base name collide 2. **Unicode rejection**: The \/files/{name}\ endpoint validates against an ASCII-only regex, rejecting filenames containing unicode characters (e.g. CJK test directory names like \鿀蜒枛遫䡫煉\) The previous workaround reconstructed permalink URIs from the \FileName\ field, but this still routed through the broken \/files/\ endpoint which rejects unicode. ## Fix Use the separate \ListFiles\ endpoint (\GET .../workitems/{id}/files\) which returns direct blob storage URIs. These URIs: - Preserve full subdirectory paths - Have properly percent-encoded unicode - Don't route through the permalink/regex validation layer Verified against PR #124125 CI artifacts: 53 files with unicode paths all return HTTP 200 via ListFiles blob URIs, vs broken/colliding URIs from the Details endpoint.
Change the boot config's DefineStaticWebAssets ContentRoot from wwwroot to so the asset Identity points to the actual file location on disk rather than a stale copy in the output wwwroot folder. This fixes SRI integrity failures during incremental Blazor WASM builds where the compressed boot config used a stale fingerprint from the wwwroot copy instead of the fresh file in obj/. Fixes aspnetcore#65271
Replace the fragile FileName-based scanning of all StaticWebAsset items with direct references to _WasmBuildBootConfigStaticWebAsset and _WasmPublishBootConfigStaticWebAsset. These items are already produced by the DefineStaticWebAssets task in _GenerateBuildWasmBootJson and _AddPublishWasmBootJsonToStaticWebAssets respectively. The previous approach relied on FileName containing the fingerprint (e.g. dotnet.FINGERPRINT.js), which is an implementation detail of how DefineStaticWebAssets computes Identity. Using the pipeline's own output items is correct regardless of ContentRoot or Identity format.
WebCil candidates come from multiple source directories (obj/webcil/ for converted DLLs, runtime pack for native files, etc.) but were all defined with ContentRoot pointing to OutputPath/wwwroot. Use IntermediateOutputPath as ContentRoot instead. Files outside obj/ (e.g., runtime pack native files) get synthesized Identities with CopyCandidates to materialize the fingerprinted copies. Files already under obj/ (webcil-converted DLLs) use their physical path directly. This avoids the stale wwwroot Identity problem that caused SRI integrity failures during incremental builds, while maintaining correct publish behavior through CopyCandidate materialization.
dc5c351 to
2e74845
Compare
Summary
Fix a .NET 11 regression causing SRI integrity failures during incremental Blazor WASM builds. Three changes in
Microsoft.NET.Sdk.WebAssembly.Browser.targets:DefineStaticWebAssetsContentRootfrom$(OutDir)wwwrootto$(IntermediateOutputPath)%(FileName)%(Extension)-based scanning with direct references to the boot config output itemsDefineStaticWebAssetsContentRootfrom$(_WasmBuildOuputPath)($(OutputPath)wwwroot) to$(IntermediateOutputPath)Regression
This is a regression in .NET 11 (works in 10.0). It was introduced by dotnet/sdk#52283, which fixed an esproj compression bug by flipping the order in
AssetToCompress.TryFindInputFilePathto preferRelatedAsset(Identity) overRelatedAssetOriginalItemSpec. That fix was correct for esproj, but exposed a latent issue in the WASM SDK targets: the boot config and webcil assets' Identity pointed to awwwrootcopy rather than the actual source files.Before sdk#52283,
OriginalItemSpechappened to point to the real file and was checked first, masking the wrongContentRoot. After the flip,RelatedAsset(Identity) is checked first, and its stalewwwrootpath is used — producing incorrect SRI hashes on incremental builds.Reported in aspnetcore#65271.
Problem
The WASM boot config file (e.g.
dotnet.boot.js) is generated at$(IntermediateOutputPath)(theobj/folder), but its static web asset was defined withContentRoot="$(OutDir)wwwroot". This causedDefineStaticWebAssetsto compute an Identity pointing to thewwwrootcopy rather than the actual file inobj/.The same issue applied to WebCil asset candidates — files from
obj/webcil/, the runtime pack, and other directories were all defined withContentRoot="$(OutputPath)wwwroot", producing synthetic Identities underwwwroot/that could become stale during incremental builds.Fix
1. Boot config ContentRoot
Change
ContentRootto$(IntermediateOutputPath)so the asset Identity matches the real file location on disk. TheCopyToOutputDirectory="PreserveNewest"attribute still ensures the file is copied towwwrootfor serving.This follows Javier's suggestion in dotnet/sdk#52847 to "stop defining these assets with an item spec in the wwwroot folder and just define them in their original location on disk".
2. Preload matching simplification
The
_AddWasmPreloadBuildPropertiesand_AddWasmPreloadPublishPropertiestargets previously scanned all@(StaticWebAsset)items by%(FileName)%(Extension)to find the boot config asset. This relied on the Identity path containing the fingerprint in the filename, which is an implementation detail of howDefineStaticWebAssetscomputes Identity based onContentRoot.The fix replaces the scanning with direct references to
@(_WasmBuildBootConfigStaticWebAsset)and@(_WasmPublishBootConfigStaticWebAsset)— the output items already produced byDefineStaticWebAssets. This is both correct and simpler.3. WebCil ContentRoot
Change the WebCil
DefineStaticWebAssetsContentRootfrom$(_WasmBuildOuputPath)to$(IntermediateOutputPath). This means:obj/webcil/are under$(IntermediateOutputPath), so Identity = physical path (no synthesis needed)dotnet.native.js, ICU.datfiles) are outside$(IntermediateOutputPath), soComputeCandidateIdentitysynthesizes Identity underobj/and creates CopyCandidate entries to materialize the fingerprinted copiesThis avoids the stale
wwwrootIdentity problem while maintaining correct publish behavior through CopyCandidate materialization.What's not changed
ContentRoot="$(PublishDir)wwwroot"): Publish builds are clean and don't have the incremental staleness problem.Fixes dotnet/aspnetcore#65271