Skip to content

CI: Update version of cargo-mutants in use. #850

CI: Update version of cargo-mutants in use.

CI: Update version of cargo-mutants in use. #850

Workflow file for this run

name: AIC Build, Test, Deploy
permissions: {}
on:
pull_request:
workflow_dispatch:
push:
branches:
# Test everything that goes on on main.
- main
# The special branch “ci” is used for testing CI behaviors even without a PR.
- ci
# next/* branches are used for testing with future versions of dependencies,
# usually by way of `[patch]`ing a dependency, thus won’t have outstanding PRs.
- "next/*"
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: |
cargo install --locked [email protected] [email protected]
# Not locked so that we can have a newer `syn` than is in the lockfile
cargo install [email protected]
- 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-pages-artifact@v3
with:
path: all-is-cubes-wasm/dist
- run: df -h .
deploy:
needs: build
runs-on: ubuntu-latest
permissions:
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
# 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:
# This action uses the artifact previously uploaded by actions/upload-pages-artifact
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
# 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
# next/* branches are expected to have git dependencies or otherwise break cargo-deny rules,
# so don't run cargo-deny on them. We still want to do so in pull requests, but that doesn't
# need a special rule because according to the GitHub docs, this will not be the branch name:
# “For pull requests, the format is `<pr_number>/merge`.”
# -- <https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/accessing-contextual-information-about-workflow-runs#github-context>
if: ${{ !startsWith(github.ref, 'refs/heads/next/') }}
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
# Not locked so that we can have a newer `syn` than is in the lockfile
- run: cargo install [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 -p all-is-cubes-ui -p all-is-cubes-mesh
- 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 -p all-is-cubes-ui -p all-is-cubes-mesh
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