From 6fafecd6e4917a356e396a7fed64dd523fb68e9d Mon Sep 17 00:00:00 2001 From: Suriyakumarvijayanayagam Date: Mon, 28 Sep 2026 18:08:48 +0530 Subject: [PATCH] deploy.sh died at step 1 on the machine it was written on "go: command not found". Go sits in a directory the operator's .zprofile adds and a script does not inherit, so the very first step of the deploy failed for a reason having nothing to do with the deploy. Found the only way it could be - by somebody running it - and a deploy that needs the operator to fix their environment before it works is a deploy that gets skipped, which is the failure this script exists to end. It now looks in the three places Go actually lands and says so plainly if it finds none. Step 7 also verified five routes and none of them were the nine that shipped in the last two commits. It checks all of them now, and treats 401 as a PASS on purpose: an unauthenticated call to a route that exists is refused, while a route the binary never registered is a 404. That makes this step prove the ROUTING rather than the auth - which is precisely what a deploy gets wrong, and what otherwise surfaces weeks later as a console reporting "Backend integration required" against an API that had already shipped. A missing route now fails the deploy loudly instead of printing a number nobody reads. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01KGcjxF1cNLcuwc3DAPcnfj --- server/deploy.sh | 41 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) 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; }