Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 39 additions & 19 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,20 @@ on:
type: choice
default: auto
options: [auto, force, skip]
os:
# Run only one OS's jobs (plus the clippy and release-readiness
# preflights every leg waits on). A fix for a Windows-only nightly
# failure dispatches `-f os=windows` instead of re-running ~95 Linux
# and macOS jobs (~140 job-minutes) its PR run and the merge queue
# already cover. hosted-e2e is a Linux job and skips too. Only a
# dispatch sets inputs.os; on every other event it is empty, so the
# `inputs.os != ...` terms below are always true there. Each
# OS-filtered dispatch gets its own concurrency group, so
# dispatching one per OS runs them all.
description: 'Only run jobs for this OS (all = the full nightly matrix)'
type: choice
default: all
options: [all, linux, windows, macos]

permissions:
contents: read
Expand All @@ -45,7 +59,7 @@ permissions:
# cancelled the real run, skipped every job, and left ci-ok green on a head
# nothing had tested.
concurrency:
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' || '' }}
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) || '' }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}

# Linux jobs run on Depot's runners (depot-ubuntu-*-4: 4 vCPU, like GitHub's
Expand Down Expand Up @@ -144,7 +158,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) && needs.release-readiness.outputs.pr_unchanged != 'true'
if: ((github.event.pull_request.draft != true) && needs.release-readiness.outputs.pr_unchanged != 'true') && (inputs.os != 'windows' && inputs.os != 'macos')
needs: [release-readiness, clippy]
runs-on: ${{ vars.DISABLE_DEPOT_RUNNERS == 'true' && 'ubuntu-latest' || 'depot-ubuntu-24.04-4' }}
timeout-minutes: 30
Expand Down Expand Up @@ -182,7 +196,7 @@ jobs:
# Check the standalone installer, release scripts, and native installer
# test harnesses.
lint-ecosystems:
if: github.event.pull_request.draft != true
if: (github.event.pull_request.draft != true) && (inputs.os != 'windows' && inputs.os != 'macos')
runs-on: ${{ vars.DISABLE_DEPOT_RUNNERS == 'true' && 'ubuntu-latest' || 'depot-ubuntu-24.04-4' }}
timeout-minutes: 10
steps:
Expand Down Expand Up @@ -362,7 +376,7 @@ jobs:
bash scripts/release-lint.sh --sync-only

test:
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'
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')
needs: [release-readiness, clippy]
# No ubuntu-latest leg: `coverage` runs this same `cargo test
# --workspace` (debug, default features, plus Go and vexctl) on ubuntu,
Expand All @@ -381,6 +395,8 @@ jobs:
exclude:
# macOS legs run on main, the merge queue and nightly, not per PR push.
- os: ${{ github.event_name == 'pull_request' && 'macos-latest' || '' }}
# `workflow_dispatch -f os=windows|macos` runs that OS's legs only.
- os: ${{ inputs.os == 'windows' && 'macos-latest' || inputs.os == 'macos' && 'windows-latest' || '' }}
# One compile-only cache writer per OS is enough for an already
# tested SHA.
- shard: ${{ needs.release-readiness.outputs.reuse == 'true' && 2 || 0 }}
Expand Down Expand Up @@ -559,7 +575,7 @@ jobs:
# Each PR and main push runs the complete release-mode suite. The merge
# queue already skips this job because each constituent PR ran it, so
# an unchanged merge-main PR push (pr_unchanged) still runs it too.
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')
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')
needs: clippy
runs-on: ${{ vars.DISABLE_DEPOT_RUNNERS == 'true' && 'ubuntu-latest' || 'depot-ubuntu-24.04-16' }}
strategy:
Expand Down Expand Up @@ -607,7 +623,7 @@ jobs:
run: python3 scripts/ci-test-shard.py "$TEST_SHARD" "$TEST_SHARD_COUNT" --locked --profile ci-release

coverage:
if: (github.event.pull_request.draft != true) && needs.release-readiness.outputs.pr_unchanged != 'true'
if: ((github.event.pull_request.draft != true) && needs.release-readiness.outputs.pr_unchanged != 'true') && (inputs.os != 'windows' && inputs.os != 'macos')
needs: release-readiness
# Code coverage via cargo-llvm-cov (LLVM source-based instrumentation).
# Reports as a markdown table in the job summary and uploads the raw
Expand Down Expand Up @@ -765,7 +781,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 && 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'
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')
needs: [release-readiness, clippy]
runs-on: ${{ vars.DISABLE_DEPOT_RUNNERS == 'true' && 'ubuntu-22.04' || 'depot-ubuntu-22.04-4' }}
timeout-minutes: 30
Expand Down Expand Up @@ -1018,7 +1034,7 @@ jobs:
retention-days: 30

dispatch-tests:
if: github.event.pull_request.draft != true
if: (github.event.pull_request.draft != true) && (inputs.os != 'windows' && inputs.os != 'macos')
runs-on: ${{ vars.DISABLE_DEPOT_RUNNERS == 'true' && 'ubuntu-latest' || 'depot-ubuntu-24.04-4' }}
timeout-minutes: 10
steps:
Expand Down Expand Up @@ -1055,7 +1071,7 @@ 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) && needs.release-readiness.outputs.pr_unchanged != 'true'
if: ((github.event.pull_request.draft != true) && needs.release-readiness.outputs.pr_unchanged != 'true') && (inputs.os != 'windows' && inputs.os != 'macos')
needs: release-readiness
outputs:
reuse: ${{ needs.release-readiness.outputs.reuse }}
Expand Down Expand Up @@ -1162,7 +1178,7 @@ jobs:
# Builds the Windows test binaries for e2e-windows and
# cargo-vex-matrix-windows. The lean merge queue runs
# windows-compile-check instead.
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'
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')
needs: [release-readiness, clippy]
outputs:
reuse: ${{ needs.release-readiness.outputs.reuse }}
Expand All @@ -1176,7 +1192,7 @@ jobs:
steps: *e2e-build-steps

e2e-build-macos:
if: (github.event_name != 'pull_request') && (vars.CI_SCOPE == 'full' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch')
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')
needs: [release-readiness, clippy]
outputs:
reuse: ${{ needs.release-readiness.outputs.reuse }}
Expand Down Expand Up @@ -2317,7 +2333,7 @@ jobs:
# Dropping that `needs` also dropped the draft skip it inherited, so
# gate on draft here directly (push/merge_group/schedule still run).
# Only wait for the clippy and release-readiness preflights.
if: (github.event.pull_request.draft != true && needs.release-readiness.outputs.reuse != 'true') && needs.release-readiness.outputs.pr_unchanged != 'true'
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')
needs: [release-readiness, clippy]
runs-on: ${{ vars.DISABLE_DEPOT_RUNNERS == 'true' && 'ubuntu-latest' || 'depot-ubuntu-24.04-4' }}
timeout-minutes: 40
Expand Down Expand Up @@ -2363,7 +2379,7 @@ jobs:
# Dropping that `needs` also dropped the draft skip it inherited, so
# gate on draft here directly (push/merge_group/schedule still run).
# Only wait for the clippy and release-readiness preflights.
if: (github.event.pull_request.draft != true && needs.release-readiness.outputs.reuse != 'true') && needs.release-readiness.outputs.pr_unchanged != 'true'
if: ((github.event.pull_request.draft != true && needs.release-readiness.outputs.reuse != 'true') && needs.release-readiness.outputs.pr_unchanged != 'true') && (inputs.os != 'macos')
needs: [release-readiness, clippy]
strategy:
fail-fast: false
Expand All @@ -2372,7 +2388,7 @@ jobs:
# `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.
# LEAN SCOPE: the newest Linux release only, unless CI_SCOPE=full / nightly.
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"}]') }}
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"}]') }}
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 }}
timeout-minutes: 30
steps: &yarn-berry-steps
Expand Down Expand Up @@ -2406,7 +2422,7 @@ jobs:
# 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' && needs.release-readiness.outputs.reuse != 'true') && (vars.CI_SCOPE == 'full' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch')
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')
name: yarn-berry ${{ matrix.yarn }} (${{ matrix.os }})
needs: [release-readiness, clippy]
strategy:
Expand All @@ -2424,7 +2440,7 @@ jobs:
yarn-berry-full:
name: yarn-berry ${{ matrix.yarn }} (${{ matrix.os }})
# Same gate as e2e-full.
if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' || (github.event_name == 'push' && vars.CI_SCOPE == 'full') || github.head_ref == 'release/v5-prerelease'
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')
needs: clippy
strategy:
fail-fast: false
Expand Down Expand Up @@ -2604,7 +2620,7 @@ jobs:
# Dropping that `needs` also dropped the draft skip it inherited, so
# gate on draft here directly (push/merge_group/schedule still run).
# Only wait for the clippy and release-readiness preflights.
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'
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')
needs: [release-readiness, clippy]
runs-on: ${{ vars.DISABLE_DEPOT_RUNNERS == 'true' && 'ubuntu-latest' || 'depot-ubuntu-24.04-4' }}
timeout-minutes: 30
Expand Down Expand Up @@ -2676,7 +2692,7 @@ jobs:
# ----------------------------------------------------------------------
hosted-e2e:
name: hosted-e2e # may be a required check; do not rename
if: github.event.pull_request.draft != true
if: (github.event.pull_request.draft != true) && (inputs.os != 'windows' && inputs.os != 'macos')
needs: clippy
runs-on: ${{ vars.DISABLE_DEPOT_RUNNERS == 'true' && 'ubuntu-latest' || 'depot-ubuntu-24.04-4' }}
permissions:
Expand Down Expand Up @@ -2882,7 +2898,11 @@ jobs:
# every job above, so adding a job here is how it becomes merge-blocking.
# Skipped jobs (the nightly `full` tier) pass; failed or cancelled ones fail.
ci-ok:
name: ci-ok # registered as a required check; do not rename
# Registered as a required check; do not rename. A one-OS dispatch
# (inputs.os, #1818) skips the other OSes, so its verdict gets another
# name: a green `ci-ok` on the branch head must mean every PR-tier job
# passed, and a skipped required check would count as passing too.
name: ${{ inputs.os && inputs.os != 'all' && format('ci-ok ({0} only)', inputs.os) || 'ci-ok' }}
if: always()
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]
# GitHub-hosted, not Depot: the check is one 2 s python3 call that runs
Expand Down
12 changes: 9 additions & 3 deletions scripts/tests/test_ci_e2e_tiers.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,15 @@ def test_full_jobs_run_nightly_only_and_share_steps(self):
# Nightly, dispatch (release-qa) and v5 landings, like
# e2e-docker: not on PRs, the merge queue or a lean push to
# main, where its 41 legs ran on every landing.
self.assertIn(" if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'"
" || (github.event_name == 'push' && vars.CI_SCOPE == 'full')"
" || github.head_ref == 'release/v5-prerelease'\n", text)
# yarn-berry-full waits only on clippy, so it carries the
# Linux-only term for `workflow_dispatch -f os=...` itself
# (#1818); the others skip with e2e-build.
gate = (" if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'"
" || (github.event_name == 'push' && vars.CI_SCOPE == 'full')"
" || github.head_ref == 'release/v5-prerelease'")
if job == "yarn-berry-full":
gate = gate.replace(" if: ", " if: (") + ") && (inputs.os != 'windows' && inputs.os != 'macos')"
self.assertIn(gate + "\n", text)
self.assertIn(f"steps: *{anchor}", text)
self.assertIn(f"steps: &{anchor}", TEXT)

Expand Down
Loading
Loading