From 0ea334f1d7d0b203846c458f2ac5be3ae67c84cf Mon Sep 17 00:00:00 2001 From: ankurmans Date: Fri, 30 Oct 2026 09:43:22 +0100 Subject: [PATCH] CI: drafts and Dependabot run nothing; the full suite runs in its own job on main and nightly --- .github/workflows/ci.yml | 65 +++++++++++++++++++++++++++------------- 1 file changed, 45 insertions(+), 20 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f9263f8..f13163d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,23 +1,28 @@ # Lint, tests and production build. Never deploys. -# Runs on the self-hosted Contabo runner. This repo is PUBLIC, so pull requests from forks are skipped: they must never run on that machine. +# Runs on the self-hosted Contabo runners (up to two jobs at once across every repo, queued by repo, then push to main before pull +# requests before nightly). This repo is PUBLIC, so pull requests from forks are skipped: they must never run on that machine. # -# One job runs at a time across every repo on that runner, so a pull request runs only what its change affects: -# - Every pull request: lint, then the tests scripts/affected-tests.mjs picks from the changed files, then the Next.js build only if -# the change can reach it (app/, components/, public/, proxy.js, instrumentation.js, or any file those import, the Next, PostCSS or -# package config, the lockfile). -# - Everything (all tests, the build) runs on: push to main, nightly at 05:00 UTC, and a manual run (workflow_dispatch). -# - Those full runs also write the test map (which files each test loaded) and cache it for the pull requests. +# Two jobs: +# check The gate. A ready pull request (not a draft, not Dependabot's) runs lint, then the tests scripts/affected-tests.mjs picks +# from the changed files, then the Next.js build only if the change can reach it (app/, components/, public/, proxy.js, +# instrumentation.js, or any file those import, the Next, PostCSS or package config, the lockfile). A push to main, the +# nightly run and a manual run (workflow_dispatch) run lint and the build. +# full-suite Every test. Push to main, nightly at 05:00 UTC and manual runs only. Nothing waits for it, so a slow or red suite +# never holds back the build; a failure turns the run red and GitHub mails the owner. It also writes the test map (which +# files each test loaded) and caches it for the pull requests. # # A pull request runs the FULL suite and the build when it changes any of these (scripts/affected-tests.mjs, FOUNDATIONAL): # package.json and the lockfile; the Next, OpenNext, ESLint, PostCSS, Wrangler, Vitest and components configs and jsconfig.json; # .github/ (this file); tests/setup, tests/stubs, tests/helpers/app.mjs and shallow.mjs; scripts/test-all.mjs and # scripts/affected-tests.mjs; migrations/; models/; perf-budgets.json; worker-entry.mjs. # It also runs everything when a changed file maps to no test, or when a third or more of the suite is affected. -# If a failure ever shows up only on the main run, say so in that pull request so the list above can be tightened. +# If a failure ever shows up only on the full-suite job, say so in that pull request so the list above can be tightened. name: CI on: pull_request: + # A draft runs nothing; marking it ready starts the gate. + types: [opened, synchronize, reopened, ready_for_review] push: branches: [main] schedule: @@ -33,7 +38,12 @@ concurrency: jobs: check: - if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository + if: >- + github.event_name != 'pull_request' || ( + github.event.pull_request.head.repo.full_name == github.repository + && !github.event.pull_request.draft + && github.actor != 'dependabot[bot]' + ) runs-on: [self-hosted, linux, contabo] # Jobs also count the wait for the runner's shared lock. timeout-minutes: 360 @@ -66,28 +76,43 @@ jobs: run: node scripts/affected-tests.mjs --base "origin/${{ github.base_ref }}" --map .ci/test-map.json --list .ci/affected-tests.txt --github-output "$GITHUB_OUTPUT" - name: Tests (everything) - if: github.event_name != 'pull_request' || steps.plan.outputs.mode == 'all' + if: github.event_name == 'pull_request' && steps.plan.outputs.mode == 'all' + run: npm test + + - name: Tests (affected only) + if: github.event_name == 'pull_request' && steps.plan.outputs.mode == 'subset' + run: node --import ./tests/setup/register.mjs --test $(cat .ci/affected-tests.txt) + + - name: Build + if: github.event_name != 'pull_request' || steps.plan.outputs.build == 'true' + run: npm run build + + full-suite: + if: github.event_name != 'pull_request' + runs-on: [self-hosted, linux, contabo] + timeout-minutes: 360 + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: 24 + cache: npm + + - run: npm ci + + - name: Tests (everything) env: TEST_MAP_DIR: ${{ runner.temp }}/test-map run: | mkdir -p "$TEST_MAP_DIR" npm test - - name: Tests (affected only) - if: github.event_name == 'pull_request' && steps.plan.outputs.mode == 'subset' - run: node --import ./tests/setup/register.mjs --test $(cat .ci/affected-tests.txt) - - name: Write the test map - if: github.event_name != 'pull_request' run: node scripts/test-map.mjs "${{ runner.temp }}/test-map" .ci/test-map.json - name: Cache the test map - if: github.event_name != 'pull_request' uses: actions/cache/save@v4 with: path: .ci/test-map.json key: test-map-${{ github.sha }} - - - name: Build - if: github.event_name != 'pull_request' || steps.plan.outputs.build == 'true' - run: npm run build