From 1130284025dc4749c02dd7d775cdaac93399b3c0 Mon Sep 17 00:00:00 2001 From: Simon Davies Date: Tue, 30 Jun 2026 13:33:42 +0100 Subject: [PATCH 1/3] update PR validation and daily runs to reduce PR dependance on ARM64 runners Signed-off-by: Simon Davies --- .github/workflows/DailyArm64.yml | 106 ++++++++++++++++++++++ .github/workflows/ValidatePullRequest.yml | 16 +--- .github/workflows/dep_build_test.yml | 18 +++- 3 files changed, 127 insertions(+), 13 deletions(-) create mode 100644 .github/workflows/DailyArm64.yml diff --git a/.github/workflows/DailyArm64.yml b/.github/workflows/DailyArm64.yml new file mode 100644 index 000000000..34e87009a --- /dev/null +++ b/.github/workflows/DailyArm64.yml @@ -0,0 +1,106 @@ +# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json + +name: Daily aarch64 + +# Full aarch64 coverage runs here on a schedule rather than on every PR, because +# there are only limited aarch64 runners. PRs run a reduced aarch64 +# build-test (build + default Rust tests only) and skip aarch64 examples; this +# workflow restores Miri, the single-driver tests, and the examples once a day. + +on: + schedule: + - cron: '0 5 * * *' # Runs at 05:00 UTC every day + workflow_dispatch: # Allow manual triggering + +env: + CARGO_TERM_COLOR: always + RUST_BACKTRACE: full + +permissions: + contents: read + +defaults: + run: + shell: bash + +jobs: + # Build aarch64 guest binaries once and upload them as artifacts for the + # build-test and run-examples jobs to download. + build-guests: + strategy: + fail-fast: false + matrix: + config: [debug, release] + uses: ./.github/workflows/dep_build_guests.yml + secrets: inherit + with: + arch: arm64 + config: ${{ matrix.config }} + + # Full aarch64 build-and-test. full_aarch64: "true" re-enables the Miri and + # single-driver steps that are skipped on PRs. + build-test: + needs: build-guests + strategy: + fail-fast: false + matrix: + config: [debug, release] + uses: ./.github/workflows/dep_build_test.yml + secrets: inherit + with: + hypervisor: kvm + cpu_vendor: apple + arch: arm64 + config: ${{ matrix.config }} + full_aarch64: "true" + + run-examples: + needs: build-guests + strategy: + fail-fast: false + matrix: + config: [debug, release] + uses: ./.github/workflows/dep_run_examples.yml + secrets: inherit + with: + hypervisor: kvm + cpu_vendor: apple + arch: arm64 + config: ${{ matrix.config }} + + # Fuzz on aarch64. This coverage was removed from PRs in #1594 to conserve the + # limited arm64 runners, and runs here daily instead. The tracing + # fuzzers (fuzz_guest_trace, fuzz_guest_estimate_trace_event) are x86_64-only + fuzzing: + needs: build-guests + strategy: + fail-fast: false + matrix: + target: ['fuzz_host_print', 'fuzz_guest_call', 'fuzz_host_call'] + uses: ./.github/workflows/dep_fuzzing.yml + secrets: inherit + with: + target: ${{ matrix.target }} + arch: arm64 + max_total_time: 300 # 5 minutes in seconds + + # File (or update) a release-blocking GitHub issue if any job fails. The first + # label (area/ci-periodics-aarch64) is the de-duplication key used by + # notify-ci-failure.sh, so this workflow maintains its own issue lineage and is + # guaranteed to carry release-blocker, instead of commenting on another periodic + # job's issue. NOTE: that label must exist in the repo (Issues -> Labels) or the + # `gh issue create` call will fail. + notify-failure: + runs-on: ubuntu-latest + needs: [build-guests, build-test, run-examples, fuzzing] + if: always() && (needs.build-guests.result == 'failure' || needs.build-test.result == 'failure' || needs.run-examples.result == 'failure' || needs.fuzzing.result == 'failure') + permissions: + issues: write + steps: + - name: Checkout code + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + + - name: Notify Daily aarch64 Failure + run: ./dev/notify-ci-failure.sh --title="Daily aarch64 Failure - ${{ github.run_number }}" --labels="area/ci-periodics-aarch64,area/ci-periodics,area/testing,lifecycle/needs-review,release-blocker" + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/ValidatePullRequest.yml b/.github/workflows/ValidatePullRequest.yml index aa640bd0e..0adf9f5b9 100644 --- a/.github/workflows/ValidatePullRequest.yml +++ b/.github/workflows/ValidatePullRequest.yml @@ -138,10 +138,9 @@ jobs: hypervisor: hyperv-ws2025 - cpu_vendor: apple hypervisor: mshv3 - - cpu_vendor: amd - arch: arm64 - - cpu_vendor: intel - arch: arm64 + # aarch64 examples are exercised by the daily schedule (DailyArm64.yml) + # only, to keep the limited arm64 runners free on PRs. + - arch: arm64 - cpu_vendor: apple arch: X64 uses: ./.github/workflows/dep_run_examples.yml @@ -166,13 +165,8 @@ jobs: target: ['fuzz_host_print', 'fuzz_guest_call', 'fuzz_host_call', 'fuzz_guest_estimate_trace_event', 'fuzz_guest_trace'] arch: - X64 - # arm64 disabled to conserve the limited self-hosted Apple runners. - # - arm64 - # exclude: - # - arch: arm64 - # target: fuzz_guest_trace - # - arch: arm64 - # target: fuzz_guest_estimate_trace_event + # arm64 fuzzing runs on the daily schedule (DailyArm64.yml) instead of on + # PRs, to conserve the limited arm64 runners. uses: ./.github/workflows/dep_fuzzing.yml secrets: inherit with: diff --git a/.github/workflows/dep_build_test.yml b/.github/workflows/dep_build_test.yml index 985949b7c..fbd98045f 100644 --- a/.github/workflows/dep_build_test.yml +++ b/.github/workflows/dep_build_test.yml @@ -26,6 +26,16 @@ on: description: CPU architecture for the build (passed from caller matrix) required: true type: string + full_aarch64: + description: >- + When "true", run the full aarch64 test set (Miri + single-driver tests). + PRs leave this "false" so the aarch64 runner only + builds and runs the default Rust tests; the daily schedule + (DailyArm64.yml) sets it "true". Has no effect on X64, which always + runs the full set. + required: false + type: string + default: "false" env: CARGO_TERM_COLOR: always @@ -94,7 +104,9 @@ jobs: run: just build ${{ inputs.config }} - name: Run Miri tests - if: runner.os == 'Linux' + # Skipped on aarch64 PRs to conserve the limited runners; the + # daily schedule (full_aarch64 == 'true') restores it. X64 always runs. + if: runner.os == 'Linux' && (inputs.arch == 'X64' || inputs.full_aarch64 == 'true') run: env -u RUSTC_WRAPPER just miri-tests - name: Run Rust tests @@ -103,7 +115,9 @@ jobs: just test ${{ inputs.config }} - name: Run Rust tests with single driver - if: runner.os == 'Linux' + # Skipped on aarch64 PRs to conserve the limited runners; the + # daily schedule (full_aarch64 == 'true') restores it. X64 always runs. + if: runner.os == 'Linux' && (inputs.arch == 'X64' || inputs.full_aarch64 == 'true') run: | # with only one driver enabled (kvm/mshv3 features are unix-only, no-op on Windows) just test ${{ inputs.config }} ${{ inputs.hypervisor == 'mshv3' && 'mshv3' || 'kvm' }} From 578adeb4218f34c279c3693993a6d4b0298d0218 Mon Sep 17 00:00:00 2001 From: Simon Davies Date: Tue, 30 Jun 2026 14:24:36 +0100 Subject: [PATCH 2/3] updtes after copilot review Signed-off-by: Simon Davies --- .github/workflows/DailyArm64.yml | 3 +++ .github/workflows/dep_build_test.yml | 20 +++++++++++--------- docs/github-labels.md | 2 ++ 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/.github/workflows/DailyArm64.yml b/.github/workflows/DailyArm64.yml index 34e87009a..67252d597 100644 --- a/.github/workflows/DailyArm64.yml +++ b/.github/workflows/DailyArm64.yml @@ -95,6 +95,9 @@ jobs: needs: [build-guests, build-test, run-examples, fuzzing] if: always() && (needs.build-guests.result == 'failure' || needs.build-test.result == 'failure' || needs.run-examples.result == 'failure' || needs.fuzzing.result == 'failure') permissions: + # Job-level permissions replace (not merge with) the workflow-level grant, + # so contents:read must be re-declared for actions/checkout to work. + contents: read issues: write steps: - name: Checkout code diff --git a/.github/workflows/dep_build_test.yml b/.github/workflows/dep_build_test.yml index fbd98045f..34d733289 100644 --- a/.github/workflows/dep_build_test.yml +++ b/.github/workflows/dep_build_test.yml @@ -28,11 +28,11 @@ on: type: string full_aarch64: description: >- - When "true", run the full aarch64 test set (Miri + single-driver tests). - PRs leave this "false" so the aarch64 runner only - builds and runs the default Rust tests; the daily schedule - (DailyArm64.yml) sets it "true". Has no effect on X64, which always - runs the full set. + When "true", also run the Miri and single-driver tests on aarch64. + PRs leave this "false" so the aarch64 runner only builds and runs the + default Rust tests; the daily schedule (DailyArm64.yml) sets it "true". + This input only affects aarch64: it does not change X64, where those + tests already run on Linux and are skipped on Windows regardless. required: false type: string default: "false" @@ -104,8 +104,9 @@ jobs: run: just build ${{ inputs.config }} - name: Run Miri tests - # Skipped on aarch64 PRs to conserve the limited runners; the - # daily schedule (full_aarch64 == 'true') restores it. X64 always runs. + # Linux-only. Skipped on aarch64 PRs to conserve the limited runners; + # the daily schedule (full_aarch64 == 'true') restores it. On X64 Linux + # it always runs. if: runner.os == 'Linux' && (inputs.arch == 'X64' || inputs.full_aarch64 == 'true') run: env -u RUSTC_WRAPPER just miri-tests @@ -115,8 +116,9 @@ jobs: just test ${{ inputs.config }} - name: Run Rust tests with single driver - # Skipped on aarch64 PRs to conserve the limited runners; the - # daily schedule (full_aarch64 == 'true') restores it. X64 always runs. + # Linux-only. Skipped on aarch64 PRs to conserve the limited runners; + # the daily schedule (full_aarch64 == 'true') restores it. On X64 Linux + # it always runs. if: runner.os == 'Linux' && (inputs.arch == 'X64' || inputs.full_aarch64 == 'true') run: | # with only one driver enabled (kvm/mshv3 features are unix-only, no-op on Windows) diff --git a/docs/github-labels.md b/docs/github-labels.md index 5133f048a..23a91faa4 100644 --- a/docs/github-labels.md +++ b/docs/github-labels.md @@ -48,6 +48,8 @@ In addition to lifecycle labels, we use the following labels to further categori In addition to **kind/*** labels, we use optional **area/*** labels to specify the focus of a PR or issue. These labels are purely for categorization, and are not mandatory. - **area/API** - Related to the API or public interface. +- **area/ci-periodics** - Applied to issues that track failures from scheduled (periodic) CI jobs. These issues are opened automatically by the CI failure notifier (`dev/notify-ci-failure.sh`). +- **area/ci-periodics-aarch64** - De-duplication label for failures from the daily aarch64 workflow (`.github/workflows/DailyArm64.yml`). It keeps those failures on their own dedicated, release-blocking issue instead of sharing the general `area/ci-periodics` issue. - **area/dependencies** - Concerns dependencies or related components. This label is different from **kind/dependencies**, which should only used for PRs. - **area/documentation** - Related to documentation updates or improvements. - **area/infrastructure** - Concerns infrastructure rather than core functionality. From d90ef441ca2209dd6d841b822ec758ed7e7dad69 Mon Sep 17 00:00:00 2001 From: Simon Davies Date: Tue, 30 Jun 2026 19:57:01 +0100 Subject: [PATCH 3/3] review feedback Signed-off-by: Simon Davies --- .github/workflows/ValidatePullRequest.yml | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/.github/workflows/ValidatePullRequest.yml b/.github/workflows/ValidatePullRequest.yml index 0adf9f5b9..0224952b8 100644 --- a/.github/workflows/ValidatePullRequest.yml +++ b/.github/workflows/ValidatePullRequest.yml @@ -129,20 +129,12 @@ jobs: strategy: fail-fast: true matrix: - hypervisor: ['hyperv-ws2025', mshv3, kvm] - cpu_vendor: [amd, intel, apple] - arch: [X64, arm64] - config: [debug, release] - exclude: - - cpu_vendor: apple - hypervisor: hyperv-ws2025 - - cpu_vendor: apple - hypervisor: mshv3 # aarch64 examples are exercised by the daily schedule (DailyArm64.yml) # only, to keep the limited arm64 runners free on PRs. - - arch: arm64 - - cpu_vendor: apple - arch: X64 + hypervisor: ['hyperv-ws2025', mshv3, kvm] + cpu_vendor: [amd, intel] + arch: [X64] + config: [debug, release] uses: ./.github/workflows/dep_run_examples.yml secrets: inherit with: