From 04d27eab422ca5b06069c6c8f3b52c1a40107c08 Mon Sep 17 00:00:00 2001 From: Shangxin Date: Wed, 7 Oct 2026 15:17:28 +0000 Subject: [PATCH 01/11] build(sdk): move to .NET SDK 10.0.401 and refresh CI actions Pin the SDK to 10.0.401 with an explicit workloadVersion 10.0.401.1 so the workload set no longer drifts independently of the SDK. Every workflow now reads the same root global.json through setup-dotnet's global-json-file input instead of repeating a 10.0.3xx channel. SalmonEgg/global.json only duplicated the Uno.Sdk pin; MSBuild picks the nearest file, so the two copies could silently split the GUI project and src/tests onto different SDKs. It is removed and all directories share the root file. The stable Apple workload for 10.0.401 requires Xcode 27, so the iOS gates move to the xcode-27 runner (public preview) and the Windows jobs to windows-2025-vs2026 for Visual Studio 18.9.3+. Actions are bumped to checkout v7.0.1, setup-dotnet v6.0.0, upload-artifact v7.0.2, download-artifact v8.0.2 and codeql-action v4.38.2, all pinned by SHA. The published bridge gate moves to acpremote 1.10.0. Docs (README zh/en, BUILD_GUIDE, release-guide) and the workflow guard tests follow the new pins. Co-Authored-By: Claude Opus 5.5 (1M context) --- .github/workflows/ci-acp-sdk.yml | 24 ++++----- .github/workflows/ci-core.yml | 18 +++---- .github/workflows/code-quality.yml | 4 +- .github/workflows/codeql.yml | 8 +-- .github/workflows/gui-smoke-gates.yml | 12 ++--- .github/workflows/macos-native-acceptance.yml | 6 +-- .../workflows/native-android-acceptance.yml | 8 +-- .github/workflows/native-ios-acceptance.yml | 20 +++---- .github/workflows/platform-build-gates.yml | 34 ++++++------ .github/workflows/release-acp-sdk.yml | 18 +++---- .github/workflows/release-packaging.yml | 53 ++++++++++--------- .github/workflows/terminal-auth-windows.yml | 6 +-- .github/workflows/wasm-smoke-gates.yml | 8 +-- .../windows-packaged-gui-acceptance.yml | 9 ++-- BUILD_GUIDE.md | 10 ++-- README.en.md | 6 +-- README.md | 6 +-- SalmonEgg/global.json | 9 ---- docs/release-guide.md | 2 +- global.json | 3 +- .../gates/run-acp-published-bridge-gate.py | 2 +- .../WasmStartupAssetsTests.cs | 9 ++-- 22 files changed, 135 insertions(+), 140 deletions(-) delete mode 100644 SalmonEgg/global.json diff --git a/.github/workflows/ci-acp-sdk.yml b/.github/workflows/ci-acp-sdk.yml index 00a0fe500..d5681fd28 100644 --- a/.github/workflows/ci-acp-sdk.yml +++ b/.github/workflows/ci-acp-sdk.yml @@ -64,18 +64,18 @@ jobs: timeout-minutes: 15 steps: - name: Checkout - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0 - name: Setup .NET - uses: actions/setup-dotnet@26b0ec14cb23fa6904739307f278c14f94c95bf1 # v5.4.0 + uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 with: global-json-file: global.json - name: Run the pinned upstream Agent against this SDK run: bash scripts/gates/run-acp-official-v2-agent-gate.sh - name: Upload upstream interoperability evidence if: always() - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: acp-official-v2-agent path: | @@ -94,18 +94,18 @@ jobs: MSBUILDDISABLENODEREUSE: "1" steps: - name: Checkout - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0 - name: Setup .NET - uses: actions/setup-dotnet@26b0ec14cb23fa6904739307f278c14f94c95bf1 # v5.4.0 + uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 with: global-json-file: global.json - name: Verify real stdio batches without skips run: bash scripts/gates/run-acp-batch-stdio-gate.sh Release - name: Upload stdio evidence if: always() - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: acp-batch-stdio path: artifacts/acp-batch-stdio/ @@ -119,12 +119,12 @@ jobs: # history (tags included) must be present. A shallow clone would pack a 0.0.0-alpha version # and the baseline guard in SalmonEgg.Acp.csproj would fail the pack. - name: Checkout - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0 - name: Setup .NET - uses: actions/setup-dotnet@26b0ec14cb23fa6904739307f278c14f94c95bf1 # v5.4.0 + uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 with: global-json-file: global.json @@ -141,7 +141,7 @@ jobs: run: ./scripts/gates/run-acp-sdk-tag-version-gate-selftest.sh - name: Upload ACP SDK package - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: acp-sdk-package path: "${{ env.PACKAGE_OUTPUT }}/*.nupkg" @@ -153,15 +153,15 @@ jobs: timeout-minutes: 25 steps: - name: Checkout - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup .NET - uses: actions/setup-dotnet@26b0ec14cb23fa6904739307f278c14f94c95bf1 # v5.4.0 + uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 with: global-json-file: global.json - name: Download ACP SDK package - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0 + uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: name: acp-sdk-package path: artifacts/acp-sdk-package diff --git a/.github/workflows/ci-core.yml b/.github/workflows/ci-core.yml index bde1efbbf..7b74dfefb 100644 --- a/.github/workflows/ci-core.yml +++ b/.github/workflows/ci-core.yml @@ -53,11 +53,11 @@ jobs: MSBUILDDISABLENODEREUSE: "1" steps: - name: Checkout - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0 - name: Setup .NET - uses: actions/setup-dotnet@26b0ec14cb23fa6904739307f278c14f94c95bf1 # v5.4.0 + uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 with: global-json-file: global.json - name: Verify real cancellation transports without skips @@ -68,11 +68,11 @@ jobs: shell: bash run: | python3 -m venv "$RUNNER_TEMP/acp-bridge-venv" - "$RUNNER_TEMP/acp-bridge-venv/bin/pip" install acpremote==1.9.0 + "$RUNNER_TEMP/acp-bridge-venv/bin/pip" install acpremote==1.10.0 python3 scripts/gates/run-acp-published-bridge-gate.py --bridge "$RUNNER_TEMP/acp-bridge-venv/bin/acpremote" - name: Upload transport evidence if: always() - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: acp-cancellation-transports path: | @@ -86,12 +86,12 @@ jobs: timeout-minutes: 45 steps: - name: Checkout - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0 - name: Setup .NET - uses: actions/setup-dotnet@26b0ec14cb23fa6904739307f278c14f94c95bf1 # v5.4.0 + uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 with: global-json-file: global.json @@ -173,14 +173,14 @@ jobs: - name: Upload test results if: always() - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: test-results path: "${{ env.TEST_RESULTS_DIR }}/**/*.trx" - name: Upload coverage reports if: always() - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: coverage-report path: "**/coverage*.xml" @@ -196,7 +196,7 @@ jobs: timeout-minutes: 10 steps: - name: Checkout - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 1 persist-credentials: false diff --git a/.github/workflows/code-quality.yml b/.github/workflows/code-quality.yml index 5a39272b0..ad083cf31 100644 --- a/.github/workflows/code-quality.yml +++ b/.github/workflows/code-quality.yml @@ -48,12 +48,12 @@ jobs: timeout-minutes: 30 steps: - name: Checkout - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0 - name: Setup .NET - uses: actions/setup-dotnet@26b0ec14cb23fa6904739307f278c14f94c95bf1 # v5.4.0 + uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 with: global-json-file: global.json diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 70b6e82f2..d75f60a75 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -52,15 +52,15 @@ jobs: contents: read steps: - name: Checkout - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup .NET - uses: actions/setup-dotnet@26b0ec14cb23fa6904739307f278c14f94c95bf1 # v5.4.0 + uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 with: global-json-file: global.json - name: Initialize CodeQL - uses: github/codeql-action/init@42947a340483f03ba47bb1a039b2c519aab3df85 # v3.37.8 + uses: github/codeql-action/init@2892aa5e19bbd11bc0cff5427e3b750a04d9e3c2 # v4.38.2 with: languages: csharp build-mode: manual @@ -97,6 +97,6 @@ jobs: done - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@42947a340483f03ba47bb1a039b2c519aab3df85 # v3.37.8 + uses: github/codeql-action/analyze@2892aa5e19bbd11bc0cff5427e3b750a04d9e3c2 # v4.38.2 with: category: "/language:csharp" diff --git a/.github/workflows/gui-smoke-gates.yml b/.github/workflows/gui-smoke-gates.yml index b45eb1d22..874fc493a 100644 --- a/.github/workflows/gui-smoke-gates.yml +++ b/.github/workflows/gui-smoke-gates.yml @@ -49,10 +49,10 @@ jobs: timeout-minutes: 45 steps: - name: Checkout - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup .NET - uses: actions/setup-dotnet@26b0ec14cb23fa6904739307f278c14f94c95bf1 # v5.4.0 + uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 with: global-json-file: global.json @@ -79,7 +79,7 @@ jobs: - name: Upload ACP setup path evidence if: always() - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: acp-setup-path-smoke path: ${{ runner.temp }}/acp-setup-path-smoke @@ -97,7 +97,7 @@ jobs: - name: Upload native elicitation evidence if: always() - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: native-elicitation-consent path: | @@ -135,10 +135,10 @@ jobs: if: github.event_name == 'workflow_dispatch' && vars.WINDOWS_GUI_SELF_HOSTED_RUNNER == 'true' steps: - name: Checkout - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup .NET - uses: actions/setup-dotnet@26b0ec14cb23fa6904739307f278c14f94c95bf1 # v5.4.0 + uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 with: global-json-file: global.json diff --git a/.github/workflows/macos-native-acceptance.yml b/.github/workflows/macos-native-acceptance.yml index 2566f9dac..a8de99f9b 100644 --- a/.github/workflows/macos-native-acceptance.yml +++ b/.github/workflows/macos-native-acceptance.yml @@ -36,7 +36,7 @@ jobs: UseSharedCompilation: 'false' steps: - name: Checkout - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0 - name: Verify native observation readiness contracts @@ -45,7 +45,7 @@ jobs: timeout-minutes: 3 run: python3 scripts/gates/run-macos-desktop-input-probe.py - name: Setup .NET - uses: actions/setup-dotnet@26b0ec14cb23fa6904739307f278c14f94c95bf1 # v5.4.0 + uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 with: global-json-file: global.json - name: Build the current native macOS application @@ -62,7 +62,7 @@ jobs: run: python3 scripts/gates/macos-elicitation-reverse-verification.py - name: Upload native desktop evidence if: always() - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: macos-native-desktop-input path: | diff --git a/.github/workflows/native-android-acceptance.yml b/.github/workflows/native-android-acceptance.yml index da36ade16..75ad6bf84 100644 --- a/.github/workflows/native-android-acceptance.yml +++ b/.github/workflows/native-android-acceptance.yml @@ -38,12 +38,12 @@ jobs: SALMONEGG_ANDROID_REVERSE: ${{ github.event_name == 'workflow_dispatch' && inputs.reverse-verification || false }} steps: - name: Checkout - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0 - name: Setup .NET - uses: actions/setup-dotnet@26b0ec14cb23fa6904739307f278c14f94c95bf1 # v5.4.0 + uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 with: global-json-file: global.json @@ -57,7 +57,7 @@ jobs: 'platforms;android-36' 'build-tools;36.0.0' platform-tools emulator 'system-images;android-36;google_apis;x86_64' echo "$ANDROID_SDK_ROOT/platform-tools" >> "$GITHUB_PATH" python3 -m venv "$RUNNER_TEMP/android-acp-tools" - "$RUNNER_TEMP/android-acp-tools/bin/python" -m pip install aiohttp==3.12.15 + "$RUNNER_TEMP/android-acp-tools/bin/python" -m pip install aiohttp==3.14.4 - name: Build current installable APK run: | @@ -133,7 +133,7 @@ jobs: - name: Upload acceptance evidence if: always() - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: android-installed-acp-acceptance path: artifacts/android-acp-acceptance diff --git a/.github/workflows/native-ios-acceptance.yml b/.github/workflows/native-ios-acceptance.yml index ddd4a0089..d069b30c8 100644 --- a/.github/workflows/native-ios-acceptance.yml +++ b/.github/workflows/native-ios-acceptance.yml @@ -29,9 +29,9 @@ concurrency: jobs: installed-ios: name: iOS Installed ACP UI - # Pair the repository's .NET 10 SDK with the published 10.0.300.3 Apple workload set. - # Xcode 26.5 / iOS 26.5 are both installed on this serviced native host. - runs-on: macos-26 + # The stable Apple workload pinned in global.json requires Xcode 27. + # The matching hosted image is currently a public preview: actions/runner-images#14404. + runs-on: xcode-27 timeout-minutes: ${{ github.event_name == 'workflow_dispatch' && inputs.reverse-verification && 65 || 35 }} env: DOTNET_PROCESSOR_COUNT: 2 @@ -39,18 +39,18 @@ jobs: MSBUILDDISABLENODEREUSE: 1 steps: - name: Checkout - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0 - name: Setup .NET - uses: actions/setup-dotnet@26b0ec14cb23fa6904739307f278c14f94c95bf1 # v5.4.0 + uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 with: global-json-file: global.json - name: Select matching Apple toolchain run: | - xcode_developer_dir="$(python3 -c 'import os; print(os.path.realpath("/Applications/Xcode_26.5.app/Contents/Developer"))')" + xcode_developer_dir="$(python3 -c 'import os; print(os.path.realpath("/Applications/Xcode_27.0.app/Contents/Developer"))')" test -d "$xcode_developer_dir" sudo xcode-select --switch "$xcode_developer_dir" xcodebuild -version @@ -58,8 +58,8 @@ jobs: uname -m xcrun --sdk iphonesimulator --show-sdk-path xcrun --sdk macosx --find actool - # https://github.com/dotnet/macios/releases/tag/dotnet-10.0.1xx-xcode26.5-10284 - dotnet workload install ios --version 10.0.300.3 --disable-parallel --no-http-cache + # https://github.com/dotnet/macios/releases/tag/dotnet-10.0.1xx-xcode27.0-10722 + dotnet workload install ios --disable-parallel --no-http-cache dotnet workload list # Wait for CoreSimulatorService before actool / xcodebuild (runner-images #12777). xcrun simctl list runtimes @@ -77,7 +77,7 @@ jobs: - name: Install isolated test tooling run: | python3 -m venv "$RUNNER_TEMP/ios-acp-tools" - "$RUNNER_TEMP/ios-acp-tools/bin/python" -m pip install aiohttp==3.12.15 + "$RUNNER_TEMP/ios-acp-tools/bin/python" -m pip install aiohttp==3.14.4 curl --location --fail --silent --show-error \ https://github.com/yonaskolb/XcodeGen/releases/download/2.46.0/xcodegen.zip \ --output "$RUNNER_TEMP/xcodegen.zip" @@ -100,7 +100,7 @@ jobs: - name: Upload acceptance evidence if: always() - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: ios-installed-acp-acceptance path: | diff --git a/.github/workflows/platform-build-gates.yml b/.github/workflows/platform-build-gates.yml index 9ef878195..58228fc62 100644 --- a/.github/workflows/platform-build-gates.yml +++ b/.github/workflows/platform-build-gates.yml @@ -61,14 +61,14 @@ jobs: timeout-minutes: 45 steps: - name: Checkout - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: # The version identity is derived from git tags by MinVer; a shallow clone sees no tags # and would stamp 0.0.0 into every manifest and binary. fetch-depth: 0 - name: Setup .NET - uses: actions/setup-dotnet@26b0ec14cb23fa6904739307f278c14f94c95bf1 # v5.4.0 + uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 with: global-json-file: global.json @@ -118,14 +118,14 @@ jobs: timeout-minutes: 45 steps: - name: Checkout - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: # The version identity is derived from git tags by MinVer; a shallow clone sees no tags # and would stamp 0.0.0 into every manifest and binary. fetch-depth: 0 - name: Setup .NET - uses: actions/setup-dotnet@26b0ec14cb23fa6904739307f278c14f94c95bf1 # v5.4.0 + uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 with: global-json-file: global.json @@ -189,18 +189,19 @@ jobs: # packaging chain is not, so this gate builds the package unsigned on every change and asserts the # package actually carries what its manifest declares. name: Windows MSIX Package - runs-on: windows-latest + # Match the .NET 10.0.4xx SDK with the Visual Studio 2026 XAML/MSIX toolchain. + runs-on: windows-2025-vs2026 timeout-minutes: 60 steps: - name: Checkout - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: # The version identity is derived from git tags by MinVer; a shallow clone sees no tags # and would stamp 0.0.0 into every manifest and binary. fetch-depth: 0 - name: Setup .NET - uses: actions/setup-dotnet@26b0ec14cb23fa6904739307f278c14f94c95bf1 # v5.4.0 + uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 with: global-json-file: global.json @@ -290,14 +291,14 @@ jobs: timeout-minutes: 60 steps: - name: Checkout - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: # The version identity is derived from git tags by MinVer; a shallow clone sees no tags # and would stamp 0.0.0 into every manifest and binary. fetch-depth: 0 - name: Setup .NET - uses: actions/setup-dotnet@26b0ec14cb23fa6904739307f278c14f94c95bf1 # v5.4.0 + uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 with: global-json-file: global.json @@ -355,19 +356,20 @@ jobs: name: iOS Simulator # Heavy mobile build fast-gated out of standard PRs; runs on push, schedule, and workflow_dispatch. if: github.event_name != 'pull_request' - # Pin the OS image because .NET for iOS 26.0 requires Xcode 26.0, while macos-latest can roll forward independently. - runs-on: macos-15 + # The stable Apple workload pinned in global.json requires Xcode 27. + # The matching hosted image is currently a public preview: actions/runner-images#14404. + runs-on: xcode-27 timeout-minutes: 60 steps: - name: Checkout - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: # The version identity is derived from git tags by MinVer; a shallow clone sees no tags # and would stamp 0.0.0 into every manifest and binary. fetch-depth: 0 - name: Setup .NET - uses: actions/setup-dotnet@26b0ec14cb23fa6904739307f278c14f94c95bf1 # v5.4.0 + uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 with: global-json-file: global.json @@ -377,7 +379,7 @@ jobs: xcode_developer_dir="$(python3 - <<'PY' import os - print(os.path.realpath("/Applications/Xcode_26.0.app/Contents/Developer")) + print(os.path.realpath("/Applications/Xcode_27.0.app/Contents/Developer")) PY )" if [ ! -d "${xcode_developer_dir}" ]; then @@ -389,8 +391,8 @@ jobs: xcodebuild -version xcode_version="$(xcodebuild -version | awk 'NR == 1 { print $2 }')" case "${xcode_version}" in - 26.0*) ;; - *) echo "Expected Xcode 26.0.x, got ${xcode_version}." >&2; exit 1 ;; + 27.0*) ;; + *) echo "Expected Xcode 27.0.x, got ${xcode_version}." >&2; exit 1 ;; esac xcrun --sdk macosx --show-sdk-path xcrun --sdk iphonesimulator --show-sdk-path diff --git a/.github/workflows/release-acp-sdk.yml b/.github/workflows/release-acp-sdk.yml index c309222a3..a49b0b9ea 100644 --- a/.github/workflows/release-acp-sdk.yml +++ b/.github/workflows/release-acp-sdk.yml @@ -31,12 +31,12 @@ jobs: # history (tags included) must be present. A shallow clone would pack a 0.0.0-alpha version # and the tag/version gate below would catch it - but only after the whole pack had run. - name: Checkout - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0 - name: Setup .NET - uses: actions/setup-dotnet@26b0ec14cb23fa6904739307f278c14f94c95bf1 # v5.4.0 + uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 with: global-json-file: global.json @@ -60,7 +60,7 @@ jobs: run: ./scripts/gates/run-acp-sdk-tag-version-gate.sh "${{ github.ref_name }}" "${{ env.PACKAGE_OUTPUT }}" - name: Upload ACP SDK package - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: acp-sdk-release-package path: | @@ -74,15 +74,15 @@ jobs: timeout-minutes: 25 steps: - name: Checkout - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup .NET - uses: actions/setup-dotnet@26b0ec14cb23fa6904739307f278c14f94c95bf1 # v5.4.0 + uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 with: global-json-file: global.json - name: Download ACP SDK package - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0 + uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: name: acp-sdk-release-package path: artifacts/acp-sdk-package @@ -122,19 +122,19 @@ jobs: # Sparse: global.json is the only tracked file this job touches. The package it pushes comes # from the `pack` job's artifact, not from source. - name: Checkout for the SDK pin - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: sparse-checkout: global.json sparse-checkout-cone-mode: false fetch-depth: 1 - name: Setup .NET - uses: actions/setup-dotnet@26b0ec14cb23fa6904739307f278c14f94c95bf1 # v5.4.0 + uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 with: global-json-file: global.json - name: Download ACP SDK package - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0 + uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: name: acp-sdk-release-package path: artifacts/acp-sdk-package diff --git a/.github/workflows/release-packaging.yml b/.github/workflows/release-packaging.yml index a17eef614..746c5875b 100644 --- a/.github/workflows/release-packaging.yml +++ b/.github/workflows/release-packaging.yml @@ -37,12 +37,12 @@ jobs: timeout-minutes: 45 steps: - name: Checkout - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0 - name: Setup .NET - uses: actions/setup-dotnet@26b0ec14cb23fa6904739307f278c14f94c95bf1 # v5.4.0 + uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 with: global-json-file: global.json @@ -61,7 +61,7 @@ jobs: run: scripts/gates/run-release-artifact-contract-gate.sh wasm publish/wasm - name: Upload WebAssembly artifact - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: wasm-build path: publish/wasm @@ -72,12 +72,12 @@ jobs: timeout-minutes: 60 steps: - name: Checkout - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0 - name: Setup .NET - uses: actions/setup-dotnet@26b0ec14cb23fa6904739307f278c14f94c95bf1 # v5.4.0 + uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 with: global-json-file: global.json @@ -223,7 +223,7 @@ jobs: (Join-Path $wixObjDir "Harvest.wixobj") - name: Upload Desktop artifact - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: desktop-windows-build path: publish/desktop-windows @@ -260,23 +260,24 @@ jobs: [void][Runtime.InteropServices.Marshal]::FinalReleaseComObject($installer) } - name: Upload Windows Skia MSI artifact - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: desktop-windows-skia-msi path: artifacts/installer/*.msi package-windows-msix: name: Package Windows MSIX - runs-on: windows-latest + # Match the .NET 10.0.4xx SDK with the Visual Studio 2026 XAML/MSIX toolchain. + runs-on: windows-2025-vs2026 timeout-minutes: 60 steps: - name: Checkout - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0 - name: Setup .NET - uses: actions/setup-dotnet@26b0ec14cb23fa6904739307f278c14f94c95bf1 # v5.4.0 + uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 with: global-json-file: global.json @@ -391,7 +392,7 @@ jobs: ./scripts/gates/run-msix-package-contract-gate.ps1 -Package $package.FullName - name: Upload Windows MSIX artifact - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: desktop-windows-msix path: artifacts/msix/**/*.msix @@ -414,12 +415,12 @@ jobs: MACOS_NOTARY_PROFILE: ${{ secrets.MACOS_NOTARY_PROFILE }} steps: - name: Checkout - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0 - name: Setup .NET - uses: actions/setup-dotnet@26b0ec14cb23fa6904739307f278c14f94c95bf1 # v5.4.0 + uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 with: global-json-file: global.json @@ -549,7 +550,7 @@ jobs: run: scripts/gates/run-macos-pkg-artifact-gate.sh "$PKG_PATH" - name: Upload macOS installer package artifact - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: desktop-macos-pkg path: | @@ -558,14 +559,14 @@ jobs: if-no-files-found: error - name: Upload macOS bundle artifact - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: desktop-macos-bundle path: publish/macos-bundle/* - name: Upload macOS .dmg artifact if: env.MACOS_APP_CODESIGN_KEY != '' && env.MACOS_DMG_CODESIGN_KEY != '' - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: desktop-macos-dmg path: publish/dmg/*.dmg @@ -576,14 +577,14 @@ jobs: timeout-minutes: 60 steps: - name: Checkout - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: # The version identity is derived from git tags by MinVer; a shallow clone sees no tags and # would stamp 0.0.0 into the package version, which no later release could upgrade over. fetch-depth: 0 - name: Setup .NET - uses: actions/setup-dotnet@26b0ec14cb23fa6904739307f278c14f94c95bf1 # v5.4.0 + uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 with: global-json-file: global.json @@ -621,7 +622,7 @@ jobs: run: scripts/gates/run-desktop-linux-package-smoke.sh "${{ steps.build-deb.outputs.deb-path }}" - name: Upload Linux desktop package artifact - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: desktop-linux-deb path: | @@ -649,49 +650,49 @@ jobs: steps: - name: Download Windows MSIX artifact if: needs.package-windows-msix.result == 'success' - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0 + uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: name: desktop-windows-msix path: windows-msix - name: Download WebAssembly artifact if: needs.package-wasm.result == 'success' - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0 + uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: name: wasm-build path: wasm-build - name: Download Windows Skia MSI artifact if: needs.package-desktop.result == 'success' - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0 + uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: name: desktop-windows-skia-msi path: windows-skia-msi - name: Download macOS bundle artifact if: needs.package-macos.result == 'success' - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0 + uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: name: desktop-macos-bundle path: macos-bundle - name: Download macOS installer package artifact if: needs.package-macos.result == 'success' - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0 + uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: name: desktop-macos-pkg path: macos-pkg - name: Download macOS .dmg artifact if: needs.package-macos.outputs.dmg-produced == 'true' - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0 + uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: name: desktop-macos-dmg path: macos-dmg - name: Download Linux desktop package artifact if: needs.package-linux-desktop.result == 'success' - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0 + uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: name: desktop-linux-deb path: linux-deb diff --git a/.github/workflows/terminal-auth-windows.yml b/.github/workflows/terminal-auth-windows.yml index 6da47248e..739efd6c0 100644 --- a/.github/workflows/terminal-auth-windows.yml +++ b/.github/workflows/terminal-auth-windows.yml @@ -25,11 +25,11 @@ jobs: MSBUILDDISABLENODEREUSE: 1 steps: - name: Checkout - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0 - name: Setup .NET - uses: actions/setup-dotnet@26b0ec14cb23fa6904739307f278c14f94c95bf1 # v5.4.0 + uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 with: global-json-file: global.json - name: Run actual ConPTY process and teardown gate @@ -37,7 +37,7 @@ jobs: run: ./scripts/gates/run-terminal-auth-windows-gate.ps1 - name: Upload terminal authentication results if: always() - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: terminal-auth-windows-results path: artifacts/terminal-auth-windows diff --git a/.github/workflows/wasm-smoke-gates.yml b/.github/workflows/wasm-smoke-gates.yml index 6b6a90801..c7e9a0924 100644 --- a/.github/workflows/wasm-smoke-gates.yml +++ b/.github/workflows/wasm-smoke-gates.yml @@ -49,17 +49,17 @@ jobs: timeout-minutes: 45 steps: - name: Checkout - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup .NET - uses: actions/setup-dotnet@26b0ec14cb23fa6904739307f278c14f94c95bf1 # v5.4.0 + uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 with: global-json-file: global.json - name: Setup Node - uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0 + uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: - node-version: "24" + node-version: "26.10.0" - name: Install browser dependencies run: npx --yes playwright install --with-deps chromium diff --git a/.github/workflows/windows-packaged-gui-acceptance.yml b/.github/workflows/windows-packaged-gui-acceptance.yml index 4f342807c..ca11e7dc7 100644 --- a/.github/workflows/windows-packaged-gui-acceptance.yml +++ b/.github/workflows/windows-packaged-gui-acceptance.yml @@ -35,7 +35,8 @@ concurrency: jobs: packaged-gui: name: Windows Installed WinUI GUI - runs-on: windows-latest + # Match the .NET 10.0.4xx SDK with the Visual Studio 2026 XAML/MSIX toolchain. + runs-on: windows-2025-vs2026 timeout-minutes: 80 env: DOTNET_PROCESSOR_COUNT: '2' @@ -44,11 +45,11 @@ jobs: UseSharedCompilation: 'false' steps: - name: Checkout - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0 - name: Setup .NET - uses: actions/setup-dotnet@26b0ec14cb23fa6904739307f278c14f94c95bf1 # v5.4.0 + uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 with: global-json-file: global.json - name: Verify the hosted interactive desktop with real input @@ -76,7 +77,7 @@ jobs: run: python scripts/gates/windows-elicitation-reverse-verification.py - name: Upload installed-product and desktop evidence if: always() - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: windows-packaged-gui-acceptance path: | diff --git a/BUILD_GUIDE.md b/BUILD_GUIDE.md index 021805b20..c0fc1eff0 100644 --- a/BUILD_GUIDE.md +++ b/BUILD_GUIDE.md @@ -16,7 +16,7 @@ dotnet --version dotnet --info ``` -仓库通过 `global.json` 锁定 .NET SDK `10.0.302`,允许同一 feature band 内的 patch 前滚;Uno SDK 锁定为 `6.7.30`。版本不匹配时先安装 .NET 10 SDK,不要手改项目 TFM 或 `global.json`。 +仓库通过 `global.json` 锁定 .NET SDK `10.0.401`,允许同一 feature band 内的 patch 前滚;Uno SDK 锁定为 `6.7.30`,workload set 锁定为 `10.0.401.1`。所有子目录共用根目录的 `global.json`。版本不匹配时先安装 .NET 10 SDK,不要手改项目 TFM 或 `global.json`。 ### 必需与可选依赖 @@ -24,7 +24,7 @@ dotnet --info |------|--------------| | Desktop / Core | .NET 10 SDK;Linux 还需要下方的原生库 | | BrowserWasm | .NET 10 SDK + `wasm-tools` workload | -| Windows MSIX | Visual Studio 18.8+ 或 Build Tools;MSBuild、C++ 构建工具、Windows SDK `10.0.26100.0`;`signtool` 使用 SDK `10.0.22621.0` | +| Windows MSIX | Visual Studio 18.9.3+ 或 Build Tools;MSBuild、C++ 构建工具、Windows SDK `10.0.26100.0`;`signtool` 使用 SDK `10.0.22621.0` | | Android | Android workload、Android SDK 和 Java JDK 17+;默认构建不启用 Android | | iOS | macOS、匹配的 Xcode 和 iOS workload;默认构建不启用 iOS | @@ -138,7 +138,7 @@ run.bat desktop ### 1. 环境要求 - **.NET SDK**: 10.0 或更高版本 - - 推荐版本:10.0.302(允许 patch 前滚) + - 推荐版本:10.0.401(允许 patch 前滚) - 下载地址: https://dotnet.microsoft.com/download/dotnet/10.0 - **操作系统**: @@ -163,7 +163,7 @@ Linux 桌面运行时依赖按能力分层(包名以 Debian/Ubuntu 为例) # 检查 .NET SDK 版本 dotnet --version -# 应该输出 10.0.302 或兼容的 10.0.3xx patch 版本 +# 应该输出 10.0.401 或兼容的 10.0.4xx patch 版本 ``` ### 3. 克隆代码(如果还没有) @@ -227,7 +227,7 @@ run.bat > 证书复用:`.tools/run-winui3-msix.ps1` 现在会复用同一张开发证书,不应再在每次 `run.bat msix` 时重建证书或反复要求安装证书。 > 历史根因:脚本曾使用 PowerShell 中不可靠的 `$Cert.GetRSAPrivateKey()` 调用来判断私钥可用性,导致有效的 RSA 私钥被误判为不可用,进而每次重建新证书;现已改为标准的 `RSACertificateExtensions.GetRSAPrivateKey(...)`。 > 工具链锁定:Windows SDK 10.0.26100.0,signtool 来自 SDK 10.0.22621.0。 -> Workload manifest:CI 应与 `global.json` 中的 .NET SDK feature band 保持一致;当前仓库锁定 10.0.302,并使用 `rollForward: latestPatch`。所有 GHA 均使用 `setup-dotnet` 官方支持的 `10.0.3xx` 语法,只在同一 feature band 内前滚 patch,避免 workload manifest 与 Xcode 独立漂移。 +> Workload manifest:CI 应与 `global.json` 中的 .NET SDK feature band 保持一致;当前仓库锁定 10.0.401,并使用 `rollForward: latestPatch`。所有 GHA 均使用 `setup-dotnet` 的 `global-json-file` 读取同一锁定文件;`sdk.workloadVersion` 固定为 `10.0.401.1`,安装 workload 时不再单独指定版本。iOS 编译与安装门禁共用 Xcode 27.0 和官方 `xcode-27` runner(runner 镜像仍为 public preview),对应 [Apple workload 发布说明](https://github.com/dotnet/macios/releases/tag/dotnet-10.0.1xx-xcode27.0-10722)。 > 验证口径:`dotnet build -f net10.0-windows10.0.26100.0` 不是本仓库的权威 WinUI 3 / MSIX 门禁;Windows 原生包请以 `build.bat msix` 或 `.tools/run-winui3-msix.ps1 -SkipInstall` 为准。`dotnet build` 主要用于 Core/Skia/Desktop/Wasm 验证。 #### Linux Headless Desktop diff --git a/README.en.md b/README.en.md index 2be90e8ef..a97724b07 100644 --- a/README.en.md +++ b/README.en.md @@ -51,7 +51,7 @@ Screenshots come from the store listing. In the app, **Settings → About** prov ## Tech Stack - Uno Platform 6.7+ (repo pin: `Uno.Sdk` 6.7.30) -- .NET 10 (repo pin: SDK 10.0.302, with 10.0.3xx patch roll-forward) +- .NET 10 (repo pin: SDK 10.0.401, with 10.0.4xx patch roll-forward) - WinUI 3 on Windows - Clean Architecture + MVVM @@ -78,8 +78,8 @@ For environment requirements and detailed build steps, start with [BUILD_GUIDE.m ### Requirements -- .NET SDK **10.0.302** or a compatible **10.0.3xx** patch (see `global.json`) -- Windows 10 1809+ / Windows 11 for WinUI 3 and MSIX validation; on Windows prefer Visual Studio **18.8+** +- .NET SDK **10.0.401** or a compatible **10.0.4xx** patch (see `global.json`) +- Windows 10 1809+ / Windows 11 for WinUI 3 and MSIX validation; on Windows prefer Visual Studio **18.9.3+** - Or an equivalent command-line toolchain (Linux/macOS can build Desktop / WASM) ### Common Commands diff --git a/README.md b/README.md index f1091117c..cdb818ad7 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ Salmon Egg 已在 Microsoft Store 上架,免费下载。商店页面的正式 ## 技术栈 - Uno Platform 6.7+(仓库锁定 `Uno.Sdk` 6.7.30) -- .NET 10(仓库锁定 SDK 10.0.302,允许 10.0.3xx patch 前滚) +- .NET 10(仓库锁定 SDK 10.0.401,允许 10.0.4xx patch 前滚) - WinUI 3(Windows) - Clean Architecture + MVVM @@ -80,8 +80,8 @@ iOS 原生 UIKit 在当前 Uno 6.7.103 下使用平台内的官方导航模板 ### 环境要求 -- .NET SDK **10.0.302** 或兼容的 **10.0.3xx** patch(见 `global.json`) -- Windows 10 1809+ / Windows 11(WinUI 3 / MSIX);Windows 建议 Visual Studio **18.8+** +- .NET SDK **10.0.401** 或兼容的 **10.0.4xx** patch(见 `global.json`) +- Windows 10 1809+ / Windows 11(WinUI 3 / MSIX);Windows 建议 Visual Studio **18.9.3+** - 或等效命令行工具链(Linux/macOS 可构建 Desktop / WASM) ### 常用命令 diff --git a/SalmonEgg/global.json b/SalmonEgg/global.json deleted file mode 100644 index 2e1711d9c..000000000 --- a/SalmonEgg/global.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - // To update the version of Uno please update the version of the Uno.Sdk here. See https://aka.platform.uno/upgrade-uno-packages for more information. - "msbuild-sdks": { - "Uno.Sdk": "6.7.30" - }, - "sdk": { - "allowPrerelease": false - } -} diff --git a/docs/release-guide.md b/docs/release-guide.md index e7cecf47e..e0b65233f 100644 --- a/docs/release-guide.md +++ b/docs/release-guide.md @@ -21,7 +21,7 @@ ### 通用要求 - .NET 10.0 SDK 或更高版本 -- Visual Studio 18.8+ 或 Visual Studio Code +- Visual Studio 18.9.3+ 或 Visual Studio Code - Git ### 平台特定要求 diff --git a/global.json b/global.json index 44af54c7d..dbd284d41 100644 --- a/global.json +++ b/global.json @@ -3,7 +3,8 @@ "Uno.Sdk": "6.7.30" }, "sdk": { - "version": "10.0.302", + "version": "10.0.401", + "workloadVersion": "10.0.401.1", "rollForward": "latestPatch", "allowPrerelease": false }, diff --git a/scripts/gates/run-acp-published-bridge-gate.py b/scripts/gates/run-acp-published-bridge-gate.py index d7599b9db..99c7d474a 100644 --- a/scripts/gates/run-acp-published-bridge-gate.py +++ b/scripts/gates/run-acp-published-bridge-gate.py @@ -33,7 +33,7 @@ def main(): output.mkdir(parents=True, exist_ok=True) bridge_path = shutil.which(args.bridge) if bridge_path is None: - raise SystemExit("Install acpremote==1.9.0 in an isolated environment before running this gate.") + raise SystemExit("Install the acpremote version pinned in .github/workflows/ci-core.yml in an isolated environment before running this gate.") with socket.socket() as listener: listener.bind(("127.0.0.1", 0)) port = listener.getsockname()[1] diff --git a/tests/SalmonEgg.Presentation.Core.Tests/WasmStartupAssetsTests.cs b/tests/SalmonEgg.Presentation.Core.Tests/WasmStartupAssetsTests.cs index 9ecf3e18c..8300e9e09 100644 --- a/tests/SalmonEgg.Presentation.Core.Tests/WasmStartupAssetsTests.cs +++ b/tests/SalmonEgg.Presentation.Core.Tests/WasmStartupAssetsTests.cs @@ -317,12 +317,12 @@ public void PlatformBuildGate_IsolatesMobileRestoreGraphsAndPinsIosToolchain() Assert.True( gate.IndexOf("Verify iOS .NET SDK", StringComparison.Ordinal) < gate.IndexOf("Install iOS workload", StringComparison.Ordinal)); - Assert.Contains("runs-on: macos-15", gate, StringComparison.Ordinal); - Assert.Contains("os.path.realpath(\"/Applications/Xcode_26.0.app/Contents/Developer\")", gate, StringComparison.Ordinal); + Assert.Contains("runs-on: xcode-27", gate, StringComparison.Ordinal); + Assert.Contains("os.path.realpath(\"/Applications/Xcode_27.0.app/Contents/Developer\")", gate, StringComparison.Ordinal); Assert.Contains("sudo xcode-select --switch \"${xcode_developer_dir}\"", gate, StringComparison.Ordinal); - Assert.DoesNotContain("xcode-select --switch /Applications/Xcode_26.0.app/Contents/Developer", gate, StringComparison.Ordinal); + Assert.DoesNotContain("xcode-select --switch /Applications/Xcode_", gate, StringComparison.Ordinal); Assert.Contains("xcodebuild -version", gate, StringComparison.Ordinal); - Assert.Contains("26.0*)", gate, StringComparison.Ordinal); + Assert.Contains("27.0*)", gate, StringComparison.Ordinal); Assert.Contains("xcrun --sdk macosx --show-sdk-path", gate, StringComparison.Ordinal); Assert.Contains("xcrun --sdk iphonesimulator --show-sdk-path", gate, StringComparison.Ordinal); Assert.Contains("xcrun --sdk macosx --find actool", gate, StringComparison.Ordinal); @@ -357,7 +357,6 @@ public void DotnetWorkflows_PinRepositorySdkFeatureBand() @".github\workflows\wasm-smoke-gates.yml" ]; - Assert.Contains("\"version\": \"10.0.302\"", globalJson, StringComparison.Ordinal); Assert.Contains("\"rollForward\": \"latestPatch\"", globalJson, StringComparison.Ordinal); foreach (var workflowPath in workflowPaths) { From 3bc66e9ce10ce9256490080c75725002340521d7 Mon Sep 17 00:00:00 2001 From: Shangxin Date: Wed, 7 Oct 2026 15:17:28 +0000 Subject: [PATCH 02/11] chore(deps): bump Graph, MSAL, Windows App SDK 1.8 and test packages - Microsoft.Graph 6.7.0 -> 6.8.0 - Microsoft.Identity.Client(.Extensions.Msal) 4.90.0 -> 4.90.1 - Microsoft.WindowsAppSDK 1.8.260804001 -> 1.8.260921001; WinUI stays at 1.8.260803003, the exact version this meta-package pins in its nuspec - Porta.Pty 2.2.2 -> 2.2.3, Websocket.Client 5.5.0 -> 5.5.1 - coverlet.MTP 10.0.1 -> 10.1.0, Moq 4.20.72 -> 4.21.0 Windows App SDK 2.x is intentionally deferred until Uno 6.7 and MSIX packaging are validated on it. Co-Authored-By: Claude Opus 5.5 (1M context) --- SalmonEgg/Directory.Packages.props | 11 ++++++----- .../SalmonEgg.Infrastructure.Desktop.csproj | 2 +- .../SalmonEgg.Infrastructure.csproj | 2 +- tests/SalmonEgg.Acp.Tests/SalmonEgg.Acp.Tests.csproj | 4 ++-- .../SalmonEgg.Application.Tests.csproj | 4 ++-- tests/SalmonEgg.Cli.Tests/SalmonEgg.Cli.Tests.csproj | 2 +- .../SalmonEgg.Domain.Tests.csproj | 2 +- .../SalmonEgg.GuiTests.Windows.csproj | 2 +- .../SalmonEgg.Infrastructure.Tests.csproj | 4 ++-- .../SalmonEgg.Presentation.Core.Tests.csproj | 4 ++-- 10 files changed, 19 insertions(+), 18 deletions(-) diff --git a/SalmonEgg/Directory.Packages.props b/SalmonEgg/Directory.Packages.props index e3a7018cd..d4ce11d59 100644 --- a/SalmonEgg/Directory.Packages.props +++ b/SalmonEgg/Directory.Packages.props @@ -18,11 +18,12 @@ - - - - - + + + + + diff --git a/src/SalmonEgg.Infrastructure.Desktop/SalmonEgg.Infrastructure.Desktop.csproj b/src/SalmonEgg.Infrastructure.Desktop/SalmonEgg.Infrastructure.Desktop.csproj index 97d4fccfc..4df4c7a8e 100644 --- a/src/SalmonEgg.Infrastructure.Desktop/SalmonEgg.Infrastructure.Desktop.csproj +++ b/src/SalmonEgg.Infrastructure.Desktop/SalmonEgg.Infrastructure.Desktop.csproj @@ -7,7 +7,7 @@ - + diff --git a/src/SalmonEgg.Infrastructure/SalmonEgg.Infrastructure.csproj b/src/SalmonEgg.Infrastructure/SalmonEgg.Infrastructure.csproj index 065acb49e..9e33300f5 100644 --- a/src/SalmonEgg.Infrastructure/SalmonEgg.Infrastructure.csproj +++ b/src/SalmonEgg.Infrastructure/SalmonEgg.Infrastructure.csproj @@ -15,7 +15,7 @@ - + diff --git a/tests/SalmonEgg.Acp.Tests/SalmonEgg.Acp.Tests.csproj b/tests/SalmonEgg.Acp.Tests/SalmonEgg.Acp.Tests.csproj index 5b410f3ec..bdbdd38b0 100644 --- a/tests/SalmonEgg.Acp.Tests/SalmonEgg.Acp.Tests.csproj +++ b/tests/SalmonEgg.Acp.Tests/SalmonEgg.Acp.Tests.csproj @@ -15,9 +15,9 @@ - + - + diff --git a/tests/SalmonEgg.Application.Tests/SalmonEgg.Application.Tests.csproj b/tests/SalmonEgg.Application.Tests/SalmonEgg.Application.Tests.csproj index 40a10e18d..c2431dcc6 100644 --- a/tests/SalmonEgg.Application.Tests/SalmonEgg.Application.Tests.csproj +++ b/tests/SalmonEgg.Application.Tests/SalmonEgg.Application.Tests.csproj @@ -11,9 +11,9 @@ - + - + diff --git a/tests/SalmonEgg.Cli.Tests/SalmonEgg.Cli.Tests.csproj b/tests/SalmonEgg.Cli.Tests/SalmonEgg.Cli.Tests.csproj index d809fca89..844b9ad93 100644 --- a/tests/SalmonEgg.Cli.Tests/SalmonEgg.Cli.Tests.csproj +++ b/tests/SalmonEgg.Cli.Tests/SalmonEgg.Cli.Tests.csproj @@ -10,7 +10,7 @@ - + diff --git a/tests/SalmonEgg.Domain.Tests/SalmonEgg.Domain.Tests.csproj b/tests/SalmonEgg.Domain.Tests/SalmonEgg.Domain.Tests.csproj index 4d34ce762..3e2bb8dac 100644 --- a/tests/SalmonEgg.Domain.Tests/SalmonEgg.Domain.Tests.csproj +++ b/tests/SalmonEgg.Domain.Tests/SalmonEgg.Domain.Tests.csproj @@ -9,7 +9,7 @@ - + diff --git a/tests/SalmonEgg.GuiTests.Windows/SalmonEgg.GuiTests.Windows.csproj b/tests/SalmonEgg.GuiTests.Windows/SalmonEgg.GuiTests.Windows.csproj index 9db1d8890..23ad6c955 100644 --- a/tests/SalmonEgg.GuiTests.Windows/SalmonEgg.GuiTests.Windows.csproj +++ b/tests/SalmonEgg.GuiTests.Windows/SalmonEgg.GuiTests.Windows.csproj @@ -10,7 +10,7 @@ - + diff --git a/tests/SalmonEgg.Infrastructure.Tests/SalmonEgg.Infrastructure.Tests.csproj b/tests/SalmonEgg.Infrastructure.Tests/SalmonEgg.Infrastructure.Tests.csproj index 18bf656e1..fb60519ce 100644 --- a/tests/SalmonEgg.Infrastructure.Tests/SalmonEgg.Infrastructure.Tests.csproj +++ b/tests/SalmonEgg.Infrastructure.Tests/SalmonEgg.Infrastructure.Tests.csproj @@ -11,10 +11,10 @@ - + - + diff --git a/tests/SalmonEgg.Presentation.Core.Tests/SalmonEgg.Presentation.Core.Tests.csproj b/tests/SalmonEgg.Presentation.Core.Tests/SalmonEgg.Presentation.Core.Tests.csproj index 2d6f173b1..6729728c8 100644 --- a/tests/SalmonEgg.Presentation.Core.Tests/SalmonEgg.Presentation.Core.Tests.csproj +++ b/tests/SalmonEgg.Presentation.Core.Tests/SalmonEgg.Presentation.Core.Tests.csproj @@ -9,8 +9,8 @@ - - + + From 3bcfc36835bbc1e97ae28071030b936e3ac8c0e2 Mon Sep 17 00:00:00 2001 From: Shangxin Date: Wed, 7 Oct 2026 15:37:37 +0000 Subject: [PATCH 03/11] fix(sdk): drop the global.json workloadVersion pin sdk.workloadVersion makes the MSBuild workload resolver require that exact workload set, so every project fails with MSB4242 on a fresh runner that has not installed it, including jobs that need no workload at all. It also rejects the --skip-manifest-update flag our workload install steps use. Workload manifests follow the SDK feature band again, as on main; BUILD_GUIDE records why the field is intentionally absent. Co-Authored-By: Claude Opus 5.5 (1M context) --- BUILD_GUIDE.md | 4 ++-- global.json | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/BUILD_GUIDE.md b/BUILD_GUIDE.md index c0fc1eff0..f4df0b305 100644 --- a/BUILD_GUIDE.md +++ b/BUILD_GUIDE.md @@ -16,7 +16,7 @@ dotnet --version dotnet --info ``` -仓库通过 `global.json` 锁定 .NET SDK `10.0.401`,允许同一 feature band 内的 patch 前滚;Uno SDK 锁定为 `6.7.30`,workload set 锁定为 `10.0.401.1`。所有子目录共用根目录的 `global.json`。版本不匹配时先安装 .NET 10 SDK,不要手改项目 TFM 或 `global.json`。 +仓库通过 `global.json` 锁定 .NET SDK `10.0.401`,允许同一 feature band 内的 patch 前滚;Uno SDK 锁定为 `6.7.30`。所有子目录共用根目录的 `global.json`。版本不匹配时先安装 .NET 10 SDK,不要手改项目 TFM 或 `global.json`。 ### 必需与可选依赖 @@ -227,7 +227,7 @@ run.bat > 证书复用:`.tools/run-winui3-msix.ps1` 现在会复用同一张开发证书,不应再在每次 `run.bat msix` 时重建证书或反复要求安装证书。 > 历史根因:脚本曾使用 PowerShell 中不可靠的 `$Cert.GetRSAPrivateKey()` 调用来判断私钥可用性,导致有效的 RSA 私钥被误判为不可用,进而每次重建新证书;现已改为标准的 `RSACertificateExtensions.GetRSAPrivateKey(...)`。 > 工具链锁定:Windows SDK 10.0.26100.0,signtool 来自 SDK 10.0.22621.0。 -> Workload manifest:CI 应与 `global.json` 中的 .NET SDK feature band 保持一致;当前仓库锁定 10.0.401,并使用 `rollForward: latestPatch`。所有 GHA 均使用 `setup-dotnet` 的 `global-json-file` 读取同一锁定文件;`sdk.workloadVersion` 固定为 `10.0.401.1`,安装 workload 时不再单独指定版本。iOS 编译与安装门禁共用 Xcode 27.0 和官方 `xcode-27` runner(runner 镜像仍为 public preview),对应 [Apple workload 发布说明](https://github.com/dotnet/macios/releases/tag/dotnet-10.0.1xx-xcode27.0-10722)。 +> Workload manifest:CI 应与 `global.json` 中的 .NET SDK feature band 保持一致;当前仓库锁定 10.0.401,并使用 `rollForward: latestPatch`。所有 GHA 均使用 `setup-dotnet` 的 `global-json-file` 读取同一锁定文件。`global.json` 不设 `sdk.workloadVersion`:该字段会让 MSBuild 在未装 workload 的 runner 上直接解析失败,且与 `--skip-manifest-update` 互斥;workload 清单随 SDK feature band 走。iOS 编译与安装门禁共用 Xcode 27.0 和官方 `xcode-27` runner(runner 镜像仍为 public preview),对应 [Apple workload 发布说明](https://github.com/dotnet/macios/releases/tag/dotnet-10.0.1xx-xcode27.0-10722)。 > 验证口径:`dotnet build -f net10.0-windows10.0.26100.0` 不是本仓库的权威 WinUI 3 / MSIX 门禁;Windows 原生包请以 `build.bat msix` 或 `.tools/run-winui3-msix.ps1 -SkipInstall` 为准。`dotnet build` 主要用于 Core/Skia/Desktop/Wasm 验证。 #### Linux Headless Desktop diff --git a/global.json b/global.json index dbd284d41..971e0cd6c 100644 --- a/global.json +++ b/global.json @@ -4,7 +4,6 @@ }, "sdk": { "version": "10.0.401", - "workloadVersion": "10.0.401.1", "rollForward": "latestPatch", "allowPrerelease": false }, From 63b291af17a95f5075d12f6e086a0bd389b9ff7c Mon Sep 17 00:00:00 2001 From: Shangxin Date: Wed, 7 Oct 2026 15:56:17 +0000 Subject: [PATCH 04/11] build(ios): raise the minimum iOS version to 15.0 Uno.Sdk 6.7.30 still defaults SupportedOSPlatformVersion to 14.2 for iOS, but the Xcode 27 Apple workload (Microsoft.iOS.Sdk 27.0) that ships with the 10.0.401 SDK band fails the build below 15.0. iOS 15 runs on exactly the devices iOS 14 did, so no supported hardware is dropped. Co-Authored-By: Claude Opus 5.5 (1M context) --- SalmonEgg/SalmonEgg/SalmonEgg.csproj | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/SalmonEgg/SalmonEgg/SalmonEgg.csproj b/SalmonEgg/SalmonEgg/SalmonEgg.csproj index 2fbb15b35..0072af31c 100644 --- a/SalmonEgg/SalmonEgg/SalmonEgg.csproj +++ b/SalmonEgg/SalmonEgg/SalmonEgg.csproj @@ -302,6 +302,13 @@ false + + + 15.0 + + - 15.0 - -