Deploy Worker on release with post-deploy smoke test + rollback#24
Deploy Worker on release with post-deploy smoke test + rollback#24sergical wants to merge 1 commit into
Conversation
Deploys the Worker to Cloudflare when a new version is released (on release: published), so production always tracks a released tag rather than raw main — keeping serverInfo.version honest. Also runnable via workflow_dispatch. - deploy.yml: pnpm run deploy (wrangler + Sentry release/sourcemaps, all via env tokens — no interactive login) → wait → smoke test → wrangler rollback if the smoke test fails. - bin/smoke.mjs (+ `pnpm smoke`): MCP initialize handshake against the live /mcp endpoint asserting the worker is up and reports the released version. Requires repo secrets: CLOUDFLARE_API_TOKEN (account-scoped "Edit Cloudflare Workers"), CLOUDFLARE_ACCOUNT_ID, SENTRY_AUTH_TOKEN. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
| if (EXPECTED && serverInfo.version !== EXPECTED) | ||
| fail(`version mismatch: live=${serverInfo.version} expected=${EXPECTED}`); |
There was a problem hiding this comment.
Bug: The server version is hardcoded in src/server.ts, but the smoke test compares it against the dynamic version from package.json, which will cause future deployment failures.
Severity: CRITICAL
Suggested Fix
To prevent future deployment failures, replace the hardcoded version string in src/server.ts. Import the version from package.json directly into src/server.ts so that the server always reports the correct, current version. This ensures the smoke test will pass after a version bump.
Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.
Location: bin/smoke.mjs#L69-L70
Potential issue: The server's version is hardcoded as "0.4.0" in `src/server.ts`.
However, the smoke test in `bin/smoke.mjs` dynamically reads the expected version from
`package.json`. While both versions currently match, any future update to the
`package.json` version for a new release will cause a mismatch. This will lead the smoke
test to fail with a "version mismatch" error, consequently breaking the automated
deployment pipeline for all subsequent releases.
Also affects:
src/server.ts
Did we get this right? 👍 / 👎 to inform future reviews.
There was a problem hiding this comment.
Validated as a false positive — no change needed.
src/server.ts and package.json don't drift: bin/bump-version.sh (added in #23, craft's preReleaseCommand) seds the released version into src/server.ts on every release, with a grep -q guard that fails the release loudly if the substitution doesn't take. deploy.yml triggers on the release tag, so the checked-out commit always has server.ts == package.json (confirmed: both 0.4.0 on main today).
So the smoke test comparing the live serverInfo.version to package.json is an intentional end-to-end check on that sync — if it ever broke, the smoke fails and the deploy rolls back. That's the guard working as designed, not a latent failure.
The suggested fix (import the version from package.json into server.ts) is the approach we deliberately rejected in #23: the same createServer() is bundled into the Cloudflare Worker, which has no filesystem, and a JSON import breaks the tsc rootDir layout. The build-time sed is what works for both targets.
Automates Worker deployment so production tracks released versions — fixing the gap that left prod on
0.2.0while we'd released0.3.1/0.4.0.What
.github/workflows/deploy.yml— triggers onrelease: published(craft's GitHub Release) andworkflow_dispatch. Steps:pnpm run deploy→ wait → smoke test →wrangler rollbackif the smoke fails.bin/smoke.mjs(+pnpm smoke) — MCPinitializehandshake against the live/mcpendpoint, asserting the worker is reachable and reports the just-released version. Verified locally: passes on0.4.0, fails on a mismatch.Why release-triggered (not on-main)
Deploy-on-main would ship unreleased commits while
serverInfo.versionstayed frozen at the last release — the drift we just fixed, reintroduced. Triggering on the release tag keeps prod == a released version and the smoke test asserts exactly that. (sentry-mcpdeploys continuously on main + canary; we don't have canary infra and prefer version-pinned deploys here.)Required repo secrets (add before enabling)
CLOUDFLARE_API_TOKEN— account-scoped "Edit Cloudflare Workers" (CF tokens can't scope to a single Worker; account-scoped is the tightest).CLOUDFLARE_ACCOUNT_IDSENTRY_AUTH_TOKEN— for the release + sourcemap upload.Follow-up (not in this PR)
pnpm deployruns thedeployscript despitedeploybeing a pnpm builtin — an easy footgun (evenpnpm deploy --helpruns it). Consider renaming the script todeploy:cf. The workflow uses the explicitpnpm run deploy.🤖 Generated with Claude Code