Repository navigation
Isolate the NodeIterator stress fixture #752
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: NuGet packages | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| publish: | |
| description: Publish the verified repository version to NuGet.org | |
| required: true | |
| default: false | |
| type: boolean | |
| push: | |
| branches: | |
| - main | |
| tags: | |
| - 'v*' | |
| pull_request: | |
| branches: | |
| - main | |
| - release/* | |
| paths: | |
| - '.github/workflows/native-runtime-packages.yml' | |
| - '.github/actions/graphics-sdk/**' | |
| - 'eng/graphics/**' | |
| - 'experiments/WebScene.NativeEngine.Probe/**' | |
| - 'packaging/WebScene.NativeEngine.Runtime/**' | |
| - 'scripts/build-native-engine-runtime.sh' | |
| - 'scripts/build-native-engine-runtime-linux-container.sh' | |
| - 'scripts/build-native-engine-runtime.ps1' | |
| - 'scripts/V8WindowsEnvironment.psm1' | |
| - 'scripts/pack-packages.sh' | |
| - 'scripts/verify-cross-rid-compatibility.py' | |
| - 'scripts/tests/test_native_runtime_workflow_policy.py' | |
| - 'scripts/tests/test_verify_cross_rid_compatibility.py' | |
| - 'scripts/tests/test_v8_windows_environment.ps1' | |
| - 'scripts/verify-release-packages.py' | |
| - 'src/WebScene.Backend.Abstractions/**' | |
| - 'src/WebScene.Backend.Avalonia/**' | |
| - 'src/WebScene.Backend.Uno/**' | |
| - 'src/WebScene.Sdk.Avalonia/**' | |
| - 'src/WebScene.Sdk.NativeHost.Shared/**' | |
| - 'src/WebScene.Sdk.Uno/**' | |
| - 'src/WebScene.Diagnostics.Cdp/**' | |
| - 'tests/WebPlatformSubset/**' | |
| - 'tests/WebScene.Runtime.PackageSmoke/**' | |
| - 'tests/Shared/**' | |
| - 'tests/WebScene.Uno.PackageSmoke/**' | |
| - 'third-party/v8-patches/**' | |
| permissions: | |
| actions: read | |
| contents: read | |
| jobs: | |
| metadata: | |
| runs-on: [self-hosted, Linux, X64] | |
| outputs: | |
| package-version: ${{ steps.version.outputs.package-version }} | |
| publish: ${{ steps.version.outputs.publish }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Test cross-RID evidence verifier | |
| run: | | |
| python3 -m unittest \ | |
| scripts/tests/test_native_runtime_workflow_policy.py \ | |
| scripts/tests/test_verify_cross_rid_compatibility.py | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v5 | |
| env: | |
| DOTNET_INSTALL_DIR: ${{ runner.temp }}/dotnet | |
| with: | |
| dotnet-version: 8.0.x | |
| global-json-file: global.json | |
| - id: version | |
| name: Resolve and validate package version | |
| shell: bash | |
| env: | |
| REQUESTED_PUBLISH: ${{ inputs.publish }} | |
| run: | | |
| version="$( | |
| dotnet msbuild src/WebScene.Core/WebScene.Core.csproj \ | |
| -getProperty:PackageVersion -nologo | | |
| tail -n 1 | tr -d '\r' | |
| )" | |
| publish="${REQUESTED_PUBLISH:-false}" | |
| if [[ "$GITHUB_REF_TYPE" == tag ]]; then | |
| tag_version="${GITHUB_REF_NAME#v}" | |
| if [[ "$tag_version" != "$version" ]]; then | |
| echo "Tag version '$tag_version' does not match repository PackageVersion '$version'." >&2 | |
| exit 1 | |
| fi | |
| publish=true | |
| fi | |
| if [[ -z "$version" ]]; then | |
| echo "Unable to resolve the repository package version." >&2 | |
| exit 1 | |
| fi | |
| echo "package-version=$version" >> "$GITHUB_OUTPUT" | |
| echo "publish=$publish" >> "$GITHUB_OUTPUT" | |
| release-ci-gate: | |
| name: Require successful CI for release commit | |
| needs: metadata | |
| if: needs.metadata.outputs.publish == 'true' | |
| runs-on: [self-hosted, Linux, X64] | |
| steps: | |
| - name: Require successful CI for the exact commit | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| shell: bash | |
| run: | | |
| IFS=$'\t' read -r conclusion url <<< "$( | |
| gh run list \ | |
| --repo "$GITHUB_REPOSITORY" \ | |
| --workflow CI.yml \ | |
| --commit "$GITHUB_SHA" \ | |
| --event push \ | |
| --status completed \ | |
| --limit 20 \ | |
| --json conclusion,url,databaseId \ | |
| --jq '(sort_by(.databaseId) | last // {}) | [(.conclusion // "missing"), (.url // "")] | @tsv' | |
| )" | |
| if [[ "$conclusion" != success ]]; then | |
| echo "The exact release commit '$GITHUB_SHA' has no successful completed CI push run (latest conclusion: '$conclusion')." >&2 | |
| exit 1 | |
| fi | |
| echo "Release CI gate passed: $url" | |
| packages: | |
| name: Pack .NET packages | |
| needs: metadata | |
| runs-on: [self-hosted, Linux, X64] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v5 | |
| env: | |
| DOTNET_INSTALL_DIR: ${{ runner.temp }}/dotnet | |
| with: | |
| dotnet-version: 8.0.x | |
| global-json-file: global.json | |
| - name: Pack and verify .NET packages | |
| shell: bash | |
| run: | | |
| scripts/pack-packages.sh \ | |
| --package-version '${{ needs.metadata.outputs.package-version }}' \ | |
| --output "$GITHUB_WORKSPACE/artifacts/nuget-packages" | |
| - name: Upload .NET packages | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: packages-${{ needs.metadata.outputs.package-version }} | |
| path: | | |
| artifacts/nuget-packages/*.nupkg | |
| artifacts/nuget-packages/*.snupkg | |
| artifacts/nuget-packages/packages.json | |
| if-no-files-found: error | |
| native: | |
| name: Build ${{ matrix.rid }} | |
| needs: metadata | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - os: [self-hosted, macOS, ARM64] | |
| rid: osx-arm64 | |
| cpu: arm64 | |
| monolith: libv8_monolith.a | |
| script: unix | |
| v8_revision: 15.3.10 | |
| partition_alloc: true | |
| v8_configuration: ReleasePartitionAlloc | |
| v8_cache_generation: v9-v8-15.3.10-pa-no-process-shim-macos-inspector | |
| v8_cache_script: scripts/build-native-engine-runtime.sh | |
| v8_cache_patch: packaging/WebScene.NativeEngine.Runtime/patches/V8PartitionAllocMacVisibilityPatch.txt | |
| - os: [self-hosted, Linux, X64] | |
| rid: linux-x64 | |
| cpu: x64 | |
| monolith: libv8_monolith.a | |
| script: unix | |
| v8_revision: 15.3.10 | |
| partition_alloc: true | |
| v8_configuration: ReleasePartitionAlloc | |
| v8_cache_generation: v12-v8-15.3.10-pa-no-process-shim-ubuntu22-gcc12-lld-no-crel-shared-inspector | |
| v8_cache_script: scripts/build-native-engine-runtime.sh | |
| v8_cache_patch: packaging/WebScene.NativeEngine.Runtime/patches/V8BuildNoCrelPatch.txt | |
| - os: windows-2022 | |
| rid: win-x64 | |
| cpu: x64 | |
| monolith: v8_monolith.lib | |
| script: windows | |
| v8_revision: 15.3.10 | |
| partition_alloc: true | |
| v8_configuration: ReleasePartitionAlloc | |
| v8_cache_generation: v9-v8-15.3.10-pa-windows-compat-inspector | |
| v8_cache_script: scripts/build-native-engine-runtime.ps1 | |
| v8_cache_patch: packaging/WebScene.NativeEngine.Runtime/patches/V8WindowsCompatibilityPatch.txt | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v5 | |
| env: | |
| DOTNET_INSTALL_DIR: ${{ runner.temp }}/dotnet | |
| with: | |
| dotnet-version: 8.0.x | |
| global-json-file: global.json | |
| - name: Test V8 Windows child environment | |
| if: matrix.rid == 'win-x64' | |
| shell: pwsh | |
| run: ./scripts/tests/test_v8_windows_environment.ps1 | |
| - name: Expose the self-hosted Rust toolchain | |
| if: matrix.rid == 'osx-arm64' | |
| shell: bash | |
| run: | | |
| echo "$HOME/.cargo/bin" >> "$GITHUB_PATH" | |
| "$HOME/.cargo/bin/cargo" --version | |
| - name: Build Ubuntu 22.04 Linux runtime image | |
| if: matrix.rid == 'linux-x64' | |
| shell: bash | |
| run: | | |
| docker build \ | |
| --platform linux/amd64 \ | |
| --file packaging/WebScene.NativeEngine.Runtime/Dockerfile.linux-x64 \ | |
| --tag webscene-native-linux-builder:ubuntu-22.04 \ | |
| packaging/WebScene.NativeEngine.Runtime | |
| - id: v8-cache-key | |
| name: Resolve pinned V8 SDK cache identity | |
| shell: bash | |
| run: | | |
| echo "image-version=${ImageVersion:-unknown}" >> "$GITHUB_OUTPUT" | |
| - id: v8-cache | |
| name: Restore pinned V8 SDK | |
| uses: actions/cache/restore@v4 | |
| with: | |
| path: | | |
| artifacts/native-engine-v8/${{ matrix.rid }}/v8/include | |
| artifacts/native-engine-v8/${{ matrix.rid }}/v8/out/${{ matrix.cpu }}/${{ matrix.v8_configuration }}/args.gn | |
| artifacts/native-engine-v8/${{ matrix.rid }}/v8/out/${{ matrix.cpu }}/${{ matrix.v8_configuration }}/obj/${{ matrix.monolith }} | |
| artifacts/native-engine-v8/${{ matrix.rid }}/v8/out/${{ matrix.cpu }}/${{ matrix.v8_configuration }}/icudtl.dat | |
| artifacts/native-engine-v8/${{ matrix.rid }}/v8/out/${{ matrix.cpu }}/${{ matrix.v8_configuration }}/gen/third_party/partition_alloc/src | |
| artifacts/native-engine-v8/${{ matrix.rid }}/v8/LICENSE | |
| artifacts/native-engine-v8/${{ matrix.rid }}/v8/third_party/icu/LICENSE | |
| artifacts/native-engine-v8/${{ matrix.rid }}/v8/third_party/partition_alloc/src | |
| key: webscene-v8-sdk-${{ matrix.v8_cache_generation }}-${{ matrix.rid }}-${{ hashFiles('third-party/v8-patches/**') }}-${{ steps.v8-cache-key.outputs.image-version }}-${{ hashFiles(matrix.v8_cache_script, matrix.v8_cache_patch, 'scripts/V8WindowsEnvironment.psm1') }} | |
| restore-keys: | | |
| ${{ matrix.rid != 'win-x64' && format('webscene-v8-sdk-{0}-{1}-{2}-', matrix.v8_cache_generation, matrix.rid, hashFiles('third-party/v8-patches/**')) || '' }} | |
| ${{ matrix.rid != 'win-x64' && format('webscene-v8-sdk-{0}-{1}-', matrix.v8_cache_generation, matrix.rid) || '' }} | |
| - id: restored-v8-sdk | |
| name: Validate restored V8 SDK compatibility | |
| shell: bash | |
| run: | | |
| root="artifacts/native-engine-v8/${{ matrix.rid }}/v8" | |
| args="$root/out/${{ matrix.cpu }}/${{ matrix.v8_configuration }}/args.gn" | |
| monolith="$root/out/${{ matrix.cpu }}/${{ matrix.v8_configuration }}/obj/${{ matrix.monolith }}" | |
| if [[ '${{ matrix.rid }}' == 'win-x64' \ | |
| && '${{ steps.v8-cache.outputs.cache-hit }}' != 'true' ]]; then | |
| echo "The exact Windows V8 cache identity was not restored; forcing a clean child build." | |
| rm -rf "$root" | |
| echo "ready=false" >> "$GITHUB_OUTPUT" | |
| echo "cold-build=true" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| echo "cold-build=false" >> "$GITHUB_OUTPUT" | |
| partition_alloc_is_compatible() { | |
| [[ '${{ matrix.partition_alloc }}' != 'true' ]] \ | |
| || { [[ -d "$root/third_party/partition_alloc/src" ]] \ | |
| && [[ -f "$root/out/${{ matrix.cpu }}/${{ matrix.v8_configuration }}/gen/third_party/partition_alloc/src/partition_alloc/buildflags.h" ]]; } | |
| } | |
| args_are_compatible() { | |
| grep -Eq '^v8_enable_pointer_compression *= *true$' "$args" \ | |
| && grep -Eq '^v8_enable_pointer_compression_shared_cage *= *true$' "$args" \ | |
| && grep -Eq '^v8_enable_partition_alloc *= *${{ matrix.partition_alloc }}$' "$args" \ | |
| && { [[ '${{ matrix.partition_alloc }}' != 'true' ]] \ | |
| || [[ '${{ matrix.rid }}' == 'win-x64' ]] \ | |
| || { grep -Eq '^use_allocator_shim *= *false$' "$args" \ | |
| && grep -Eq '^use_partition_alloc_as_malloc *= *false$' "$args"; }; } \ | |
| && { [[ '${{ matrix.rid }}' != 'linux-x64' ]] \ | |
| || { grep -Eq '^use_lld *= *true$' "$args" \ | |
| && grep -Eq '^use_sysroot *= *false$' "$args" \ | |
| && grep -Eq '^v8_monolithic_for_shared_library *= *true$' "$args"; }; } | |
| } | |
| if [[ -f "$root/include/v8.h" \ | |
| && -f "$root/include/v8-inspector.h" \ | |
| && $(grep -c 'virtual void consoleAPICalled' "$root/include/v8-inspector.h") -gt 0 \ | |
| && -f "$args" \ | |
| && -f "$monolith" \ | |
| && -f "$root/out/${{ matrix.cpu }}/${{ matrix.v8_configuration }}/icudtl.dat" \ | |
| && -f "$root/LICENSE" \ | |
| && -f "$root/third_party/icu/LICENSE" ]] \ | |
| && args_are_compatible \ | |
| && partition_alloc_is_compatible; then | |
| echo "ready=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "ready=false" >> "$GITHUB_OUTPUT" | |
| if [[ -d "$root" ]]; then | |
| echo "Discarding an incomplete or incompatible restored V8 SDK at '$root'." | |
| rm -rf "$root" | |
| fi | |
| fi | |
| - name: Prepare pinned Dawn runtime dependency | |
| if: matrix.rid != 'linux-x64' | |
| uses: ./.github/actions/graphics-sdk | |
| with: | |
| rid: ${{ matrix.rid }} | |
| component: dawn | |
| - name: Prepare pinned Windows ANGLE composition dependency | |
| if: matrix.rid == 'win-x64' | |
| uses: ./.github/actions/graphics-sdk | |
| with: | |
| rid: ${{ matrix.rid }} | |
| component: angle | |
| - name: Build, pack, and test macOS runtime | |
| env: | |
| WEBSCENE_NATIVE_SKIP_HARDWARE_TESTS: '1' | |
| if: matrix.rid == 'osx-arm64' | |
| shell: bash | |
| run: | | |
| v8_root= | |
| restored_v8="$GITHUB_WORKSPACE/artifacts/native-engine-v8/${{ matrix.rid }}/v8" | |
| if [[ '${{ steps.restored-v8-sdk.outputs.ready }}' == 'true' ]]; then | |
| v8_root="$restored_v8" | |
| fi | |
| scripts/build-native-engine-runtime.sh \ | |
| --rid '${{ matrix.rid }}' \ | |
| --graphics-sdk "$GITHUB_WORKSPACE/artifacts/graphics-sdk/${{ matrix.rid }}" \ | |
| --package-version '${{ needs.metadata.outputs.package-version }}' \ | |
| --v8-root "$v8_root" \ | |
| --v8-revision '${{ matrix.v8_revision }}' \ | |
| --upstream-v8 \ | |
| --partition-alloc \ | |
| --output "$GITHUB_WORKSPACE/artifacts/nuget-packages" | |
| - name: Build, pack, and test Linux runtime | |
| if: matrix.rid == 'linux-x64' | |
| shell: bash | |
| run: | | |
| v8_root= | |
| if [[ '${{ steps.restored-v8-sdk.outputs.ready }}' == 'true' ]]; then | |
| v8_root="/workspace/artifacts/native-engine-v8/${{ matrix.rid }}/v8" | |
| fi | |
| docker run --rm \ | |
| --platform linux/amd64 \ | |
| --user "$(id -u):$(id -g)" \ | |
| --env HOME=/tmp/webscene-home \ | |
| --env DOTNET_CLI_HOME=/tmp/webscene-home \ | |
| --env CARGO_HOME=/tmp/webscene-home/.cargo \ | |
| --env NUGET_PACKAGES=/tmp/webscene-home/.nuget/packages \ | |
| --volume "$GITHUB_WORKSPACE:/workspace" \ | |
| --workdir /workspace \ | |
| webscene-native-linux-builder:ubuntu-22.04 \ | |
| bash -lc " | |
| mkdir -p \"\$HOME\" | |
| mkdir -p \"\$CARGO_HOME\" | |
| scripts/build-native-engine-runtime-linux-container.sh \ | |
| --rid '${{ matrix.rid }}' \ | |
| --package-version '${{ needs.metadata.outputs.package-version }}' \ | |
| --v8-root '$v8_root' \ | |
| --v8-revision '${{ matrix.v8_revision }}' \ | |
| --upstream-v8 \ | |
| --partition-alloc \ | |
| --output /workspace/artifacts/nuget-packages | |
| " | |
| - name: Build, pack, and test Windows runtime | |
| env: | |
| WEBSCENE_NATIVE_SKIP_HARDWARE_TESTS: '1' | |
| if: matrix.script == 'windows' | |
| shell: pwsh | |
| run: | | |
| $v8Root = "" | |
| $restoredV8 = "$env:GITHUB_WORKSPACE/artifacts/native-engine-v8/${{ matrix.rid }}/v8" | |
| if ('${{ steps.restored-v8-sdk.outputs.ready }}' -eq 'true') { | |
| $v8Root = $restoredV8 | |
| } | |
| ./scripts/build-native-engine-runtime.ps1 ` | |
| -Rid '${{ matrix.rid }}' ` | |
| -GraphicsSdk "$env:GITHUB_WORKSPACE/artifacts/graphics-sdk/${{ matrix.rid }}" ` | |
| -PackageVersion '${{ needs.metadata.outputs.package-version }}' ` | |
| -V8Root $v8Root ` | |
| -V8Revision '${{ matrix.v8_revision }}' ` | |
| -UpstreamV8 ` | |
| -PartitionAlloc ` | |
| -Output "$env:GITHUB_WORKSPACE/artifacts/nuget-packages" | |
| - name: Verify fresh Windows V8 child build | |
| if: matrix.rid == 'win-x64' && steps.v8-cache.outputs.cache-hit != 'true' | |
| shell: pwsh | |
| run: | | |
| if ('${{ steps.restored-v8-sdk.outputs.ready }}' -ne 'false' ` | |
| -or '${{ steps.restored-v8-sdk.outputs.cold-build }}' -ne 'true') { | |
| throw "Windows V8 qualification did not record a cold build." | |
| } | |
| $root = "$env:GITHUB_WORKSPACE/artifacts/native-engine-v8/${{ matrix.rid }}" | |
| $required = @( | |
| "$root/depot_tools/.git", | |
| "$root/v8/.git", | |
| "$root/v8/out/${{ matrix.cpu }}/${{ matrix.v8_configuration }}/args.gn", | |
| "$root/v8/out/${{ matrix.cpu }}/${{ matrix.v8_configuration }}/obj/${{ matrix.monolith }}", | |
| "$root/v8/out/${{ matrix.cpu }}/${{ matrix.v8_configuration }}/icudtl.dat" | |
| ) | |
| foreach ($path in $required) { | |
| if (-not (Test-Path $path)) { | |
| throw "Fresh Windows V8 child output is missing: $path" | |
| } | |
| } | |
| Write-Host "Fresh Windows V8 checkout, GN generation, and Ninja output verified." | |
| - name: Run candidate compatibility discovery | |
| continue-on-error: true | |
| shell: bash | |
| run: | | |
| case '${{ matrix.rid }}' in | |
| osx-arm64) native_name=libwebscene_native_engine.dylib ;; | |
| linux-x64) native_name=libwebscene_native_engine.so ;; | |
| win-x64) native_name=webscene_native_engine.dll ;; | |
| *) echo "Unsupported discovery RID '${{ matrix.rid }}'." >&2; exit 1 ;; | |
| esac | |
| native_path="$( | |
| find artifacts/native-engine-runtime-build \ | |
| -path "*/package-smoke/runtimes/${{ matrix.rid }}/native/$native_name" \ | |
| -print -quit | |
| )" | |
| if [[ -z "$native_path" ]]; then | |
| echo "Unable to locate the packaged ${{ matrix.rid }} native runtime." >&2 | |
| exit 1 | |
| fi | |
| build_dir="${native_path%%/package-smoke/runtimes/*}" | |
| dotnet run \ | |
| --project tests/WebPlatformSubset/runner/WebScene.WebPlatformSubset.Runner.csproj \ | |
| -c Release --no-build -- \ | |
| --selection candidate \ | |
| --native-library "$native_path" \ | |
| --native-cache-directory "$build_dir/code-cache" \ | |
| --output "$build_dir/wpt-candidate-results" | |
| - id: v8-sdk-ready | |
| name: Validate completed V8 SDK for caching | |
| if: always() && steps.v8-cache.outputs.cache-hit != 'true' | |
| shell: bash | |
| run: | | |
| root="artifacts/native-engine-v8/${{ matrix.rid }}/v8" | |
| args="$root/out/${{ matrix.cpu }}/${{ matrix.v8_configuration }}/args.gn" | |
| monolith="$root/out/${{ matrix.cpu }}/${{ matrix.v8_configuration }}/obj/${{ matrix.monolith }}" | |
| partition_alloc_is_compatible() { | |
| [[ '${{ matrix.partition_alloc }}' != 'true' ]] \ | |
| || { [[ -d "$root/third_party/partition_alloc/src" ]] \ | |
| && [[ -f "$root/out/${{ matrix.cpu }}/${{ matrix.v8_configuration }}/gen/third_party/partition_alloc/src/partition_alloc/buildflags.h" ]]; } | |
| } | |
| args_are_compatible() { | |
| grep -Eq '^v8_enable_pointer_compression *= *true$' "$args" \ | |
| && grep -Eq '^v8_enable_pointer_compression_shared_cage *= *true$' "$args" \ | |
| && grep -Eq '^v8_enable_partition_alloc *= *${{ matrix.partition_alloc }}$' "$args" \ | |
| && { [[ '${{ matrix.rid }}' != 'linux-x64' ]] \ | |
| || { grep -Eq '^use_lld *= *true$' "$args" \ | |
| && grep -Eq '^use_sysroot *= *false$' "$args" \ | |
| && grep -Eq '^v8_monolithic_for_shared_library *= *true$' "$args" \ | |
| && grep -Eq '^use_allocator_shim *= *false$' "$args" \ | |
| && grep -Eq '^use_partition_alloc_as_malloc *= *false$' "$args"; }; } | |
| } | |
| if [[ -f "$root/include/v8.h" \ | |
| && -f "$root/include/v8-inspector.h" \ | |
| && $(grep -c 'virtual void consoleAPICalled' "$root/include/v8-inspector.h") -gt 0 \ | |
| && -f "$args" \ | |
| && -f "$monolith" \ | |
| && -f "$root/out/${{ matrix.cpu }}/${{ matrix.v8_configuration }}/icudtl.dat" \ | |
| && -f "$root/LICENSE" \ | |
| && -f "$root/third_party/icu/LICENSE" ]] \ | |
| && args_are_compatible \ | |
| && partition_alloc_is_compatible; then | |
| echo "ready=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "ready=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Save completed V8 SDK | |
| if: always() && steps.v8-sdk-ready.outputs.ready == 'true' | |
| uses: actions/cache/save@v4 | |
| with: | |
| path: | | |
| artifacts/native-engine-v8/${{ matrix.rid }}/v8/include | |
| artifacts/native-engine-v8/${{ matrix.rid }}/v8/out/${{ matrix.cpu }}/${{ matrix.v8_configuration }}/args.gn | |
| artifacts/native-engine-v8/${{ matrix.rid }}/v8/out/${{ matrix.cpu }}/${{ matrix.v8_configuration }}/obj/${{ matrix.monolith }} | |
| artifacts/native-engine-v8/${{ matrix.rid }}/v8/out/${{ matrix.cpu }}/${{ matrix.v8_configuration }}/icudtl.dat | |
| artifacts/native-engine-v8/${{ matrix.rid }}/v8/out/${{ matrix.cpu }}/${{ matrix.v8_configuration }}/gen/third_party/partition_alloc/src | |
| artifacts/native-engine-v8/${{ matrix.rid }}/v8/LICENSE | |
| artifacts/native-engine-v8/${{ matrix.rid }}/v8/third_party/icu/LICENSE | |
| artifacts/native-engine-v8/${{ matrix.rid }}/v8/third_party/partition_alloc/src | |
| key: webscene-v8-sdk-${{ matrix.v8_cache_generation }}-${{ matrix.rid }}-${{ hashFiles('third-party/v8-patches/**') }}-${{ steps.v8-cache-key.outputs.image-version }}-${{ hashFiles(matrix.v8_cache_script, matrix.v8_cache_patch, 'scripts/V8WindowsEnvironment.psm1') }} | |
| - name: Upload required compatibility evidence | |
| if: success() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: compatibility-required-${{ matrix.rid }}-${{ needs.metadata.outputs.package-version }} | |
| path: artifacts/native-engine-runtime-build/**/wpt-results/** | |
| if-no-files-found: error | |
| - name: Upload failed compatibility evidence | |
| if: failure() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: compatibility-required-${{ matrix.rid }}-${{ needs.metadata.outputs.package-version }} | |
| path: artifacts/native-engine-runtime-build/**/wpt-results/** | |
| if-no-files-found: warn | |
| - name: Upload candidate compatibility evidence | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: compatibility-candidate-${{ matrix.rid }}-${{ needs.metadata.outputs.package-version }} | |
| path: artifacts/native-engine-runtime-build/**/wpt-candidate-results/** | |
| if-no-files-found: warn | |
| - name: Upload verified RID package | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: native-${{ matrix.rid }}-${{ needs.metadata.outputs.package-version }} | |
| path: artifacts/nuget-packages/*.nupkg | |
| if-no-files-found: error | |
| required-evidence: | |
| name: Verify cross-RID required evidence | |
| needs: [metadata, native] | |
| runs-on: [self-hosted, Linux, X64] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Download required compatibility evidence | |
| uses: actions/download-artifact@v4 | |
| with: | |
| pattern: compatibility-required-* | |
| path: artifacts/required-compatibility | |
| - name: Verify exact required profile across released RIDs | |
| run: | | |
| python3 scripts/verify-cross-rid-compatibility.py \ | |
| --input-root artifacts/required-compatibility \ | |
| --profile tests/WebPlatformSubset/webscene-component-profile.json \ | |
| --selection required \ | |
| --expected-rid osx-arm64 \ | |
| --expected-rid linux-x64 \ | |
| --expected-rid win-x64 \ | |
| --output artifacts/required-compatibility/cross-rid-summary.json | |
| - name: Upload cross-RID required summary | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: compatibility-required-summary-${{ needs.metadata.outputs.package-version }} | |
| path: artifacts/required-compatibility/cross-rid-summary.json | |
| if-no-files-found: error | |
| package-set: | |
| name: Verify release package set | |
| needs: [metadata, packages, native, required-evidence] | |
| runs-on: [self-hosted, Linux, X64] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Download .NET packages | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: packages-${{ needs.metadata.outputs.package-version }} | |
| path: artifacts/nuget-packages | |
| - name: Download native packages | |
| uses: actions/download-artifact@v4 | |
| with: | |
| pattern: native-*-${{ needs.metadata.outputs.package-version }} | |
| path: artifacts/nuget-packages | |
| merge-multiple: true | |
| - name: Verify versions, dependencies, symbols, and package inventory | |
| shell: bash | |
| run: | | |
| python3 scripts/verify-release-packages.py \ | |
| artifacts/nuget-packages \ | |
| --version '${{ needs.metadata.outputs.package-version }}' \ | |
| --native-rid osx-arm64 \ | |
| --native-rid linux-x64 \ | |
| --native-rid win-x64 \ | |
| --output artifacts/nuget-packages/release-packages.json | |
| shasum -a 256 \ | |
| artifacts/nuget-packages/*.nupkg \ | |
| artifacts/nuget-packages/*.snupkg \ | |
| > artifacts/nuget-packages/packages.sha256 | |
| - name: Upload complete verified package set | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: release-${{ needs.metadata.outputs.package-version }} | |
| path: | | |
| artifacts/nuget-packages/*.nupkg | |
| artifacts/nuget-packages/*.snupkg | |
| artifacts/nuget-packages/*.json | |
| artifacts/nuget-packages/packages.sha256 | |
| if-no-files-found: error | |
| candidate-evidence: | |
| name: Verify cross-RID candidate evidence | |
| needs: [metadata, native] | |
| if: always() && needs.metadata.result == 'success' | |
| runs-on: [self-hosted, Linux, X64] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Download candidate compatibility evidence | |
| continue-on-error: true | |
| uses: actions/download-artifact@v4 | |
| with: | |
| pattern: compatibility-candidate-* | |
| path: artifacts/candidate-compatibility | |
| - name: Verify exact candidate profile across released RIDs | |
| if: always() | |
| run: | | |
| python3 scripts/verify-cross-rid-compatibility.py \ | |
| --input-root artifacts/candidate-compatibility \ | |
| --profile tests/WebPlatformSubset/webscene-component-profile.json \ | |
| --selection candidate \ | |
| --advisory-test-failures \ | |
| --expected-rid osx-arm64 \ | |
| --expected-rid linux-x64 \ | |
| --expected-rid win-x64 \ | |
| --output artifacts/candidate-compatibility/cross-rid-summary.json | |
| - name: Upload cross-RID candidate summary | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: compatibility-candidate-summary-${{ needs.metadata.outputs.package-version }} | |
| path: artifacts/candidate-compatibility/cross-rid-summary.json | |
| if-no-files-found: warn | |
| consumer: | |
| name: Package consumer ${{ matrix.rid }} | |
| needs: [metadata, package-set] | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - os: [self-hosted, macOS, ARM64] | |
| rid: osx-arm64 | |
| - os: [self-hosted, Linux, X64] | |
| rid: linux-x64 | |
| - os: windows-2022 | |
| rid: win-x64 | |
| runs-on: ${{ matrix.os }} | |
| env: | |
| # PR builds intentionally reuse package versions. Keep their extracted | |
| # packages isolated so a self-hosted runner cannot consume an older build | |
| # of the same version from its persistent global NuGet cache. runner.temp | |
| # is unavailable while GitHub evaluates a job-level environment. | |
| NUGET_PACKAGES: ${{ github.workspace }}/artifacts/nuget-${{ github.run_id }}-${{ github.run_attempt }}-${{ matrix.rid }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v5 | |
| env: | |
| DOTNET_INSTALL_DIR: ${{ runner.temp }}/dotnet | |
| with: | |
| dotnet-version: 8.0.x | |
| global-json-file: global.json | |
| - name: Download verified package set | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: release-${{ needs.metadata.outputs.package-version }} | |
| path: artifacts/nuget-packages | |
| - name: Restore clean package consumer | |
| shell: bash | |
| run: | | |
| dotnet restore tests/WebScene.Runtime.PackageSmoke/WebScene.Runtime.PackageSmoke.csproj \ | |
| -p:RuntimeIdentifier='${{ matrix.rid }}' \ | |
| -p:WebScenePackageVersion='${{ needs.metadata.outputs.package-version }}' \ | |
| --configfile tests/WebScene.Runtime.PackageSmoke/NuGet.config | |
| dotnet restore tests/WebScene.Uno.PackageSmoke/WebScene.Uno.PackageSmoke.csproj \ | |
| -p:RuntimeIdentifier='${{ matrix.rid }}' \ | |
| -p:WebScenePackageVersion='${{ needs.metadata.outputs.package-version }}' \ | |
| --configfile tests/WebScene.Uno.PackageSmoke/NuGet.config | |
| - name: Build and run clean package consumer | |
| shell: bash | |
| run: | | |
| dotnet run \ | |
| --project tests/WebScene.Runtime.PackageSmoke/WebScene.Runtime.PackageSmoke.csproj \ | |
| -c Release \ | |
| -r '${{ matrix.rid }}' \ | |
| --no-restore \ | |
| -p:WebScenePackageVersion='${{ needs.metadata.outputs.package-version }}' | |
| dotnet run \ | |
| --project tests/WebScene.Uno.PackageSmoke/WebScene.Uno.PackageSmoke.csproj \ | |
| -c Release \ | |
| -r '${{ matrix.rid }}' \ | |
| --no-restore \ | |
| -p:WebScenePackageVersion='${{ needs.metadata.outputs.package-version }}' | |
| publish: | |
| name: Publish to NuGet.org | |
| needs: [metadata, consumer, release-ci-gate] | |
| if: needs.metadata.outputs.publish == 'true' | |
| runs-on: [self-hosted, Linux, X64] | |
| environment: nuget.org | |
| permissions: | |
| contents: read | |
| id-token: write | |
| env: | |
| NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }} | |
| NUGET_USER: ${{ secrets.NUGET_USER }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Download verified package set | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: release-${{ needs.metadata.outputs.package-version }} | |
| path: artifacts/nuget-packages | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v5 | |
| env: | |
| DOTNET_INSTALL_DIR: ${{ runner.temp }}/dotnet | |
| with: | |
| dotnet-version: 8.0.x | |
| global-json-file: global.json | |
| - id: trusted-publishing | |
| name: Exchange GitHub identity for a temporary NuGet API key | |
| if: env.NUGET_API_KEY == '' && env.NUGET_USER != '' | |
| uses: NuGet/login@v1 | |
| with: | |
| user: ${{ env.NUGET_USER }} | |
| - name: Publish packages and symbols | |
| env: | |
| TRUSTED_PUBLISHING_API_KEY: ${{ steps.trusted-publishing.outputs.NUGET_API_KEY }} | |
| shell: bash | |
| run: | | |
| api_key="${NUGET_API_KEY:-$TRUSTED_PUBLISHING_API_KEY}" | |
| if [[ -z "$api_key" ]]; then | |
| echo "Configure either NUGET_API_KEY or NUGET_USER in the nuget.org environment." >&2 | |
| exit 1 | |
| fi | |
| for package in artifacts/nuget-packages/*.nupkg; do | |
| dotnet nuget push "$package" \ | |
| --api-key "$api_key" \ | |
| --source https://api.nuget.org/v3/index.json \ | |
| --skip-duplicate | |
| done |