WI-022: Deploy the API, and prove the secrets are real
WI-022: Deploy the API, and prove the secrets are real
Two gaps, both recorded earlier and both the same shape: something reports success without evidence.
Gap one — the API was never deployed
Docs deploy on merge. The API did not, so wrangler deploy was a manual step nobody would remember and the running Worker could drift from main with nothing noticing.
Gap two — a secret can be empty and look configured
gh secret list prints a name and a timestamp whether the value is forty characters or zero. NEON_API_KEY was stored empty for a day: every surface reported it present, and the only thing that revealed the truth was a job that tried to use it.
That incident produced a line in the definition of done — “each secret is proven non-empty by a job that consumes it” — which nothing enforced until now.
No pull request deploys for the API
The docs deploy on PRs and get a preview URL. The API deliberately does not.
A preview Worker still binds to the real Hyperdrive configuration, and therefore to the production database. Today that means a preview could read live data; after WI-030 it could write to it. Docs are static and have no such reach.
Giving the API previews needs a second Hyperdrive pointing at a Neon branch. That is a decision with a cost, not a default, and it is not this item.
A deploy that succeeds is not an API that works
wrangler deploy proves the upload worked. It says nothing about whether Hyperdrive points at a reachable database with a current password — which is exactly the state this project has been in since the Neon password was rotated.
So the deploy is followed by a smoke test that fails on:
- no response at all, after five attempts with backoff for cold start
"database":"unreachable"— the stale-credential case, which otherwise looks like a green deploy- a search returning nothing, which means reachable but unseeded
A missing CLERK_JWT_KEY is a warning, not a failure. The API is useful for public reads without it, and blocking a deploy over it would be worse than saying so.
Definition of done
- Merging a change under
apps/api,packages/dborpackages/shareddeploys the Worker. -
workflow_dispatchallows a redeploy after a secret or Hyperdrive change, without an empty commit. - The deploy is smoke-tested, and a stale Hyperdrive credential fails it.
- No PR deploys the API.
- Every required secret is checked by a job that consumes it.
- A truncated or malformed value fails, not only an absent one.
- The check never prints a secret value.
- Each check proven able to fail.
- Gate green.
Verification
node scripts/check-secrets.mjs # fails locally; nothing is setpnpm gateNotes
Secrets set with wrangler secret put survive a deploy, so CLERK_JWT_KEY is not re-sent by the workflow — and could not be, since CI does not have it. That is the right shape: the key reaches Cloudflare from a human’s terminal and never passes through GitHub.
The smoke logic was exercised before shipping, against a local API in four states: healthy, nothing listening, database reachable but unseeded, and healthy again. Shipping unproven bash into a workflow that only runs on main would mean discovering its bugs by breaking a deploy.
The secret check reports length and shape, never a value. A 32-character account id that is not hex is caught, because a truncated or mangled paste looks exactly like a working one until a deploy fails.