Skip to content

Where people and agents ship software together. The open-source git platform for the whole job: issues, agents, checks and deploys to the edge.

402 linesCodeBlameRaw
1# Keeps, on main, the cache entries that only other workflows' runs would
2# otherwise make. A run restores from its own ref, then its pull request's
3# base branch, then main (docs.g1t.sh/guides/actions/#the-cache): a release
4# tag's run never sees another tag's entries, and before this every release
5# built its Rust from the start (desktop: 10 of 14 Linux and 12 of 13
6# Windows builds found nothing). So what a release restores is saved here.
7#
8# look looks every key up without downloading anything; a
9# lookup counts as a use, so a warm entry is never taken
10# for an unused one, and an entry past its 28 days is
11# simply made again
12# npm npm's downloads for the whole lockfile, which every npm
13# install in every workflow starts from
14# runner the runner release's build, for each target
15# desktop-linux the desktop release's Linux build
16# desktop-windows its Windows cross build, cargo-xwin, the MSVC CRT and
17# apt's downloads for it
18# cli the CLI release's build of every platform, in the
19# cargo-zigbuild image
20#
21# A job runs only when its key is missing (a new lockfile, a new toolchain,
22# or an expired entry), and builds what the release builds. Nothing waits for
23# this workflow, and a failed build only leaves the cache as it was. CI
24# keeps the rest of main's caches (ci.yml); CONTRIBUTING.md ("How g1t's own
25# CI caches") has the whole scheme, and the paths and keys here must stay
26# the same as the steps that restore them (repository_workflows.rs checks).
27name: Caches
28
29on:
30 push:
31 branches: [main]
32 workflow_dispatch:
33
34permissions:
35 contents: read
36
37# A build half done saves nothing, so one is never cut off; the next run
38# waits, and finds the key saved.
39concurrency:
40 group: caches-${{ github.ref }}
41 cancel-in-progress: false
42
43env:
44 CARGO_TERM_COLOR: never
45
46jobs:
47 look:
48 name: What is missing
49 runs-on: ubuntu-latest
50 timeout-minutes: 10
51 outputs:
52 npm: ${{ steps.npm.outputs.cache-hit != 'true' }}
53 runner: ${{ steps.missing.outputs.runner }}
54 desktop-linux: ${{ steps.desktop-linux.outputs.cache-hit != 'true' }}
55 desktop-windows: ${{ steps.desktop-windows.outputs.cache-hit != 'true' || steps.xwin.outputs.cache-hit != 'true' || steps.apt-windows.outputs.cache-hit != 'true' }}
56 cli: ${{ steps.cli.outputs.cache-hit != 'true' }}
57 steps:
58 - uses: actions/checkout@v5
59 - name: Cache keys
60 id: keys
61 run: node scripts/deploy/ci-cache.mjs keys
62 - id: npm
63 uses: actions/cache/restore@v4
64 with:
65 path: ~/.npm
66 key: npm-full-${{ runner.os }}-${{ hashFiles('package-lock.json') }}
67 lookup-only: true
68 - id: zig
69 uses: actions/cache/restore@v4
70 with:
71 path: |
72 ~/.local/lib/python3*/site-packages/ziglang
73 ~/.local/bin
74 ~/.cargo/bin/cargo-zigbuild
75 key: zig-0.13.0-zigbuild-${{ runner.os }}-1
76 lookup-only: true
77 - id: runner-linux-x64
78 uses: actions/cache/restore@v4
79 with:
80 path: |
81 target
82 !target/runner-release
83 !target/**/incremental
84 key: runner-release-${{ runner.os }}-linux-x64-${{ steps.keys.outputs.rust }}-${{ steps.keys.outputs.cargo }}
85 lookup-only: true
86 - id: runner-linux-arm64
87 uses: actions/cache/restore@v4
88 with:
89 path: |
90 target
91 !target/runner-release
92 !target/**/incremental
93 key: runner-release-${{ runner.os }}-linux-arm64-${{ steps.keys.outputs.rust }}-${{ steps.keys.outputs.cargo }}
94 lookup-only: true
95 - id: runner-windows-x64
96 uses: actions/cache/restore@v4
97 with:
98 path: |
99 target
100 !target/runner-release
101 !target/**/incremental
102 key: runner-release-${{ runner.os }}-windows-x64-${{ steps.keys.outputs.rust }}-${{ steps.keys.outputs.cargo }}
103 lookup-only: true
104 - id: desktop-linux
105 uses: actions/cache/restore@v4
106 with:
107 path: |
108 ~/.cargo/registry/index
109 ~/.cargo/registry/cache
110 apps/desktop/src-tauri/target/release
111 !apps/desktop/src-tauri/target/release/bundle
112 !apps/desktop/src-tauri/target/**/incremental
113 key: desktop-release-linux-${{ runner.os }}-${{ steps.keys.outputs.rust }}-${{ steps.keys.outputs.desktop }}
114 lookup-only: true
115 - id: desktop-windows
116 uses: actions/cache/restore@v4
117 with:
118 path: |
119 ~/.cargo/registry/index
120 ~/.cargo/registry/cache
121 apps/desktop/src-tauri/target/release
122 apps/desktop/src-tauri/target/x86_64-pc-windows-msvc/release
123 !apps/desktop/src-tauri/target/**/bundle
124 !apps/desktop/src-tauri/target/**/incremental
125 key: desktop-release-windows-${{ runner.os }}-${{ steps.keys.outputs.rust }}-${{ steps.keys.outputs.desktop }}
126 lookup-only: true
127 - id: xwin
128 uses: actions/cache/restore@v4
129 with:
130 path: |
131 ~/.cargo/bin/cargo-xwin
132 ~/.cache/cargo-xwin
133 key: xwin-${{ runner.os }}-0.23.1
134 lookup-only: true
135 - id: apt-windows
136 uses: actions/cache/restore@v4
137 with:
138 path: ~/.cache/apt/tauri-windows
139 key: apt-tauri-windows-${{ runner.os }}-${{ hashFiles('scripts/apt-install.sh') }}
140 lookup-only: true
141 - id: cli
142 uses: actions/cache/restore@v4
143 with:
144 path: |
145 target/zig
146 !target/zig/**/incremental
147 key: cli-release-${{ runner.os }}-${{ steps.keys.outputs.zigbuild }}-${{ steps.keys.outputs.cargo }}
148 lookup-only: true
149 # The runner's targets to build: those whose build is missing, or all
150 # of them when zig is (each saves it, the first to finish wins).
151 - name: The runner's targets to build
152 id: missing
153 env:
154 ZIG: ${{ steps.zig.outputs.cache-hit }}
155 LINUX_X64: ${{ steps.runner-linux-x64.outputs.cache-hit }}
156 LINUX_ARM64: ${{ steps.runner-linux-arm64.outputs.cache-hit }}
157 WINDOWS_X64: ${{ steps.runner-windows-x64.outputs.cache-hit }}
158 # Each with its Rust triple, as scripts/runner-release.mjs names it.
159 run: |
160 targets=()
161 [ "$ZIG" = true ] && [ "$LINUX_X64" = true ] || targets+=('{"target":"linux-x64","triple":"x86_64-unknown-linux-musl"}')
162 [ "$ZIG" = true ] && [ "$LINUX_ARM64" = true ] || targets+=('{"target":"linux-arm64","triple":"aarch64-unknown-linux-musl"}')
163 [ "$ZIG" = true ] && [ "$WINDOWS_X64" = true ] || targets+=('{"target":"windows-x64","triple":"x86_64-pc-windows-gnu"}')
164 list="[$(IFS=,; echo "${targets[*]}")]"
165 echo "runner=$list" >> "$GITHUB_OUTPUT"
166 echo "The runner's targets to build: $list"
167
168 # npm's downloads for the whole lockfile, saved once for each lockfile.
169 # Before, every job saved its own part under one key, and the first to
170 # finish (Wrangler alone, 73 MB) stood in for the rest: each stage then
171 # downloaded hundreds of MB through the runner's egress, 50 MB tarballs
172 # among them. Starts from the last lockfile's, with scripts off.
173 npm:
174 name: npm's downloads
175 needs: look
176 if: ${{ needs.look.outputs.npm == 'true' }}
177 runs-on: ubuntu-latest
178 timeout-minutes: 20
179 steps:
180 - uses: actions/checkout@v5
181 - name: Start from the last lockfile's
182 uses: actions/cache/restore@v4
183 with:
184 path: ~/.npm
185 key: npm-full-${{ runner.os }}-${{ hashFiles('package-lock.json') }}
186 restore-keys: npm-full-${{ runner.os }}-
187 # A failed download leaves the cache as it was, and the run green.
188 - name: Download every package
189 id: download
190 continue-on-error: true
191 run: node scripts/deploy/npm-ci.mjs --prefer-offline --ignore-scripts --no-audit --no-fund
192 - name: Save them
193 if: ${{ steps.download.outcome == 'success' }}
194 uses: actions/cache/save@v4
195 with:
196 path: ~/.npm
197 key: npm-full-${{ runner.os }}-${{ hashFiles('package-lock.json') }}
198
199 # The steps of runner-release.yml's binaries job that fill its cache.
200 runner:
201 name: The runner's build for ${{ matrix.target }}
202 needs: look
203 if: ${{ needs.look.outputs.runner != '[]' }}
204 runs-on: ubuntu-latest
205 timeout-minutes: 60
206 strategy:
207 fail-fast: false
208 matrix:
209 include: ${{ fromJSON(needs.look.outputs.runner) }}
210 env:
211 G1T_RUNNER_RELEASE_KEY: ${{ vars.RUNNER_RELEASE_PUBLIC_KEY }}
212 steps:
213 - uses: actions/checkout@v5
214 - name: Cache zig and cargo-zigbuild
215 id: zig
216 uses: actions/cache@v4
217 with:
218 path: |
219 ~/.local/lib/python3*/site-packages/ziglang
220 ~/.local/bin
221 ~/.cargo/bin/cargo-zigbuild
222 key: zig-0.13.0-zigbuild-${{ runner.os }}-1
223 - name: Install zig and cargo-zigbuild
224 if: steps.zig.outputs.cache-hit != 'true'
225 run: |
226 pip install --user --break-system-packages ziglang==0.13.0
227 cargo install --locked cargo-zigbuild
228 - name: zig on the PATH
229 run: echo "$HOME/.local/bin" >> "$GITHUB_PATH"
230 - name: Cache keys
231 id: keys
232 run: node scripts/deploy/ci-cache.mjs keys
233 - name: Cache crates
234 uses: actions/cache/restore@v4
235 with:
236 path: |
237 ~/.cargo/registry/index
238 ~/.cargo/registry/cache
239 key: cargo-crates-${{ runner.os }}-${{ steps.keys.outputs.cargo }}
240 restore-keys: cargo-crates-${{ runner.os }}-
241 - name: Cache the runner's build
242 id: runner-build
243 uses: actions/cache@v4
244 with:
245 path: |
246 target
247 !target/runner-release
248 !target/**/incremental
249 key: runner-release-${{ runner.os }}-${{ matrix.target }}-${{ steps.keys.outputs.rust }}-${{ steps.keys.outputs.cargo }}
250 restore-keys: runner-release-${{ runner.os }}-${{ matrix.target }}-${{ steps.keys.outputs.rust }}-
251 - name: sccache
252 run: bash scripts/sccache.sh install
253 - name: Build
254 run: node scripts/runner-release.mjs build --targets ${{ matrix.target }}
255 - name: Only this build's files are saved
256 if: ${{ steps.runner-build.outputs.cache-hit != 'true' }}
257 run: node scripts/deploy/ci-cache.mjs prune target/release target/${{ matrix.triple }}/release -- zigbuild --release --locked --package g1t-runner --target ${{ matrix.triple }}
258 - name: sccache's hits and misses
259 if: ${{ always() }}
260 run: bash scripts/sccache.sh stats
261
262 # desktop-release.yml's Linux build, without its installers: `tauri
263 # build --no-bundle` compiles exactly what `tauri build` does, and needs
264 # no signing key.
265 desktop-linux:
266 name: The desktop app's Linux build
267 needs: look
268 if: ${{ needs.look.outputs.desktop-linux == 'true' }}
269 # The larger machine: linking Tauri on the small one dies with a bus error.
270 runs-on: g1t-4core
271 timeout-minutes: 60
272 steps:
273 - uses: actions/checkout@v5
274 - name: Cache keys
275 id: keys
276 run: node scripts/deploy/ci-cache.mjs keys
277 # Saved by CI's desktop job; only restored here.
278 - name: Cache apt's downloads
279 uses: actions/cache/restore@v4
280 with:
281 path: ~/.cache/apt/tauri
282 key: apt-tauri-${{ runner.os }}-${{ hashFiles('scripts/apt-install.sh') }}
283 - name: What Tauri needs on Linux
284 run: bash scripts/apt-install.sh tauri
285 - name: Cache the release build
286 uses: actions/cache@v4
287 with:
288 path: |
289 ~/.cargo/registry/index
290 ~/.cargo/registry/cache
291 apps/desktop/src-tauri/target/release
292 !apps/desktop/src-tauri/target/release/bundle
293 !apps/desktop/src-tauri/target/**/incremental
294 key: desktop-release-linux-${{ runner.os }}-${{ steps.keys.outputs.rust }}-${{ steps.keys.outputs.desktop }}
295 restore-keys: desktop-release-linux-${{ runner.os }}-${{ steps.keys.outputs.rust }}-
296 - name: Cache npm's downloads
297 uses: actions/cache/restore@v4
298 with:
299 path: ~/.npm
300 key: npm-full-${{ runner.os }}-${{ hashFiles('package-lock.json') }}
301 restore-keys: npm-full-${{ runner.os }}-
302 - name: Install
303 run: node scripts/deploy/npm-ci.mjs --prefer-offline --no-audit --no-fund
304 - name: Build
305 working-directory: apps/desktop
306 run: npx tauri build --ci --no-bundle
307
308 # desktop-release.yml's Windows cross build, without its installer.
309 desktop-windows:
310 name: The desktop app's Windows build
311 needs: look
312 if: ${{ needs.look.outputs.desktop-windows == 'true' && vars.DESKTOP_WINDOWS_FROM_LINUX == 'true' && vars.DESKTOP_WINDOWS_RUNNER != 'true' }}
313 runs-on: g1t-4core
314 timeout-minutes: 60
315 steps:
316 - uses: actions/checkout@v5
317 - name: Cache keys
318 id: keys
319 run: node scripts/deploy/ci-cache.mjs keys
320 - name: Cache apt's downloads
321 uses: actions/cache@v4
322 with:
323 path: ~/.cache/apt/tauri-windows
324 key: apt-tauri-windows-${{ runner.os }}-${{ hashFiles('scripts/apt-install.sh') }}
325 - name: What the cross build needs
326 run: bash scripts/desktop-cross-tools.sh
327 - name: Cache cargo-xwin and the MSVC CRT
328 id: xwin
329 uses: actions/cache@v4
330 with:
331 path: |
332 ~/.cargo/bin/cargo-xwin
333 ~/.cache/cargo-xwin
334 key: xwin-${{ runner.os }}-0.23.1
335 - name: cargo-xwin
336 if: ${{ steps.xwin.outputs.cache-hit != 'true' }}
337 run: cargo install --locked cargo-xwin@0.23.1
338 - name: Cache the release build
339 uses: actions/cache@v4
340 with:
341 path: |
342 ~/.cargo/registry/index
343 ~/.cargo/registry/cache
344 apps/desktop/src-tauri/target/release
345 apps/desktop/src-tauri/target/x86_64-pc-windows-msvc/release
346 !apps/desktop/src-tauri/target/**/bundle
347 !apps/desktop/src-tauri/target/**/incremental
348 key: desktop-release-windows-${{ runner.os }}-${{ steps.keys.outputs.rust }}-${{ steps.keys.outputs.desktop }}
349 restore-keys: desktop-release-windows-${{ runner.os }}-${{ steps.keys.outputs.rust }}-
350 - name: Cache npm's downloads
351 uses: actions/cache/restore@v4
352 with:
353 path: ~/.npm
354 key: npm-full-${{ runner.os }}-${{ hashFiles('package-lock.json') }}
355 restore-keys: npm-full-${{ runner.os }}-
356 - name: Install
357 run: node scripts/deploy/npm-ci.mjs --prefer-offline --no-audit --no-fund
358 - name: Build
359 working-directory: apps/desktop
360 run: |
361 rustup target add x86_64-pc-windows-msvc
362 npx tauri build --ci --runner cargo-xwin --target x86_64-pc-windows-msvc --no-bundle
363 # What the CRT and SDK came to, for the cache's 2 GB an entry may hold.
364 - name: How large the MSVC CRT is
365 run: du -sh ~/.cache/cargo-xwin || true
366
367 # cli-release.yml's build of every platform, in the cargo-zigbuild image
368 # (scripts/cli-release.mjs). Built whole whenever its key is new (a new
369 # image or new dependencies), never started from an older entry: what
370 # zigbuild built cannot be listed by this machine's Cargo to prune it, so
371 # nothing old is carried in to begin with.
372 cli:
373 name: The CLI's release build
374 needs: look
375 if: ${{ needs.look.outputs.cli == 'true' }}
376 # The builder runs in Docker, which g1t's own machines give each job.
377 runs-on: g1t-4core
378 timeout-minutes: 60
379 steps:
380 - uses: actions/checkout@v5
381 - name: Cache keys
382 id: keys
383 run: node scripts/deploy/ci-cache.mjs keys
384 - name: Cache crates
385 uses: actions/cache/restore@v4
386 with:
387 path: |
388 ~/.cargo/registry/index
389 ~/.cargo/registry/cache
390 key: cargo-crates-${{ runner.os }}-${{ steps.keys.outputs.cargo }}
391 restore-keys: cargo-crates-${{ runner.os }}-
392 - name: Cache the CLI's build
393 uses: actions/cache@v4
394 with:
395 path: |
396 target/zig
397 !target/zig/**/incremental
398 key: cli-release-${{ runner.os }}-${{ steps.keys.outputs.zigbuild }}-${{ steps.keys.outputs.cargo }}
399 - name: Build
400 run: node scripts/cli-release.mjs build
401 - name: How large the build is
402 run: du -sh target/zig || true