Deploying
How a commit reaches production, how to roll back, and how to read the logs.
The Path to Production
- A commit lands on
mainin GitHub. - Vercel builds it with
next build. A type error fails the build and production is untouched. - When the build passes, Vercel switches production to it. There is no staging environment; every push to
mainis a production deploy.
The docs site is a second Vercel project with its root directory set to docs-site. It deploys from the same pushes.
Before You Push
npx tsc --noEmit
npm test
git diff --cached -U0 | grep -P "\x{2014}|\x{2013}" # must print nothing
git fetch origin && git rebase origin/main
git push origin HEAD:mainIf the push is rejected, somebody else pushed first. Rebase again; never force.
Rolling Back
Vercel, Deployments, pick the previous successful deploy, Promote to Production. It takes under a minute and needs no code change. Fix forward afterwards.
Reading Logs
- Build logs under the deployment.
- Runtime logs under Logs, filterable by route or by "error". Scheduled jobs log what they did at the end of each run.
- Errors with a stack trace in Sentry.
Environment Variables
Changing a value in Vercel does not change the running deploy. Redeploy (Deployments, the latest, Redeploy) after changing one. NEXT_PUBLIC_ variables are baked into the build. See Environment Variables.
Scheduled Jobs
vercel.json holds the daily cron schedule. Adding a job means adding a route under app/api/cron/ that checks the bearer token, and an entry in vercel.json. The Hobby plan allows daily jobs only. See Scheduled Jobs.
Database Changes
A migration is applied to Supabase by hand before the code that needs it is deployed, so the new code never runs against the old schema. See Database and Migrations.
A Note on the Blocked Deploy
Each push also triggers a build in a personal Vercel scope that shows "Deployment was blocked". That scope is not production and the message can be ignored. Production is the project under the team scope with www.impacthubos.com attached.

