diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index be4e28f9..4d1ac13d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,6 +8,13 @@ # Tests are built once and run in 4 shards. A few heavy tests (see .config/nextest.toml) are # skipped on pull requests and run on pushes to main and nightly. # Cross-compilation is opt-in through Run workflow; release builds remain in release.yml. +# Pushes to main and merge-queue groups use both pools: Clippy, the doc tests and test shards +# 1-2 run on the self-hosted runner (`self-hosted-fast`, warm build directories via +# scripts/ci/warm-target.sh), everything else on GitHub's runners. The test archive is built on +# GitHub's runners: the self-hosted machine has a newer glibc, so its binaries wouldn't start +# on ubuntu-24.04, while the archive runs there unchanged (same /home/runner/work checkout +# path). Pull requests, the nightly run and Run workflow use GitHub's runners only; the +# self-hosted runner refuses any job that isn't a push to main or a merge-queue group. name: CI on: @@ -134,14 +141,19 @@ jobs: name: Native Linux Clippy needs: changes if: needs.changes.outputs.native == 'true' - runs-on: ubuntu-24.04 + runs-on: ${{ (github.event_name == 'merge_group' || (github.event_name == 'push' && github.ref == 'refs/heads/main')) && 'self-hosted-fast' || 'ubuntu-24.04' }} timeout-minutes: 30 steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - name: Warm build directory (self-hosted runner) + if: runner.environment == 'self-hosted' + run: scripts/ci/warm-target.sh clippy - uses: dtolnay/rust-toolchain@stable with: components: clippy - - uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 + # The self-hosted runner keeps its build directory and Cargo home instead. + - if: runner.environment == 'github-hosted' + uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 with: key: native-clippy - name: Clippy @@ -200,7 +212,7 @@ jobs: tests: name: Native Linux tests (${{ matrix.shard }}/4) needs: [changes, build-tests] - runs-on: ubuntu-24.04 + runs-on: ${{ ((github.event_name == 'merge_group' || (github.event_name == 'push' && github.ref == 'refs/heads/main')) && matrix.shard <= 2) && 'self-hosted-fast' || 'ubuntu-24.04' }} timeout-minutes: 60 strategy: fail-fast: false @@ -356,7 +368,7 @@ jobs: name: Doc tests needs: changes if: needs.changes.outputs.native == 'true' - runs-on: ubuntu-24.04 + runs-on: ${{ (github.event_name == 'merge_group' || (github.event_name == 'push' && github.ref == 'refs/heads/main')) && 'self-hosted-fast' || 'ubuntu-24.04' }} timeout-minutes: 45 env: CARGO_INCREMENTAL: "0" @@ -365,8 +377,13 @@ jobs: SCCACHE_IGNORE_SERVER_IO_ERROR: "1" steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - name: Warm build directory (self-hosted runner) + if: runner.environment == 'self-hosted' + run: scripts/ci/warm-target.sh doc-tests - uses: dtolnay/rust-toolchain@stable - - uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 + # The self-hosted runner keeps its build directory and Cargo home instead. + - if: runner.environment == 'github-hosted' + uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 with: key: doc-tests - name: Set up compiler cache diff --git a/scripts/ci/warm-target.sh b/scripts/ci/warm-target.sh new file mode 100755 index 00000000..6bbb3aed --- /dev/null +++ b/scripts/ci/warm-target.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +# Self-hosted runner only: keep a job's Cargo build directory between runs, outside the +# checkout (actions/checkout's clean would delete it), and point CARGO_TARGET_DIR at it for the +# rest of the job. Usage: warm-target.sh NAME +# Each self-hosted runner has its own /home/runner, so two never share a directory. +set -euo pipefail +name=${1:?usage: warm-target.sh NAME} +dir=/home/runner/work/cargo-target/$name +# Start over when it has grown past 40 GB: old dependency versions pile up. +if [ -d "$dir" ] && [ "$(du -sm "$dir" | cut -f1)" -gt 40000 ]; then + echo "warm-target: $dir is over 40 GB, starting a fresh build" + rm -rf "$dir" +fi +mkdir -p "$dir" +echo "CARGO_TARGET_DIR=$dir" >> "$GITHUB_ENV" +echo "warm-target: $dir ($(du -sh "$dir" | cut -f1))"