diff --git a/.github/workflows/DailyArm64.yml b/.github/workflows/DailyArm64.yml new file mode 100644 index 000000000..67252d597 --- /dev/null +++ b/.github/workflows/DailyArm64.yml @@ -0,0 +1,109 @@ +# 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: + # 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 + 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..0224952b8 100644 --- a/.github/workflows/ValidatePullRequest.yml +++ b/.github/workflows/ValidatePullRequest.yml @@ -129,21 +129,12 @@ jobs: strategy: fail-fast: true matrix: + # aarch64 examples are exercised by the daily schedule (DailyArm64.yml) + # only, to keep the limited arm64 runners free on PRs. hypervisor: ['hyperv-ws2025', mshv3, kvm] - cpu_vendor: [amd, intel, apple] - arch: [X64, arm64] + cpu_vendor: [amd, intel] + arch: [X64] config: [debug, release] - exclude: - - cpu_vendor: apple - hypervisor: hyperv-ws2025 - - cpu_vendor: apple - hypervisor: mshv3 - - cpu_vendor: amd - arch: arm64 - - cpu_vendor: intel - arch: arm64 - - cpu_vendor: apple - arch: X64 uses: ./.github/workflows/dep_run_examples.yml secrets: inherit with: @@ -166,13 +157,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..34d733289 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", 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" env: CARGO_TERM_COLOR: always @@ -94,7 +104,10 @@ jobs: run: just build ${{ inputs.config }} - name: Run Miri tests - if: runner.os == 'Linux' + # 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 - name: Run Rust tests @@ -103,7 +116,10 @@ jobs: just test ${{ inputs.config }} - name: Run Rust tests with single driver - if: runner.os == 'Linux' + # 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) just test ${{ inputs.config }} ${{ inputs.hypervisor == 'mshv3' && 'mshv3' || 'kvm' }} 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.