Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ is the hardening knob). — full detail: `docs/src/security/threat-model.md`.
checks (`bash -n`, the `host.sh` dry-run recipe, and — on a Nix+KVM box — `nix flake check` /
`bash tests/boot.sh` / a `--shell` pass for TTY changes); if green, commit without stopping to ask
per item. Surface anything only verifiable on a Nix+KVM box so it gets checked before being
claimed done.
claimed done. `./ci.sh` runs the exact `flake-check.yml` steps locally (it reads their `run:`
scripts straight from the workflow) — the fastest way to reproduce CI before a commit.
- **Definition of done for a behaviour change:** `nix flake check` green **and** a stub-package boot
test asserting the new behaviour under `tcg`/`q35` — plus a human `--shell` pass if it touches the
TTY. Full loop + the fast stub-`claude` pattern: `docs/src/developing/build-test-debug.md`.
Expand Down
43 changes: 43 additions & 0 deletions ci.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#!/usr/bin/env bash
# Local CI — runs the SAME checks as .github/workflows/flake-check.yml by pulling
# each step's `run:` script straight from that workflow, so the command list lives
# in exactly one place. Run before every commit.
#
# Safety: these `run:` scripts execute as your user with NO sandbox. If the workflow
# differs from origin/main (an unreviewed/unexpected change), the commands are shown
# and confirmation is required first — a silent edit to .github can't run behind your
# back. (A compromised origin/main is out of scope: it auto-deploys the docs site to
# GitHub Pages anyway.)
#
# `--inputs-from .` resolves every `nixpkgs#tool` against this flake's locked
# nixpkgs, so the tools are hash-pinned to flake.lock (no unpinned registry fetch).
set -euo pipefail
cd "$(dirname "${BASH_SOURCE[0]}")"

workflow=.github/workflows/flake-check.yml

steps=$(nix run --inputs-from . nixpkgs#yq -- -r \
'.jobs.check.steps[] | select(.run) | "echo; echo \"» \(.name)\"\n\(.run)"' \
"$workflow")

# Gate: if the workflow deviates from the trusted remote, show what runs and confirm.
ref=origin/main
if git rev-parse --verify --quiet "$ref" >/dev/null &&
! git diff --quiet "$ref" -- "$workflow"; then
echo "⚠ $workflow differs from $ref — these commands will run as $(whoami):"
printf '%s\n' "----------------------------------------" "$steps" "----------------------------------------"
[ -t 0 ] || {
echo "refusing to auto-run a modified workflow non-interactively."
exit 1
}
read -rp "Proceed? [y/N] " reply
[ "$reply" = y ] || [ "$reply" = Y ] || {
echo "aborted."
exit 1
}
fi

bash -euo pipefail <<<"$steps"

echo
echo "✓ local CI passed"