diff --git a/.github/workflows/crap-crates.yml b/.github/workflows/crap-crates.yml index 8a325ab1a..0b8b79bf5 100644 --- a/.github/workflows/crap-crates.yml +++ b/.github/workflows/crap-crates.yml @@ -58,8 +58,28 @@ env: jobs: crap-stack-auth: - name: CRAP (stack-auth) - runs-on: blacksmith-16vcpu-ubuntu-2204 + # RunsOn trial: this job on every runner in `runner`. Collapse before merging. + name: CRAP (stack-auth) (${{ matrix.runner.name }}) + runs-on: ${{ matrix.runner.label }} + strategy: + fail-fast: false + matrix: + runner: + - id: blacksmith + name: blacksmith 16vcpu + label: blacksmith-16vcpu-ubuntu-2204 + - id: github + name: github + label: ubuntu-22.04 + - id: runs-on-4 + name: runs-on c8a 4cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=4/image=ubuntu22-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-8 + name: runs-on c8a 8cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=8/image=ubuntu22-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-16 + name: runs-on c8a 16cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=16/image=ubuntu22-full-x64/volume=80gb/extras=s3-cache timeout-minutes: 45 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 @@ -82,8 +102,28 @@ jobs: run: mise run crap:stack-auth -- --format github crap-stack-encrypt: - name: CRAP (stack-encrypt) - runs-on: blacksmith-16vcpu-ubuntu-2204 + # RunsOn trial: this job on every runner in `runner`. Collapse before merging. + name: CRAP (stack-encrypt) (${{ matrix.runner.name }}) + runs-on: ${{ matrix.runner.label }} + strategy: + fail-fast: false + matrix: + runner: + - id: blacksmith + name: blacksmith 16vcpu + label: blacksmith-16vcpu-ubuntu-2204 + - id: github + name: github + label: ubuntu-22.04 + - id: runs-on-4 + name: runs-on c8a 4cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=4/image=ubuntu22-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-8 + name: runs-on c8a 8cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=8/image=ubuntu22-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-16 + name: runs-on c8a 16cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=16/image=ubuntu22-full-x64/volume=80gb/extras=s3-cache timeout-minutes: 45 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 diff --git a/.github/workflows/fuzz.yml b/.github/workflows/fuzz.yml index baa8e8cd8..f4c9244a9 100644 --- a/.github/workflows/fuzz.yml +++ b/.github/workflows/fuzz.yml @@ -61,23 +61,227 @@ env: jobs: fuzz-regression: - name: fuzz regression (${{ matrix.slug }}) + # RunsOn trial: this job on every runner in `runner`. Collapse before merging. + name: fuzz regression (${{ matrix.slug }}) (${{ matrix.runner.name }}) # Not on the nightly schedule, which is the campaign's. A manual dispatch # runs both jobs. if: github.event_name != 'schedule' - runs-on: blacksmith-4vcpu-ubuntu-2404 + runs-on: ${{ matrix.runner.label }} timeout-minutes: 30 strategy: fail-fast: false matrix: include: - - { task: "fuzz:access-key", slug: access-key } - - { task: "fuzz:jwt-decode", slug: jwt-decode } - - { task: "fuzz:client-key", slug: client-key } - - { task: "fuzz:sealed-value", slug: sealed-value } - - { task: "fuzz:term-decode", slug: term-decode } - - { task: "fuzz:check-record", slug: check-record } - - { task: "fuzz:plan-build", slug: plan-build } + - task: "fuzz:access-key" + slug: access-key + runner: + id: blacksmith + name: blacksmith 4vcpu + label: blacksmith-4vcpu-ubuntu-2404 + - task: "fuzz:access-key" + slug: access-key + runner: + id: github + name: github + label: ubuntu-24.04 + - task: "fuzz:access-key" + slug: access-key + runner: + id: runs-on-2 + name: runs-on c8a 2cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=2/image=ubuntu24-full-x64/volume=80gb/extras=s3-cache + - task: "fuzz:access-key" + slug: access-key + runner: + id: runs-on-4 + name: runs-on c8a 4cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=4/image=ubuntu24-full-x64/volume=80gb/extras=s3-cache + - task: "fuzz:access-key" + slug: access-key + runner: + id: runs-on-8 + name: runs-on c8a 8cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=8/image=ubuntu24-full-x64/volume=80gb/extras=s3-cache + - task: "fuzz:jwt-decode" + slug: jwt-decode + runner: + id: blacksmith + name: blacksmith 4vcpu + label: blacksmith-4vcpu-ubuntu-2404 + - task: "fuzz:jwt-decode" + slug: jwt-decode + runner: + id: github + name: github + label: ubuntu-24.04 + - task: "fuzz:jwt-decode" + slug: jwt-decode + runner: + id: runs-on-2 + name: runs-on c8a 2cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=2/image=ubuntu24-full-x64/volume=80gb/extras=s3-cache + - task: "fuzz:jwt-decode" + slug: jwt-decode + runner: + id: runs-on-4 + name: runs-on c8a 4cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=4/image=ubuntu24-full-x64/volume=80gb/extras=s3-cache + - task: "fuzz:jwt-decode" + slug: jwt-decode + runner: + id: runs-on-8 + name: runs-on c8a 8cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=8/image=ubuntu24-full-x64/volume=80gb/extras=s3-cache + - task: "fuzz:client-key" + slug: client-key + runner: + id: blacksmith + name: blacksmith 4vcpu + label: blacksmith-4vcpu-ubuntu-2404 + - task: "fuzz:client-key" + slug: client-key + runner: + id: github + name: github + label: ubuntu-24.04 + - task: "fuzz:client-key" + slug: client-key + runner: + id: runs-on-2 + name: runs-on c8a 2cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=2/image=ubuntu24-full-x64/volume=80gb/extras=s3-cache + - task: "fuzz:client-key" + slug: client-key + runner: + id: runs-on-4 + name: runs-on c8a 4cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=4/image=ubuntu24-full-x64/volume=80gb/extras=s3-cache + - task: "fuzz:client-key" + slug: client-key + runner: + id: runs-on-8 + name: runs-on c8a 8cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=8/image=ubuntu24-full-x64/volume=80gb/extras=s3-cache + - task: "fuzz:sealed-value" + slug: sealed-value + runner: + id: blacksmith + name: blacksmith 4vcpu + label: blacksmith-4vcpu-ubuntu-2404 + - task: "fuzz:sealed-value" + slug: sealed-value + runner: + id: github + name: github + label: ubuntu-24.04 + - task: "fuzz:sealed-value" + slug: sealed-value + runner: + id: runs-on-2 + name: runs-on c8a 2cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=2/image=ubuntu24-full-x64/volume=80gb/extras=s3-cache + - task: "fuzz:sealed-value" + slug: sealed-value + runner: + id: runs-on-4 + name: runs-on c8a 4cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=4/image=ubuntu24-full-x64/volume=80gb/extras=s3-cache + - task: "fuzz:sealed-value" + slug: sealed-value + runner: + id: runs-on-8 + name: runs-on c8a 8cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=8/image=ubuntu24-full-x64/volume=80gb/extras=s3-cache + - task: "fuzz:term-decode" + slug: term-decode + runner: + id: blacksmith + name: blacksmith 4vcpu + label: blacksmith-4vcpu-ubuntu-2404 + - task: "fuzz:term-decode" + slug: term-decode + runner: + id: github + name: github + label: ubuntu-24.04 + - task: "fuzz:term-decode" + slug: term-decode + runner: + id: runs-on-2 + name: runs-on c8a 2cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=2/image=ubuntu24-full-x64/volume=80gb/extras=s3-cache + - task: "fuzz:term-decode" + slug: term-decode + runner: + id: runs-on-4 + name: runs-on c8a 4cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=4/image=ubuntu24-full-x64/volume=80gb/extras=s3-cache + - task: "fuzz:term-decode" + slug: term-decode + runner: + id: runs-on-8 + name: runs-on c8a 8cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=8/image=ubuntu24-full-x64/volume=80gb/extras=s3-cache + - task: "fuzz:check-record" + slug: check-record + runner: + id: blacksmith + name: blacksmith 4vcpu + label: blacksmith-4vcpu-ubuntu-2404 + - task: "fuzz:check-record" + slug: check-record + runner: + id: github + name: github + label: ubuntu-24.04 + - task: "fuzz:check-record" + slug: check-record + runner: + id: runs-on-2 + name: runs-on c8a 2cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=2/image=ubuntu24-full-x64/volume=80gb/extras=s3-cache + - task: "fuzz:check-record" + slug: check-record + runner: + id: runs-on-4 + name: runs-on c8a 4cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=4/image=ubuntu24-full-x64/volume=80gb/extras=s3-cache + - task: "fuzz:check-record" + slug: check-record + runner: + id: runs-on-8 + name: runs-on c8a 8cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=8/image=ubuntu24-full-x64/volume=80gb/extras=s3-cache + - task: "fuzz:plan-build" + slug: plan-build + runner: + id: blacksmith + name: blacksmith 4vcpu + label: blacksmith-4vcpu-ubuntu-2404 + - task: "fuzz:plan-build" + slug: plan-build + runner: + id: github + name: github + label: ubuntu-24.04 + - task: "fuzz:plan-build" + slug: plan-build + runner: + id: runs-on-2 + name: runs-on c8a 2cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=2/image=ubuntu24-full-x64/volume=80gb/extras=s3-cache + - task: "fuzz:plan-build" + slug: plan-build + runner: + id: runs-on-4 + name: runs-on c8a 4cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=4/image=ubuntu24-full-x64/volume=80gb/extras=s3-cache + - task: "fuzz:plan-build" + slug: plan-build + runner: + id: runs-on-8 + name: runs-on c8a 8cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=8/image=ubuntu24-full-x64/volume=80gb/extras=s3-cache steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: diff --git a/.github/workflows/integration-drizzle.yml b/.github/workflows/integration-drizzle.yml index ddbf73c2c..4d32f7ac8 100644 --- a/.github/workflows/integration-drizzle.yml +++ b/.github/workflows/integration-drizzle.yml @@ -203,8 +203,9 @@ on: jobs: integration: - name: Drizzle v3 integration (db=${{ matrix.db }}) - runs-on: blacksmith-4vcpu-ubuntu-2404 + # RunsOn trial: this job on every runner in `runner`. Collapse before merging. + name: Drizzle v3 integration (db=${{ matrix.db }}) (${{ matrix.runner.name }}) + runs-on: ${{ matrix.runner.label }} # No concurrency group: `integration-db` gives each job its own compose # project and ephemeral host ports, so live-DB jobs no longer contend and do # not need serialising. See that action for why the old @@ -232,6 +233,22 @@ jobs: # harness assert the `anon` path on the database it is actually running # against.) matrix: + runner: + - id: blacksmith + name: blacksmith 4vcpu + label: blacksmith-4vcpu-ubuntu-2404 + - id: github + name: github + label: ubuntu-24.04 + - id: runs-on-2 + name: runs-on c8a 2cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=2/image=ubuntu24-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-4 + name: runs-on c8a 4cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=4/image=ubuntu24-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-8 + name: runs-on c8a 8cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=8/image=ubuntu24-full-x64/volume=80gb/extras=s3-cache db: [postgres, supabase] env: diff --git a/.github/workflows/integration-prisma-next.yml b/.github/workflows/integration-prisma-next.yml index ed74631f2..768f57539 100644 --- a/.github/workflows/integration-prisma-next.yml +++ b/.github/workflows/integration-prisma-next.yml @@ -113,8 +113,9 @@ on: jobs: integration: - name: prisma-next v3 integration (db=${{ matrix.db }}) - runs-on: blacksmith-4vcpu-ubuntu-2404 + # RunsOn trial: this job on every runner in `runner`. Collapse before merging. + name: prisma-next v3 integration (db=${{ matrix.db }}) (${{ matrix.runner.name }}) + runs-on: ${{ matrix.runner.label }} # No concurrency group: `integration-db` gives each job its own compose # project and ephemeral host ports, so live-DB jobs no longer contend and do # not need serialising. See that action for why the old @@ -137,6 +138,22 @@ jobs: # is not a superuser, so the EQL install takes its self-skipping path. A # suite that passes on a superuser database can still fail there. matrix: + runner: + - id: blacksmith + name: blacksmith 4vcpu + label: blacksmith-4vcpu-ubuntu-2404 + - id: github + name: github + label: ubuntu-24.04 + - id: runs-on-2 + name: runs-on c8a 2cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=2/image=ubuntu24-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-4 + name: runs-on c8a 4cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=4/image=ubuntu24-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-8 + name: runs-on c8a 8cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=8/image=ubuntu24-full-x64/volume=80gb/extras=s3-cache db: [postgres, supabase] env: diff --git a/.github/workflows/integration-protect-ffi.yml b/.github/workflows/integration-protect-ffi.yml index 8b8f4ff03..f92940121 100644 --- a/.github/workflows/integration-protect-ffi.yml +++ b/.github/workflows/integration-protect-ffi.yml @@ -159,8 +159,28 @@ concurrency: jobs: integration: - name: protect-ffi integration suite - runs-on: blacksmith-4vcpu-ubuntu-2404 + # RunsOn trial: this job on every runner in `runner`. Collapse before merging. + name: protect-ffi integration suite (${{ matrix.runner.name }}) + runs-on: ${{ matrix.runner.label }} + strategy: + fail-fast: false + matrix: + runner: + - id: blacksmith + name: blacksmith 4vcpu + label: blacksmith-4vcpu-ubuntu-2404 + - id: github + name: github + label: ubuntu-24.04 + - id: runs-on-2 + name: runs-on c8a 2cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=2/image=ubuntu24-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-4 + name: runs-on c8a 4cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=4/image=ubuntu24-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-8 + name: runs-on c8a 8cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=8/image=ubuntu24-full-x64/volume=80gb/extras=s3-cache # Generous, because a cold `build-ffi-binding` compiles the cipherstash # client graph from scratch. It is also the backstop for `mise run # start-db`, whose readiness loop retries `pg_isready` forever rather than diff --git a/.github/workflows/integration-supabase.yml b/.github/workflows/integration-supabase.yml index 16d4da21e..9dbc0475c 100644 --- a/.github/workflows/integration-supabase.yml +++ b/.github/workflows/integration-supabase.yml @@ -172,8 +172,9 @@ on: jobs: integration: - name: Supabase v3 integration (db=${{ matrix.db }}) - runs-on: blacksmith-4vcpu-ubuntu-2404 + # RunsOn trial: this job on every runner in `runner`. Collapse before merging. + name: Supabase v3 integration (db=${{ matrix.db }}) (${{ matrix.runner.name }}) + runs-on: ${{ matrix.runner.label }} # No concurrency group: `integration-db` gives each job its own compose # project and ephemeral host ports, so live-DB jobs no longer contend and do # not need serialising. See that action for why the old @@ -190,10 +191,27 @@ jobs: if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }} strategy: + fail-fast: false # A one-element matrix, not a cross-product: the Supabase adapter only ever # runs against the Supabase variant. Kept as a matrix so adding a second # database is a one-line change. matrix: + runner: + - id: blacksmith + name: blacksmith 4vcpu + label: blacksmith-4vcpu-ubuntu-2404 + - id: github + name: github + label: ubuntu-24.04 + - id: runs-on-2 + name: runs-on c8a 2cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=2/image=ubuntu24-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-4 + name: runs-on c8a 4cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=4/image=ubuntu24-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-8 + name: runs-on c8a 8cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=8/image=ubuntu24-full-x64/volume=80gb/extras=s3-cache db: [supabase] env: diff --git a/.github/workflows/mutants.yml b/.github/workflows/mutants.yml index 65cabc4c0..5c8809708 100644 --- a/.github/workflows/mutants.yml +++ b/.github/workflows/mutants.yml @@ -62,10 +62,47 @@ env: CARGO_NET_GIT_FETCH_WITH_CLI: true jobs: + # RunsOn trial: the same job on the current Blacksmith runner, GitHub's + # runner and RunsOn sizes, for a side-by-side timing comparison. Collapse + # back to a single runner before merging. mutants: - name: Mutants gate - runs-on: blacksmith-16vcpu-ubuntu-2204 + name: Mutants gate (${{ matrix.name }}) + runs-on: ${{ matrix.label }} timeout-minutes: 120 + strategy: + fail-fast: false + matrix: + # The run id is shared by every entry, so each RunsOn label must + # differ, or one entry's runner can be taken by another. + # `family=c8a`: cargo-mutants builds and tests one mutant at a time, + # so per-core speed decides the run time. c8a (AMD Turin) has the + # best x64 single-thread score in RunsOn's EC2 benchmark and about + # 1.7x m8i's multi-core score at about the same price; older + # generations save ~5% an hour and run slower. + # `image=ubuntu22-full-x64` matches the Blacksmith baseline's Ubuntu + # 22.04; RunsOn defaults to 24.04. + # The default root volume leaves ~10 GiB free, which a Rust build + # fills; rust-lld then dies with SIGBUS (seen in cipherstash/vitaminc#487). + # `s3-cache` serves actions/cache from the stack's S3 bucket, so + # RunsOn entries share no cache entries with GitHub's or Blacksmith's. + include: + - name: blacksmith 16vcpu + label: blacksmith-16vcpu-ubuntu-2204 + - name: github + label: ubuntu-22.04 + - name: runs-on c8a 4cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=4/image=ubuntu22-full-x64/volume=80gb/extras=s3-cache + - name: runs-on c8a 8cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=8/image=ubuntu22-full-x64/volume=80gb/extras=s3-cache + - name: runs-on c8a 16cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=16/image=ubuntu22-full-x64/volume=80gb/extras=s3-cache + # arm64 (Graviton4) at the c8a sizes above, c8g only so the + # comparison is one CPU against another. `c8g.*`, not `c8g`: a bare + # family is a prefix, and RunsOn handed out c8gd and c8gn for it. + - name: runs-on c8g 16cpu arm64 + label: runs-on=${{ github.run_id }}/family=c8g.*/cpu=16/image=ubuntu22-full-arm64/volume=80gb/extras=s3-cache + - name: runs-on c8g 8cpu arm64 + label: runs-on=${{ github.run_id }}/family=c8g.*/cpu=8/image=ubuntu22-full-arm64/volume=80gb/extras=s3-cache permissions: contents: read # Posts and updates the report comment on the PR. @@ -83,21 +120,24 @@ jobs: install: true working_directory: . install_args: rust cargo:cargo-nextest cargo:cargo-mutants - cache: true - # Must name runs-on's image; see scripts/__tests__/workflow-mise-cache-image.test.mjs - cache_key_prefix: mise-v1-ubuntu-2204 + # Off for the trial: a matrix `runs-on` names no image to key the + # cache by (scripts/__tests__/workflow-mise-cache-image.test.mjs). + # Every entry pays the same tool install, so compare the + # "Run cargo-mutants" step times, not only the job totals. + cache: false - uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 # PR only: a manual dispatch has no base to diff against, so it sweeps # both crates instead (see the next step). + # RunsOn trial: this PR changes no crate source, so its own diff has no + # mutants and every runner would finish in seconds. Mutate the lines of + # a fixed stack-auth/stack-encrypt commit range instead (125 mutants), so + # every entry does the same real work. - name: Compute the PR diff if: github.event_name == 'pull_request' - env: - BASE_REF: ${{ github.base_ref }} run: | - git fetch --no-tags origin "$BASE_REF" - git diff "origin/$BASE_REF" > pr.diff + git diff fb75f40d541df8158154b86ec5b7708aefe66836 9b7e122e4a0b74215743e6b4a60770160d38884e > pr.diff echo "Changed lines under mutation:" cat pr.diff @@ -164,7 +204,8 @@ jobs: # Posted before the gate, so the comment always shows what tripped it. # Best effort: a comment failure must not turn the gate red. - name: Post the report as a sticky PR comment - if: always() && github.event_name == 'pull_request' + # Trial: one entry posts, so the matrix does not race on the comment. + if: always() && github.event_name == 'pull_request' && matrix.name == 'blacksmith 16vcpu' continue-on-error: true uses: actions/github-script@v9 with: diff --git a/.github/workflows/test-eql.yml b/.github/workflows/test-eql.yml index b3d0c2d60..d3187c0c3 100644 --- a/.github/workflows/test-eql.yml +++ b/.github/workflows/test-eql.yml @@ -291,7 +291,8 @@ jobs: # Compile the test binaries ONCE. Runs on every non-PR event, and on PRs only # when relevant files changed (docs-only PRs never pay the ~4-min compile). build-archive: - name: "Build test archive" + # RunsOn trial: this job on every runner in `runner`. Collapse before merging. + name: "Build test archive (${{ matrix.runner.name }})" needs: [changes] # This repo is PUBLIC and accepts fork PRs (the approval policy only gates # first-time contributors). build-archive is the sole holder of the CS_* @@ -313,7 +314,26 @@ jobs: || needs.changes.outputs.relevant == 'true') && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) - runs-on: blacksmith-16vcpu-ubuntu-2204 + runs-on: ${{ matrix.runner.label }} + strategy: + fail-fast: false + matrix: + runner: + - id: blacksmith + name: blacksmith 16vcpu + label: blacksmith-16vcpu-ubuntu-2204 + - id: github + name: github + label: ubuntu-22.04 + - id: runs-on-4 + name: runs-on c8a 4cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=4/image=ubuntu22-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-8 + name: runs-on c8a 8cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=8/image=ubuntu22-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-16 + name: runs-on c8a 16cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=16/image=ubuntu22-full-x64/volume=80gb/extras=s3-cache env: # test:sqlx:archive depends on test:sqlx:prep, which copies the built EQL # into migrations/, applies it to a live Postgres, and regenerates the @@ -380,8 +400,11 @@ jobs: # `nextest.tar.zst` and `release/*.sql` at its top level and the shard's # `download-artifact` puts them back where the archive expects them. - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + # RunsOn trial: one archive per runner. The test binaries bake in + # their build's checkout path (`env!("CARGO_MANIFEST_DIR")`), and + # GitHub-hosted runners check out to `work/`, not `_work/`. with: - name: nextest-archive + name: nextest-archive-${{ matrix.runner.id }} path: | packages/eql/nextest.tar.zst packages/eql/release/*.sql @@ -391,16 +414,33 @@ jobs: # Sharded sqlx suite. No longer needs [schema, codegen] (gate removed) — # shards start right after build-archive. test: - name: "Shard PG${{ matrix.postgres-version }} ${{ matrix.shard }}/${{ needs.setup.outputs.shard-total }}" + # RunsOn trial: this job on every runner in `runner`. Collapse before merging. + name: "Shard PG${{ matrix.postgres-version }} ${{ matrix.shard }}/${{ needs.setup.outputs.shard-total }} (${{ matrix.runner.name }})" needs: [changes, setup, build-archive] # Exclusion, not an allowlist — see the note on `build-archive`. if: >- github.event_name != 'pull_request' || needs.changes.outputs.relevant == 'true' - runs-on: blacksmith-16vcpu-ubuntu-2204 + runs-on: ${{ matrix.runner.label }} strategy: fail-fast: false matrix: + runner: + - id: blacksmith + name: blacksmith 16vcpu + label: blacksmith-16vcpu-ubuntu-2204 + - id: github + name: github + label: ubuntu-22.04 + - id: runs-on-4 + name: runs-on c8a 4cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=4/image=ubuntu22-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-8 + name: runs-on c8a 8cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=8/image=ubuntu22-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-16 + name: runs-on c8a 16cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=16/image=ubuntu22-full-x64/volume=80gb/extras=s3-cache postgres-version: ${{ fromJSON(needs.setup.outputs.pg-versions) }} shard: ${{ fromJSON(needs.setup.outputs.shards) }} env: @@ -438,7 +478,7 @@ jobs: # workspace remap and the build_validation_tests expect them. - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 with: - name: nextest-archive + name: nextest-archive-${{ matrix.runner.id }} path: packages/eql - name: Setup database (Postgres ${{ matrix.postgres-version }}) @@ -453,16 +493,33 @@ jobs: # they follow the event's PG set (PG17 on PR; 14-17 in the queue). Moved out # of the old per-version test job so they run ONCE per version, not per shard. validate: - name: "Validate (Postgres ${{ matrix.postgres-version }})" + # RunsOn trial: this job on every runner in `runner`. Collapse before merging. + name: "Validate (Postgres ${{ matrix.postgres-version }}) (${{ matrix.runner.name }})" needs: [changes, setup] # Exclusion, not an allowlist — see the note on `build-archive`. if: >- github.event_name != 'pull_request' || needs.changes.outputs.relevant == 'true' - runs-on: blacksmith-16vcpu-ubuntu-2204 + runs-on: ${{ matrix.runner.label }} strategy: fail-fast: false matrix: + runner: + - id: blacksmith + name: blacksmith 16vcpu + label: blacksmith-16vcpu-ubuntu-2204 + - id: github + name: github + label: ubuntu-22.04 + - id: runs-on-4 + name: runs-on c8a 4cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=4/image=ubuntu22-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-8 + name: runs-on c8a 8cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=8/image=ubuntu22-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-16 + name: runs-on c8a 16cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=16/image=ubuntu22-full-x64/volume=80gb/extras=s3-cache postgres-version: ${{ fromJSON(needs.setup.outputs.pg-versions) }} env: POSTGRES_VERSION: ${{ matrix.postgres-version }} @@ -512,13 +569,33 @@ jobs: mise run test:clean_install_v3 schema: - name: "JSON Schema validation" + # RunsOn trial: this job on every runner in `runner`. Collapse before merging. + name: "JSON Schema validation (${{ matrix.runner.name }})" needs: [changes] # Exclusion, not an allowlist — see the note on `build-archive`. if: >- github.event_name != 'pull_request' || needs.changes.outputs.relevant == 'true' - runs-on: blacksmith-16vcpu-ubuntu-2204 + runs-on: ${{ matrix.runner.label }} + strategy: + fail-fast: false + matrix: + runner: + - id: blacksmith + name: blacksmith 16vcpu + label: blacksmith-16vcpu-ubuntu-2204 + - id: github + name: github + label: ubuntu-22.04 + - id: runs-on-4 + name: runs-on c8a 4cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=4/image=ubuntu22-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-8 + name: runs-on c8a 8cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=8/image=ubuntu22-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-16 + name: runs-on c8a 16cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=16/image=ubuntu22-full-x64/volume=80gb/extras=s3-cache steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: @@ -541,13 +618,33 @@ jobs: mise run test:schema rust-crates: - name: "Rust workspace crates" + # RunsOn trial: this job on every runner in `runner`. Collapse before merging. + name: "Rust workspace crates (${{ matrix.runner.name }})" needs: [changes] # Exclusion, not an allowlist — see the note on `build-archive`. if: >- github.event_name != 'pull_request' || needs.changes.outputs.relevant == 'true' - runs-on: blacksmith-16vcpu-ubuntu-2204 + runs-on: ${{ matrix.runner.label }} + strategy: + fail-fast: false + matrix: + runner: + - id: blacksmith + name: blacksmith 16vcpu + label: blacksmith-16vcpu-ubuntu-2204 + - id: github + name: github + label: ubuntu-22.04 + - id: runs-on-4 + name: runs-on c8a 4cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=4/image=ubuntu22-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-8 + name: runs-on c8a 8cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=8/image=ubuntu22-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-16 + name: runs-on c8a 16cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=16/image=ubuntu22-full-x64/volume=80gb/extras=s3-cache services: encryption-postgres: image: postgres:17 @@ -669,13 +766,33 @@ jobs: exit "$status" codegen: - name: "Encrypted-domain codegen" + # RunsOn trial: this job on every runner in `runner`. Collapse before merging. + name: "Encrypted-domain codegen (${{ matrix.runner.name }})" needs: [changes] # Exclusion, not an allowlist — see the note on `build-archive`. if: >- github.event_name != 'pull_request' || needs.changes.outputs.relevant == 'true' - runs-on: blacksmith-16vcpu-ubuntu-2204 + runs-on: ${{ matrix.runner.label }} + strategy: + fail-fast: false + matrix: + runner: + - id: blacksmith + name: blacksmith 16vcpu + label: blacksmith-16vcpu-ubuntu-2204 + - id: github + name: github + label: ubuntu-22.04 + - id: runs-on-4 + name: runs-on c8a 4cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=4/image=ubuntu22-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-8 + name: runs-on c8a 8cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=8/image=ubuntu22-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-16 + name: runs-on c8a 16cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=16/image=ubuntu22-full-x64/volume=80gb/extras=s3-cache steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: @@ -701,13 +818,33 @@ jobs: mise run test:schemas:parity self-contained-v3: - name: "eql_v3 self-containment" + # RunsOn trial: this job on every runner in `runner`. Collapse before merging. + name: "eql_v3 self-containment (${{ matrix.runner.name }})" needs: [changes] # Exclusion, not an allowlist — see the note on `build-archive`. if: >- github.event_name != 'pull_request' || needs.changes.outputs.relevant == 'true' - runs-on: blacksmith-16vcpu-ubuntu-2204 + runs-on: ${{ matrix.runner.label }} + strategy: + fail-fast: false + matrix: + runner: + - id: blacksmith + name: blacksmith 16vcpu + label: blacksmith-16vcpu-ubuntu-2204 + - id: github + name: github + label: ubuntu-22.04 + - id: runs-on-4 + name: runs-on c8a 4cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=4/image=ubuntu22-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-8 + name: runs-on c8a 8cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=8/image=ubuntu22-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-16 + name: runs-on c8a 16cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=16/image=ubuntu22-full-x64/volume=80gb/extras=s3-cache steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: @@ -737,13 +874,33 @@ jobs: run: mise run test:build_ordering_helpers matrix-coverage: - name: "Matrix coverage inventory" + # RunsOn trial: this job on every runner in `runner`. Collapse before merging. + name: "Matrix coverage inventory (${{ matrix.runner.name }})" needs: [changes] # Exclusion, not an allowlist — see the note on `build-archive`. if: >- github.event_name != 'pull_request' || needs.changes.outputs.relevant == 'true' - runs-on: blacksmith-16vcpu-ubuntu-2204 + runs-on: ${{ matrix.runner.label }} + strategy: + fail-fast: false + matrix: + runner: + - id: blacksmith + name: blacksmith 16vcpu + label: blacksmith-16vcpu-ubuntu-2204 + - id: github + name: github + label: ubuntu-22.04 + - id: runs-on-4 + name: runs-on c8a 4cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=4/image=ubuntu22-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-8 + name: runs-on c8a 8cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=8/image=ubuntu22-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-16 + name: runs-on c8a 16cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=16/image=ubuntu22-full-x64/volume=80gb/extras=s3-cache steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: @@ -779,13 +936,33 @@ jobs: run: mise run test:matrix:catalog-coverage splinter: - name: "Supabase splinter" + # RunsOn trial: this job on every runner in `runner`. Collapse before merging. + name: "Supabase splinter (${{ matrix.runner.name }})" needs: [changes] # Exclusion, not an allowlist — see the note on `build-archive`. if: >- github.event_name != 'pull_request' || needs.changes.outputs.relevant == 'true' - runs-on: blacksmith-16vcpu-ubuntu-2204 + runs-on: ${{ matrix.runner.label }} + strategy: + fail-fast: false + matrix: + runner: + - id: blacksmith + name: blacksmith 16vcpu + label: blacksmith-16vcpu-ubuntu-2204 + - id: github + name: github + label: ubuntu-22.04 + - id: runs-on-4 + name: runs-on c8a 4cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=4/image=ubuntu22-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-8 + name: runs-on c8a 8cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=8/image=ubuntu22-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-16 + name: runs-on c8a 16cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=16/image=ubuntu22-full-x64/volume=80gb/extras=s3-cache env: POSTGRES_VERSION: "17" steps: @@ -844,8 +1021,28 @@ jobs: # validated. DB-free and creds-free (the psql-backed syntax check stays in the # per-version `validate` job). docs-static: - name: "SQL doc validation" - runs-on: blacksmith-16vcpu-ubuntu-2204 + # RunsOn trial: this job on every runner in `runner`. Collapse before merging. + name: "SQL doc validation (${{ matrix.runner.name }})" + runs-on: ${{ matrix.runner.label }} + strategy: + fail-fast: false + matrix: + runner: + - id: blacksmith + name: blacksmith 16vcpu + label: blacksmith-16vcpu-ubuntu-2204 + - id: github + name: github + label: ubuntu-22.04 + - id: runs-on-4 + name: runs-on c8a 4cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=4/image=ubuntu22-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-8 + name: runs-on c8a 8cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=8/image=ubuntu22-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-16 + name: runs-on c8a 16cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=16/image=ubuntu22-full-x64/volume=80gb/extras=s3-cache steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: @@ -883,8 +1080,28 @@ jobs: # Credential-free and DB-free — it only reads the registry and asks GitHub for # issue state, so it runs on every PR rather than hiding behind the e2e job. known-failures: - name: "known-failure markers" - runs-on: blacksmith-16vcpu-ubuntu-2204 + # RunsOn trial: this job on every runner in `runner`. Collapse before merging. + name: "known-failure markers (${{ matrix.runner.name }})" + runs-on: ${{ matrix.runner.label }} + strategy: + fail-fast: false + matrix: + runner: + - id: blacksmith + name: blacksmith 16vcpu + label: blacksmith-16vcpu-ubuntu-2204 + - id: github + name: github + label: ubuntu-22.04 + - id: runs-on-4 + name: runs-on c8a 4cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=4/image=ubuntu22-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-8 + name: runs-on c8a 8cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=8/image=ubuntu22-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-16 + name: runs-on c8a 16cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=16/image=ubuntu22-full-x64/volume=80gb/extras=s3-cache permissions: contents: read issues: read @@ -921,8 +1138,28 @@ jobs: # `relevant` filter (src/**, crates/**) would skip it on exactly the docs-only # PRs it exists to check. doc-anchors: - name: "doc anchor links" - runs-on: blacksmith-16vcpu-ubuntu-2204 + # RunsOn trial: this job on every runner in `runner`. Collapse before merging. + name: "doc anchor links (${{ matrix.runner.name }})" + runs-on: ${{ matrix.runner.label }} + strategy: + fail-fast: false + matrix: + runner: + - id: blacksmith + name: blacksmith 16vcpu + label: blacksmith-16vcpu-ubuntu-2204 + - id: github + name: github + label: ubuntu-22.04 + - id: runs-on-4 + name: runs-on c8a 4cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=4/image=ubuntu22-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-8 + name: runs-on c8a 8cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=8/image=ubuntu22-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-16 + name: runs-on c8a 16cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=16/image=ubuntu22-full-x64/volume=80gb/extras=s3-cache steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: @@ -946,7 +1183,8 @@ jobs: # e2e oracle. Like build-archive, it holds CS_* and so carries the same # fork-PR guard to keep the secrets off fork runs. e2e: - name: "e2e property suite (fresh encryption)" + # RunsOn trial: this job on every runner in `runner`. Collapse before merging. + name: "e2e property suite (fresh encryption) (${{ matrix.runner.name }})" needs: [changes, setup] # Exclusion, not an allowlist — see the note on `build-archive`, which # carries the same two clauses for the same two reasons. @@ -955,7 +1193,26 @@ jobs: || needs.changes.outputs.relevant == 'true') && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) - runs-on: blacksmith-16vcpu-ubuntu-2204 + runs-on: ${{ matrix.runner.label }} + strategy: + fail-fast: false + matrix: + runner: + - id: blacksmith + name: blacksmith 16vcpu + label: blacksmith-16vcpu-ubuntu-2204 + - id: github + name: github + label: ubuntu-22.04 + - id: runs-on-4 + name: runs-on c8a 4cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=4/image=ubuntu22-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-8 + name: runs-on c8a 8cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=8/image=ubuntu22-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-16 + name: runs-on c8a 16cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=16/image=ubuntu22-full-x64/volume=80gb/extras=s3-cache env: POSTGRES_VERSION: "17" CS_CLIENT_ACCESS_KEY: ${{ secrets.CS_CLIENT_ACCESS_KEY }} diff --git a/.github/workflows/tests-crates.yml b/.github/workflows/tests-crates.yml index 40cc572cc..b4aa5f70b 100644 --- a/.github/workflows/tests-crates.yml +++ b/.github/workflows/tests-crates.yml @@ -78,8 +78,28 @@ env: jobs: rust: - name: fmt, clippy, nextest, doctests, rustdoc - runs-on: blacksmith-16vcpu-ubuntu-2204 + # RunsOn trial: this job on every runner in `runner`. Collapse before merging. + name: fmt, clippy, nextest, doctests, rustdoc (${{ matrix.runner.name }}) + runs-on: ${{ matrix.runner.label }} + strategy: + fail-fast: false + matrix: + runner: + - id: blacksmith + name: blacksmith 16vcpu + label: blacksmith-16vcpu-ubuntu-2204 + - id: github + name: github + label: ubuntu-22.04 + - id: runs-on-4 + name: runs-on c8a 4cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=4/image=ubuntu22-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-8 + name: runs-on c8a 8cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=8/image=ubuntu22-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-16 + name: runs-on c8a 16cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=16/image=ubuntu22-full-x64/volume=80gb/extras=s3-cache timeout-minutes: 60 env: # Job-level, not workflow-level: RUSTFLAGS replaces the @@ -157,8 +177,28 @@ jobs: run: cargo publish --locked --dry-run --allow-dirty -p stack-profile -p stack-auth -p stack-kms -p stack-encrypt-derive -p stack-encrypt node-bindings: - name: node bindings, napi typings, stack-auth-wasm - runs-on: blacksmith-16vcpu-ubuntu-2204 + # RunsOn trial: this job on every runner in `runner`. Collapse before merging. + name: node bindings, napi typings, stack-auth-wasm (${{ matrix.runner.name }}) + runs-on: ${{ matrix.runner.label }} + strategy: + fail-fast: false + matrix: + runner: + - id: blacksmith + name: blacksmith 16vcpu + label: blacksmith-16vcpu-ubuntu-2204 + - id: github + name: github + label: ubuntu-22.04 + - id: runs-on-4 + name: runs-on c8a 4cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=4/image=ubuntu22-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-8 + name: runs-on c8a 8cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=8/image=ubuntu22-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-16 + name: runs-on c8a 16cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=16/image=ubuntu22-full-x64/volume=80gb/extras=s3-cache timeout-minutes: 45 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 diff --git a/.github/workflows/tests-golang.yml b/.github/workflows/tests-golang.yml index 9bfff334a..e7141a7dc 100644 --- a/.github/workflows/tests-golang.yml +++ b/.github/workflows/tests-golang.yml @@ -94,8 +94,28 @@ env: jobs: wasi-check: - name: WASI check, guests and Go (Linux) - runs-on: blacksmith-16vcpu-ubuntu-2204 + # RunsOn trial: this job on every runner in `runner`. Collapse before merging. + name: WASI check, guests and Go (Linux) (${{ matrix.runner.name }}) + runs-on: ${{ matrix.runner.label }} + strategy: + fail-fast: false + matrix: + runner: + - id: blacksmith + name: blacksmith 16vcpu + label: blacksmith-16vcpu-ubuntu-2204 + - id: github + name: github + label: ubuntu-22.04 + - id: runs-on-4 + name: runs-on c8a 4cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=4/image=ubuntu22-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-8 + name: runs-on c8a 8cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=8/image=ubuntu22-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-16 + name: runs-on c8a 16cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=16/image=ubuntu22-full-x64/volume=80gb/extras=s3-cache timeout-minutes: 60 env: # wasm:guest:test and wasm:auth-guest:test run nextest, which is pinned @@ -191,6 +211,9 @@ jobs: done - name: Hand the guests to the other jobs + # RunsOn trial: one entry uploads, because an artifact name is unique per + # run; every runner's consumers test the baseline's build. + if: matrix.runner.id == 'blacksmith' uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: name: wasm-guests @@ -241,8 +264,28 @@ jobs: # Linux only: macOS and Windows would report the same findings. Needs no # guests: the packages embed a directory and compile without them. go-lint: - name: Go lint - runs-on: blacksmith-4vcpu-ubuntu-2404 + # RunsOn trial: this job on every runner in `runner`. Collapse before merging. + name: Go lint (${{ matrix.runner.name }}) + runs-on: ${{ matrix.runner.label }} + strategy: + fail-fast: false + matrix: + runner: + - id: blacksmith + name: blacksmith 4vcpu + label: blacksmith-4vcpu-ubuntu-2404 + - id: github + name: github + label: ubuntu-24.04 + - id: runs-on-2 + name: runs-on c8a 2cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=2/image=ubuntu24-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-4 + name: runs-on c8a 4cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=4/image=ubuntu24-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-8 + name: runs-on c8a 8cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=8/image=ubuntu24-full-x64/volume=80gb/extras=s3-cache timeout-minutes: 15 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 @@ -332,9 +375,29 @@ jobs: # stack-encrypt examples read CS_* through `StackCipher::new()`; tests-crates # builds them, and this job runs them. live: - name: Go live tests and stack-encrypt examples + # RunsOn trial: this job on every runner in `runner`. Collapse before merging. + name: Go live tests and stack-encrypt examples (${{ matrix.runner.name }}) needs: wasi-check - runs-on: blacksmith-4vcpu-ubuntu-2404 + runs-on: ${{ matrix.runner.label }} + strategy: + fail-fast: false + matrix: + runner: + - id: blacksmith + name: blacksmith 4vcpu + label: blacksmith-4vcpu-ubuntu-2404 + - id: github + name: github + label: ubuntu-24.04 + - id: runs-on-2 + name: runs-on c8a 2cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=2/image=ubuntu24-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-4 + name: runs-on c8a 4cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=4/image=ubuntu24-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-8 + name: runs-on c8a 8cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=8/image=ubuntu24-full-x64/volume=80gb/extras=s3-cache timeout-minutes: 30 env: CS_WORKSPACE_CRN: ${{ vars.CS_WORKSPACE_CRN }} diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index b596f07b9..a28ff44c4 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -20,8 +20,34 @@ jobs: # plugin (at `warn`) surfaces new `as any`/`never`/`unknown` without blocking. # Tightening to fail on warnings is tracked in #625. lint: - name: Lint (Biome) - runs-on: blacksmith-4vcpu-ubuntu-2404 + # RunsOn trial: this job on every runner in `runner`. Collapse before merging. + name: Lint (Biome) (${{ matrix.runner.name }}) + runs-on: ${{ matrix.runner.label }} + strategy: + fail-fast: false + matrix: + runner: + - id: blacksmith + name: blacksmith 4vcpu + label: blacksmith-4vcpu-ubuntu-2404 + - id: github + name: github + label: ubuntu-24.04 + - id: runs-on-2 + name: runs-on c8a 2cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=2/image=ubuntu24-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-4 + name: runs-on c8a 4cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=4/image=ubuntu24-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-8 + name: runs-on c8a 8cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=8/image=ubuntu24-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-c8g-4 + name: runs-on c8g 4cpu arm64 + label: runs-on=${{ github.run_id }}/family=c8g.*/cpu=4/image=ubuntu24-full-arm64/volume=80gb/extras=s3-cache + - id: runs-on-c8g-8 + name: runs-on c8g 8cpu arm64 + label: runs-on=${{ github.run_id }}/family=c8g.*/cpu=8/image=ubuntu24-full-arm64/volume=80gb/extras=s3-cache steps: - name: Checkout Repo uses: actions/checkout@v6 @@ -51,13 +77,44 @@ jobs: - name: Biome check (format + lint) run: pnpm run code:check + # RunsOn trial: the same job on the current Blacksmith runner, GitHub's + # runner and RunsOn sizes, for a side-by-side timing comparison. Collapse + # back to a single runner before merging. run-tests: - name: Run Tests (Node ${{ matrix.node-version }}) - runs-on: blacksmith-4vcpu-ubuntu-2404 + name: Run Tests (Node ${{ matrix.node-version }}, ${{ matrix.runner.name }}) + runs-on: ${{ matrix.runner.label }} strategy: + fail-fast: false matrix: node-version: [22, 24] postgres-version: [16, 17] + # The run id is shared by every entry, so each RunsOn size's label + # must differ, or one size's runner can be taken by another's job. + # The two Node entries on one size share a label, which is harmless: + # the runners they launch are identical. + # `family=c8a` pins one instance family, so the sizes compare cleanly; + # the built-in `Ncpu-linux-x64` runners picked a different family on + # each run. + # The default root volume leaves ~10 GiB free, which the Rust binding + # builds can fill; rust-lld then dies with SIGBUS (seen in + # cipherstash/vitaminc#487). + # `s3-cache` serves actions/cache from the stack's S3 bucket, so + # RunsOn entries share no cache entries with GitHub's or Blacksmith's. + runner: + - name: blacksmith 4vcpu + label: blacksmith-4vcpu-ubuntu-2404 + - name: github + label: ubuntu-latest + - name: runs-on c8a 2cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=2/volume=80gb/extras=s3-cache + - name: runs-on c8a 4cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=4/volume=80gb/extras=s3-cache + - name: runs-on c8a 8cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=8/volume=80gb/extras=s3-cache + - name: runs-on c8g 4cpu arm64 + label: runs-on=${{ github.run_id }}/family=c8g.*/cpu=4/image=ubuntu24-full-arm64/volume=80gb/extras=s3-cache + - name: runs-on c8g 8cpu arm64 + label: runs-on=${{ github.run_id }}/family=c8g.*/cpu=8/image=ubuntu24-full-arm64/volume=80gb/extras=s3-cache exclude: - node-version: 22 postgres-version: 17 @@ -385,8 +442,34 @@ jobs: run: pnpm exec turbo run test:e2e --filter stash e2e-tests: - name: Run E2E Tests - runs-on: blacksmith-4vcpu-ubuntu-2404 + # RunsOn trial: this job on every runner in `runner`. Collapse before merging. + name: Run E2E Tests (${{ matrix.runner.name }}) + runs-on: ${{ matrix.runner.label }} + strategy: + fail-fast: false + matrix: + runner: + - id: blacksmith + name: blacksmith 4vcpu + label: blacksmith-4vcpu-ubuntu-2404 + - id: github + name: github + label: ubuntu-24.04 + - id: runs-on-2 + name: runs-on c8a 2cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=2/image=ubuntu24-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-4 + name: runs-on c8a 4cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=4/image=ubuntu24-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-8 + name: runs-on c8a 8cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=8/image=ubuntu24-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-c8g-4 + name: runs-on c8g 4cpu arm64 + label: runs-on=${{ github.run_id }}/family=c8g.*/cpu=4/image=ubuntu24-full-arm64/volume=80gb/extras=s3-cache + - id: runs-on-c8g-8 + name: runs-on c8g 8cpu arm64 + label: runs-on=${{ github.run_id }}/family=c8g.*/cpu=8/image=ubuntu24-full-arm64/volume=80gb/extras=s3-cache # Auth-dependent suites in `e2e/` skip themselves unless these env vars # are set. We expose them at the job level so the wizard subprocess @@ -466,8 +549,34 @@ jobs: # bindings available. The deno.json deliberately omits --allow-ffi so # a silent fallback to the NAPI module is impossible. wasm-e2e-tests: - name: Run WASM E2E Tests (Deno) - runs-on: blacksmith-4vcpu-ubuntu-2404 + # RunsOn trial: this job on every runner in `runner`. Collapse before merging. + name: Run WASM E2E Tests (Deno) (${{ matrix.runner.name }}) + runs-on: ${{ matrix.runner.label }} + strategy: + fail-fast: false + matrix: + runner: + - id: blacksmith + name: blacksmith 4vcpu + label: blacksmith-4vcpu-ubuntu-2404 + - id: github + name: github + label: ubuntu-24.04 + - id: runs-on-2 + name: runs-on c8a 2cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=2/image=ubuntu24-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-4 + name: runs-on c8a 4cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=4/image=ubuntu24-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-8 + name: runs-on c8a 8cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=8/image=ubuntu24-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-c8g-4 + name: runs-on c8g 4cpu arm64 + label: runs-on=${{ github.run_id }}/family=c8g.*/cpu=4/image=ubuntu24-full-arm64/volume=80gb/extras=s3-cache + - id: runs-on-c8g-8 + name: runs-on c8g 8cpu arm64 + label: runs-on=${{ github.run_id }}/family=c8g.*/cpu=8/image=ubuntu24-full-arm64/volume=80gb/extras=s3-cache permissions: contents: read @@ -609,8 +718,34 @@ jobs: run: deno task test run-tests-bun: - name: Run Tests (Bun) - runs-on: blacksmith-4vcpu-ubuntu-2404 + # RunsOn trial: this job on every runner in `runner`. Collapse before merging. + name: Run Tests (Bun) (${{ matrix.runner.name }}) + runs-on: ${{ matrix.runner.label }} + strategy: + fail-fast: false + matrix: + runner: + - id: blacksmith + name: blacksmith 4vcpu + label: blacksmith-4vcpu-ubuntu-2404 + - id: github + name: github + label: ubuntu-24.04 + - id: runs-on-2 + name: runs-on c8a 2cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=2/image=ubuntu24-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-4 + name: runs-on c8a 4cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=4/image=ubuntu24-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-8 + name: runs-on c8a 8cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=8/image=ubuntu24-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-c8g-4 + name: runs-on c8g 4cpu arm64 + label: runs-on=${{ github.run_id }}/family=c8g.*/cpu=4/image=ubuntu24-full-arm64/volume=80gb/extras=s3-cache + - id: runs-on-c8g-8 + name: runs-on c8g 8cpu arm64 + label: runs-on=${{ github.run_id }}/family=c8g.*/cpu=8/image=ubuntu24-full-arm64/volume=80gb/extras=s3-cache continue-on-error: true services: diff --git a/.github/workflows/udeps.yml b/.github/workflows/udeps.yml index db3d33b98..c22688c66 100644 --- a/.github/workflows/udeps.yml +++ b/.github/workflows/udeps.yml @@ -67,8 +67,28 @@ env: jobs: udeps: - name: Check unused Rust dependencies - runs-on: blacksmith-4vcpu-ubuntu-2404 + # RunsOn trial: this job on every runner in `runner`. Collapse before merging. + name: Check unused Rust dependencies (${{ matrix.runner.name }}) + runs-on: ${{ matrix.runner.label }} + strategy: + fail-fast: false + matrix: + runner: + - id: blacksmith + name: blacksmith 4vcpu + label: blacksmith-4vcpu-ubuntu-2404 + - id: github + name: github + label: ubuntu-24.04 + - id: runs-on-2 + name: runs-on c8a 2cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=2/image=ubuntu24-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-4 + name: runs-on c8a 4cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=4/image=ubuntu24-full-x64/volume=80gb/extras=s3-cache + - id: runs-on-8 + name: runs-on c8a 8cpu + label: runs-on=${{ github.run_id }}/family=c8a/cpu=8/image=ubuntu24-full-x64/volume=80gb/extras=s3-cache timeout-minutes: 45 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 diff --git a/scripts/__tests__/workflow-mise-cache-image.test.mjs b/scripts/__tests__/workflow-mise-cache-image.test.mjs index 4007ba9d3..a0e2e8679 100644 --- a/scripts/__tests__/workflow-mise-cache-image.test.mjs +++ b/scripts/__tests__/workflow-mise-cache-image.test.mjs @@ -24,8 +24,15 @@ import { readWorkflow, workflowFiles } from './lib/workflows.mjs' * * So each cached step sets `cache_key_prefix: mise-v1-`, where `` * is the `ubuntu-NNNN` its job's `runs-on` names (`ubuntu-24.04` counts as - * `ubuntu-2404`). A job whose `runs-on` names no image (a matrix, - * `ubuntu-latest`) must turn the cache off. No step sets `cache_key`, which + * `ubuntu-2404`, and a RunsOn label's `image=ubuntu24-full-x64` does too). A + * `runs-on` that is one matrix value (`${{ matrix.runner.label }}`) names the + * image every value of that axis names, and only when they all name the same + * one. The architecture is no part of ``: mise-action puts + * `linux-` in the key after the prefix, so an arm64 entry + * (`image=ubuntu22-full-arm64`) and an x64 one never share a cache. + * A job whose `runs-on` names no image (`ubuntu-latest`, a RunsOn label + * with no `image=`, a matrix mixing images) must turn the cache off. No step + * sets `cache_key`, which * mise-action prefers over the prefix and so would bring the shared key back. * A step with the cache off sets no prefix: it would read as a cache in use, * on paths `scripts/lint-no-workflow-caching.mjs` keeps cache-free. @@ -51,7 +58,13 @@ function miseSteps() { for (const [job, def] of Object.entries(readWorkflow(file)?.jobs ?? {})) { for (const step of def?.steps ?? []) { if (isMise(step)) - found.push({ file, job, runsOn: def['runs-on'], step }) + found.push({ + file, + job, + runsOn: def['runs-on'], + matrix: def.strategy?.matrix, + step, + }) } } } @@ -63,12 +76,45 @@ const IMAGE_INDEPENDENT_TOOLS = new Set(['aqua:wasm-bindgen/wasm-pack']) /** The `ubuntu-NNNN` a runs-on label names, or undefined. */ function imageOf(runsOn) { - const m = /ubuntu-(\d{2})\.?(\d{2})/.exec(String(runsOn)) + const label = String(runsOn) + // RunsOn picks its image from an `image=` segment, and only ships LTS ones. + if (label.startsWith('runs-on=')) { + const m = /\/image=ubuntu(\d{2})-/.exec(label) + return m ? `ubuntu-${m[1]}04` : undefined + } + const m = /ubuntu-(\d{2})\.?(\d{2})/.exec(label) return m ? `ubuntu-${m[1]}${m[2]}` : undefined } +/** + * Every label a `${{ matrix. }}` or `${{ matrix.. }}` runs-on + * can take, read from the axis and the include rows, or undefined when runs-on + * is not one matrix value. + */ +function matrixLabels(runsOn, matrix) { + const m = /^\$\{\{\s*matrix\.([\w-]+)(?:\.([\w-]+))?\s*\}\}$/.exec( + String(runsOn), + ) + if (!m || !matrix || typeof matrix !== 'object') return undefined + const [, key, field] = m + const values = [ + ...(Array.isArray(matrix[key]) ? matrix[key] : []), + ...(Array.isArray(matrix.include) + ? matrix.include.map((row) => row?.[key]) + : []), + ].filter((value) => value !== undefined) + return values.map((value) => (field ? value?.[field] : value)) +} + +/** The one image every label names, or undefined. */ +function imageOfAll(labels) { + const images = new Set(labels.map(imageOf)) + if (labels.length === 0 || images.size !== 1) return undefined + return [...images][0] +} + /** The finding for one mise step, or null when the step is correct. */ -function cacheKeyFinding({ file, job, runsOn, step }) { +function cacheKeyFinding({ file, job, runsOn, matrix, step }) { const where = `${file} ${job}` const prefix = step.with?.cache_key_prefix if (step.with?.cache_key !== undefined) @@ -77,9 +123,12 @@ function cacheKeyFinding({ file, job, runsOn, step }) { return prefix === undefined ? null : `${where}: the cache is off, so cache_key_prefix ${prefix} does nothing; remove it` - const image = imageOf(runsOn) + const labels = matrixLabels(runsOn, matrix) + const image = labels ? imageOfAll(labels) : imageOf(runsOn) if (!image) - return `${where}: runs-on ${runsOn} names no ubuntu-NNNN image, so the mise cache must be off (cache: false)` + return labels + ? `${where}: runs-on ${runsOn} takes ${labels.join(', ')}, which name no single ubuntu-NNNN image between them, so the mise cache must be off (cache: false)` + : `${where}: runs-on ${runsOn} names no ubuntu-NNNN image, so the mise cache must be off (cache: false)` const want = `mise-v1-${image}` return prefix === want ? null @@ -141,12 +190,100 @@ describe('mise-action cache keys', () => { ).toBeNull() }) + it('keys a matrix runs-on by the image its every value names', () => { + // biome-ignore lint/suspicious/noTemplateCurlyInString: a GitHub Actions expression, the literal `runs-on` value under test. + const runsOn = '${{ matrix.runner.label }}' + const runOn = (...labels) => ({ + runner: labels.map((label) => ({ label })), + }) + const check = (matrix, input) => + cacheKeyFinding({ + file: 'w.yml', + job: 'j', + runsOn, + matrix, + step: { uses: 'jdx/mise-action@sha', with: input }, + }) + const same = runOn( + 'blacksmith-16vcpu-ubuntu-2204', + 'ubuntu-22.04', + 'runs-on=1/family=c8a/cpu=4/image=ubuntu22-full-x64', + ) + expect(check(same, { cache_key_prefix: 'mise-v1-ubuntu-2204' })).toBeNull() + expect(check(same, { cache_key_prefix: 'mise-v1-ubuntu-2404' })).toMatch( + /want mise-v1-ubuntu-2204/, + ) + // One prefix cannot key two images: the glibc split this file exists for. + expect( + check(runOn('blacksmith-16vcpu-ubuntu-2204', 'ubuntu-24.04'), { + cache_key_prefix: 'mise-v1-ubuntu-2204', + }), + ).toMatch(/no single ubuntu-NNNN image/) + // RunsOn's default image is stack configuration, not something a label shows. + expect( + check(runOn('runs-on=1/family=c8a/cpu=4'), { + cache_key_prefix: 'mise-v1-ubuntu-2404', + }), + ).toMatch(/no single ubuntu-NNNN image/) + expect(check(runOn('ubuntu-latest'), { cache: false })).toBeNull() + // An include-only matrix whose rows carry the label. + expect( + cacheKeyFinding({ + file: 'w.yml', + job: 'j', + // biome-ignore lint/suspicious/noTemplateCurlyInString: a GitHub Actions expression, the literal `runs-on` value under test. + runsOn: '${{ matrix.label }}', + matrix: { + include: [ + { label: 'ubuntu-22.04' }, + { label: 'blacksmith-4vcpu-ubuntu-2204' }, + ], + }, + step: { + uses: 'jdx/mise-action@sha', + with: { cache_key_prefix: 'mise-v1-ubuntu-2204' }, + }, + }), + ).toBeNull() + }) + it('reads both forms of an image label', () => { expect(imageOf('blacksmith-4vcpu-ubuntu-2404')).toBe('ubuntu-2404') expect(imageOf('ubuntu-22.04')).toBe('ubuntu-2204') expect(imageOf('ubuntu-24.04-arm')).toBe('ubuntu-2404') expect(imageOf('ubuntu-latest')).toBeUndefined() expect(imageOf(undefined)).toBeUndefined() + expect( + imageOf('runs-on=1/family=c8a/cpu=4/image=ubuntu24-full-x64/volume=80gb'), + ).toBe('ubuntu-2404') + expect( + imageOf( + 'runs-on=1/family=c8g/cpu=8/image=ubuntu22-full-arm64/volume=80gb', + ), + ).toBe('ubuntu-2204') + expect(imageOf('runs-on=1/runner=4cpu-linux-x64')).toBeUndefined() + }) + + it('keys a matrix mixing x64 and arm64 entries of one image', () => { + expect( + cacheKeyFinding({ + file: 'w.yml', + job: 'j', + // biome-ignore lint/suspicious/noTemplateCurlyInString: a GitHub Actions expression, the literal `runs-on` value under test. + runsOn: '${{ matrix.label }}', + matrix: { + include: [ + { label: 'blacksmith-16vcpu-ubuntu-2204' }, + { label: 'runs-on=1/family=c8a/cpu=16/image=ubuntu22-full-x64' }, + { label: 'runs-on=1/family=c8g/cpu=16/image=ubuntu22-full-arm64' }, + ], + }, + step: { + uses: 'jdx/mise-action@sha', + with: { cache_key_prefix: 'mise-v1-ubuntu-2204' }, + }, + }), + ).toBeNull() }) it('lets a composite action cache only image-independent tools', () => {