2026-02-09 12:24:11 -08:00
---
title: CI Pipeline
2026-02-22 20:36:39 +01:00
summary: "CI job graph, scope gates, and local command equivalents"
read_when:
- You need to understand why a CI job did or did not run
- You are debugging failing GitHub Actions checks
2026-02-09 12:24:11 -08:00
---
# CI Pipeline
2026-03-13 19:42:08 +00:00
The CI runs on every push to `main` and every pull request. It uses smart scoping to skip expensive jobs when only unrelated areas changed.
2026-02-09 12:24:11 -08:00
2026-02-09 18:30:05 -08:00
## Job Overview
2026-02-09 12:24:11 -08:00
2026-03-23 05:28:40 +00:00
| Job | Purpose | When it runs |
| ----------------- | ------------------------------------------------------------------------- | ------------------------------------------------ |
| `preflight` | Docs scope, change scope, key scan, workflow audit, prod dependency audit | Always; node-based audit only on non-doc changes |
| `docs-scope` | Detect docs-only changes | Always |
| `changed-scope` | Detect which areas changed (node/macos/android/windows) | Non-doc changes |
| `check` | TypeScript types, lint, format | Non-docs, node changes |
| `check-docs` | Markdown lint + broken link check | Docs changed |
| `secrets` | Detect leaked secrets | Always |
| `build-artifacts` | Build dist once, share with `release-check` | Pushes to `main` , node changes |
| `release-check` | Validate npm pack contents | Pushes to `main` after build |
| `checks` | Node tests + protocol check on PRs; Bun compat on push | Non-docs, node changes |
| `compat-node22` | Minimum supported Node runtime compatibility | Pushes to `main` , node changes |
| `checks-windows` | Windows-specific tests | Non-docs, windows-relevant changes |
| `macos` | Swift lint/build/test + TS tests | PRs with macos changes |
| `android` | Gradle build + tests | Non-docs, android changes |
2026-02-09 12:24:11 -08:00
2026-02-09 18:30:05 -08:00
## Fail-Fast Order
2026-02-09 12:24:11 -08:00
2026-02-09 18:30:05 -08:00
Jobs are ordered so cheap checks fail before expensive ones run:
2026-02-09 12:24:11 -08:00
2026-03-13 19:42:08 +00:00
1. `docs-scope` + `changed-scope` + `check` + `secrets` (parallel, cheap gates first)
2026-03-13 20:38:03 +00:00
2. PRs: `checks` (Linux Node test split into 2 shards), `checks-windows` , `macos` , `android`
3. Pushes to `main` : `build-artifacts` + `release-check` + Bun compat + `compat-node22`
2026-02-09 12:24:11 -08:00
2026-03-03 02:37:04 +00:00
Scope logic lives in `scripts/ci-changed-scope.mjs` and is covered by unit tests in `src/scripts/ci-changed-scope.test.ts` .
2026-03-22 12:58:08 -07:00
The same shared scope module also drives the separate `install-smoke` workflow through a narrower `changed-smoke` gate, so Docker/install smoke only runs for install, packaging, and container-relevant changes.
2026-03-03 02:37:04 +00:00
2026-02-09 18:30:05 -08:00
## Runners
2026-02-09 12:24:11 -08:00
2026-02-19 17:25:15 +01:00
| Runner | Jobs |
| -------------------------------- | ------------------------------------------ |
| `blacksmith-16vcpu-ubuntu-2404` | Most Linux jobs, including scope detection |
2026-03-03 02:42:27 +00:00
| `blacksmith-32vcpu-windows-2025` | `checks-windows` |
2026-02-19 17:25:15 +01:00
| `macos-latest` | `macos` , `ios` |
2026-02-09 12:24:11 -08:00
2026-02-09 18:30:05 -08:00
## Local Equivalents
2026-02-09 12:24:11 -08:00
2026-02-09 18:30:05 -08:00
``` bash
pnpm check # types + lint + format
pnpm test # vitest tests
pnpm check:docs # docs format + lint + broken links
pnpm release:check # validate npm pack
```