commit d37c6289137cc9ab2fb068f9e633d3ea779caddb from: isaac date: Sat Jun 27 01:08:05 2026 UTC add clean-check pipeline: make check = clean-room build + full regress Wipes all build artifacts, does a fresh DEFAULT build, runs every regress suite from scratch, exits non-zero on any failure. This is the canonical verification step. Incremental builds bit us twice: a stale in-tree binary, and an FUGU_DEBUG build left in src/ that dies under pledge and hangs chat/compact/tui. Wired as the make check target, shipped in the distfile, and documented in AGENTS.md (Testing). commit - 36ff1dbc2ebdbcd1ec00a70eeb4a3f5382e195cf commit + d37c6289137cc9ab2fb068f9e633d3ea779caddb blob - 5d698d507c141ae6341126006fb465c715709410 blob + c6e43f01290a4b45639b4af3b288fe98541f8991 --- AGENTS.md +++ AGENTS.md @@ -13,3 +13,13 @@ Five canonical roles, default strings (`needs-triage`, ### Domain docs Single-context: one `CONTEXT.md` and one `docs/adr/` at the repo root (created lazily). See `docs/agents/domain.md`. + +## Testing + +### Clean-room builds (the verification step) + +Verify every change with **`make check`** (which runs `./clean-check`), not an incremental `make`. It wipes all build artifacts, does a fresh **default** build, and runs every regress suite from scratch, exiting non-zero if the build or any suite fails. + +Use it on every rebuild you intend to trust. Incremental builds bit this project twice: a stale in-tree binary, and an `FUGU_DEBUG=1` build left in `src/` — which dies under `pledge(2)` and hangs `chat`/`compact`/`tui` (only those three exec the in-tree binaries; the rest compile their own copy into `regress//obj/`). A clean-room run sidesteps both. See `.scratch/regress-debug-binary-gotcha`. + +Each suite is also runnable standalone: `make -C regress/ regress`. Suites self-abort after a 15s alarm rather than hanging. blob - 7ac86ed774c4324a94572ea3a4703c4bdd0aa43b blob + e1a73701b6efa347e8a11093b00cbd1a9242c56e --- Makefile +++ Makefile @@ -10,6 +10,13 @@ SUBDIR= src .include +# Clean-room build + full regress: the canonical verification step. Wipes all +# build artifacts, does a fresh DEFAULT build, runs every suite from scratch. +# Fails non-zero on any build or test failure. See ./clean-check. +.PHONY: check +check: + @sh ${.CURDIR}/clean-check + # Package the working tree into the source distfile the port consumes: a clean # ${DISTNAME}.tar.gz (top directory ${DISTNAME}/, no build artifacts) written to # ${DISTDIR}. Afterwards, in the port: `make makesum` to refresh distinfo, then @@ -19,8 +26,8 @@ SUBDIR= src dist: rm -rf ${DISTNAME} mkdir ${DISTNAME} - pax -rw LICENSE Makefile README.md docs etc man regress run-fugu src \ - ${DISTNAME} + pax -rw LICENSE Makefile README.md docs etc man regress run-fugu \ + clean-check src ${DISTNAME} find ${DISTNAME} \( -name '*.o' -o -name '*.d' \) -exec rm -f {} + find ${DISTNAME} -type d -name obj -exec rm -rf {} + find ${DISTNAME}/regress -type f -name '*_test' -exec rm -f {} + blob - /dev/null blob + dfd805bd0cc28260c79fa613cb14b33e7391b828 (mode 755) --- /dev/null +++ clean-check @@ -0,0 +1,53 @@ +#!/bin/sh +# +# clean-check -- clean-room build and full regress run. +# +# The canonical "did I break anything" check: wipe every build artifact, do a +# fresh DEFAULT build, then run every regress suite from scratch. Prefer this +# over incremental `make` when verifying a change -- it sidesteps the two traps +# this project hit with incremental builds: a stale in-tree binary, and an +# FUGU_DEBUG=1 build left in src/ (which dies under pledge(2), hanging +# chat/compact/tui). See .scratch/regress-debug-binary-gotcha. +# +# Exits 0 only if the build is clean and every suite passes. + +set -u +cd "$(dirname "$0")" || exit 1 + +echo '== clean: removing all build artifacts ==' +if [ -d .git ]; then + git clean -fdX +else + find . \( -name '*.o' -o -name '*.d' -o -name '*.core' \) -delete + find . -type d -name obj -prune -exec rm -rf {} + + rm -f src/parent/parse.c src/parent/parse.h \ + regress/parse/parse.c regress/parse/parse.h + rm -f src/parent/fugu src/ui/fugu-ui src/net/fugu-net \ + src/exec/fugu-exec src/fetch/fugu-fetch + rm -f regress/*/*_test +fi + +echo '== build: src (DEFAULT flavor -- FUGU_DEBUG breaks chat/compact/tui) ==' +if ! ( cd src && make ); then + echo 'clean-check: BUILD FAILED' >&2 + exit 1 +fi + +echo '== regress: every suite from clean ==' +fail='' +for mk in regress/*/Makefile; do + d=${mk%/Makefile} + s=${d#regress/} + printf '\n--- %s ---\n' "$s" + if ! ( cd "$d" && timeout -k 5 60 make regress ); then + fail="$fail $s" + fi +done + +echo +if [ -z "$fail" ]; then + echo 'clean-check: PASS -- all suites green' +else + echo "clean-check: FAIL --$fail" >&2 + exit 1 +fi