- Dankserver stack: RomM, Copyparty, Calibre-Web, node-exporter - Dankclaw stack: Gluetun VPN (SearXNG tunnel), SearXNG+Valkey, ComfyUI (CPU backend), OpenWebUI, Hermes, Gitea+Postgres (migrated), Caddy reverse proxy, Grafana+Prometheus+Loki+Alloy observability - Caddyfiles with .local hostname convention and basicauth homepage - bind-mount storage policy, no named volumes - deploy.sh mirroring vllmScripts git workflow (push -> pull -> restart -> health) - docs/ Obsidian vault: per-service docs from frank-default-small research subagents (promtail EOL -> Alloy; gitea SECRET_KEY preservation; ComfyUI --cpu) - bats test suite at 6 seams — 22 tests green
42 lines
1.6 KiB
Bash
42 lines
1.6 KiB
Bash
#!/usr/bin/env bats
|
|
# Seam: environment variable consistency and secret hygiene.
|
|
# Every ${VAR} referenced in a compose.yaml or Caddyfile must be defined in the
|
|
# matching .env.example. .env.example files must contain only placeholders, and
|
|
# the live gitea database password must never appear in tracked files.
|
|
|
|
load helpers
|
|
|
|
@test "every compose.yaml has a sibling .env.example" {
|
|
while IFS= read -r f; do
|
|
local envfile
|
|
envfile="$(dirname "$f")/.env.example"
|
|
[ -f "$envfile" ] || { echo "missing $envfile for $f"; return 1; }
|
|
done < <(find "$REPO_ROOT" -name 'compose.yaml' -not -path '*/.git/*' | sort)
|
|
}
|
|
|
|
@test "every \${VAR} in compose.yaml is defined in the sibling .env.example" {
|
|
while IFS= read -r f; do
|
|
local envfile
|
|
envfile="$(dirname "$f")/.env.example"
|
|
while IFS= read -r var; do
|
|
[ -z "$var" ] && continue
|
|
if ! env_vars_defined "$envfile" | grep -qx "$var"; then
|
|
echo "$f references \${$var} but $envfile does not define it"
|
|
return 1
|
|
fi
|
|
done < <(env_vars_in "$f")
|
|
done < <(find "$REPO_ROOT" -name 'compose.yaml' -not -path '*/.git/*' | sort)
|
|
}
|
|
|
|
@test ".env.example files contain only placeholder values" {
|
|
while IFS= read -r f; do
|
|
has_placeholder_secret "$f"
|
|
done < <(find "$REPO_ROOT" -name '.env.example' -not -path '*/.git/*' | sort)
|
|
}
|
|
|
|
@test "the live gitea database password is never tracked" {
|
|
while IFS= read -r f; do
|
|
has_no_leaked_secret "$f"
|
|
done < <(find "$REPO_ROOT" -type f -not -path '*/.git/*' -not -path '*/.pi-subagents/*' | sort)
|
|
}
|