Skip to content

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/db or packages/shared deploys the Worker.
  • workflow_dispatch allows 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

Terminal window
node scripts/check-secrets.mjs # fails locally; nothing is set
pnpm gate

Notes

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.