Conditioning Vercel deployments on successful CircleCI workflows
The way Vercel connects to GitHub is kinda mind-blowing. Getting started is so simple that, before you even google "how to deploy", your app is already live.
That first experience is amazing! No doubt, this ease of use is why I keep choosing Vercel for every new API I build. But if you're working solo and committing straight to main, you might soon run into an issue: magic in excess can be a problem.
One of the first things I do when kicking off a new project is setting up its "skeleton". Without a skeleton, our body wouldn't be able to stand upright. I don't think it's any different for a web application. Without Continuous Integration (CI) and Continuous Deployment (CD), things will soon fall apart. And this is where Vercel's magic approach becomes an issue. Even if you have a Continuous Integration service running checks on every commit, Vercel doesn’t care — it deploys instantly with every new commit to the main branch, completely ignoring your CI tests.
To fix this, we need to disable Vercel’s auto-deploy feature and let our CI tool — CircleCI in this case — handle deployments.
Assuming you’ve already connected your repo to Vercel, here’s what you need to do to stop auto-deployments and only deploy when your CI pipeline succeeds:
- Disable auto-deploy in
vercel.json
- Create a Deploy Hook in Vercel
- Add a deploy job to your CircleCI config
Vercel JSON
In your vercel.json
, add the following code to turn off auto-deployments:
{
// existing config
+ "git": {
+ "deploymentEnabled": false
+ }
}
Deploy Hook
Log in to Vercel and go to your project settings. Click on Git in the left-hand menu and scroll down to the Deploy Hooks section. Create a new hook by giving it a name and specifying which branch it should trigger a deployment for.
Once the hook is created, Vercel will generate a unique URL. Treat this URL as a secret — never hardcode it in your project!
Deploy Hook settings in Vercel
CircleCI
Finally, add a new job to your CircleCI config:
deploy:
<<: *default_env
steps:
- attach_workspace:
at: ~/app
- run:
name: Deploy to Vercel
command: curl -X POST $VERCEL_DEPLOYMENT_URL
This job just makes a POST request to the Deploy Hook URL, triggering a deploy. The URL is stored as an environment variable in CircleCI.
In the workflows section of your CircleCI config, make sure this job only runs after critical jobs (like formatting and testing) have passed. Also, restrict it to the main branch so it doesn’t trigger on branches other than the main one:
workflows:
version: 2
branch-workflow:
jobs:
# ...other jobs
- deploy:
requires:
- format
- test
filters:
branches:
only:
- main
Successful deploy job on CircleCI
You can check out this GitHub repo for a minimal project setup with just one API endpoint and full CI/CD setup with CircleCI and Vercel. If anything in this post is still unclear, you can dive into the repo and see the implementation in detail.
Learn more: If you liked this post, you might also enjoy my lessons learned from building a Serverless NodeJS API with Vercel, Neon, and Prisma ORM