Rafael Camargo

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:

  1. Disable auto-deploy in vercel.json
  2. Create a Deploy Hook in Vercel
  3. 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!

Screenshot of the Git settings view in Vercel
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

Screenshot of deploy job on CircleCI
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

Great everyday programming tips every month.

You can also stay in the loop via RSS