diff --git a/server/deploy.sh b/server/deploy.sh index 4612c3b..9874788 100755 --- a/server/deploy.sh +++ b/server/deploy.sh @@ -28,6 +28,17 @@ REMOTE_DIR=/root/behavision PUBLIC=https://mcp.loyaly.ai SSH=(ssh -i "$KEY" -o BatchMode=yes -o ConnectTimeout=10 "$HOST") +# Go is not always on an interactive shell's PATH - a Homebrew or tarball +# install lands in a directory that .zprofile adds but a script does not +# inherit, so this failed at step 1 with "go: command not found" on the very +# machine it was written on. Found the only way it could be: by somebody +# running it. A deploy that needs the operator to fix their environment first +# is a deploy that gets skipped. +for d in "$HOME/go/bin" /usr/local/go/bin /opt/homebrew/bin; do + [ -x "$d/go" ] && case ":$PATH:" in *":$d:"*) ;; *) PATH="$PATH:$d";; esac +done +command -v go >/dev/null || { echo "go not found - install it or add it to PATH" >&2; exit 1; } + VERSION=$(git describe --tags --always --dirty) case "$VERSION" in *-dirty) echo "refusing to deploy uncommitted changes ($VERSION)" >&2; exit 1;; esac @@ -65,7 +76,33 @@ step "6. Switch" "${SSH[@]}" "cd $REMOTE_DIR && docker compose up -d --no-build --no-deps backend && sleep 4 && docker logs --tail 15 behavision-backend" step "7. Verify over $PUBLIC" -for p in /healthz /api/admin/clients /api/team /api/visits /api/cameras; do - printf ' %-20s %s\n' "$p" "$(curl -s -o /dev/null -w '%{http_code}' -m 15 "$PUBLIC$p")" +# 401 is a PASS, and that distinction is the whole point of this step. An +# unauthenticated call to a route that EXISTS is refused; a route the binary +# never registered is a 404. So this proves the routing rather than the auth - +# which is precisely what a deploy gets wrong, and what otherwise surfaces as a +# console showing "Backend integration required" against an API that shipped. +# +# The uuid matches nothing on purpose: the admin drill-down must answer 401 +# with no session, never 404. +NOBODY=00000000-0000-4000-8000-000000000000 +fail=0 +for p in /healthz \ + /api/admin/clients \ + "/api/admin/clients/$NOBODY" \ + "/api/admin/clients/$NOBODY/sites" \ + "/api/admin/clients/$NOBODY/sites/x/cameras" \ + /api/admin/monitoring/summary \ + /api/sales \ + /api/sales/x \ + /api/dashboard/summary \ + /api/team /api/visits /api/cameras; do + code=$(curl -s -o /dev/null -w '%{http_code}' -m 15 "$PUBLIC$p") + case "$code" in + 200|401) verdict="ok" ;; + 404) verdict="MISSING - this binary does not serve that route"; fail=1 ;; + *) verdict="unexpected"; fail=1 ;; + esac + printf ' %-46s %s %s\n' "$p" "$code" "$verdict" done curl -s -m 15 "$PUBLIC/healthz" | head -c 300; echo +[ "$fail" = 0 ] || { echo; echo "VERIFY FAILED - routes above marked MISSING did not ship" >&2; exit 1; }