diff --git a/build/ci/stage-build-linux-tests.yml b/build/ci/stage-build-linux-tests.yml index 4d6e2d294..31dc984d1 100644 --- a/build/ci/stage-build-linux-tests.yml +++ b/build/ci/stage-build-linux-tests.yml @@ -45,6 +45,12 @@ jobs: OverWrite: false flattenFolders: false + ## Validate dotnet.js fingerprint matches actual file + - bash: | + $(build.sourcesdirectory)/build/scripts/validate-dotnetjs-fingerprint.sh \ + "$(build.sourcesdirectory)/src/Uno.Wasm.Sample.RayTracer/bin/Release/net10.0/publish/wwwroot" + displayName: Validate dotnet.js fingerprint (RayTracer) + ## Raytracer validation - bash: | $(build.sourcesdirectory)/build/scripts/run-tests.sh \ @@ -102,6 +108,12 @@ jobs: OverWrite: false flattenFolders: false + ## Validate dotnet.js fingerprint matches actual file (SWA build) + - bash: | + $(build.sourcesdirectory)/build/scripts/validate-dotnetjs-fingerprint.sh \ + "$(build.sourcesdirectory)/src/Uno.Wasm.Sample.RayTracer/bin/Release/net10.0/publish/wwwroot" + displayName: Validate dotnet.js fingerprint (SWA) + - bash: | $(build.sourcesdirectory)/build/scripts/run-tests-swa.sh \ "$(build.sourcesdirectory)/src/Uno.Wasm.Sample.RayTracer/bin/Release/net10.0/publish/wwwroot" \ diff --git a/build/ci/stage-build-macos-tests.yml b/build/ci/stage-build-macos-tests.yml index 01add7a86..5082fbc99 100644 --- a/build/ci/stage-build-macos-tests.yml +++ b/build/ci/stage-build-macos-tests.yml @@ -33,6 +33,12 @@ jobs: dotnet publish -c Release /m:1 /p:DISABLE_CLIHOST_NET6=true /p:WasmShellEmccLinkOptimization=false /p:WasmShellILLinkerEnabled=false /bl:$(build.artifactstagingdirectory)/SampleNet5-nolinker-macos.binlog displayName: Build StaticLinking.Interpreter Sample (net5 without linker) + ## Validate dotnet.js fingerprint matches actual file + - bash: | + $(build.sourcesdirectory)/build/scripts/validate-dotnetjs-fingerprint.sh \ + "$(build.sourcesdirectory)/src/Uno.Wasm.StaticLinking.Interpreter/bin/Release/net10.0/publish/wwwroot" + displayName: Validate dotnet.js fingerprint (StaticLinking.Interpreter) + - bash: | $(build.sourcesdirectory)/build/scripts/run-tests.sh \ "$(build.sourcesdirectory)/src/Uno.Wasm.StaticLinking.Interpreter/bin/Release/net10.0/publish/wwwroot" \ diff --git a/build/ci/stage-build-windows-tests.yml b/build/ci/stage-build-windows-tests.yml index 6c2e409a8..50cdf0860 100644 --- a/build/ci/stage-build-windows-tests.yml +++ b/build/ci/stage-build-windows-tests.yml @@ -66,10 +66,16 @@ jobs: - pwsh: | cd $(build.sourcesdirectory)/src/Uno.Wasm.Sample.RayTracer - dotnet clean -c Release + dotnet clean -c Release dotnet publish -c Release /m:1 /p:WasmShellEmccLinkOptimization=false /bl:$(build.artifactstagingdirectory)/SampleNet5-win.binlog displayName: Build Raytracer Sample + ## Validate dotnet.js fingerprint matches actual file + - pwsh: | + $(build.sourcesdirectory)\build\scripts\validate-dotnetjs-fingerprint.ps1 ` + -PublishPath "$(build.sourcesdirectory)\src\Uno.Wasm.Sample.RayTracer\bin\Release\net10.0\publish\wwwroot" + displayName: Validate dotnet.js fingerprint (RayTracer) + - pwsh: | $(build.sourcesdirectory)\build\scripts\run-tests-windows.ps1 ` "$(build.sourcesdirectory)\src\Uno.Wasm.Sample.RayTracer\bin\Release\net10.0\publish\wwwroot" ` diff --git a/build/scripts/validate-dotnetjs-fingerprint.ps1 b/build/scripts/validate-dotnetjs-fingerprint.ps1 new file mode 100644 index 000000000..40b1a68e3 --- /dev/null +++ b/build/scripts/validate-dotnetjs-fingerprint.ps1 @@ -0,0 +1,50 @@ +# Validates that uno-config.js references a dotnet.js fingerprint that matches an actual file +param( + [Parameter(Mandatory=$true)] + [string]$PublishPath +) + +$ErrorActionPreference = "Stop" + +Write-Host "Validating dotnet.js fingerprint in: $PublishPath" + +# Find uno-config.js (it could be in a package_* subdirectory) +$unoConfig = Get-ChildItem -Path $PublishPath -Recurse -Filter "uno-config.js" | Select-Object -First 1 + +if (-not $unoConfig) { + Write-Host "ERROR: uno-config.js not found in $PublishPath" + exit 1 +} + +Write-Host "Found uno-config.js: $($unoConfig.FullName)" + +# Read the content and extract the fingerprint +$content = Get-Content -Path $unoConfig.FullName -Raw +$match = [regex]::Match($content, 'dotnet\.([a-z0-9]+)\.js') + +if (-not $match.Success) { + Write-Host "ERROR: Could not extract dotnet.js fingerprint from uno-config.js" + Write-Host "Content of uno-config.js:" + Write-Host $content + exit 1 +} + +$fingerprint = $match.Groups[1].Value +Write-Host "Fingerprint in uno-config.js: $fingerprint" + +# Check if the fingerprinted dotnet.js file exists +$frameworkPath = Join-Path $PublishPath "_framework" +$dotnetJsFile = Join-Path $frameworkPath "dotnet.$fingerprint.js" + +if (-not (Test-Path $dotnetJsFile)) { + Write-Host "ERROR: Fingerprint mismatch!" + Write-Host " uno-config.js references: dotnet.$fingerprint.js" + Write-Host " But this file does not exist in: $frameworkPath" + Write-Host "" + Write-Host "Available dotnet.*.js files in _framework:" + Get-ChildItem -Path $frameworkPath -Filter "dotnet.*.js" -ErrorAction SilentlyContinue | ForEach-Object { Write-Host " $($_.Name)" } + exit 1 +} + +Write-Host "SUCCESS: dotnet.$fingerprint.js exists in _framework" +Write-Host "Fingerprint validation passed!" diff --git a/build/scripts/validate-dotnetjs-fingerprint.sh b/build/scripts/validate-dotnetjs-fingerprint.sh new file mode 100755 index 000000000..0a1bd8f7a --- /dev/null +++ b/build/scripts/validate-dotnetjs-fingerprint.sh @@ -0,0 +1,51 @@ +#!/bin/bash +# Validates that uno-config.js references a dotnet.js fingerprint that matches an actual file +set -e + +PUBLISH_PATH=$1 + +if [ -z "$PUBLISH_PATH" ]; then + echo "Usage: validate-dotnetjs-fingerprint.sh " + exit 1 +fi + +echo "Validating dotnet.js fingerprint in: $PUBLISH_PATH" + +# Find uno-config.js (it could be in a package_* subdirectory) +UNO_CONFIG=$(find "$PUBLISH_PATH" -name "uno-config.js" -type f | head -1) + +if [ -z "$UNO_CONFIG" ]; then + echo "ERROR: uno-config.js not found in $PUBLISH_PATH" + exit 1 +fi + +echo "Found uno-config.js: $UNO_CONFIG" + +# Extract the fingerprint from uno-config.js (portable across GNU and BSD grep/sed) +FINGERPRINT=$(sed -n 's/.*dotnet\.\([a-z0-9]*\)\.js.*/\1/p' "$UNO_CONFIG" | head -1) + +if [ -z "$FINGERPRINT" ]; then + echo "ERROR: Could not extract dotnet.js fingerprint from uno-config.js" + echo "Content of uno-config.js:" + cat "$UNO_CONFIG" + exit 1 +fi + +echo "Fingerprint in uno-config.js: $FINGERPRINT" + +# Check if the fingerprinted dotnet.js file exists +FRAMEWORK_PATH="$PUBLISH_PATH/_framework" +DOTNET_JS_FILE="$FRAMEWORK_PATH/dotnet.$FINGERPRINT.js" + +if [ ! -f "$DOTNET_JS_FILE" ]; then + echo "ERROR: Fingerprint mismatch!" + echo " uno-config.js references: dotnet.$FINGERPRINT.js" + echo " But this file does not exist in: $FRAMEWORK_PATH" + echo "" + echo "Available dotnet.*.js files in _framework:" + ls -la "$FRAMEWORK_PATH"/dotnet.*.js 2>/dev/null || echo " (none found)" + exit 1 +fi + +echo "SUCCESS: dotnet.$FINGERPRINT.js exists in _framework" +echo "Fingerprint validation passed!" diff --git a/src/Uno.Wasm.Bootstrap/build/Uno.Wasm.Bootstrap.targets b/src/Uno.Wasm.Bootstrap/build/Uno.Wasm.Bootstrap.targets index 4c6d40bd4..172bc9088 100644 --- a/src/Uno.Wasm.Bootstrap/build/Uno.Wasm.Bootstrap.targets +++ b/src/Uno.Wasm.Bootstrap/build/Uno.Wasm.Bootstrap.targets @@ -452,15 +452,18 @@ AfterTargets="ResolvePublishStaticWebAssets"> + We look for assets where AssetMode is 'All' or 'Publish' to get the publish-time fingerprint. + During publish, the RelativePath may already be resolved to the actual fingerprinted value + (e.g., '_framework/dotnet.abc123.js') instead of the placeholder pattern, so we match both. --> <_UnoDotnetJsAssetPublish Include="@(StaticWebAsset)" - Condition="$([System.String]::Copy('%(RelativePath)').StartsWith('_framework/dotnet#[.{fingerprint}]')) AND $([System.String]::Copy('%(RelativePath)').EndsWith('.js')) AND !$([System.String]::Copy('%(RelativePath)').Contains('.native')) AND !$([System.String]::Copy('%(RelativePath)').Contains('.runtime')) AND ('%(AssetMode)' == 'All' OR '%(AssetMode)' == 'Publish' OR '%(AssetMode)' == '')" /> + Condition="($([System.String]::Copy('%(RelativePath)').StartsWith('_framework/dotnet#[.{fingerprint}]')) OR $([System.Text.RegularExpressions.Regex]::IsMatch('%(RelativePath)', '^_framework/dotnet\.[a-z0-9]+\.js$'))) AND $([System.String]::Copy('%(RelativePath)').EndsWith('.js')) AND !$([System.String]::Copy('%(RelativePath)').Contains('.native')) AND !$([System.String]::Copy('%(RelativePath)').Contains('.runtime')) AND ('%(AssetMode)' == 'All' OR '%(AssetMode)' == 'Publish' OR '%(AssetMode)' == '')" /> - + <_UnoDotnetJsFingerprintPublish>%(_UnoDotnetJsAssetPublish.Fingerprint) + <_UnoDotnetJsFingerprintPublish Condition="'$(_UnoDotnetJsFingerprintPublish)' == ''">$([System.Text.RegularExpressions.Regex]::Match('%(_UnoDotnetJsAssetPublish.RelativePath)', 'dotnet\.([a-z0-9]+)\.js$').Groups[1].Value) <_UnoConfigJsPath>$(IntermediateOutputPath)unowwwrootassets/uno-config.js diff --git a/src/Uno.Wasm.Sample.RayTracer/Uno.Wasm.Sample.RayTracer.csproj b/src/Uno.Wasm.Sample.RayTracer/Uno.Wasm.Sample.RayTracer.csproj index 9c2049663..b32a8c2a6 100644 --- a/src/Uno.Wasm.Sample.RayTracer/Uno.Wasm.Sample.RayTracer.csproj +++ b/src/Uno.Wasm.Sample.RayTracer/Uno.Wasm.Sample.RayTracer.csproj @@ -56,6 +56,9 @@ <_appOutput>$(PublishDir)wwwroot/$(WasmShellOutputPackagePath) <_unoConfigJsContent>$([System.IO.File]::ReadAllText('$(_appOutput)/uno-config.js')) + <_frameworkPath>$(PublishDir)wwwroot/_framework + + <_configDotnetJsFingerprint>$([System.Text.RegularExpressions.Regex]::Match('$(_unoConfigJsContent)', 'dotnet\.([a-z0-9]+)\.js').Groups[1].Value) @@ -72,6 +75,10 @@ + + +