From d4a0637fd0818cf71055df6fa067556e5611f734 Mon Sep 17 00:00:00 2001 From: Renaud Laborbe <150821561+BluegReeno@users.noreply.github.com> Date: Sat, 25 Jul 2026 20:10:57 +0200 Subject: [PATCH] docs(operations): deploy prerequisites learned the hard way MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three things §2 did not say, each of which cost a failed deploy on 2026-07-25: - direnv does not fire in a non-interactive shell, so a scripted `make deploy` silently uses the personal account and 403s. - deno.lock is version 5; CLI < ~2.9x cannot bundle it. Says not to regenerate the lockfile, which pins what ships to production. - neither `make test` nor CI runs the hal-mcp unit tests (#78) — documents the command that does, and why SUPABASE_URL must be the real project URL. Refs #78 Co-Authored-By: Claude Opus 5 --- docs/operations.md | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/docs/operations.md b/docs/operations.md index f7f43f1..932ea2f 100644 --- a/docs/operations.md +++ b/docs/operations.md @@ -105,6 +105,34 @@ The token is loaded per-directory by `direnv` from `/Users/renaud/Projects/hal/. supabase projects list # the row shows ● in the LINKED column when authed + visible ``` +**direnv does not fire in a non-interactive shell.** An agent, a script, a CI runner or anything +driving `make deploy` without an interactive `cd` gets **no token at all** and falls through to +the personal account — which fails with a 403 that reads like a permissions problem rather than a +missing token. Source it explicitly first, exactly as Path B does: + +```bash +source /Users/renaud/Projects/hal/.envrc +``` + +### CLI version prerequisite + +`supabase/functions/hal-mcp/deno.lock` is **lockfile version 5** (since `c19bec9`, June 2026). +The Deno bundled in older CLI releases cannot read it, and the deploy dies *after* auth succeeds: + +``` +Error: Failed reading lockfile at '.../deno.lock' +Caused by: Unsupported lockfile version '5'. Try upgrading Deno or recreating the lockfile +``` + +**Do not delete or regenerate `deno.lock` to work around this** — it pins the exact dependency +versions that ship to production. Upgrade the CLI instead (2.72.7 → 2.109.1 fixed it on +2026-07-25): + +```bash +brew trust --formula supabase/tap/supabase # Homebrew now refuses untrusted taps +brew upgrade supabase +``` + ### Pre-deploy check (non-negotiable) `supabase/functions/hal-mcp/index.ts` **must** end with: @@ -123,6 +151,20 @@ an unauthenticated call must be rejected (401/400/405) by a live function. `make offline counterpart (deno type-check both edge functions + offline pytest) for pre-deploy sanity before ever reaching the live probe. +⚠️ **`make test` does not run the `hal-mcp` unit tests, and neither does CI** (see #78). It +type-checks. To actually exercise `index.test.ts` before a deploy — worth doing whenever the +deploy carries a behavioural change: + +```bash +cd supabase/functions/hal-mcp +SUPABASE_URL="https://zgkvbjqlvebttbnkklpo.supabase.co" \ +SUPABASE_SECRET_KEYS='{"default":"test-admin"}' \ +deno test --allow-all index.test.ts # ok | 63 passed | 0 failed +``` + +`SUPABASE_URL` must be the **real** project URL: four OAuth-metadata tests assert the exact +`resource_metadata` value, so a placeholder fails those four while the other 59 pass. + ### Path A — deploy from `main` (the normal case) ```bash