Files
Kuddevandkuddev 914f427332 ci: review external PRs after CI with Copilot allowance fallback (#332)
* ci: request one Copilot review after required checks pass

* ci: route exhausted Copilot allowance to CodeRabbit

---------

Co-authored-by: kuddev <kuddev@users.noreply.github.com>
2026-09-28 11:55:22 +08:00

230 lines
9.3 KiB
YAML

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.")