-
Notifications
You must be signed in to change notification settings - Fork 8
519 lines (426 loc) · 16.5 KB
/
ci.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
name: AIC Build, Test, Deploy
permissions: {}
on:
pull_request:
workflow_dispatch:
push:
branches:
- main
- ci
env:
CARGO_TERM_COLOR: always
# Disable incremental compilation because we aren't caching incremental compilation
# artifacts, so they won't be useful for anything (other than maybe the exhaustive
# builds with different features).
CARGO_INCREMENTAL: 0
# Collect backtrace on panic.
RUST_BACKTRACE: 1
# Tell `anyhow` *not* to collect backtraces for errors.
# <https://users.rust-lang.org/t/anyhow-backtraces/107437>
RUST_LIB_BACKTRACE: 0
jobs:
build:
strategy:
fail-fast: false
matrix:
# This matrix doesn't do any actual Cartesian products, but instead has a
# basic configuration (Linux, stable Rust, using lockfile) and also tries
# changing one of those parameters but not the others.
include:
# This is the configuration we use for the wasm build and exhaustive tests.
- os: ubuntu
toolchain: stable
depversions: locked
primary: true
# Additional configurations to try:
# Windows
- os: windows
toolchain: stable
depversions: locked
primary: false
# macOS
- os: macos
toolchain: stable
depversions: locked
primary: false
# Nightly Rust
# We test on this so that we can report new compiler bugs fast.
# However, by the same premise, it breaks often.
- os: ubuntu
toolchain: nightly
depversions: locked
primary: false
# Beta Rust (future stable release)
# We test on this so that we can report compiler bugs that made it out of
# nightly and their fixes should be backported, and so that we have signal
# that is less unstable than nightly.
- os: ubuntu
toolchain: beta
depversions: locked
primary: false
# Dependencies updated
- os: ubuntu
toolchain: stable
depversions: latest
primary: false
# Dependencies reverted to minimal-versions
- os: ubuntu
toolchain: stable
depversions: minimal
primary: false
runs-on: ${{ matrix.os }}-latest
continue-on-error: ${{ !matrix.primary }}
steps:
# Free some disk space so our largest builds can complete reliably.
- uses: jlumbroso/[email protected]
if: ${{ matrix.os == 'ubuntu' }}
with:
large-packages: false # slow
swap-storage: false
- run: df -h .
- uses: actions/checkout@v4
- run: df -h .
- name: Set Rust toolchain
# The rust-toolchain.toml file specifies the targets and components we need,
# but we may want to override the toolchain.
if: ${{ matrix.toolchain != 'stable' }}
run: |
sed -i.origstable "s/stable/${{ matrix.toolchain }}/" rust-toolchain.toml
rustup show # triggers installation of selected toolchain
- name: Install nightly for -Z direct-minimal-versions
if: ${{ matrix.depversions == 'minimal' }}
run: rustup toolchain install nightly --profile=minimal
- name: Install native libraries
if: ${{ runner.os == 'Linux' }}
run: |
sudo apt update
sudo apt-get -y install libxrandr-dev xorg-dev libx11-xcb-dev libwayland-dev libasound2-dev libudev-dev
# libxrandr-dev xorg-dev libx11-xcb-dev libwayland-dev: needed for windowing
# Note that `libwayland-dev` provides the library called `wayland-client`
# libasound2-dev: needed for audio via `kira`
# libudev-dev: needed for gamepad input via `gilrs`
- run: df -h .
# Load cache before doing any Rust builds
- uses: Swatinem/[email protected]
with:
# This is not necessary for keying, but makes the GHA cache viewing page more helpful.
prefix-key: "v1-rust-${{ matrix.os }}-${{ matrix.toolchain }}-${{ matrix.depversions }}"
# Override the default job-id-based key explicitly so that our dependent jobs can
# reuse this cache.
shared-key: "build"
workspaces: |
./
all-is-cubes-wasm/
- run: df -h .
# break this out as a separate non-silenced build step
- name: Compile xtask
run: cargo build --package xtask
- name: Update dependencies
run: |
cargo xtask update "${{ matrix.depversions }}"
cargo tree --all-features
- run: df -h .
- name: Install tools
# Note: Swatinem/rust-cache will cache these installed binaries, so we don't have to worry
# about caching the builds of them.
# cargo-mutants is not used in this step but it will be cached for later use.
run: |
- run: df -h .
- name: Compile tests
# compile is broken out so we have visibility into compile vs. run times
run: cargo xtask --scope=only-normal test --timings --no-run
- name: Run tests
run: cargo xtask --scope=only-normal test --timings
- run: df -h .
# Save the test-renderers results so we can download and view them
- name: Save test-renderers output
if: ${{ always() }}
uses: actions/upload-artifact@v4
with:
name: test-renderers-output ${{ matrix.os }} ${{ matrix.toolchain }} ${{ matrix.depversions }}
path: |
target/test-renderers-output/
- run: df -h .
# Save timing reports so we can download and view them
# (for understanding build performance in CI)
- name: Save cargo --timings output
if: ${{ always() }}
uses: actions/upload-artifact@v4
with:
name: cargo-timings build ${{ matrix.os }} ${{ matrix.toolchain }} ${{ matrix.depversions }}
path: |
target/cargo-timings/cargo-timing-*.html
# Save wasm build so that we can optionally deploy it without rebuilding
# (but only for the stablest matrix version)
- name: Save wasm dist artifact
if: ${{ matrix.primary }}
uses: actions/upload-artifact@v4
with:
name: wasm-dist
path: all-is-cubes-wasm/dist
- run: df -h .
deploy:
needs: build
runs-on: ubuntu-latest
permissions:
contents: write
# Do this only if we are pushing to main, not to pull requests.
# (Or if we're on a special 'pages-alt' branch, so we can experiment with
# deployment before pushing to main.)
#
# Caution: GitHub's parsing is weird around multiline expressions so just don't.
# https://github.community/t/how-to-write-multi-line-condition-in-if/128477
if: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/pages-alt') }}
steps:
- name: Download wasm dist artifact
uses: actions/download-artifact@v4
with:
name: wasm-dist
path: dist-for-deploy
- name: Deploy to GitHub Pages
uses: crazy-max/ghaction-github-pages@v4
with:
target_branch: gh-pages
build_dir: dist-for-deploy
keep_history: false
jekyll: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Run `xtask lint`.
#
# This job is separate from the main "build" job so that:
# * Lint results are delivered quickly by running them in parallel with other jobs.
# * We build with `-Dwarnings` so the failures aren't silent, but don't want this to
# cause *re*building in the main build job and its cache.
lint:
strategy:
fail-fast: false
matrix:
toolchain: ["stable", "nightly", "beta"]
runs-on: ubuntu-latest
continue-on-error: false
env:
RUSTFLAGS: '-Dwarnings'
steps:
- uses: actions/checkout@v4
- name: Set Rust toolchain
# The rust-toolchain.toml file specifies the targets and components we need,
# but we may want to override the toolchain.
if: ${{ matrix.toolchain != 'stable' }}
run: |
sed -i.origstable "s/stable/${{ matrix.toolchain }}/" rust-toolchain.toml
rustup show # triggers installation of selected toolchain
- name: Install native libraries
if: ${{ runner.os == 'Linux' }}
run: |
sudo apt update
sudo apt-get -y install libxrandr-dev xorg-dev libx11-xcb-dev libwayland-dev libasound2-dev libudev-dev
- run: df -h .
- uses: Swatinem/[email protected]
with:
# We cannot reuse the cache from the `build` job, because `RUSTFLAGS=-Dwarnings`
# would invalidate all cached artifacts anyway.
prefix-key: "v1-rust-${{ matrix.toolchain }}"
shared-key: "lint"
# Job's likely to fail and yet have useful cache material.
cache-on-failure: true
workspaces: |
./
all-is-cubes-wasm/
- name: Install tools
run: |
cargo install --locked [email protected]
- run: df -h .
# break this out as a separate non-silenced build step
- name: Compile xtask
run: cargo build --package xtask
# Kludge: Avoid dependency on `cargo-about` by making the generated license info file look fresh.
- name: Skip license generation
run: touch all-is-cubes-wasm/static/third-party-licenses.html
- name: Lint
run: cargo xtask --scope=only-normal lint --timings
- run: df -h .
- name: Save cargo --timings output
if: ${{ always() }}
uses: actions/upload-artifact@v4
with:
name: cargo-timings lint ${{ matrix.toolchain }}
path: |
target/cargo-timings/cargo-timing-*.html
# Run `xtask test-more` to look for broken `features`.
features:
# Don't spend time on this if the normal builds failed.
# Also, we reuse the cache from it.
needs: build
runs-on: ubuntu-latest
continue-on-error: false
steps:
# Free some disk space so our largest builds can complete reliably.
- uses: jlumbroso/[email protected]
with:
large-packages: false # slow
swap-storage: false
- uses: actions/checkout@v4
- name: Install native libraries
if: ${{ runner.os == 'Linux' }}
run: |
sudo apt update
sudo apt-get -y install libxrandr-dev xorg-dev libx11-xcb-dev libwayland-dev libasound2-dev libudev-dev
# Load cache before doing any Rust builds
- uses: Swatinem/[email protected]
with:
# Reuse the cache from the normal `build` job instead of creating an independent one,
# to reduce redundant work and save disk space — but don't *write* to that cache, so
# we don't bloat it or conflict.
prefix-key: "v1-rust-ubuntu-stable-locked"
shared-key: "build"
save-if: false
workspaces: |
./
all-is-cubes-wasm/
# break this out as a separate non-silenced build step
- name: Compile xtask
run: cargo build --package xtask
- name: Install tools
# These should already be installed but we might have a cache miss, so don't fail in that case.
run: |
cargo install --locked [email protected] [email protected]
- run: df -h .
# Run tests in `test-more` mode which exercises each library's features.
- name: Run exhaustive tests
run: cargo xtask --scope=only-normal test-more --timings
- run: df -h .
# Save timing reports so we can download and view them
# (for understanding build performance in CI)
- name: Save cargo --timings output
if: ${{ always() }}
uses: actions/upload-artifact@v4
with:
name: cargo-timings features
path: |
target/cargo-timings/cargo-timing-*.html
deny:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: EmbarkStudios/[email protected]
with:
# disables default --all-features
arguments:
command-arguments: --config=tools/deny.toml
# Run mutation testing against the changed code
# Based on example from https://mutants.rs/pr-diff.html
incremental-mutants:
runs-on: ubuntu-latest
# Running on push would require more work to determine the base revision
if: github.event_name == 'pull_request'
steps:
- uses: actions/checkout@v4
with:
# Needed to ensure `main` branch is needed
fetch-depth: 0
# Load cache before doing any Rust builds
# Note: we aren't depending on the build job so this cache might be stale, but the
# shorter time-to-useful-results seems worth it.
- uses: Swatinem/[email protected]
with:
# Reuse the cache from the normal `build` job instead of creating an independent one,
# to reduce redundant work and save disk space — but don't *write* to that cache, so
# we don't bloat it.
prefix-key: "v1-rust-ubuntu-stable-locked"
shared-key: "build"
save-if: false
workspaces: |
./
all-is-cubes-wasm/
# Install cargo-mutants
# This should usually be already installed, but is present in case of cache miss
- run: cargo install --locked [email protected]
- name: Relative diff
run: |
git branch -av
git diff origin/${{ github.base_ref }}.. | tee git.diff
- name: Mutants
# See mutants.yml for notes on the package selection
run: cargo mutants --in-diff git.diff --package all-is-cubes -- --all-features
- uses: actions/upload-artifact@v4
if: ${{ always() }}
with:
name: mutants-incremental.out
path: mutants.out
miri:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: Swatinem/[email protected]
- name: Install Rust toolchain
run: |
rustup toolchain install nightly --component miri
- name: Run Miri tests, std
# `universe::owning_guard` is the only module that contains nontrivial unsafe code,
# and the tests in `universe` are those most worth running to exercise it.
run: |
cargo +nightly miri test --no-default-features -p all-is-cubes universe:: --features std
- name: Run Miri tests, no_std
run: |
cargo +nightly miri test --no-default-features -p all-is-cubes universe::
no_std:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# The build is faster *without* this cache.
# - uses: Swatinem/[email protected]
- name: Install Rust toolchain
run: |
rustup toolchain install stable --profile minimal
rustup target add thumbv7em-none-eabihf
# TODO: move this command into xtask so it centrally tracks package info like "no_std compatible"
- name: no_std lint
run: |
cargo clippy --target=thumbv7em-none-eabihf --no-default-features -p all-is-cubes -p all-is-cubes-render
- name: no_std build
# This is `cargo build`, not `cargo check`, because `cargo check` won't detect problems like
# use of undefined linker symbols. Not sure if that matters.
run: |
cargo build --target=thumbv7em-none-eabihf --no-default-features -p all-is-cubes -p all-is-cubes-render
fuzz:
# Don't spend time on fuzzing if the build failed indicating the code is bad other ways
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# Cache both the main workspace (for xtask builds) and the fuzzing workspace
- uses: Swatinem/[email protected]
with:
workspaces: |
.
fuzz
- name: Install Rust toolchain
run: |
rustup toolchain install nightly --profile=minimal --component=clippy --component=rustfmt
rustup override set nightly
- name: Install cargo-fuzz
run: cargo install cargo-fuzz
- name: Cache fuzzer corpus
uses: actions/cache@v4
with:
# Failed runs are useful to cache since they expand the corpus
save-always: true
key: fuzz-corpus
path: |
fuzz/corpus
- name: Lint
# We run lint because otherwise the fuzz code won't get linted.
run: cargo xtask --scope=only-fuzz lint
- name: Fuzz
# Note: The specified timeout value is per-fuzz-target; as of this writing
# there are 6 fuzz targets and so the total time will be 720 seconds = 12 minutes.
run: cargo xtask --scope=only-fuzz fuzz 120
# Save the fuzz artifacts so we can repro elsewhere
- name: Save fuzz artifacts
if: ${{ failure() }}
uses: actions/upload-artifact@v4
with:
name: fuzz-artifacts
path: fuzz/artifacts