Skip to content

Speed up each CI run: shallow checkouts, cached server deps, retire legacy check-name jobs #4734

Description

@atomantic

Follow-up to the CI-topology change that removed the main push trigger and made the release reuse its PR's full-CI gate. That change eliminated whole runs; these three make each remaining run cheaper. They are independent — ship them separately.

1. Stop doing full-history checkouts (biggest win, hits every PR)

ci.yml does fetch-depth: 0 in four jobs (impact, server, client, windows-server) on a ~13k-commit / ~100 MiB repo. Nothing needs full history:

  • scripts/ci-test-plan.js needs only git diff <base>...<head> and git ls-files.
  • scripts/run-ci-tests.js needs vitest --changed <baseSha>, i.e. the base tree, not its ancestry.
  • On full runs (nightly, dispatch, release fallback, and the mainrelease PR) CI_FORCE_FULL skips the diff entirely, so impact needs no history at all and the other three touch git not at all.

Cheapest version is one line per job:

fetch-depth: ${{ github.event_name == 'pull_request' && 0 || 1 }}

The fuller version is depth-1 everywhere plus a targeted git fetch --depth=1 origin $BASE_SHA where the base is actually needed.

Estimated: ~10–15s per job, ~40–60 billed runner-seconds per run — and because impact gates every other job, ~10–15s off the wall-clock critical path of every PR.

Verify: a scoped PR plan and a full plan both still select the same test files as they do today.

2. Cache server/node_modules instead of reinstalling it three times

npm ci --prefix server + node scripts/trusted-rebuilds.js server run in server, database, and windows-server. setup-node's npm cache only preserves ~/.npm (the tarball cache) — npm ci still wipes and repopulates node_modules, and the rebuild recompiles node-pty and re-runs onnxruntime-node's postinstall, which downloads platform binaries, on each of the three.

Cache server/node_modules keyed on hashFiles('server/package-lock.json'), folding the native rebuild into the cache-miss path.

Estimated: ~60–90s on each of the two redundant jobs, ~2–3 billed minutes per full run. Windows is the biggest single winner at 2× billing.

Careful: server/.npmrc pins ignore-scripts=true, so a restored cache must still be a rebuilt one — cache after the rebuild, not before, or the native addons are unusable.

3. Retire the lint and test (24.x) legacy check names

The lint job burns a whole runner to echo — it exists only to mirror the client job's lint result under a historical required-check name, and server carries name: test (24.x) for the same reason. GitHub bills a 1-minute minimum per job plus provisioning.

Neither main nor release currently has branch protection configured at all, so nothing is actually requiring these contexts today. Confirm that, then drop the lint job and rename server to something honest. CI Gate (and now Full CI Gate) are the checks that matter.

Estimated: ~1 billed minute per run.

Careful: if branch protection is ever added, add it requiring CI Gate, not the legacy names.

Context

Numbers measured 2026-08-21 against a full run (~10 min wall, ~38 billed runner-minutes: server ~7min, client+build ~7min, Windows ~10min at 2×). Baseline for comparison lives in docs/GITHUB_ACTIONS.md under "Vitest runner tuning".

Metadata

Metadata

Assignees

No one assigned

    Labels

    effort:mediumDispatch reasoning effort: mediummodel:mediumDispatch capability: routine workhorse modelplanTracked by /do:replantestsTest suite / test infrastructure

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions