name: Full native tests on: workflow_dispatch: inputs: windows_diagnostics_run: description: Diagnose a previous Windows runtime without running a release validation type: string default: "" workflow_call: push: branches: [main] # Include docs, catalogs, assets and workflow edits: every PR gets test results. # 草稿已跑完整矩阵,转为 Ready 而没有新提交时不重复申请五个原生 runner。 pull_request: types: [opened, synchronize, reopened] merge_group: concurrency: group: native-${{ github.workflow }}-${{ github.event_name }}-${{ github.ref }} # main 的过期验证也应释放 runner;手动诊断和发布调用不互相取消。 cancel-in-progress: ${{ github.event_name == 'pull_request' || github.event_name == 'merge_group' || (github.event_name == 'push' && github.ref == 'refs/heads/main') }} permissions: contents: read actions: read jobs: windows-diagnostics: if: ${{ github.event_name == 'workflow_dispatch' && inputs.windows_diagnostics_run != '' }} uses: ./.github/workflows/windows-conformance.yml with: runtime_run: ${{ inputs.windows_diagnostics_run }} # rustfmt only for now. clippy joins once the existing warning backlog is # cleared; several crates deny lints, so it cannot run advisory. lint: if: ${{ inputs.windows_diagnostics_run == '' }} name: lint outputs: native_matrix: ${{ steps.matrix.outputs.native_matrix }} release_matrix: ${{ steps.matrix.outputs.release_matrix }} runs-on: ubuntu-24.04 timeout-minutes: 10 steps: - uses: actions/checkout@v4 with: persist-credentials: false - uses: dtolnay/rust-toolchain@stable with: toolchain: "1.97.1" components: rustfmt - name: rustfmt run: cargo fmt --all -- --check - uses: actions/setup-python@v5 with: python-version: "3.13" - name: Test CI contracts before matrix planning run: | python3 -m unittest \ scripts.tests.test_ci_plan \ scripts.tests.test_ci_native_tests \ scripts.tests.test_stable_release \ scripts.tests.test_ci_cache \ scripts.tests.test_platform_cfg \ scripts.tests.test_pr_size_workflow \ scripts.tests.test_copilot_review_workflow -v - name: Check platform cfg budget before native jobs run: python3 scripts/check_platform_cfg.py - name: Plan native validation id: matrix shell: bash run: | python scripts/ci_plan.py \ --event-name "$GITHUB_EVENT_NAME" \ --event-path "$GITHUB_EVENT_PATH" \ --output "$GITHUB_OUTPUT" # The required lint job validates the matrix before heavy runners are # requested. Every PR, including a draft, requires the complete matrix. native-tests: needs: lint if: ${{ inputs.windows_diagnostics_run == '' }} name: Tests (${{ matrix.os }}) strategy: fail-fast: false matrix: include: ${{ fromJSON(needs.lint.outputs.native_matrix) }} runs-on: ${{ matrix.os }} timeout-minutes: 120 env: PYTHONUTF8: "1" CARGO_TERM_COLOR: always RUST_BACKTRACE: "1" RUST_TOOLCHAIN: "1.97.1" steps: - uses: actions/checkout@v4 with: persist-credentials: false fetch-depth: 0 - uses: actions/setup-python@v5 with: python-version: "3.13" - name: Install native dependencies if: ${{ runner.os == 'Linux' }} run: | sudo apt-get update sudo apt-get install -y --no-install-recommends \ build-essential cmake pkg-config zsh libasound2-dev libdbus-1-dev libudev-dev \ libfontconfig1-dev libfreetype6-dev \ libegl1-mesa-dev libgl1-mesa-dev \ libwayland-dev libxkbcommon-dev libxkbcommon-x11-dev \ libx11-xcb-dev libxcb1-dev libxcb-render0-dev \ libxcb-shape0-dev libxcb-xfixes0-dev libxcb-xinput-dev libxcb-xkb-dev libxi-dev - name: Require the AppKit SDK used by this PR if: ${{ runner.os == 'macOS' }} run: | sdk_version="$(xcrun --sdk macosx --show-sdk-version)" test "${sdk_version%%.*}" -ge 26 - uses: dtolnay/rust-toolchain@stable with: toolchain: "1.97.1" - name: Require a native Windows ARM64 compiler if: ${{ matrix.os == 'windows-11-arm' }} shell: pwsh run: | if ([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture -ne 'Arm64') { throw 'The Windows ARM job requires an ARM64 host.' } $compiler = rustc -vV if ($LASTEXITCODE -ne 0 -or $compiler -notcontains 'host: aarch64-pc-windows-msvc') { throw 'The Windows ARM job must compile and run ARM64 tests.' } - name: Install the pinned native test runner uses: taiki-e/install-action@v2 with: tool: cargo-nextest@0.9.146 - uses: ./.github/actions/rust-cache id: rust-cache with: key: native extra-key: ${{ runner.os != 'macOS' && '-release-check-v2' || '' }} target: | target/ci ${{ runner.os != 'macOS' && 'target/release' || '' }} # PR merge-ref 缓存不与其他 PR 共享;只由默认分支维护可复用的依赖快照。 revision: dependencies-v1 save-if: ${{ github.ref == format('refs/heads/{0}', github.event.repository.default_branch) }} # 构建前计算两类缓存身份,避免生成文件进入 hashFiles 后改变原有缓存键。 # release 保留独立产物路径,但不重复恢复同一份源码下载。 - name: Restore macOS release workload if: ${{ !cancelled() && runner.os == 'macOS' }} uses: ./.github/actions/rust-cache id: macos-release-cache with: key: native-release-check target: target/release revision: dependencies-v1 save-if: ${{ github.ref == format('refs/heads/{0}', github.event.repository.default_branch) }} restore-downloads: "false" - name: Prepare pinned Windows console runtime if: ${{ runner.os == 'Windows' }} shell: pwsh run: | $architecture = if ('${{ runner.arch }}' -eq 'ARM64') { 'arm64' } else { 'x64' } ./scripts/prepare-windows-runtime.ps1 -Destination assets/windows/conhost -Architecture $architecture ./scripts/tests/windows-runtime.tests.ps1 -Architecture $architecture - name: Test complete workspace and native harness run: python scripts/ci_native_tests.py --runner nextest - name: Check source architecture if: ${{ !cancelled() && runner.os == 'Linux' }} run: python scripts/check_architecture.py - name: Test translation and allocation contracts if: ${{ !cancelled() && runner.os == 'Linux' }} run: cargo test --locked --manifest-path tools/i18n-contract/Cargo.toml - name: Check the release workspace if: ${{ !cancelled() && runner.os != 'macOS' }} run: cargo check --locked --workspace --release # Mac 原生快照先于 release 检查保存,避免后者失败或取消丢掉已验证的编译结果。 - name: Save compiled workload if: ${{ success() && steps.rust-cache.outputs.save-enabled == 'true' && steps.rust-cache.outputs.cache-hit != 'true' }} uses: actions/cache/save@v4 with: path: | target/ci ${{ runner.os != 'macOS' && 'target/release' || '' }} key: ${{ steps.rust-cache.outputs.cache-key }} - name: Check macOS release workspace if: ${{ !cancelled() && runner.os == 'macOS' }} run: cargo check --locked --workspace --release --timings - name: Save macOS release workload if: ${{ success() && steps.macos-release-cache.outputs.save-enabled == 'true' && steps.macos-release-cache.outputs.cache-hit != 'true' }} uses: actions/cache/save@v4 with: path: target/release key: ${{ steps.macos-release-cache.outputs.cache-key }} - name: Upload native compilation timings if: ${{ always() }} uses: actions/upload-artifact@v4 with: name: native-timings-${{ matrix.os }} path: target/cargo-timings if-no-files-found: warn compression-level: 0 retention-days: 14 # 保留服务端已有的必需检查名称,但不为结果汇总再申请稀缺的 macOS runner。 # 只接受本轮完整原生矩阵成功;上游失败或跳过时不能把汇总直接标绿。 macos-release-check: needs: [lint, native-tests] if: ${{ !cancelled() && inputs.windows_diagnostics_run == '' }} name: Release workspace (${{ matrix.os }}) strategy: fail-fast: false matrix: include: ${{ fromJSON(needs.lint.outputs.release_matrix) }} runs-on: ubuntu-24.04 timeout-minutes: 5 steps: - name: Require this run's native and release checks shell: python env: NATIVE_RESULT: ${{ needs.native-tests.result }} run: | import os result = os.environ["NATIVE_RESULT"] if result != "success": raise SystemExit("Native validation did not succeed: " + result) print("Both macOS release checks passed in the native matrix.")