@konduktor/deploy-vercel
v0.2.0
Published
Opinionated staging→production Vercel deploy CLI for Wombat projects. Codifies the printf-not-echo env var rule, worktree detection, BUILD_NUMBER injection, env var mirroring, and health verification — so no future consumer rediscovers any of the Vercel d
Downloads
225
Readme
@konduktor/deploy-vercel
Opinionated staging → production Vercel deploy CLI for Wombat projects.
Codifies the deployment lessons the kit has rediscovered across Quoteroo, IDP, Grafto, and Konduktor so that no future consumer has to relearn them:
printf, neverecho— Vercel env var values are passed via stdin byte-exactly. No trailing\n, no shell interpolation, no quoting bugs.- Worktree refusal — refuses to deploy from a
.claude/worktrees/path (worktrees have no.vercel/project.jsonlinkage and silently create orphan projects). - Clean git + main branch — bail if the working tree is dirty or we're not on the expected branch.
BUILD_NUMBERinjection — computesgit rev-list --count HEADlocally (Vercel's build env has a shallow clone and will silently produce the wrong number) and sets it in both preview + production Vercel envs beforevercel deploy.- Build increment check — verifies the local build number is
greater than staging's current
/api/healthbuildNumberto catch "you forgot to pull latest" before you ship a regression. - Env var mirror — optionally copies named secrets from production to preview so staging can use live Stripe / Supabase / etc.
- Deploy + alias + health verify — runs
vercel deploy, aliases the resulting URL tostaging.<domain>, then curls/api/healthand comparesbuildNumber. If it doesn't match, it bails loudly instead of letting you promote a broken build.
Why a package?
Every consumer project used to copy-paste the same ~200 lines of bash and hit the same footguns (mostly #1 and #4 above). Now the rules live in one place with tests pinning the behaviour — update the kit, every consumer benefits on next install.
Install
# Consumers install from the vendored tarball (wombat-kit is a private workspace)
npm install --save-dev file:vendor/wombat-kit-deploy-vercel-*.tgzUsage — CLI
- Create
.wombat-kit.config.mjs(or.ts/.json) at your repo root:
import { defineConfig } from "@konduktor/deploy-vercel/config";
export default defineConfig({
project: "my-app",
apexDomain: "myapp.com",
// Inferred if omitted:
// stagingDomain: "staging.myapp.com"
// productionDomains: ["myapp.com", "www.myapp.com"]
// healthEndpoint: "/api/health"
envVarsToMirror: [
"STRIPE_SECRET_KEY",
"NEXT_PUBLIC_SUPABASE_URL",
"SUPABASE_SERVICE_ROLE_KEY",
],
preflight: {
requireCleanGit: true,
requireMainBranch: true,
mainBranchName: "main",
rejectWorktree: true,
verifyBuildIncrement: true,
},
});- Run the staging deploy:
npx wombat-deploy stagingThis runs the full flow (preflight → BUILD_NUMBER → mirror → deploy → alias → health verify) and prints each step. On success, it prints the staging URL so you can smoke-test it.
Promotion to production is a separate, explicit step and is intentionally
not covered by this package yet — do it manually with npx vercel promote
<deployment-url> once Andre has signed off on staging.
Usage — programmatic
import { deployStaging, defineConfig } from "@konduktor/deploy-vercel";
const config = defineConfig({ /* ... */ });
const result = await deployStaging(config);
console.log(result.stagingUrl, result.buildNumber);All I/O (git, vercel CLI, fetch, fs) is injected via deps so you can
unit-test your wrapper scripts without touching the network.
What's NOT in this package (yet)
- Cloudflare DNS automation for setting up the staging alias the first time. Still a one-shot manual step.
wombat-deploy promote— production promotion is intentionally explicit and manual until the safety story is nailed down.- Bugloop ticket status hooks — the flow that updates in-flight
tickets to
staging/deployed. Lives in@bugloop/nextfor now. - GitHub Actions template — a reusable workflow that wraps this CLI.
These are planned for Stage B once Stage A has shipped at least one consumer (Quoteroo will be the canary).
Testing
pnpm run build
pnpm run testThe test suite pins the printf-not-echo contract explicitly: see
tests/vercel-env.test.ts — any future refactor that lets a value leak
into argv or gets piped through a shell will fail the suite.
