Run CI in the Vercel Build (Why We Dropped GitHub Actions)
Cowpin
10/18/2026

A red GitHub Action does not stop Vercel from shipping. That split was costing money and lying about safety: green deploy, red CI, customers on broken code.
Cowpin now runs the same gate inside the production build on Vercel. If anything
fails, the build command exits non‑zero and the previous deployment keeps servingwww.cowpin.com. Scheduled checks still run on AWS Lambda (synthetic monitor,
price cron, GA digest) — we did not move ops to the Mac desk.
What runs before nuxt build
From apps/web/vercel.json (abridged):
pnpm --filter database db:generate
node scripts/validate-deploy-env.mjs # Zod: DATABASE_URL on production
pnpm deploy-gate:db # drift + read contract + FTS when DB set
pnpm --filter web test:guards # ~540 unit tests + MCP contract + CLI smoke
pnpm --filter web build
validate-deploy-env only enforces secrets on VERCEL_ENV=production; previews
stay loose so contributors are not blocked.
deploy-gate:db catches schema drift against production before traffic moves —
details in deploy safety and the staged-release follow-up
(bad builds can fail checks after compile but before publish).
test:guards is the old “CI suite”: pricing/npm honesty, Pinboard API contract,
privacy default, agent token context, MCP stdio bridge, Zapier lib, mail DNS check.
Why this beats GHA for us
| GitHub Actions | Vercel build gate |
|---|---|
| Bills per minute | Part of deploy you already run |
| Can be red while deploy is green | Failed step = failed build = no promote |
| Another place to babysit | One pipeline: pull → push → gate → (staged) live |
We removed GitHub Actions workflows intentionally — unit smoke and typecheck run in the Vercel build instead of a parallel CI bill.
What we did not put in the build
- Cypress e2e (~330 mocked specs) — needs a browser and dev server; impractical
on Vercel’s Linux runner budget. We run
pnpm test:e2e:money-pathsand friends locally / on AWS CodeBuild for money paths. - Full migration Cypress — real DB + long runtime; scheduled separately.
That trade-off is explicit: the gate is fast, deterministic unit smoke, not every click path.
Copy the pattern
- Pick commands that must pass before customers see the commit.
- Put them in
buildCommand, not a parallel CI job. - Keep slow e2e out of the build; run on a schedule or before risky releases.
- Add a second layer after build if you need it (we use staged publish + Lambda checks).
Building on Cowpin
If you are evaluating the product: import a bookmark export, wire Pinboard-style automation, or connect MCP in Cursor. The deploy gate is how we keep that API stable without a separate CI theater.