diff --git a/.github/workflows/bench.yml b/.github/workflows/bench.yml index 7ae9f211e..f8ff48804 100644 --- a/.github/workflows/bench.yml +++ b/.github/workflows/bench.yml @@ -23,7 +23,7 @@ name: Benchmarks on: pull_request: - types: [opened, synchronize, reopened, labeled, unlabeled] + types: [opened, synchronize, reopened, ready_for_review, labeled, unlabeled] paths: - '.github/workflows/bench.yml' - '.cargo/**' @@ -69,8 +69,10 @@ jobs: name: scan performance # Labels re-trigger the workflow; only this one changes the outcome. if: >- - (github.event.action != 'labeled' && github.event.action != 'unlabeled') - || github.event.label.name == 'performance-regression-accepted' + github.event.pull_request.draft != true && ( + (github.event.action != 'labeled' && github.event.action != 'unlabeled') + || github.event.label.name == 'performance-regression-accepted' + ) # Job-level, so an unrelated label (skipped above) cannot cancel a run # in progress. A newer push to the same PR supersedes the older run. concurrency: diff --git a/.github/workflows/bun-compatibility.yml b/.github/workflows/bun-compatibility.yml index 9894fe3b4..a60fe94d6 100644 --- a/.github/workflows/bun-compatibility.yml +++ b/.github/workflows/bun-compatibility.yml @@ -15,6 +15,7 @@ name: Bun patch compatibility on: pull_request: + types: [opened, synchronize, reopened, ready_for_review] paths: - '.github/actions/upload-artifact/**' - '.github/actions/pin-socket-hosts/**' @@ -111,10 +112,14 @@ env: jobs: build: + if: github.event.pull_request.draft != true strategy: fail-fast: false matrix: os: [ubuntu-latest, macos-latest, windows-latest] + exclude: + # macOS legs run on push to main (and nightly where scheduled), not per PR push. + - os: ${{ github.event_name == 'pull_request' && 'macos-latest' || '' }} runs-on: ${{ matrix.os }} timeout-minutes: 30 steps: @@ -171,6 +176,8 @@ jobs: - {os: windows-latest, bun: '0.8.1'} - {os: windows-latest, bun: '1.0.0'} - {os: windows-latest, bun: '1.0.36'} + # macOS legs run on push to main (and nightly where scheduled), not per PR push. + - os: ${{ github.event_name == 'pull_request' && 'macos-latest' || '' }} runs-on: ${{ matrix.os }} timeout-minutes: 30 steps: @@ -363,10 +370,14 @@ jobs: binary: + if: github.event.pull_request.draft != true strategy: fail-fast: false matrix: os: [ubuntu-latest, ubuntu-22.04, macos-latest, windows-latest] + exclude: + # macOS legs run on push to main (and nightly where scheduled), not per PR push. + - os: ${{ github.event_name == 'pull_request' && 'macos-latest' || '' }} runs-on: ${{ matrix.os }} timeout-minutes: 30 steps: diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6dedff584..8038c9bd6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,6 +9,7 @@ on: # workflow (cache-poisoning). branches: [main] pull_request: + types: [opened, synchronize, reopened, ready_for_review] # The merge queue tests each queued PR merged onto the tip of main (plus # the PRs ahead of it) before it lands. `ci-ok` below is the required # check, so this event has to run the same pull_request-tier job set. @@ -44,6 +45,7 @@ concurrency: jobs: clippy: + if: github.event.pull_request.draft != true runs-on: ubuntu-latest timeout-minutes: 20 steps: @@ -76,6 +78,7 @@ jobs: # The napi addon is only ever loaded by Node, so cargo's own tests never # exercise its JS loader or the engine/provider boundary. node-addon: + if: github.event.pull_request.draft != true runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -108,6 +111,7 @@ jobs: # Check the standalone installer, release scripts, and native installer # test harnesses. lint-ecosystems: + if: github.event.pull_request.draft != true runs-on: ubuntu-latest timeout-minutes: 10 steps: @@ -199,6 +203,7 @@ jobs: # CHANGELOG has a dated, non-empty section for the new version and the # tag doesn't already exist. release-readiness: + if: github.event.pull_request.draft != true runs-on: ubuntu-latest steps: - name: Checkout @@ -236,6 +241,7 @@ jobs: bash scripts/release-lint.sh --sync-only test: + if: github.event.pull_request.draft != true # No ubuntu-latest leg: `coverage` runs this same `cargo test # --workspace` (debug, default features, plus Go and vexctl) on ubuntu, # instrumented, and fails on any test failure. A plain ubuntu leg ran @@ -244,6 +250,9 @@ jobs: fail-fast: false matrix: os: [macos-latest, windows-latest] + exclude: + # macOS legs run on main, the merge queue and nightly, not per PR push. + - os: ${{ github.event_name == 'pull_request' && 'macos-latest' || '' }} runs-on: ${{ matrix.os }} timeout-minutes: 50 env: @@ -395,6 +404,7 @@ jobs: cargo test --workspace --no-fail-fast test-release: + if: github.event.pull_request.draft != true runs-on: ubuntu-latest # Every tests/ target is its own optimized link (~240 test binaries). # The manifest-less VEX suites share two multi-module binaries @@ -429,6 +439,7 @@ jobs: run: cargo test --workspace --profile ci-release coverage: + if: github.event.pull_request.draft != true # Code coverage via cargo-llvm-cov (LLVM source-based instrumentation). # Reports as a markdown table in the job summary and uploads the raw # lcov.info file as a workflow artifact. No threshold gating — the @@ -541,6 +552,7 @@ jobs: # Dockerfile.base compiles the full-LTO release binary inside Docker, with # no cache. Build it once per run and hand the image to every docker leg. docker-base: + if: github.event.pull_request.draft != true runs-on: ubuntu-22.04 timeout-minutes: 30 permissions: @@ -790,6 +802,7 @@ jobs: retention-days: 30 dispatch-tests: + if: github.event.pull_request.draft != true runs-on: ubuntu-latest timeout-minutes: 10 steps: @@ -825,10 +838,14 @@ jobs: # test binaries directly from the same checkout path, so `CARGO_BIN_EXE_*` # and `CARGO_MANIFEST_DIR` resolve as they did under `cargo test`. e2e-build: + if: github.event.pull_request.draft != true strategy: fail-fast: false matrix: os: [ubuntu-latest, macos-latest, windows-latest] + exclude: + # macOS legs run on main, the merge queue and nightly, not per PR push. + - os: ${{ github.event_name == 'pull_request' && 'macos-latest' || '' }} runs-on: ${{ matrix.os }} # Windows compiles the same ~240 targets ~1.6x slower (see `test`). timeout-minutes: ${{ matrix.os == 'windows-latest' && 60 || 45 }} @@ -954,8 +971,6 @@ jobs: # every cargo-vex-matrix leg (ubuntu, macOS and Windows). - os: ubuntu-latest suite: e2e_safety_pnpm - - os: macos-latest - suite: e2e_safety_pnpm # pnpm-on-Windows uses junctions for symlinks and copies # (not hardlinks) by default, so the CoW invariant holds # vacuously. Test still runs to verify apply doesn't error @@ -981,15 +996,10 @@ jobs: - os: ubuntu-latest suite: e2e_redirect_npm_build npm_required: '1' - - os: macos-latest - suite: e2e_redirect_npm_build - npm_required: '1' - os: windows-latest suite: e2e_redirect_npm_build - os: ubuntu-latest suite: e2e_redirect_rush_sim - - os: macos-latest - suite: e2e_redirect_rush_sim - os: windows-latest suite: e2e_redirect_rush_sim # Hermetic real-bun capstones (wiremock patch service, real `bun @@ -1020,10 +1030,6 @@ jobs: suite: e2e_redirect_bun_build bun: '1.4.2' test_filter: --include-ignored - - os: macos-latest - suite: e2e_redirect_bun_build - bun: '1.4.2' - test_filter: --include-ignored - os: windows-latest suite: e2e_redirect_bun_build bun: '1.4.2' @@ -1040,10 +1046,6 @@ jobs: suite: e2e_vendor_bun_build bun: '1.4.2' test_filter: --include-ignored - - os: macos-latest - suite: e2e_vendor_bun_build - bun: '1.4.2' - test_filter: --include-ignored - os: windows-latest suite: e2e_vendor_bun_build bun: '1.4.2' @@ -1060,10 +1062,6 @@ jobs: suite: mode_migration_bun bun: '1.4.2' test_filter: --include-ignored - - os: macos-latest - suite: mode_migration_bun - bun: '1.4.2' - test_filter: --include-ignored - os: windows-latest suite: mode_migration_bun bun: '1.4.2' @@ -1097,7 +1095,6 @@ jobs: # 0.0.0-32, B rc.12/rc.14 (rc.14 legs reach public npm), C rc.32, # D 1.0.4/1.0.7, E 1.1.1, F 1.2.0. - {os: ubuntu-latest, suite: e2e_redirect_vlt_build, vlt: '1.2.0', test_filter: --include-ignored vlt_pinned_matrix} - - {os: macos-latest, suite: e2e_redirect_vlt_build, vlt: '1.2.0', test_filter: --include-ignored vlt_pinned_matrix} - {os: windows-latest, suite: e2e_redirect_vlt_build, vlt: '1.2.0', test_filter: --include-ignored vlt_pinned_matrix} - {os: ubuntu-latest, suite: e2e_redirect_vlt_build, vlt: '0.0.0-16', test_filter: --include-ignored vlt_pinned_matrix} - {os: ubuntu-latest, suite: e2e_redirect_vlt_build, vlt: '0.0.0-32', test_filter: --include-ignored vlt_pinned_matrix} @@ -1106,7 +1103,6 @@ jobs: - {os: ubuntu-latest, suite: e2e_redirect_vlt_build, vlt: '1.0.4', test_filter: --include-ignored vlt_pinned_matrix} - {os: ubuntu-latest, suite: e2e_redirect_vlt_build, vlt: '1.1.1', test_filter: --include-ignored vlt_pinned_matrix} - {os: ubuntu-latest, suite: e2e_vendor_vlt_build, vlt: '1.2.0', test_filter: --include-ignored vlt_pinned_matrix} - - {os: macos-latest, suite: e2e_vendor_vlt_build, vlt: '1.2.0', test_filter: --include-ignored vlt_pinned_matrix} - {os: windows-latest, suite: e2e_vendor_vlt_build, vlt: '1.2.0', test_filter: --include-ignored vlt_pinned_matrix} - {os: ubuntu-latest, suite: e2e_vendor_vlt_build, vlt: '0.0.0-32', test_filter: --include-ignored vlt_pinned_matrix} - {os: ubuntu-latest, suite: e2e_vendor_vlt_build, vlt: '1.0.0-rc.14', test_filter: --include-ignored vlt_pinned_matrix} @@ -1114,7 +1110,6 @@ jobs: - {os: ubuntu-latest, suite: e2e_vendor_vlt_build, vlt: '1.0.4', test_filter: --include-ignored vlt_pinned_matrix} - {os: windows-latest, suite: e2e_vendor_vlt_build, vlt: '1.0.0-rc.14', test_filter: --include-ignored vlt_pinned_matrix} - {os: ubuntu-latest, suite: mode_migration_vlt, vlt: '1.2.0', test_filter: --include-ignored vlt_pinned_matrix} - - {os: macos-latest, suite: mode_migration_vlt, vlt: '1.2.0', test_filter: --include-ignored vlt_pinned_matrix} - {os: windows-latest, suite: mode_migration_vlt, vlt: '1.2.0', test_filter: --include-ignored vlt_pinned_matrix} - {os: ubuntu-latest, suite: mode_migration_vlt, vlt: '0.0.0-32', test_filter: --include-ignored vlt_pinned_matrix} - {os: ubuntu-latest, suite: mode_migration_vlt, vlt: '1.0.0-rc.14', test_filter: --include-ignored vlt_pinned_matrix, vlt_upgrade: '1.2.0'} @@ -1123,12 +1118,10 @@ jobs: # explicit hardlink linker. - {os: ubuntu-latest, suite: e2e_safety_vlt, vlt: '1.2.0', test_filter: --include-ignored vlt_pinned_matrix} - {os: ubuntu-latest, suite: e2e_safety_vlt, vlt: '1.2.0', test_filter: --include-ignored vlt_pinned_matrix, vlt_store_linker: 'hardlink'} - - {os: macos-latest, suite: e2e_safety_vlt, vlt: '1.2.0', test_filter: --include-ignored vlt_pinned_matrix, vlt_store_linker: 'hardlink'} - {os: windows-latest, suite: e2e_safety_vlt, vlt: '1.2.0', test_filter: --include-ignored vlt_pinned_matrix, vlt_store_linker: 'hardlink'} # rc.12 gets the definite no-hook advisory; windows rc.14 runs the # legacy DepIDs on NTFS with pre-junction symlinks. - {os: ubuntu-latest, suite: e2e_vlt, vlt: '1.2.0', test_filter: --include-ignored vlt_pinned_matrix} - - {os: macos-latest, suite: e2e_vlt, vlt: '1.2.0', test_filter: --include-ignored vlt_pinned_matrix} - {os: windows-latest, suite: e2e_vlt, vlt: '1.2.0', test_filter: --include-ignored vlt_pinned_matrix} - {os: ubuntu-latest, suite: e2e_vlt, vlt: '0.0.0-32', test_filter: --include-ignored vlt_pinned_matrix} - {os: ubuntu-latest, suite: e2e_vlt, vlt: '1.0.0-rc.12', test_filter: --include-ignored vlt_pinned_matrix} @@ -1141,7 +1134,6 @@ jobs: # skip. Node 24 (step below): the # corepack pnpm@10/11 legs require it. - {os: ubuntu-latest, suite: e2e_redirect_pnpm_build, test_filter: '--ignored --skip pnpm_pinned_matrix'} - - {os: macos-latest, suite: e2e_redirect_pnpm_build, test_filter: '--ignored --skip pnpm_pinned_matrix'} - {os: windows-latest, suite: e2e_redirect_pnpm_build, test_filter: '--ignored --skip pnpm_pinned_matrix'} # Real-uv hosted/vendored capstones ending in manifest-less VEX: # the oldest and newest line + the 0.5.x boundary (0.5.4 still @@ -1152,12 +1144,10 @@ jobs: - {os: ubuntu-latest, suite: e2e_redirect_uv_build, uv: '0.5.4'} - {os: ubuntu-latest, suite: e2e_redirect_uv_build, uv: '0.5.5'} - {os: ubuntu-latest, suite: e2e_redirect_uv_build, uv: '0.12.17'} - - {os: macos-latest, suite: e2e_redirect_uv_build, uv: '0.12.17'} - {os: ubuntu-latest, suite: e2e_vendor_pypi_build, uv: '0.1.45', test_filter: --include-ignored} - {os: ubuntu-latest, suite: e2e_vendor_pypi_build, uv: '0.5.4', test_filter: --include-ignored} - {os: ubuntu-latest, suite: e2e_vendor_pypi_build, uv: '0.5.5', test_filter: --include-ignored} - {os: ubuntu-latest, suite: e2e_vendor_pypi_build, uv: '0.12.17', test_filter: --include-ignored} - - {os: macos-latest, suite: e2e_vendor_pypi_build, uv: '0.12.17', test_filter: --include-ignored} # The Poetry / PDM / Hatch / Pipenv / pip / deno manifest-less VEX # capstones share ONE test binary (`e2e_vex_build`, a module per # tool — one optimized link in test-release instead of six), so @@ -1172,7 +1162,6 @@ jobs: - {os: ubuntu-latest, suite: e2e_vex_build, test_filter: 'poetry:: --ignored', poetry: '1.8.5'} - {os: ubuntu-latest, suite: e2e_vex_build, test_filter: 'poetry:: --ignored', poetry: '2.0.1'} - {os: ubuntu-latest, suite: e2e_vex_build, test_filter: 'poetry:: --ignored', poetry: '2.4.3'} - - {os: macos-latest, suite: e2e_vex_build, test_filter: 'poetry:: --ignored', poetry: '2.4.3'} # Real PDM / Hatch capstones (wiremock Socket API that also serves # the hosted wheel; PyPI for the tool bootstrap + six). # PDM: lock 2 (1.4), refused 3.1 (1.15) and 4.2 (2.7), 4.3 (2.8), @@ -1183,7 +1172,6 @@ jobs: - {os: ubuntu-latest, suite: e2e_vex_build, test_filter: 'pdm:: --ignored', pdm: '2.8.2'} - {os: ubuntu-latest, suite: e2e_vex_build, test_filter: 'pdm:: --ignored', pdm: '2.25.9'} - {os: ubuntu-latest, suite: e2e_vex_build, test_filter: 'pdm:: --ignored', pdm: '2.29.2'} - - {os: macos-latest, suite: e2e_vex_build, test_filter: 'pdm:: --ignored', pdm: '2.29.2'} # Hatch: 1.0 (hatch.toml env vendoring refused, needs >= 1.2), # 1.2, the virtualenv<21 window (1.9, 1.14) and current. - {os: ubuntu-latest, suite: e2e_vex_build, test_filter: 'hatch:: --ignored', hatch: '1.0.0'} @@ -1191,16 +1179,13 @@ jobs: - {os: ubuntu-latest, suite: e2e_vex_build, test_filter: 'hatch:: --ignored', hatch: '1.9.7'} - {os: ubuntu-latest, suite: e2e_vex_build, test_filter: 'hatch:: --ignored', hatch: '1.14.2'} - {os: ubuntu-latest, suite: e2e_vex_build, test_filter: 'hatch:: --ignored', hatch: '1.18.1'} - - {os: macos-latest, suite: e2e_vex_build, test_filter: 'hatch:: --ignored', hatch: '1.18.1'} # Real Pipenv / pip capstones (mock patch server; the tools are # bootstrapped from PyPI). `pipenv:` / `pip:` hold one or more # space-separated releases the suite loops over. The middle # Pipenv releases are in e2e-full. - {os: ubuntu-latest, suite: e2e_vex_build, test_filter: 'pipenv:: --ignored', pipenv: '2022.12.19'} - {os: ubuntu-latest, suite: e2e_vex_build, test_filter: 'pipenv:: --ignored', pipenv: '2026.8.0'} - - {os: macos-latest, suite: e2e_vex_build, test_filter: 'pipenv:: --ignored', pipenv: '2022.12.19 2026.8.0'} - {os: ubuntu-latest, suite: e2e_vex_build, test_filter: 'pip:: --ignored', pip: '22 23 24 25 26'} - - {os: macos-latest, suite: e2e_vex_build, test_filter: 'pip:: --ignored', pip: '22 26'} # Real-Maven hosted + vendored capstones, one leg per Maven line: # 3.6 (pre http-blocker), 3.8 (resolver 1.6: no trusted checksums), # 3.9 (trusted checksums), 4.0 rc. Hosted also runs both sides of @@ -1212,18 +1197,15 @@ jobs: - {os: ubuntu-latest, suite: e2e_redirect_maven_build, jvm_tool: maven, maven: '3.9.4'} - {os: ubuntu-latest, suite: e2e_redirect_maven_build, jvm_tool: maven, maven: '3.9.16'} - {os: ubuntu-latest, suite: e2e_redirect_maven_build, jvm_tool: maven, maven: '4.0.0-rc-6'} - - {os: macos-latest, suite: e2e_redirect_maven_build, jvm_tool: maven, maven: '3.9.16'} - {os: ubuntu-latest, suite: e2e_vendor_maven_build, jvm_tool: maven, maven: '3.6.3'} - {os: ubuntu-latest, suite: e2e_vendor_maven_build, jvm_tool: maven, maven: '3.8.9'} - {os: ubuntu-latest, suite: e2e_vendor_maven_build, jvm_tool: maven, maven: '3.9.16'} - {os: ubuntu-latest, suite: e2e_vendor_maven_build, jvm_tool: maven, maven: '4.0.0-rc-6'} - - {os: macos-latest, suite: e2e_vendor_maven_build, jvm_tool: maven, maven: '3.9.16'} - {os: ubuntu-latest, suite: e2e_vendor_jvm_build, jvm_tool: maven, maven: '3.6.3', test_filter: '--ignored maven_reactor'} - {os: ubuntu-latest, suite: e2e_vendor_jvm_build, jvm_tool: maven, maven: '3.8.9', test_filter: '--ignored maven_reactor'} - {os: ubuntu-latest, suite: e2e_vendor_jvm_build, jvm_tool: maven, maven: '3.9.2', test_filter: '--ignored maven_reactor'} - {os: ubuntu-latest, suite: e2e_vendor_jvm_build, jvm_tool: maven, maven: '3.9.16', test_filter: '--ignored maven_reactor'} - {os: ubuntu-latest, suite: e2e_vendor_jvm_build, jvm_tool: maven, maven: '4.0.0-rc-6', test_filter: '--ignored maven_reactor'} - - {os: macos-latest, suite: e2e_vendor_jvm_build, jvm_tool: maven, maven: '3.9.16', test_filter: '--ignored maven_reactor'} - {os: windows-latest, suite: e2e_vendor_jvm_build, jvm_tool: maven, maven: '3.9.16', test_filter: '--ignored maven_reactor'} # Real-Gradle capstones, PR tier: one leg per Gradle line x {agent + # hosted, vendor + multi-project} on ubuntu, each on its line's LTS @@ -1256,7 +1238,6 @@ jobs: # the oldest and newest here, 7-9 on ubuntu in e2e-full. - {os: ubuntu-latest, suite: e2e_nuget_dotnet_build, dotnet: '6'} - {os: ubuntu-latest, suite: e2e_nuget_dotnet_build, dotnet: '10'} - - {os: macos-latest, suite: e2e_nuget_dotnet_build, dotnet: '8'} # Real deno negative capstone (no hosted/vendored wiring exists for # deno; VEX must attest nothing), one leg per major. - {os: ubuntu-latest, suite: e2e_vex_build, test_filter: 'deno:: --ignored', deno: '1.46.3'} @@ -1711,6 +1692,67 @@ jobs: # and newest release of each tool and every vlt era there); main pushes, # v5 landings, the nightly schedule and dispatch run them with the `e2e` # steps. + + # The macOS rows of `e2e`: they run on main, the merge queue and + # nightly, not on every PR push, so PRs stop queueing on the small + # macOS runner pool. + e2e-macos: + if: github.event_name != 'pull_request' + # These jobs consume e2e-build's binaries and can run alongside unit tests. + needs: [e2e-build] + strategy: + fail-fast: false + matrix: + include: + - os: macos-latest + suite: e2e_safety_pnpm + - os: macos-latest + suite: e2e_redirect_npm_build + npm_required: '1' + - os: macos-latest + suite: e2e_redirect_rush_sim + - os: macos-latest + suite: e2e_redirect_bun_build + bun: '1.4.2' + test_filter: --include-ignored + - os: macos-latest + suite: e2e_vendor_bun_build + bun: '1.4.2' + test_filter: --include-ignored + - os: macos-latest + suite: mode_migration_bun + bun: '1.4.2' + test_filter: --include-ignored + - {os: macos-latest, suite: e2e_redirect_vlt_build, vlt: '1.2.0', test_filter: --include-ignored vlt_pinned_matrix} + - {os: macos-latest, suite: e2e_vendor_vlt_build, vlt: '1.2.0', test_filter: --include-ignored vlt_pinned_matrix} + - {os: macos-latest, suite: mode_migration_vlt, vlt: '1.2.0', test_filter: --include-ignored vlt_pinned_matrix} + - {os: macos-latest, suite: e2e_safety_vlt, vlt: '1.2.0', test_filter: --include-ignored vlt_pinned_matrix, vlt_store_linker: 'hardlink'} + - {os: macos-latest, suite: e2e_vlt, vlt: '1.2.0', test_filter: --include-ignored vlt_pinned_matrix} + - {os: macos-latest, suite: e2e_redirect_pnpm_build, test_filter: '--ignored --skip pnpm_pinned_matrix'} + - {os: macos-latest, suite: e2e_redirect_uv_build, uv: '0.12.17'} + - {os: macos-latest, suite: e2e_vendor_pypi_build, uv: '0.12.17', test_filter: --include-ignored} + - {os: macos-latest, suite: e2e_vex_build, test_filter: 'poetry:: --ignored', poetry: '2.4.3'} + - {os: macos-latest, suite: e2e_vex_build, test_filter: 'pdm:: --ignored', pdm: '2.29.2'} + - {os: macos-latest, suite: e2e_vex_build, test_filter: 'hatch:: --ignored', hatch: '1.18.1'} + - {os: macos-latest, suite: e2e_vex_build, test_filter: 'pipenv:: --ignored', pipenv: '2022.12.19 2026.8.0'} + - {os: macos-latest, suite: e2e_vex_build, test_filter: 'pip:: --ignored', pip: '22 26'} + - {os: macos-latest, suite: e2e_redirect_maven_build, jvm_tool: maven, maven: '3.9.16'} + - {os: macos-latest, suite: e2e_vendor_maven_build, jvm_tool: maven, maven: '3.9.16'} + - {os: macos-latest, suite: e2e_vendor_jvm_build, jvm_tool: maven, maven: '3.9.16', test_filter: '--ignored maven_reactor'} + - {os: macos-latest, suite: e2e_nuget_dotnet_build, dotnet: '8'} + runs-on: ${{ matrix.os }} + # The real-toolchain capstones loop several releases per leg (pip, + # pipenv) or bootstrap a tool from PyPI before the suite (poetry, pdm, + # hatch), hence more than the 25 minutes the older legs needed. + timeout-minutes: 40 + # What .cargo/config.toml's [env] gives processes cargo launches; these + # legs launch the test binaries themselves. + env: + SOCKET_NO_CONFIG: '1' + SOCKET_NO_UPDATE_CHECK: '1' + # e2e-full runs these same steps over its rows. + steps: *e2e-steps + e2e-full: # merge_group runs the pull_request tier: the queue gates on ci-ok. if: (github.event_name != 'pull_request' && github.event_name != 'merge_group') || github.head_ref == 'release/v5-prerelease' @@ -1905,7 +1947,6 @@ jobs: - {os: ubuntu-latest, yarn: '4.0.2'} - {os: ubuntu-latest, yarn: '4.1.0'} - {os: ubuntu-latest, yarn: '4.18.0'} - - {os: macos-latest, yarn: '4.12.0'} - {os: windows-latest, yarn: '4.12.0'} runs-on: ${{ matrix.os }} timeout-minutes: 30 @@ -1932,6 +1973,26 @@ jobs: run: scripts/yarn-berry-vex-matrix.sh "$YARN_BERRY_RELEASE" # Skipped on pull_request (except v5 landings), like e2e-full. + + # The macOS rows of `yarn-berry-e2e`: they run on main, the merge queue and + # nightly, not on every PR push, so PRs stop queueing on the small + # macOS runner pool. + yarn-berry-e2e-macos: + if: github.event_name != 'pull_request' + name: yarn-berry ${{ matrix.yarn }} (${{ matrix.os }}) + needs: [test, coverage] + strategy: + fail-fast: false + matrix: + # 4.0.2 bare-hex checksum writer (4.0.0-4.0.2), 4.1.0 first + # `10c0/` writer, current, and 4.12.0 on macOS / Windows. The rest + # of the spread (4.6.0, 4.12.0 on ubuntu) is yarn-berry-full. + include: + - {os: macos-latest, yarn: '4.12.0'} + runs-on: ${{ matrix.os }} + timeout-minutes: 30 + steps: *yarn-berry-steps + yarn-berry-full: name: yarn-berry ${{ matrix.yarn }} (${{ matrix.os }}) # merge_group runs the pull_request tier: the queue gates on ci-ok. @@ -1974,9 +2035,7 @@ jobs: - {os: ubuntu-latest, toolchain: stable, lock: '2'} - {os: ubuntu-latest, toolchain: '1.82.0', lock: '3'} - {os: ubuntu-latest, toolchain: '1.93.1', lock: '4'} - - {os: macos-latest, toolchain: stable, lock: '1'} - {os: windows-latest, toolchain: stable, lock: '1'} - - {os: macos-latest, toolchain: '1.93.1', lock: ''} - {os: windows-latest, toolchain: '1.93.1', lock: ''} steps: &cargo-vex-steps - name: Checkout @@ -2025,6 +2084,28 @@ jobs: "../../target/e2e-bin/e2e_safety_cargo_build$exe" --ignored || status=1 exit "$status" + # The macOS rows of `cargo-vex-matrix`: they run on main, the merge queue and + # nightly, not on every PR push, so PRs stop queueing on the small + # macOS runner pool. + cargo-vex-matrix-macos: + if: github.event_name != 'pull_request' + name: cargo ${{ matrix.toolchain }} lock-v${{ matrix.lock || 'own' }} (${{ matrix.os }}) + needs: [test, coverage, e2e-build] + runs-on: ${{ matrix.os }} + timeout-minutes: 40 + # What .cargo/config.toml's [env] gives processes cargo launches; these + # legs launch the test binaries themselves. + env: + SOCKET_NO_CONFIG: '1' + SOCKET_NO_UPDATE_CHECK: '1' + strategy: + fail-fast: false + matrix: + include: + - {os: macos-latest, toolchain: stable, lock: '1'} + - {os: macos-latest, toolchain: '1.93.1', lock: ''} + steps: *cargo-vex-steps + cargo-vex-matrix-full: name: cargo ${{ matrix.toolchain }} lock-v${{ matrix.lock || 'own' }} (${{ matrix.os }}) # merge_group runs the pull_request tier: the queue gates on ci-ok. @@ -2124,6 +2205,7 @@ jobs: # ---------------------------------------------------------------------- hosted-e2e: name: hosted-e2e # may be a required check; do not rename + if: github.event.pull_request.draft != true runs-on: ubuntu-latest permissions: contents: read @@ -2328,7 +2410,7 @@ jobs: ci-ok: name: ci-ok # registered as a required check; do not rename if: always() - needs: [clippy, node-addon, lint-ecosystems, release-readiness, test, test-release, coverage, docker-base, coverage-docker, coverage-merge, dispatch-tests, e2e-build, e2e, e2e-full, e2e-docker, yarn-classic-matrix, yarn-berry-e2e, yarn-berry-full, cargo-vex-matrix, cargo-vex-matrix-full, cargo-old-toolchains, hosted-e2e] + needs: [clippy, node-addon, lint-ecosystems, release-readiness, test, test-release, coverage, docker-base, coverage-docker, coverage-merge, dispatch-tests, e2e-build, e2e, e2e-full, e2e-docker, yarn-classic-matrix, yarn-berry-e2e, yarn-berry-full, cargo-vex-matrix, cargo-vex-matrix-full, cargo-old-toolchains, hosted-e2e, e2e-macos, yarn-berry-e2e-macos, cargo-vex-matrix-macos] runs-on: ubuntu-latest timeout-minutes: 5 steps: diff --git a/.github/workflows/composer-compatibility.yml b/.github/workflows/composer-compatibility.yml index e19c35340..99cdf0627 100644 --- a/.github/workflows/composer-compatibility.yml +++ b/.github/workflows/composer-compatibility.yml @@ -21,6 +21,7 @@ name: Composer patch compatibility on: pull_request: + types: [opened, synchronize, reopened, ready_for_review] paths: - '.github/workflows/composer-compatibility.yml' - 'tests/docker/Dockerfile.composer' @@ -79,6 +80,7 @@ env: jobs: native: name: composer ${{ matrix.composer }} / php ${{ matrix.php }} / ${{ matrix.os }} + if: github.event.pull_request.draft != true strategy: fail-fast: false matrix: @@ -96,12 +98,9 @@ jobs: - {os: windows-latest, composer: '2.2.30', php: '8.3', sha256: 8c2b4478b64f8f7cdf1574838fdb0033b29049ca821dad452db7a3dcfcdbffc2} - {os: windows-latest, composer: '2.9.8', php: '8.4', sha256: 59b2c50e10cafa0d8efc19ede9a326d782f096c674a26baf98cf042ce23de890} - {os: windows-latest, composer: '2.10.3', php: '8.5', sha256: 7a2d379d5b8ffdaa028580ef26494c36d2feef4b178d3dd1473a4dbc5e17c8d6} - - {os: macos-latest, composer: '1.10.28', php: '8.1', sha256: 0915af36eb01e3f0e16cd309adff7051832b9ef014e38371756804b20425cd5a} - - {os: macos-latest, composer: '2.2.30', php: '8.3', sha256: 8c2b4478b64f8f7cdf1574838fdb0033b29049ca821dad452db7a3dcfcdbffc2} - - {os: macos-latest, composer: '2.10.3', php: '8.5', sha256: 7a2d379d5b8ffdaa028580ef26494c36d2feef4b178d3dd1473a4dbc5e17c8d6} runs-on: ${{ matrix.os }} timeout-minutes: 60 - steps: + steps: &native-steps - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false @@ -167,11 +166,29 @@ jobs: -- --ignored --nocapture cargo test -p socket-patch-cli --test e2e_vex_lockfile -- composer:: --nocapture + # The macOS rows of `native`: they run on push to main (and nightly + # where scheduled), not on every PR push, so PRs stop queueing on the + # small macOS runner pool. + native-macos: + name: composer ${{ matrix.composer }} / php ${{ matrix.php }} / ${{ matrix.os }} + if: github.event_name != 'pull_request' + strategy: + fail-fast: false + matrix: + include: + - {os: macos-latest, composer: '1.10.28', php: '8.1', sha256: 0915af36eb01e3f0e16cd309adff7051832b9ef014e38371756804b20425cd5a} + - {os: macos-latest, composer: '2.2.30', php: '8.3', sha256: 8c2b4478b64f8f7cdf1574838fdb0033b29049ca821dad452db7a3dcfcdbffc2} + - {os: macos-latest, composer: '2.10.3', php: '8.5', sha256: 7a2d379d5b8ffdaa028580ef26494c36d2feef4b178d3dd1473a4dbc5e17c8d6} + runs-on: ${{ matrix.os }} + timeout-minutes: 60 + steps: *native-steps + docker: # The vendored Docker capstone against an exact composer image. Its # fixture resolves psr/log from packagist, which no longer serves # Composer 1, so 1.10.28 is covered by the native legs only. name: docker composer ${{ matrix.composer }} + if: github.event.pull_request.draft != true runs-on: ubuntu-latest timeout-minutes: 35 strategy: diff --git a/.github/workflows/go-compatibility.yml b/.github/workflows/go-compatibility.yml index 3f0e6b9b7..eea8dbbf2 100644 --- a/.github/workflows/go-compatibility.yml +++ b/.github/workflows/go-compatibility.yml @@ -7,6 +7,7 @@ name: Go patch compatibility on: pull_request: + types: [opened, synchronize, reopened, ready_for_review] paths: - '.github/workflows/go-compatibility.yml' - 'crates/socket-patch-core/src/vendor/go*.rs' @@ -38,19 +39,15 @@ env: jobs: go: + if: github.event.pull_request.draft != true strategy: fail-fast: false matrix: os: [ubuntu-latest] go: ['1.18.10', '1.21.13', '1.24.13', '1.26.3'] - include: - # macOS-latest dyld refuses binaries without LC_UUID (Go < 1.24 - # linkers; see ci.yml's vexctl step). - - {os: macos-latest, go: '1.24.13'} - - {os: macos-latest, go: '1.26.3'} runs-on: ${{ matrix.os }} timeout-minutes: 45 - steps: + steps: &go-steps - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false @@ -75,3 +72,19 @@ jobs: --test e2e_golang_hosted_build --test e2e_vendor_golang_build \ --test e2e_golang_build --test e2e_golang_workspace_build -- --nocapture cargo test -p socket-patch-cli --test e2e_vex_lockfile -- golang:: --nocapture + + # The macOS rows of `go`: they run on push to main (and nightly + # where scheduled), not on every PR push, so PRs stop queueing on the + # small macOS runner pool. + go-macos: + if: github.event_name != 'pull_request' + strategy: + fail-fast: false + matrix: + os: [macos-latest] + # macOS-latest dyld refuses binaries without LC_UUID (Go < 1.24 + # linkers; see ci.yml's vexctl step). + go: ['1.24.13', '1.26.3'] + runs-on: ${{ matrix.os }} + timeout-minutes: 45 + steps: *go-steps diff --git a/.github/workflows/gradle-compatibility.yml b/.github/workflows/gradle-compatibility.yml index 9b17fe9b1..0f3944966 100644 --- a/.github/workflows/gradle-compatibility.yml +++ b/.github/workflows/gradle-compatibility.yml @@ -40,6 +40,7 @@ name: Gradle patch compatibility on: pull_request: + types: [opened, synchronize, reopened, ready_for_review] paths: - '.github/workflows/gradle-compatibility.yml' - 'scripts/ci-e2e-bundle.py' @@ -98,10 +99,14 @@ env: jobs: build: name: build ${{ matrix.os }} + if: github.event.pull_request.draft != true strategy: fail-fast: false matrix: os: [ubuntu-latest, macos-latest, windows-latest] + exclude: + # macOS legs run on push to main (and nightly where scheduled), not per PR push. + - os: ${{ github.event_name == 'pull_request' && 'macos-latest' || '' }} runs-on: ${{ matrix.os }} timeout-minutes: 60 env: @@ -174,6 +179,9 @@ jobs: - {gradle: '7.6.6', java: '17', label: '', gradle_args: '', real_central: '', suites: '', test_filter: ''} - {gradle: '8.14.3', java: '21', label: '', gradle_args: '', real_central: '', suites: '', test_filter: ''} - {gradle: '9.8.0', java: '21', label: '', gradle_args: '', real_central: '', suites: '', test_filter: ''} + exclude: + # macOS legs run on push to main (and nightly where scheduled), not per PR push. + - os: ${{ github.event_name == 'pull_request' && 'macos-latest' || '' }} runs-on: ${{ matrix.os }} timeout-minutes: 60 steps: &cell-steps diff --git a/.github/workflows/npm-compatibility.yml b/.github/workflows/npm-compatibility.yml index 40d7a25f7..64f83abe2 100644 --- a/.github/workflows/npm-compatibility.yml +++ b/.github/workflows/npm-compatibility.yml @@ -11,6 +11,7 @@ on: # compile (a later `!` pattern excludes, a later plain one re-includes). # Main pushes stay unfiltered. pull_request: + types: [opened, synchronize, reopened, ready_for_review] paths: - '.github/actions/upload-artifact/**' - 'Cargo.lock' @@ -45,6 +46,7 @@ concurrency: jobs: build: + if: github.event.pull_request.draft != true runs-on: ubuntu-latest timeout-minutes: 25 steps: diff --git a/.github/workflows/pdm-compatibility.yml b/.github/workflows/pdm-compatibility.yml index 6f760d7c8..fcec586f6 100644 --- a/.github/workflows/pdm-compatibility.yml +++ b/.github/workflows/pdm-compatibility.yml @@ -9,6 +9,7 @@ name: PDM patch compatibility on: pull_request: + types: [opened, synchronize, reopened, ready_for_review] paths: - '.github/actions/upload-artifact/**' - '.github/workflows/pdm-compatibility.yml' @@ -60,10 +61,14 @@ env: jobs: build: + if: github.event.pull_request.draft != true strategy: fail-fast: false matrix: os: [ubuntu-latest, macos-latest] + exclude: + # macOS legs run on push to main (and nightly where scheduled), not per PR push. + - os: ${{ github.event_name == 'pull_request' && 'macos-latest' || '' }} runs-on: ${{ matrix.os }} timeout-minutes: 30 steps: @@ -107,13 +112,9 @@ jobs: # every Windows cell skipped; backtest-pdm.py now fails such a cell. os: [ubuntu-latest] pdm: ['0.12.3', '1.15.5', '2.0.3', '2.1.5', '2.3.4', '2.6.1', '2.7.4', '2.8.2', '2.9.3', '2.10.4', '2.11.2', '2.17.3', '2.20.1', '2.22.4', '2.25.9', '2.29.2'] - include: - - { os: macos-latest, pdm: '0.12.3' } - - { os: macos-latest, pdm: '2.8.2' } - - { os: macos-latest, pdm: '2.29.2' } runs-on: ${{ matrix.os }} timeout-minutes: 45 - steps: + steps: &native-steps - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false @@ -174,6 +175,23 @@ jobs: # formats (3.1, 4.0-4.2) must attest nothing. The cells ci.yml's `e2e` # job runs on every PR and main push are excluded here # (scripts/tests/test_ci_e2e_tiers.py keeps the two lists in step). + + # The macOS rows of `native`: they run on push to main (and nightly + # where scheduled), not on every PR push, so PRs stop queueing on the + # small macOS runner pool. + native-macos: + if: github.event_name != 'pull_request' + needs: build + strategy: + fail-fast: false + matrix: + # The ends of the range and the 2.8 lock-format boundary. + os: [macos-latest] + pdm: ['0.12.3', '2.8.2', '2.29.2'] + runs-on: ${{ matrix.os }} + timeout-minutes: 45 + steps: *native-steps + capstone: needs: build strategy: @@ -189,6 +207,8 @@ jobs: - {os: ubuntu-latest, pdm: '2.25.9'} - {os: ubuntu-latest, pdm: '2.29.2'} - {os: macos-latest, pdm: '2.29.2'} + # macOS legs run on push to main (and nightly where scheduled), not per PR push. + - os: ${{ github.event_name == 'pull_request' && 'macos-latest' || '' }} runs-on: ${{ matrix.os }} timeout-minutes: 30 steps: diff --git a/.github/workflows/pipenv-compatibility.yml b/.github/workflows/pipenv-compatibility.yml index c36335391..000f746c5 100644 --- a/.github/workflows/pipenv-compatibility.yml +++ b/.github/workflows/pipenv-compatibility.yml @@ -9,6 +9,7 @@ name: Pipenv compatibility on: pull_request: + types: [opened, synchronize, reopened, ready_for_review] paths: - '.github/actions/upload-artifact/**' - 'crates/socket-patch-core/src/patch/redirect/pipenv.rs' @@ -43,6 +44,7 @@ concurrency: jobs: matrix: + if: github.event.pull_request.draft != true strategy: fail-fast: false matrix: @@ -55,12 +57,9 @@ jobs: - os: ubuntu-latest versions: 2022.12.19 2026.8.0 shapes: crlf marker-excluded extras category - - os: macos-latest - versions: 2018.11.26 2022.12.19 2023.12.1 2026.8.0 - shapes: direct runs-on: ${{ matrix.os }} timeout-minutes: 60 - steps: + steps: &matrix-steps - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false @@ -111,3 +110,19 @@ jobs: ${{ runner.temp }}/pipenv-compat/summary.md if-no-files-found: warn retention-days: 7 + + # The macOS rows of `matrix`: they run on push to main (and nightly + # where scheduled), not on every PR push, so PRs stop queueing on the + # small macOS runner pool. + matrix-macos: + if: github.event_name != 'pull_request' + strategy: + fail-fast: false + matrix: + include: + - os: macos-latest + versions: 2018.11.26 2022.12.19 2023.12.1 2026.8.0 + shapes: direct + runs-on: ${{ matrix.os }} + timeout-minutes: 60 + steps: *matrix-steps diff --git a/.github/workflows/pnpm-compatibility.yml b/.github/workflows/pnpm-compatibility.yml index f742364c4..6abe6c81e 100644 --- a/.github/workflows/pnpm-compatibility.yml +++ b/.github/workflows/pnpm-compatibility.yml @@ -5,6 +5,7 @@ on: # compile (a later `!` pattern excludes, a later plain one re-includes). # Main pushes stay unfiltered. pull_request: + types: [opened, synchronize, reopened, ready_for_review] paths: - '.github/actions/upload-artifact/**' - 'Cargo.lock' @@ -37,6 +38,7 @@ concurrency: jobs: build: + if: github.event.pull_request.draft != true runs-on: ubuntu-latest timeout-minutes: 20 steps: diff --git a/.github/workflows/poetry-compatibility.yml b/.github/workflows/poetry-compatibility.yml index 3b397b89f..abcae8402 100644 --- a/.github/workflows/poetry-compatibility.yml +++ b/.github/workflows/poetry-compatibility.yml @@ -13,6 +13,7 @@ name: Poetry patch compatibility on: pull_request: + types: [opened, synchronize, reopened, ready_for_review] paths: - '.github/actions/upload-artifact/**' - '.github/actions/pin-socket-hosts/**' @@ -52,10 +53,14 @@ env: jobs: build: + if: github.event.pull_request.draft != true strategy: fail-fast: false matrix: os: [ubuntu-latest, macos-latest] + exclude: + # macOS legs run on push to main (and nightly where scheduled), not per PR push. + - os: ${{ github.event_name == 'pull_request' && 'macos-latest' || '' }} runs-on: ${{ matrix.os }} timeout-minutes: 30 steps: @@ -81,6 +86,9 @@ jobs: matrix: os: [ubuntu-latest, macos-latest] poetry: ['1.0.10', '1.1.15', '1.2.2', '1.3.2', '1.4.2', '1.5.1', '1.6.1', '1.7.1', '1.8.5', '2.0.1', '2.1.4', '2.2.1', '2.3.4', '2.4.3'] + exclude: + # macOS legs run on push to main (and nightly where scheduled), not per PR push. + - os: ${{ github.event_name == 'pull_request' && 'macos-latest' || '' }} runs-on: ${{ matrix.os }} timeout-minutes: 45 steps: diff --git a/.github/workflows/sbt-compatibility.yml b/.github/workflows/sbt-compatibility.yml index 22ea35660..0c2edb03f 100644 --- a/.github/workflows/sbt-compatibility.yml +++ b/.github/workflows/sbt-compatibility.yml @@ -21,6 +21,7 @@ name: sbt / Mill / scala-cli compatibility on: pull_request: + types: [opened, synchronize, reopened, ready_for_review] # Everything the agent, hosted and vendored cells run through, shared # engine code included (as composer-compatibility.yml does). paths: @@ -68,6 +69,7 @@ env: jobs: image: + if: github.event.pull_request.draft != true # Builds the sbt image once (base image first: Dockerfile.sbt is # `FROM socket-patch-test-base:latest`) and hands it to every leg. runs-on: ubuntu-latest @@ -117,6 +119,7 @@ jobs: retention-days: 3 linux-bins: + if: github.event.pull_request.draft != true # The Linux socket-patch and the real-tool test binaries (docker_e2e_sbt's # host side too, so no leg compiles), built once in the script's pinned # rust container. Absolute paths are kept (`tar -P`): @@ -261,6 +264,7 @@ jobs: # from sbt/setup-sbt, a Temurin JDK 17, the tests' own native runner. # The warm-seed step boots sbt once so the tests share its caches. name: sbt 1.13.0 ${{ matrix.suite }} / ${{ matrix.os }} + if: github.event.pull_request.draft != true runs-on: ${{ matrix.os }} timeout-minutes: 60 strategy: @@ -268,6 +272,9 @@ jobs: matrix: os: [macos-latest, windows-latest] suite: [e2e_sbt_build, e2e_sbt_vendor_build] + exclude: + # macOS legs run on push to main (and nightly where scheduled), not per PR push. + - os: ${{ github.event_name == 'pull_request' && 'macos-latest' || '' }} steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: diff --git a/.github/workflows/vlt-compatibility.yml b/.github/workflows/vlt-compatibility.yml index a30976d9c..a4435a561 100644 --- a/.github/workflows/vlt-compatibility.yml +++ b/.github/workflows/vlt-compatibility.yml @@ -19,6 +19,7 @@ name: vlt patch compatibility on: pull_request: + types: [opened, synchronize, reopened, ready_for_review] paths: - '.github/actions/upload-artifact/**' - '.github/actions/pin-socket-hosts/**' @@ -139,6 +140,7 @@ env: jobs: matrix-coverage: + if: github.event.pull_request.draft != true runs-on: ubuntu-latest timeout-minutes: 5 steps: @@ -149,10 +151,14 @@ jobs: run: python3 -B -m unittest scripts/tests/test_ci_vlt_rows.py -v build: + if: github.event.pull_request.draft != true strategy: fail-fast: false matrix: os: [ubuntu-latest, macos-latest, windows-latest] + exclude: + # macOS legs run on push to main (and nightly where scheduled), not per PR push. + - os: ${{ github.event_name == 'pull_request' && 'macos-latest' || '' }} runs-on: ${{ matrix.os }} timeout-minutes: 40 steps: @@ -233,17 +239,6 @@ jobs: - {os: ubuntu-latest, vlt: '1.0.10'} - {os: ubuntu-latest, vlt: '1.1.1'} - {os: ubuntu-latest, vlt: '1.2.0'} - - {os: macos-latest, vlt: '0.0.0-16'} - - {os: macos-latest, vlt: '0.0.0-30'} - - {os: macos-latest, vlt: '1.0.0-rc.8'} - - {os: macos-latest, vlt: '1.0.0-rc.13'} - - {os: macos-latest, vlt: '1.0.0-rc.14'} - - {os: macos-latest, vlt: '1.0.0-rc.15'} - - {os: macos-latest, vlt: '1.0.0-rc.22'} - - {os: macos-latest, vlt: '1.0.0-rc.33'} - - {os: macos-latest, vlt: '1.0.8'} - - {os: macos-latest, vlt: '1.1.1'} - - {os: macos-latest, vlt: '1.2.0'} - {os: windows-latest, vlt: '0.0.0-11'} - {os: windows-latest, vlt: '0.0.0-19'} - {os: windows-latest, vlt: '0.0.0-30'} @@ -270,16 +265,14 @@ jobs: - {os: ubuntu-latest, vlt: '1.2.0', linker: hardlink, suites: e2e_safety_vlt} - {os: ubuntu-latest, vlt: '1.2.0', linker: copy, suites: e2e_safety_vlt} - {os: ubuntu-latest, vlt: '1.2.0', linker: unpack, suites: e2e_safety_vlt} - - {os: macos-latest, vlt: '1.2.0', linker: auto, suites: e2e_safety_vlt} - - {os: macos-latest, vlt: '1.2.0', linker: hardlink, suites: e2e_safety_vlt} - {os: windows-latest, vlt: '1.2.0', linker: auto, suites: e2e_safety_vlt} - {os: windows-latest, vlt: '1.2.0', linker: hardlink, suites: e2e_safety_vlt} - {os: ubuntu-latest, vlt: '1.2.0', linker: hardlink, cache_root: /dev/shm/vlt-e2e-cache, suites: e2e_safety_vlt} runs-on: ${{ matrix.os }} timeout-minutes: 45 - steps: - # The capstones resolve fixtures through the build job's checkout path, - # which is the same on every runner of one OS. + # The capstones resolve fixtures through the build job's checkout path, + # which is the same on every runner of one OS. + steps: &install-proof-steps - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false @@ -365,7 +358,36 @@ jobs: path: logs/ retention-days: 14 + # The macOS rows of `install-proof`: they run on push to main (and nightly + # where scheduled), not on every PR push, so PRs stop queueing on the + # small macOS runner pool. + install-proof-macos: + if: github.event_name != 'pull_request' + needs: build + strategy: + fail-fast: false + max-parallel: 8 + matrix: + include: + - {os: macos-latest, vlt: '0.0.0-16'} + - {os: macos-latest, vlt: '0.0.0-30'} + - {os: macos-latest, vlt: '1.0.0-rc.8'} + - {os: macos-latest, vlt: '1.0.0-rc.13'} + - {os: macos-latest, vlt: '1.0.0-rc.14'} + - {os: macos-latest, vlt: '1.0.0-rc.15'} + - {os: macos-latest, vlt: '1.0.0-rc.22'} + - {os: macos-latest, vlt: '1.0.0-rc.33'} + - {os: macos-latest, vlt: '1.0.8'} + - {os: macos-latest, vlt: '1.1.1'} + - {os: macos-latest, vlt: '1.2.0'} + - {os: macos-latest, vlt: '1.2.0', linker: auto, suites: e2e_safety_vlt} + - {os: macos-latest, vlt: '1.2.0', linker: hardlink, suites: e2e_safety_vlt} + runs-on: ${{ matrix.os }} + timeout-minutes: 45 + steps: *install-proof-steps + plan: + if: github.event.pull_request.draft != true runs-on: ubuntu-latest timeout-minutes: 5 outputs: @@ -374,6 +396,8 @@ jobs: - id: plan env: VERSIONS_OVERRIDE: ${{ github.event.inputs.versions }} + # macOS legs run on main and nightly, not on every PR push. + EVENT_NAME: ${{ github.event_name }} run: | python3 - <<'PY' >> "$GITHUB_OUTPUT" import json, os @@ -383,6 +407,8 @@ jobs: 'windows-latest': ['1.0.0-rc.14', '1.2.0'], } override = os.environ.get('VERSIONS_OVERRIDE', '').split() + if os.environ.get('EVENT_NAME') == 'pull_request': + del defaults['macos-latest'] rows = [{'os': o, 'vlt': v} for o, vs in defaults.items() for v in (override or vs)] print('native=' + json.dumps({'include': rows})) PY @@ -473,12 +499,15 @@ jobs: VERSIONS_OVERRIDE: ${{ github.event.inputs.versions }} SHAPES_OVERRIDE: ${{ github.event.inputs.shapes }} MODES_OVERRIDE: ${{ github.event.inputs.modes }} + EVENT_NAME: ${{ github.event_name }} run: | required=() modes=(hosted vendored agent) if [ -n "$MODES_OVERRIDE" ]; then read -r -a modes <<<"$MODES_OVERRIDE"; fi - # The required set only covers cells the native jobs were asked to run. - if [ -z "$VERSIONS_OVERRIDE" ] && { [ -z "$SHAPES_OVERRIDE" ] || [[ " $SHAPES_OVERRIDE " == *" direct "* ]]; }; then + # The required set only covers cells the native jobs were asked to + # run. Pull requests run no macOS cells, so nothing is required there; + # the Linux and Windows locks are still compared. + if [ "$EVENT_NAME" != pull_request ] && [ -z "$VERSIONS_OVERRIDE" ] && { [ -z "$SHAPES_OVERRIDE" ] || [[ " $SHAPES_OVERRIDE " == *" direct "* ]]; }; then for v in 1.2.0 1.0.0-rc.14; do for m in "${modes[@]}"; do required+=("$v:$m:direct"); done done @@ -499,6 +528,9 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, macos-latest, windows-latest] + exclude: + # macOS legs run on push to main (and nightly where scheduled), not per PR push. + - os: ${{ github.event_name == 'pull_request' && 'macos-latest' || '' }} runs-on: ${{ matrix.os }} timeout-minutes: 45 steps: diff --git a/scripts/ci-e2e-bundle.py b/scripts/ci-e2e-bundle.py index 1dc3a010c..2b29f8699 100644 --- a/scripts/ci-e2e-bundle.py +++ b/scripts/ci-e2e-bundle.py @@ -119,7 +119,7 @@ def suites_for(os_name, text=None): jobs = reader.jobs(text if text is not None else CI.read_text(encoding="utf-8")) suites = set(CARGO_VEX_SUITES) for job in MATRIX_JOBS: - for row in reader.matrix_include(jobs[job]): + for row in reader.job_rows(jobs, job): if row["os"] == os_name: suites.update(row_suites(row)) return sorted(suites) diff --git a/scripts/ci-vlt-proof-suites.py b/scripts/ci-vlt-proof-suites.py index 8a119d680..6dbc5d138 100644 --- a/scripts/ci-vlt-proof-suites.py +++ b/scripts/ci-vlt-proof-suites.py @@ -39,7 +39,7 @@ def proof_upgrade(vlt, node): def ci_cells(text=None): reader = load_reader() - rows = reader.matrix_include(reader.jobs(text if text is not None else CI.read_text(encoding="utf-8"))["e2e"]) + rows = reader.job_rows(reader.jobs(text if text is not None else CI.read_text(encoding="utf-8")), "e2e") return {(r["suite"], r["os"], r["vlt"], r.get("vlt_store_linker", ""), r.get("vlt_upgrade", "")) for r in rows if r.get("vlt") and r.get("test_filter") == "--include-ignored vlt_pinned_matrix"} diff --git a/scripts/tests/test_ci_e2e_tiers.py b/scripts/tests/test_ci_e2e_tiers.py index 37d8195ed..9ed68b8c1 100644 --- a/scripts/tests/test_ci_e2e_tiers.py +++ b/scripts/tests/test_ci_e2e_tiers.py @@ -31,7 +31,7 @@ def load(name, path): def rows(job): - return rows_mod.matrix_include(JOBS[job]) + return rows_mod.job_rows(JOBS, job) def job_text(job): @@ -266,7 +266,8 @@ class PdmCapstone(unittest.TestCase): job = rows_mod.jobs(PDM.read_text(encoding="utf-8"))["capstone"] def test_excludes_exactly_the_cells_ci_runs_on_every_pr(self): - excluded = rows_mod.matrix_include([l.replace("exclude:", "include:") for l in self.job]) + excluded = [r for r in rows_mod.matrix_include([l.replace("exclude:", "include:") for l in self.job]) + if not r["os"].startswith("${{")] # the PR-only macOS exclude ci = {(r["os"], r["pdm"]) for r in rows("e2e") if "pdm" in r} self.assertEqual({(r["os"], r["pdm"]) for r in excluded}, ci) self.assertEqual(len(excluded), len(ci)) @@ -287,7 +288,7 @@ class VltProofDedupe(unittest.TestCase): def test_only_identical_ci_cells_are_left_out(self): cells = proof.ci_cells(TEXT) compat = rows_mod.jobs(COMPAT.read_text(encoding="utf-8")) - for row in rows_mod.matrix_include(compat["install-proof"]): + for row in rows_mod.job_rows(compat, "install-proof"): suites = row.get("suites", " ".join(self.suites)).split() keep = proof.remaining(suites, row["os"], row["vlt"], row.get("node", ""), row.get("linker", ""), row.get("cache_root", ""), TEXT) diff --git a/scripts/tests/test_ci_gradle_prefixes.py b/scripts/tests/test_ci_gradle_prefixes.py index 833221bc5..2a52cd027 100644 --- a/scripts/tests/test_ci_gradle_prefixes.py +++ b/scripts/tests/test_ci_gradle_prefixes.py @@ -143,7 +143,7 @@ def test_every_admitted_prefix_runs_in_both_tiers(self): row that runs that suite and by the gradle-compatibility.yml mode that runs it, so a conforming test runs on every PR and in every grid cell of its mode.""" - rows = [r for r in rows_mod.matrix_include(rows_mod.jobs(CI.read_text(encoding="utf-8"))["e2e"]) + rows = [r for r in rows_mod.job_rows(rows_mod.jobs(CI.read_text(encoding="utf-8")), "e2e") if r.get("jvm_tool") == "gradle" and r["os"] == "ubuntu-latest"] modes = compat_modes() self.assertEqual(set(modes), {"agent", "hosted", "vendor"}) @@ -176,7 +176,7 @@ def test_compat_overrides_select_admitted_tests(self): class AllowEmpty(unittest.TestCase): - rows = rows_mod.matrix_include(rows_mod.jobs(CI.read_text(encoding="utf-8"))["e2e"]) + rows = rows_mod.job_rows(rows_mod.jobs(CI.read_text(encoding="utf-8")), "e2e") def test_allow_empty_only_while_a_suite_is_unlanded(self): """The allowance is for rows whose owning package has not landed. Once diff --git a/scripts/tests/test_ci_vlt_rows.py b/scripts/tests/test_ci_vlt_rows.py index 567900f50..b5c105fbb 100644 --- a/scripts/tests/test_ci_vlt_rows.py +++ b/scripts/tests/test_ci_vlt_rows.py @@ -126,6 +126,15 @@ def matrix_include(job_lines): return rows +def job_rows(jobs_by_id, job): + """`matrix_include` of a job plus its `-macos` sibling, which holds + the macOS rows that run off the pull_request path.""" + rows = matrix_include(jobs_by_id[job]) + if f"{job}-macos" in jobs_by_id: + rows += matrix_include(jobs_by_id[f"{job}-macos"]) + return rows + + def steps(job_lines): """[(name, text)] of a job's steps.""" out, current = [], None @@ -148,7 +157,7 @@ def step(job_lines, name): class CiE2eVltRows(unittest.TestCase): ci = jobs(CI.read_text(encoding="utf-8")) - rows = matrix_include(ci["e2e"]) + rows = job_rows(ci, "e2e") vlt_rows = [r for r in rows if "vlt" in r or "vlt" in r.get("suite", "")] def test_every_vlt_row_pins_a_release_and_includes_the_ignored_legs(self): @@ -241,7 +250,7 @@ def test_hosted_e2e_proves_vlt_against_production(self): class CompatibilityWorkflow(unittest.TestCase): compat = jobs(COMPAT.read_text(encoding="utf-8")) - rows = matrix_include(compat["install-proof"]) + rows = job_rows(compat, "install-proof") def covered(self): cells = set() diff --git a/scripts/tests/test_vlt_coverage.py b/scripts/tests/test_vlt_coverage.py index e7262432b..e0868ace5 100644 --- a/scripts/tests/test_vlt_coverage.py +++ b/scripts/tests/test_vlt_coverage.py @@ -118,9 +118,9 @@ def ci_ids(self): compat = self.rows.jobs( (ROOT / ".github/workflows/vlt-compatibility.yml").read_text(encoding="utf-8")) ids = {f"ci:{r['suite']}:{r['os']}:{r['vlt']}" - for r in self.rows.matrix_include(ci["e2e"]) if "vlt" in r} + for r in self.rows.job_rows(ci, "e2e") if "vlt" in r} ids |= {f"compat:{r['os']}:{r['vlt']}" - for r in self.rows.matrix_include(compat["install-proof"])} + for r in self.rows.job_rows(compat, "install-proof")} return ids def test_every_code_is_mapped_and_documented(self):