Skip to content
193 linesCodeBlameRaw
1# Tests every pull request into main, so main can always be deployed. The
2# "Default branch" ruleset requires this workflow ("CI") to pass before a
3# pull request merges; people may still push to main directly, agents
4# may not. Deploy (deploy.yml) ships what lands on main.
5#
6# rust every crate's tests, natively
7# typescript type checks and tests of the apps and TS services, the
8# deploy and ops scripts, and the deploy manifest
9# build the site, sudo and the docs build as they deploy
10#
11# On a push to main `rust` and `desktop` run, keeping main's caches current:
12# a pull request's run restores from main's cache, never from another pull
13# request's, so without them each pull request would start from nothing.
14# What each cache holds, its key and which job saves it: CONTRIBUTING.md,
15# "How g1t's own CI caches". The Caches workflow (caches.yml) keeps the
16# ones only releases build.
17name: CI
18
19on:
20 pull_request:
21 branches: [main]
22 push:
23 branches: [main]
24 workflow_dispatch:
25
26# Its token only reads: it checks the code out and nothing more.
27permissions:
28 contents: read
29
30concurrency:
31 group: ci-${{ github.ref }}
32 cancel-in-progress: true
33
34env:
35 CARGO_TERM_COLOR: never
36 WRANGLER_SEND_METRICS: "false"
37
38jobs:
39 rust:
40 name: Rust
41 runs-on: g1t-4core
42 timeout-minutes: 45
43 env:
44 # Line tables, not full debug info: a panic still names its file and
45 # line, and the test build is a fraction of the size to link, keep
46 # and restore (at full debug info its cache entry reached 1.7 GB of
47 # the 2 GB an entry may hold).
48 CARGO_PROFILE_DEV_DEBUG: line-tables-only
49 steps:
50 - uses: actions/checkout@v5
51 # rust: the toolchain; cargo: Cargo.lock's crates.io and git packages,
52 # not the workspace's own versions (scripts/deploy/ci-cache.mjs).
53 - name: Cache keys
54 id: keys
55 run: node scripts/deploy/ci-cache.mjs keys
56 # Every crate the lockfile names, for every target (the fetch below):
57 # saved by this job alone, and only restored by Deploy and the
58 # releases, which each download part of it.
59 - name: Cache crates
60 uses: actions/cache@v4
61 with:
62 path: |
63 ~/.cargo/registry/index
64 ~/.cargo/registry/cache
65 key: cargo-crates-${{ runner.os }}-${{ steps.keys.outputs.cargo }}
66 restore-keys: cargo-crates-${{ runner.os }}-
67 - name: Every crate the lockfile names
68 run: cargo fetch --locked
69 # The compiled dependencies and workspace crates. Saved when the
70 # dependencies or the toolchain change; otherwise the last entry for
71 # this toolchain is a start, and only this build's files go into the
72 # new one (the prune step below).
73 - name: Cache the test build
74 id: test-build
75 uses: actions/cache@v4
76 with:
77 path: |
78 target/debug
79 !target/debug/incremental
80 key: cargo-test-${{ runner.os }}-${{ steps.keys.outputs.rust }}-${{ steps.keys.outputs.cargo }}
81 restore-keys: cargo-test-${{ runner.os }}-${{ steps.keys.outputs.rust }}-
82 # The workspace's library crates that Cargo compiles again come back
83 # from the repository's Actions cache when their inputs did not change
84 # (scripts/sccache.sh). Test harnesses and Workers' own crates are
85 # linked, and still compiled.
86 - name: sccache
87 run: bash scripts/sccache.sh install
88 - name: Tests
89 run: cargo test --workspace --locked --quiet
90 # A restored target keeps the old versions of whatever changed beside
91 # the new ones; only what this build used goes into the new entry.
92 - name: Only this build's files are saved
93 if: ${{ steps.test-build.outputs.cache-hit != 'true' }}
94 run: node scripts/deploy/ci-cache.mjs prune target/debug -- test --workspace --locked --no-run
95 - name: sccache's hits and misses
96 if: ${{ always() }}
97 run: bash scripts/sccache.sh stats
98
99 typescript:
100 name: TypeScript
101 if: ${{ github.event_name != 'push' }}
102 runs-on: ubuntu-latest
103 timeout-minutes: 30
104 steps:
105 - uses: actions/checkout@v5
106 # npm's downloads, kept between runs: an install reads them first
107 # and asks the registry only for what changed, so a dropped
108 # connection to it rarely stops the job.
109 - name: Cache npm's downloads
110 uses: actions/cache@v4
111 with:
112 path: ~/.npm
113 key: npm-full-${{ runner.os }}-${{ hashFiles('package-lock.json') }}
114 restore-keys: npm-full-${{ runner.os }}-
115 - name: Install
116 run: node scripts/deploy/npm-ci.mjs --prefer-offline --no-audit --no-fund
117 - name: Type checks
118 run: npm run typecheck
119 - name: Tests
120 run: npm test --workspaces --if-present
121 - name: The deploy tool's tests
122 run: npm run test:deploy
123 - name: The conformance report's tests
124 run: npm run test:conformance
125 - name: The ops scripts' tests
126 run: npm run test:ops
127 - name: The manifest matches every wrangler.jsonc
128 run: node scripts/deploy.mjs manifest --check
129 - name: The Claude Code plugin's tests
130 run: node --test plugins/claude-code/test/hooks.test.mjs
131
132 build:
133 name: Build
134 if: ${{ github.event_name != 'push' }}
135 runs-on: ubuntu-latest
136 timeout-minutes: 30
137 steps:
138 - uses: actions/checkout@v5
139 # npm's downloads, kept between runs: an install reads them first
140 # and asks the registry only for what changed, so a dropped
141 # connection to it rarely stops the job.
142 - name: Cache npm's downloads
143 uses: actions/cache@v4
144 with:
145 path: ~/.npm
146 key: npm-full-${{ runner.os }}-${{ hashFiles('package-lock.json') }}
147 restore-keys: npm-full-${{ runner.os }}-
148 - name: Install
149 run: node scripts/deploy/npm-ci.mjs --prefer-offline --no-audit --no-fund
150 - name: The site, sudo and the docs
151 run: node scripts/deploy.mjs build --only web,sudo,docs
152
153 desktop:
154 name: Desktop app
155 # The larger machine, as the Rust job: linking Tauri on the small one
156 # ran out of room and the linker died with a bus error.
157 runs-on: g1t-4core
158 timeout-minutes: 30
159 steps:
160 - uses: actions/checkout@v5
161 - name: Cache keys
162 id: keys
163 run: node scripts/deploy/ci-cache.mjs keys
164 # apt's lists and downloads (scripts/apt-install.sh): 110 s of every
165 # run before, mostly fetching 335 MB. Saved here, on main; the desktop
166 # release's Linux build restores the same entry.
167 - name: Cache apt's downloads
168 uses: actions/cache@v4
169 with:
170 path: ~/.cache/apt/tauri
171 key: apt-tauri-${{ runner.os }}-${{ hashFiles('scripts/apt-install.sh') }}
172 - name: What Tauri needs on Linux
173 run: bash scripts/apt-install.sh tauri
174 - name: Cache the desktop app's build
175 id: desktop-build
176 uses: actions/cache@v4
177 with:
178 path: |
179 ~/.cargo/registry/index
180 ~/.cargo/registry/cache
181 apps/desktop/src-tauri/target/debug
182 !apps/desktop/src-tauri/target/debug/incremental
183 key: desktop-check-${{ runner.os }}-${{ steps.keys.outputs.rust }}-${{ steps.keys.outputs.desktop }}
184 restore-keys: desktop-check-${{ runner.os }}-${{ steps.keys.outputs.rust }}-
185 # Outside the workspace on purpose (Cargo.toml says why): checked and
186 # tested here, built into installers by desktop-release.yml.
187 - name: Check and test
188 run: cargo test --locked --manifest-path apps/desktop/src-tauri/Cargo.toml --quiet
189 - name: Only this build's files are saved
190 if: ${{ steps.desktop-build.outputs.cache-hit != 'true' }}
191 run: node scripts/deploy/ci-cache.mjs prune apps/desktop/src-tauri/target/debug -- test --locked --manifest-path apps/desktop/src-tauri/Cargo.toml --no-run
192 - name: The release scripts' tests
193 run: node --test scripts/desktop-release.test.mjs scripts/mobile-release.test.mjs scripts/cli-release.test.mjs