The node-engine writes those as root after checking the path, and the agent account owns its home and could swap a link in between (hq ADR 0266). No module does it today; this keeps a future one from opening the gap.
101 lines
6.0 KiB
Bash
Executable File
101 lines
6.0 KiB
Bash
Executable File
#!/bin/sh
|
|
# mesh-check-toolchain: go
|
|
# mesh-check-also: typescript merge-check-typescript.sh
|
|
#
|
|
# The catalogue's own check (novox/hq ADR 0237 as amended): the second layer of a pull request's merge
|
|
# check, `mesh/repo-check`, run by the build seat in the mesh's Go toolchain.
|
|
#
|
|
# The gate — the manifests the change touches through the running controller's module check, every machine
|
|
# of the facts snapshot composed with them and validated by the node-engine's own validator, the replays
|
|
# against this tree — is the build seat's first layer (`mesh/merge-gate`), run because the mesh's module
|
|
# graph builds these modules from here. It is not repeated here. This is the repository's own:
|
|
#
|
|
# 1. every manifest through the controller's module check, so one module's change cannot leave another
|
|
# it shares a rule with refused (MESH_GATE is the controller the mesh runs) — and the count of
|
|
# long-running resources without `health` held to the number in health-undeclared, which only goes down;
|
|
# 2. the Go tests of every module the change touches that has them, under the race detector when the
|
|
# toolchain has a C compiler — and a module whose dependencies cannot be fetched here is said as not
|
|
# tested, never passed silently. A module written in TypeScript is type-checked and tested by
|
|
# merge-check-typescript.sh, declared above, in the TypeScript toolchain (novox/hq issues 302, 311);
|
|
# 3. the words (novox/hq ADR 0244): no word the glossary retired for the tools, as copied in
|
|
# retired-words, in any text a module's tools can show an agent — every string in its own code that is
|
|
# not a test, and every description in its manifest. Run over every module, not only the touched ones,
|
|
# so a word newly retired is found everywhere it stands. The check's own test runs first.
|
|
# 4. the paths (novox/hq ADR 0260): no module names a path under /run, /var/lib, /usr/local/lib or /etc
|
|
# that another module's manifest places — modules talk over the bus, not through each other's files.
|
|
# Over every module; checks/paths/shared and checks/paths/known narrow it, and known only shrinks.
|
|
# 5. the agent's home (novox/hq ADR 0266): no module unpacks an archive, or writes into a file, under
|
|
# ${machine:agent-home} — the node-engine does both after checking the path, and the agent account owns
|
|
# that home and could swap a link in between.
|
|
set -eu
|
|
|
|
(cd checks/words && go test -count=1 . && go run . ../..)
|
|
# The agent's home (novox/hq ADR 0266): no archive, and no file written into, under it.
|
|
(cd checks/agenthome && go test -count=1 . && go run . ../..)
|
|
# The lists that narrow the paths check may not grow unseen: the base branch's copies are what they are
|
|
# judged against (MESH_CHECK_BASE, main when unset), read from the clone the check runs in.
|
|
base_lists=""
|
|
base_ref="origin/${MESH_CHECK_BASE:-main}"
|
|
if git rev-parse --verify --quiet "$base_ref^{commit}" >/dev/null 2>&1 &&
|
|
git cat-file -e "$base_ref:checks/paths/known" 2>/dev/null && git cat-file -e "$base_ref:checks/paths/shared" 2>/dev/null; then
|
|
base_lists=$(mktemp -d)
|
|
git show "$base_ref:checks/paths/known" >"$base_lists/known"
|
|
git show "$base_ref:checks/paths/shared" >"$base_lists/shared"
|
|
fi
|
|
(cd checks/paths && go test -count=1 . && if [ -n "$base_lists" ]; then go run . -base "$base_lists" ../..; else go run . ../..; fi)
|
|
|
|
if [ -n "${MESH_GATE:-}" ]; then
|
|
checked=$("$MESH_GATE" module check modules/*/module.json) || { printf '%s\n' "$checked"; exit 1; }
|
|
# **The count only goes down** (novox/hq ADR 0240 rule 8): the long-running resources that do not say how
|
|
# they are ready, as the controller counts them, against the number kept in health-undeclared. A change
|
|
# that raises it fails; one that lowers it writes the new number there, so it can never rise again.
|
|
kept=$(sed -n 's/^\([0-9][0-9]*\).*/\1/p' health-undeclared | head -n 1)
|
|
counted=$(printf '%s\n' "$checked" | sed -n 's/^long-running resources without health: \([0-9][0-9]*\)$/\1/p')
|
|
if [ -z "$counted" ]; then
|
|
echo "NOT COUNTED: the controller the mesh runs is older than the count of resources without health (ADR 0240 Phase B)"
|
|
elif [ "$counted" -gt "$kept" ]; then
|
|
echo "the long-running resources without health rose from $kept to $counted: declare how each new one is ready (ADR 0240 rule 8)"
|
|
exit 1
|
|
elif [ "$counted" -lt "$kept" ]; then
|
|
echo "the long-running resources without health fell from $kept to $counted: write $counted in health-undeclared, so the count cannot rise again"
|
|
exit 1
|
|
else
|
|
echo "long-running resources without health: $counted, as kept"
|
|
fi
|
|
else
|
|
echo "NOT CHECKED: no controller was built beside this check, so the manifests were not read by one"
|
|
fi
|
|
|
|
race=""
|
|
if command -v gcc >/dev/null 2>&1; then race="-race"; else echo "NOT RACE-CHECKED: the toolchain holds no C compiler"; fi
|
|
|
|
# The modules the change reaches are the controller's planner's answer (MESH_CHECK_MODULES, hq ADR 0238):
|
|
# a module by its name, a new one by its directory. By hand, without it, the directories the changed files
|
|
# are in.
|
|
if [ -n "${MESH_CHECK_MODULES:-}" ]; then
|
|
touched=$(printf '%s\n' "$MESH_CHECK_MODULES" | tr ',' '\n' | sed -e 's#^modules/##' -e '/\//d' | sort -u)
|
|
else
|
|
touched=$(printf '%s\n' "${MESH_CHECK_CHANGED:-}" | tr ',' '\n' | sed -n 's#^modules/\([^/]*\)/.*#\1#p' | sort -u)
|
|
fi
|
|
for m in $touched; do
|
|
[ -d "modules/$m" ] || continue
|
|
if [ ! -f "modules/$m/go.mod" ]; then
|
|
[ -f "modules/$m/package.json" ] && echo "modules/$m is TypeScript: merge-check-typescript.sh type-checks and tests it"
|
|
continue
|
|
fi
|
|
if ! (cd "modules/$m" && GOPRIVATE=git.novox.be go mod download >/dev/null 2>&1); then
|
|
echo "NOT TESTED: modules/$m — its dependencies cannot be fetched by the build seat"
|
|
continue
|
|
fi
|
|
echo "testing modules/$m"
|
|
unformatted=$(cd "modules/$m" && gofmt -l .)
|
|
if [ -n "$unformatted" ]; then
|
|
echo "modules/$m is not gofmt'd: $unformatted"
|
|
exit 1
|
|
fi
|
|
cgo=0
|
|
[ -n "$race" ] && cgo=1
|
|
(cd "modules/$m" && CGO_ENABLED=$cgo GOPRIVATE=git.novox.be go vet ./... &&
|
|
CGO_ENABLED=$cgo GOPRIVATE=git.novox.be go test $race -count=1 ./...)
|
|
done
|