NODEDC_PLATFORM/infra/scripts/check-local-test-system.sh

187 lines
5.2 KiB
Bash
Executable File

#!/usr/bin/env sh
set -eu
SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
PLATFORM_ROOT=$(CDPATH= cd -- "$SCRIPT_DIR/../.." && pwd)
INFRA_DIR="$PLATFORM_ROOT/infra"
ASSISTANT_DIR="$PLATFORM_ROOT/services/ai-workspace-assistant"
HUB_DIR="$PLATFORM_ROOT/services/ai-workspace-hub"
ONTOLOGY_DIR="$PLATFORM_ROOT/services/ontology-core"
COMPOSE_ENV="${COMPOSE_ENV:-$INFRA_DIR/.env}"
if [ ! -f "$COMPOSE_ENV" ]; then
COMPOSE_ENV="$INFRA_DIR/.env.example"
fi
REQUIRE_RUNTIME="${REQUIRE_RUNTIME:-0}"
REQUIRE_REMOTE_WORKER_RELAY="${REQUIRE_REMOTE_WORKER_RELAY:-0}"
passed=0
failed=0
skipped=0
section() {
printf '\n== %s ==\n' "$1"
}
pass() {
passed=$((passed + 1))
printf 'PASS %s\n' "$1"
}
fail() {
failed=$((failed + 1))
printf 'FAIL %s\n' "$1" >&2
}
skip() {
skipped=$((skipped + 1))
printf 'SKIP %s\n' "$1"
}
run_cmd() {
label="$1"
shift
printf '\n$ %s\n' "$label"
set +e
"$@"
status=$?
set -e
if [ "$status" -eq 0 ]; then
pass "$label"
else
fail "$label (exit $status)"
fi
}
run_sh() {
label="$1"
dir="$2"
command="$3"
printf '\n$ %s\n' "$label"
set +e
(cd "$dir" && sh -lc "$command")
status=$?
set -e
if [ "$status" -eq 0 ]; then
pass "$label"
else
fail "$label (exit $status)"
fi
}
run_sh_quiet() {
label="$1"
dir="$2"
command="$3"
output_file=$(mktemp "${TMPDIR:-/tmp}/nodedc-check.XXXXXX")
printf '\n$ %s\n' "$label"
set +e
(cd "$dir" && sh -lc "$command") > "$output_file" 2>&1
status=$?
set -e
if [ "$status" -eq 0 ]; then
pass "$label"
rm -f "$output_file"
else
cat "$output_file"
rm -f "$output_file"
fail "$label (exit $status)"
fi
}
section "Static syntax"
run_cmd "Hub server syntax" node --check "$HUB_DIR/src/server.mjs"
run_cmd "Assistant server syntax" node --check "$ASSISTANT_DIR/src/server.mjs"
run_cmd "Ontology MCP server syntax" node --check "$ONTOLOGY_DIR/src/mcp-server.mjs"
run_cmd "Local environment safety checker syntax" node --check "$INFRA_DIR/scripts/check-local-environment-safety.mjs"
run_sh "Shell scripts syntax" "$PLATFORM_ROOT" \
"sh -n infra/scripts/init-dev-env.sh infra/scripts/check-local-test-system.sh infra/scripts/check-ai-workspace-topology.sh infra/scripts/check-ai-workspace-config-contract.sh infra/scripts/check-ai-workspace-release-gates.sh"
if command -v bash >/dev/null 2>&1; then
run_sh "Synology hub-only deploy scripts syntax" "$PLATFORM_ROOT" \
"bash -n infra/synology/sync-ai-hub-relay.sh infra/synology/apply-ai-hub-relay.sh"
else
skip "Synology hub-only deploy scripts syntax (bash not installed)"
fi
section "Environment contracts"
run_cmd "Local environment safety" node "$INFRA_DIR/scripts/check-local-environment-safety.mjs"
run_cmd "AI Workspace config contract" "$INFRA_DIR/scripts/check-ai-workspace-config-contract.sh"
section "Compose boundary"
if command -v docker >/dev/null 2>&1; then
compose_tmp=$(mktemp "${TMPDIR:-/tmp}/nodedc-local-compose.XXXXXX")
if docker compose --env-file "$COMPOSE_ENV" -f "$INFRA_DIR/docker-compose.dev.yml" config > "$compose_tmp"; then
pass "Local compose config renders"
else
fail "Local compose config renders"
fi
rm -f "$compose_tmp"
if grep -Fq "env_file:" "$INFRA_DIR/docker-compose.dev.yml"; then
fail "Local compose must not inject the full .env into services"
else
pass "Local compose uses explicit service environment only"
fi
else
skip "Docker compose config render (docker not installed)"
fi
section "AI Workspace smokes"
run_sh_quiet "Assistant run-profile smoke" "$ASSISTANT_DIR" "npm run smoke:run-profile"
run_sh_quiet "AI Hub Ontology MCP proxy smoke" "$HUB_DIR" "npm run smoke:ontology-mcp-proxy"
if [ -d "$ONTOLOGY_DIR" ]; then
run_sh_quiet "Ontology assistant caller smoke" "$ONTOLOGY_DIR" "npm run smoke:assistant-caller"
run_sh_quiet "Ontology MCP smoke" "$ONTOLOGY_DIR" "npm run smoke:mcp"
else
skip "Ontology assistant caller smoke (missing $ONTOLOGY_DIR)"
fi
section "Runtime classification"
topology_tmp=$(mktemp "${TMPDIR:-/tmp}/nodedc-topology.XXXXXX")
set +e
(cd "$PLATFORM_ROOT" && infra/scripts/check-ai-workspace-topology.sh) > "$topology_tmp"
topology_status=$?
set -e
cat "$topology_tmp"
classification=$(awk -F= '/^classification=/{print $2; exit}' "$topology_tmp")
rm -f "$topology_tmp"
if [ "$topology_status" -eq 0 ]; then
pass "Runtime topology classified as ${classification:-unknown}"
else
fail "Runtime topology classification failed (exit $topology_status)"
fi
if [ "$REQUIRE_RUNTIME" = "1" ]; then
case "$classification" in
true-local-e2e|tunnel-local-e2e|local-remote-worker-relay)
pass "Runtime requirement satisfied"
;;
*)
fail "Runtime requirement not satisfied (classification=${classification:-unknown})"
;;
esac
fi
if [ "$REQUIRE_REMOTE_WORKER_RELAY" = "1" ]; then
case "$classification" in
local-remote-worker-relay)
pass "Remote worker relay requirement satisfied"
;;
*)
fail "Remote worker relay requirement not satisfied (classification=${classification:-unknown})"
;;
esac
fi
section "Git hygiene"
run_sh "Platform diff hygiene" "$PLATFORM_ROOT" "git diff --check"
section "Summary"
printf 'passed=%s failed=%s skipped=%s\n' "$passed" "$failed" "$skipped"
if [ "$failed" -ne 0 ]; then
exit 1
fi