nordisk/heimdall
scripts/ci.sh
#!/bin/sh
# SPDX-License-Identifier: AGPL-3.0-only
# Heimdall CI. Heimdall is a defensive sandbox; this script builds and tests
# only Heimdall itself. Run it inside the toolchain container, from the repo
# root, e.g.:
# podman run --rm -v "$PWD":/src -w /src localhost/nordisk-cargo-toolchain:<tag> scripts/ci.sh
# Steps: fmt, clippy -D warnings, tests, cargo deny (when deny.toml and
# cargo-deny are both present), fuzz smoke runs (when cargo-fuzz and a nightly
# toolchain are present; HEIMDALL_CI_FUZZ_RUNS sets the run count, 0 skips).
set -eu
cd "$(dirname "$0")/.."
step() { printf '\n== %s\n' "$*"; }
step "cargo fmt --check"
cargo fmt --all -- --check
step "cargo clippy -D warnings"
cargo clippy --workspace --all-targets --locked -- -D warnings
step "cargo test"
cargo test --workspace --locked
# heimdall-plain's shim links libseccomp (feature `youki`, off by default).
if pkg-config --exists libseccomp 2>/dev/null; then
step "heimdall-plain --features youki: clippy + build the shim"
cargo clippy -p nordisk-heimdall-plain --features youki --all-targets --locked -- -D warnings
cargo build -p nordisk-heimdall-plain --features youki --bins --locked
else
echo "libseccomp-dev not installed: heimdall-plain's youki shim not built" >&2
fi
echo "heimdall-plain container tests: scripts/plain-tests.sh (needs privileges)"
# The wasm guests are their own workspaces (built for wasm32, not host members).
for g in guests/*/Cargo.toml; do
[ -f "$g" ] || continue
d=$(dirname "$g")
step "$d: fmt, clippy, tests (incl. the guest in the real wasm host), wasm32 build"
(cd "$d" && cargo fmt -- --check \
&& cargo clippy --all-targets --release --locked -- -D warnings \
&& cargo test --release --locked \
&& cargo build --release --lib --locked --target wasm32-unknown-unknown)
done
if [ -f deny.toml ]; then
if cargo deny --version >/dev/null 2>&1; then
step "cargo deny check"
cargo deny check
else
echo "deny.toml present but cargo-deny is not installed: skipped" >&2
fi
fi
runs=${HEIMDALL_CI_FUZZ_RUNS:-2000}
if [ -d fuzz ] && [ "$runs" -gt 0 ]; then
if cargo fuzz --version >/dev/null 2>&1 && rustup run nightly rustc --version >/dev/null 2>&1; then
for t in $(cargo +nightly fuzz list --fuzz-dir fuzz); do
step "cargo fuzz run $t ($runs runs)"
# The checked-in seeds start the corpus; new finds stay in the
# ignored fuzz/corpus, never in fuzz/seeds.
mkdir -p "fuzz/corpus/$t"
[ -d "fuzz/seeds/$t" ] && cp -n "fuzz/seeds/$t"/* "fuzz/corpus/$t"/ 2>/dev/null || true
cargo +nightly fuzz run --fuzz-dir fuzz "$t" -- -runs="$runs" -max_len=65536
done
else
step "fuzz targets: build check only (no cargo-fuzz or nightly)"
cargo check --manifest-path fuzz/Cargo.toml --bins
fi
fi
step "CI green"