2929 type : choice
3030 default : auto
3131 options : [auto, force, skip]
32+ os :
33+ # Run only one OS's jobs (plus the clippy and release-readiness
34+ # preflights every leg waits on). A fix for a Windows-only nightly
35+ # failure dispatches `-f os=windows` instead of re-running ~95 Linux
36+ # and macOS jobs (~140 job-minutes) its PR run and the merge queue
37+ # already cover. hosted-e2e is a Linux job and skips too. Only a
38+ # dispatch sets inputs.os; on every other event it is empty, so the
39+ # `inputs.os != ...` terms below are always true there. Each
40+ # OS-filtered dispatch gets its own concurrency group, so
41+ # dispatching one per OS runs them all.
42+ description : ' Only run jobs for this OS (all = the full nightly matrix)'
43+ type : choice
44+ default : all
45+ options : [all, linux, windows, macos]
3246
3347permissions :
3448 contents : read
@@ -45,7 +59,7 @@ permissions:
4559# cancelled the real run, skipped every job, and left ci-ok green on a head
4660# nothing had tested.
4761concurrency :
48- group : ci-${{ github.event.pull_request.number || (github.event_name == 'push' && github.sha) || github.ref }}${{ github.event_name == 'schedule' && '-nightly' || '' }}${{ github.event.pull_request.draft && '-draft' || '' }}
62+ group : ci-${{ github.event.pull_request.number || (github.event_name == 'push' && github.sha) || github.ref }}${{ github.event_name == 'schedule' && '-nightly' || '' }}${{ github.event.pull_request.draft && '-draft' || '' }}${{ inputs.os && inputs.os != 'all' && format('-{0}', inputs.os) || '' }}
4963 cancel-in-progress : ${{ github.event_name == 'pull_request' }}
5064
5165# Linux jobs run on Depot's runners (depot-ubuntu-*-4: 4 vCPU, like GitHub's
@@ -144,7 +158,7 @@ jobs:
144158 # The napi addon is only ever loaded by Node, so cargo's own tests never
145159 # exercise its JS loader or the engine/provider boundary.
146160 node-addon :
147- if : (github.event.pull_request.draft != true) && needs.release-readiness.outputs.pr_unchanged != 'true'
161+ if : (( github.event.pull_request.draft != true) && needs.release-readiness.outputs.pr_unchanged != 'true') && (inputs.os != 'windows' && inputs.os != 'macos')
148162 needs : [release-readiness, clippy]
149163 runs-on : ${{ vars.DISABLE_DEPOT_RUNNERS == 'true' && 'ubuntu-latest' || 'depot-ubuntu-24.04-4' }}
150164 timeout-minutes : 30
@@ -182,7 +196,7 @@ jobs:
182196 # Check the standalone installer, release scripts, and native installer
183197 # test harnesses.
184198 lint-ecosystems :
185- if : github.event.pull_request.draft != true
199+ if : ( github.event.pull_request.draft != true) && (inputs.os != 'windows' && inputs.os != 'macos')
186200 runs-on : ${{ vars.DISABLE_DEPOT_RUNNERS == 'true' && 'ubuntu-latest' || 'depot-ubuntu-24.04-4' }}
187201 timeout-minutes : 10
188202 steps :
@@ -362,7 +376,7 @@ jobs:
362376 bash scripts/release-lint.sh --sync-only
363377
364378 test :
365- if : ((github.event.pull_request.draft != true) && (vars.CI_SCOPE == 'full' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch')) && needs.release-readiness.outputs.pr_unchanged != 'true'
379+ if : ((( github.event.pull_request.draft != true) && (vars.CI_SCOPE == 'full' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch')) && needs.release-readiness.outputs.pr_unchanged != 'true') && (inputs.os != 'linux')
366380 needs : [release-readiness, clippy]
367381 # No ubuntu-latest leg: `coverage` runs this same `cargo test
368382 # --workspace` (debug, default features, plus Go and vexctl) on ubuntu,
@@ -381,6 +395,8 @@ jobs:
381395 exclude :
382396 # macOS legs run on main, the merge queue and nightly, not per PR push.
383397 - os : ${{ github.event_name == 'pull_request' && 'macos-latest' || '' }}
398+ # `workflow_dispatch -f os=windows|macos` runs that OS's legs only.
399+ - os : ${{ inputs.os == 'windows' && 'macos-latest' || inputs.os == 'macos' && 'windows-latest' || '' }}
384400 # One compile-only cache writer per OS is enough for an already
385401 # tested SHA.
386402 - shard : ${{ needs.release-readiness.outputs.reuse == 'true' && 2 || 0 }}
@@ -559,7 +575,7 @@ jobs:
559575 # Each PR and main push runs the complete release-mode suite. The merge
560576 # queue already skips this job because each constituent PR ran it, so
561577 # an unchanged merge-main PR push (pr_unchanged) still runs it too.
562- if : (github.event.pull_request.draft != true && github.event_name != 'merge_group') && (vars.CI_SCOPE == 'full' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch')
578+ if : (( github.event.pull_request.draft != true && github.event_name != 'merge_group') && (vars.CI_SCOPE == 'full' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch')) && (inputs.os != 'windows' && inputs.os != 'macos ')
563579 needs : clippy
564580 runs-on : ${{ vars.DISABLE_DEPOT_RUNNERS == 'true' && 'ubuntu-latest' || 'depot-ubuntu-24.04-16' }}
565581 strategy :
@@ -607,7 +623,7 @@ jobs:
607623 run : python3 scripts/ci-test-shard.py "$TEST_SHARD" "$TEST_SHARD_COUNT" --locked --profile ci-release
608624
609625 coverage :
610- if : (github.event.pull_request.draft != true) && needs.release-readiness.outputs.pr_unchanged != 'true'
626+ if : (( github.event.pull_request.draft != true) && needs.release-readiness.outputs.pr_unchanged != 'true') && (inputs.os != 'windows' && inputs.os != 'macos')
611627 needs : release-readiness
612628 # Code coverage via cargo-llvm-cov (LLVM source-based instrumentation).
613629 # Reports as a markdown table in the job summary and uploads the raw
@@ -765,7 +781,7 @@ jobs:
765781 # Dockerfile.base compiles the full-LTO release binary inside Docker, with
766782 # no cache. Build it once per run and hand the image to every docker leg.
767783 docker-base :
768- if : ((github.event.pull_request.draft != true && needs.release-readiness.outputs.reuse != 'true') && (vars.CI_SCOPE == 'full' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' || github.head_ref == 'release/v5-prerelease')) && needs.release-readiness.outputs.pr_unchanged != 'true'
784+ if : ((( github.event.pull_request.draft != true && needs.release-readiness.outputs.reuse != 'true') && (vars.CI_SCOPE == 'full' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' || github.head_ref == 'release/v5-prerelease')) && needs.release-readiness.outputs.pr_unchanged != 'true') && (inputs.os != 'windows' && inputs.os != 'macos')
769785 needs : [release-readiness, clippy]
770786 runs-on : ${{ vars.DISABLE_DEPOT_RUNNERS == 'true' && 'ubuntu-22.04' || 'depot-ubuntu-22.04-4' }}
771787 timeout-minutes : 30
@@ -1018,7 +1034,7 @@ jobs:
10181034 retention-days : 30
10191035
10201036 dispatch-tests :
1021- if : github.event.pull_request.draft != true
1037+ if : ( github.event.pull_request.draft != true) && (inputs.os != 'windows' && inputs.os != 'macos')
10221038 runs-on : ${{ vars.DISABLE_DEPOT_RUNNERS == 'true' && 'ubuntu-latest' || 'depot-ubuntu-24.04-4' }}
10231039 timeout-minutes : 10
10241040 steps :
@@ -1055,7 +1071,7 @@ jobs:
10551071 # test binaries directly from the same checkout path, so `CARGO_BIN_EXE_*`
10561072 # and `CARGO_MANIFEST_DIR` resolve as they did under `cargo test`.
10571073 e2e-build :
1058- if : (github.event.pull_request.draft != true) && needs.release-readiness.outputs.pr_unchanged != 'true'
1074+ if : (( github.event.pull_request.draft != true) && needs.release-readiness.outputs.pr_unchanged != 'true') && (inputs.os != 'windows' && inputs.os != 'macos')
10591075 needs : release-readiness
10601076 outputs :
10611077 reuse : ${{ needs.release-readiness.outputs.reuse }}
@@ -1162,7 +1178,7 @@ jobs:
11621178 # Builds the Windows test binaries for e2e-windows and
11631179 # cargo-vex-matrix-windows. The lean merge queue runs
11641180 # windows-compile-check instead.
1165- if : ((github.event.pull_request.draft != true) && (vars.CI_SCOPE == 'full' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch')) && needs.release-readiness.outputs.pr_unchanged != 'true'
1181+ if : ((( github.event.pull_request.draft != true) && (vars.CI_SCOPE == 'full' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch')) && needs.release-readiness.outputs.pr_unchanged != 'true') && (inputs.os != 'linux' && inputs.os != 'macos')
11661182 needs : [release-readiness, clippy]
11671183 outputs :
11681184 reuse : ${{ needs.release-readiness.outputs.reuse }}
@@ -1176,7 +1192,7 @@ jobs:
11761192 steps : *e2e-build-steps
11771193
11781194 e2e-build-macos :
1179- if : (github.event_name != 'pull_request') && (vars.CI_SCOPE == 'full' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch')
1195+ if : (( github.event_name != 'pull_request') && (vars.CI_SCOPE == 'full' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch')) && (inputs.os != 'linux' && inputs.os != 'windows ')
11801196 needs : [release-readiness, clippy]
11811197 outputs :
11821198 reuse : ${{ needs.release-readiness.outputs.reuse }}
@@ -2332,7 +2348,7 @@ jobs:
23322348 # Dropping that `needs` also dropped the draft skip it inherited, so
23332349 # gate on draft here directly (push/merge_group/schedule still run).
23342350 # Only wait for the clippy and release-readiness preflights.
2335- if : (github.event.pull_request.draft != true && needs.release-readiness.outputs.reuse != 'true') && needs.release-readiness.outputs.pr_unchanged != 'true'
2351+ if : (( github.event.pull_request.draft != true && needs.release-readiness.outputs.reuse != 'true') && needs.release-readiness.outputs.pr_unchanged != 'true') && (inputs.os != 'windows' && inputs.os != 'macos')
23362352 needs : [release-readiness, clippy]
23372353 runs-on : ${{ vars.DISABLE_DEPOT_RUNNERS == 'true' && 'ubuntu-latest' || 'depot-ubuntu-24.04-4' }}
23382354 timeout-minutes : 40
@@ -2378,7 +2394,7 @@ jobs:
23782394 # Dropping that `needs` also dropped the draft skip it inherited, so
23792395 # gate on draft here directly (push/merge_group/schedule still run).
23802396 # Only wait for the clippy and release-readiness preflights.
2381- if : (github.event.pull_request.draft != true && needs.release-readiness.outputs.reuse != 'true') && needs.release-readiness.outputs.pr_unchanged != 'true'
2397+ if : (( github.event.pull_request.draft != true && needs.release-readiness.outputs.reuse != 'true') && needs.release-readiness.outputs.pr_unchanged != 'true') && (inputs.os != 'macos')
23822398 needs : [release-readiness, clippy]
23832399 strategy :
23842400 fail-fast : false
@@ -2387,7 +2403,7 @@ jobs:
23872403 # `10c0/` writer, current, and 4.12.0 on macOS / Windows. The rest
23882404 # of the spread (4.6.0, 4.12.0 on ubuntu) is yarn-berry-full.
23892405 # LEAN SCOPE: the newest Linux release only, unless CI_SCOPE=full / nightly.
2390- include : ${{ fromJSON((vars.CI_SCOPE == 'full' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') && ' [{"os":"ubuntu-latest","yarn":"4.0.2"},{"os":"ubuntu-latest","yarn":"4.1.0"},{"os":"ubuntu-latest","yarn":"4.18.0"}, {"os":"windows-latest","yarn":"4.12.0"}]' || '[{"os":"ubuntu-latest","yarn":"4.18.0"}]') }}
2406+ include : ${{ fromJSON((vars.CI_SCOPE == 'full' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') && (inputs.os == 'windows' && ' [{"os":"windows-latest","yarn":"4.12.0"}]' || inputs.os == 'linux' && '[{"os":" ubuntu-latest","yarn":"4.0.2"},{"os":"ubuntu-latest","yarn":"4.1.0"},{"os":"ubuntu-latest","yarn":"4.18.0"}]' || '[{"os":"ubuntu-latest","yarn":"4.0.2"}, {"os":"ubuntu-latest","yarn":"4.1.0"},{"os":"ubuntu-latest","yarn":"4.18.0"},{"os":" windows-latest","yarn":"4.12.0"}]') || '[{"os":"ubuntu-latest","yarn":"4.18.0"}]') }}
23912407 runs-on : ${{ vars.DISABLE_DEPOT_RUNNERS != 'true' && (matrix.os == 'ubuntu-latest' && 'depot-ubuntu-24.04-4' || matrix.os == 'ubuntu-22.04' && 'depot-ubuntu-22.04-4') || matrix.os }}
23922408 timeout-minutes : 30
23932409 steps : &yarn-berry-steps
@@ -2421,7 +2437,7 @@ jobs:
24212437 # nightly, not on every PR push, so PRs stop queueing on the small
24222438 # macOS runner pool.
24232439 yarn-berry-e2e-macos :
2424- if : (github.event_name != 'pull_request' && needs.release-readiness.outputs.reuse != 'true') && (vars.CI_SCOPE == 'full' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch')
2440+ if : (( github.event_name != 'pull_request' && needs.release-readiness.outputs.reuse != 'true') && (vars.CI_SCOPE == 'full' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch')) && (inputs.os != 'linux' && inputs.os != 'windows ')
24252441 name : yarn-berry ${{ matrix.yarn }} (${{ matrix.os }})
24262442 needs : [release-readiness, clippy]
24272443 strategy :
@@ -2439,7 +2455,7 @@ jobs:
24392455 yarn-berry-full :
24402456 name : yarn-berry ${{ matrix.yarn }} (${{ matrix.os }})
24412457 # Same gate as e2e-full.
2442- if : github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' || (github.event_name == 'push' && vars.CI_SCOPE == 'full') || github.head_ref == 'release/v5-prerelease'
2458+ if : ( github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' || (github.event_name == 'push' && vars.CI_SCOPE == 'full') || github.head_ref == 'release/v5-prerelease') && (inputs.os != 'windows' && inputs.os != 'macos')
24432459 needs : clippy
24442460 strategy :
24452461 fail-fast : false
@@ -2619,7 +2635,7 @@ jobs:
26192635 # Dropping that `needs` also dropped the draft skip it inherited, so
26202636 # gate on draft here directly (push/merge_group/schedule still run).
26212637 # Only wait for the clippy and release-readiness preflights.
2622- if : ((github.event.pull_request.draft != true) && (vars.CI_SCOPE == 'full' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch')) && needs.release-readiness.outputs.pr_unchanged != 'true'
2638+ if : ((( github.event.pull_request.draft != true) && (vars.CI_SCOPE == 'full' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch')) && needs.release-readiness.outputs.pr_unchanged != 'true') && (inputs.os != 'windows' && inputs.os != 'macos')
26232639 needs : [release-readiness, clippy]
26242640 runs-on : ${{ vars.DISABLE_DEPOT_RUNNERS == 'true' && 'ubuntu-latest' || 'depot-ubuntu-24.04-4' }}
26252641 timeout-minutes : 30
@@ -2691,7 +2707,7 @@ jobs:
26912707 # ----------------------------------------------------------------------
26922708 hosted-e2e :
26932709 name : hosted-e2e # may be a required check; do not rename
2694- if : github.event.pull_request.draft != true
2710+ if : ( github.event.pull_request.draft != true) && (inputs.os != 'windows' && inputs.os != 'macos')
26952711 needs : clippy
26962712 runs-on : ${{ vars.DISABLE_DEPOT_RUNNERS == 'true' && 'ubuntu-latest' || 'depot-ubuntu-24.04-4' }}
26972713 permissions :
@@ -2908,7 +2924,11 @@ jobs:
29082924 # every job above, so adding a job here is how it becomes merge-blocking.
29092925 # Skipped jobs (the nightly `full` tier) pass; failed or cancelled ones fail.
29102926 ci-ok :
2911- name : ci-ok # registered as a required check; do not rename
2927+ # Registered as a required check; do not rename. A one-OS dispatch
2928+ # (inputs.os, #1818) skips the other OSes, so its verdict gets another
2929+ # name: a green `ci-ok` on the branch head must mean every PR-tier job
2930+ # passed, and a skipped required check would count as passing too.
2931+ name : ${{ inputs.os && inputs.os != 'all' && format('ci-ok ({0} only)', inputs.os) || 'ci-ok' }}
29122932 if : always()
29132933 needs : [clippy, node-addon, lint-ecosystems, release-readiness, test, test-release, coverage, docker-base, coverage-docker, coverage-merge, dispatch-tests, e2e-build, windows-compile-check, e2e-build-windows, e2e-build-macos, e2e, e2e-windows, e2e-extended, e2e-full, e2e-docker, yarn-classic-matrix, yarn-berry-e2e, yarn-berry-full, cargo-vex-matrix, cargo-vex-matrix-windows, cargo-vex-matrix-full, cargo-old-toolchains, hosted-e2e, e2e-macos, yarn-berry-e2e-macos, cargo-vex-matrix-macos]
29142934 # GitHub-hosted, not Depot: the check is one 2 s python3 call that runs
0 commit comments