.forgejo/workflows/ci.yml
# The suite holger never ran on a push (stinky SB #32).
#
# `security.yml` checks the one thing a lone checkout can: the advisories of the
# committed Cargo.lock. Everything else needs the sibling checkouts holger
# path-depends on (edda, Skidbladnir, monetize, tunnr, draupnir, modgunn,
# znippy-zoomies, facett, holger-ui), so this job lays the same constellation the
# release gate builds in — every sibling cloned beside holger from git.gunnar.rs
# at its default branch — and runs, in order:
#
# 1. rustfmt — every .rs file the push ADDS is rustfmt-clean
# (a ratchet: the older files are not, yet)
# 2. clippy — the server library under the shipped planes
# 3. the silenced-test guard — `xtask/tests/silenced_tests_guard.rs`: a test
# target that silently runs nothing is RED
# 4. the main test arms — `cargo xtask test` (the wasm guests, then the
# default and metered suites) and the server
# library under `supply-chain` and
# `supply-chain,metered`
# 5. the MVP suite — `cargo xtask suite-check` (G2, 2026-10-23): every
# MVP cargo row compiled with its own features, the
# MVP server rows' unit tests (paired.rs among
# them), paired/appliance/secure_update builds,
# holger-estate-front's suite both ways, and the
# `sign`-gated evidence tests
#
# KNOWN (2026-10-23): nordisk/holger-ui on this forge is an EMPTY repository, and
# holger-estate-front path-depends on holger-ui's holger-ui-server, so step 5's
# front and estate-front row steps stay red here until holger-ui is mirrored to it.
#
# The siblings are private: the job reads them with `secrets.SIBLINGS_TOKEN` (a
# read-only token of a user that can read nordisk/* and mikronova/*). Without it
# the job says so by name and fails — it never runs a suite against a half
# constellation. The release gate (CLAUDE.md, `cargo xtask gate`, the mock
# estate) stays where it is; this is the per-push net under it.
name: ci
on:
push:
branches: [main]
pull_request:
workflow_dispatch:
env:
CARGO_TERM_COLOR: always
CARGO_BUILD_JOBS: "4"
jobs:
suite:
runs-on: docker
container:
image: rust:1.96-slim-bookworm
timeout-minutes: 240
steps:
- name: tools
run: |
apt-get update && apt-get install -y --no-install-recommends git git-lfs ca-certificates build-essential pkg-config cmake clang
rustup component add rustfmt clippy
rustup target add wasm32-unknown-unknown x86_64-unknown-linux-musl
- uses: actions/checkout@v4
with:
path: holger
lfs: true
# the whole history: the rustfmt ratchet diffs against the push's base
fetch-depth: 0
- name: the sibling checkouts
env:
SIBLINGS_TOKEN: ${{ secrets.SIBLINGS_TOKEN }}
run: |
if [ -z "$SIBLINGS_TOKEN" ]; then
echo "REFUSED [ci-no-siblings] secrets.SIBLINGS_TOKEN is not set: holger path-depends on private sibling repositories, and a suite against a half constellation proves nothing"
exit 1
fi
host="${GITHUB_SERVER_URL#https://}"
for r in nordisk/edda nordisk/Skidbladnir nordisk/monetize nordisk/znippy-zoomies nordisk/facett nordisk/holger-ui mikronova/tunnr mikronova/draupnir mikronova/modgunn; do
for try in 1 2 3; do
git clone --depth 1 "https://ci:${SIBLINGS_TOKEN}@${host}/${r}.git" "$(basename $r)" && break
sleep $((try * 10))
done
test -d "$(basename $r)" || { echo "REFUSED [ci-no-siblings] $r could not be cloned"; exit 1; }
done
# A RATCHET, not a reformat: most of holger predates rustfmt (measured
# 2026-10-22: lib.rs, http.rs, grpc/services.rs and most of server/lib are
# not rustfmt-clean), and one `cargo fmt --all` would rewrite every lane's
# files at once (and reach into the siblings, rustfmt.toml). So every .rs
# file a push ADDS must be rustfmt-clean; the files that were already
# there are formatted when their owner chooses.
- name: the sibling patches (cargo xtask siblings)
working-directory: holger
run: cargo xtask siblings
- name: rustfmt (every added file)
working-directory: holger
env:
BEFORE: ${{ github.event.before }}
run: |
base="$BEFORE"
if [ -z "$base" ] || ! git cat-file -e "$base" 2>/dev/null || [ "$base" = "0000000000000000000000000000000000000000" ]; then
base=$(git merge-base HEAD origin/main 2>/dev/null || git rev-parse HEAD~1)
fi
added=$(git diff --diff-filter=A --name-only "$base" HEAD -- '*.rs')
if [ -z "$added" ]; then echo "no .rs file added since $base"; exit 0; fi
echo "$added" | xargs rustfmt --edition 2021 --check
# Fails on what clippy denies (and on a build that does not compile);
# its warnings are reported, not yet a refusal.
- name: clippy (server library, the shipped planes)
working-directory: holger
run: cargo clippy -p holger-server-lib --features supply-chain,metered --all-targets
- name: the silenced-test guard
working-directory: holger
run: cargo test -p xtask --test silenced_tests_guard
- name: the default and metered suites (cargo xtask test)
working-directory: holger
run: cargo xtask test
- name: server library, supply-chain
working-directory: holger
run: cargo test -p holger-server-lib --features supply-chain --no-fail-fast
- name: server library, supply-chain + metered
working-directory: holger
run: cargo test -p holger-server-lib --features supply-chain,metered --no-fail-fast
- name: the MVP suite (cargo xtask suite-check)
working-directory: holger
run: cargo xtask suite-check