Deploying a Monorepo to Vercel with Github Actions p1

12th Jun 2023

Deploying a Monorepo to Vercel with Github Actions p1

I have recently added wasm-pack builds into my Soniq project but found that it is a nightmare trying to get rustup and cargo installed in the Vercel build alongside my yarn monorepo.

I have been planning to migrate my deployments to pure Github actions and this was the push to strap myself in and get my hands dirty.

So here is part 1 in a series where I will explain the steps I have taken to get my monorepo building and deploying efficiently with Github Actions using Turborepo and a few, key, architecture decisions.

The Vercel Recommended Github Actions

The natural place to start for me was to go through the How can I use Github Actions with Vercel documentation. I have a few key takeaways from looking through this document.

  1. It is not designed to work with a monorepo where individual apps deploy separately
  2. It will not work alongside the turborepo cache functionality to enable the run to only deploy changes.
  3. It is fixed to a single Vercel project

However, the important commands to use when deploying a vercel application will be:

  1. We will need to build to the .vercel/output using vercel build --token=${{ secrets.VERCEL_TOKEN }}
  2. We will need to deploy this output using vercel deploy --prebuilt --token=${{ secrets.VERCEL_TOKEN }}
  3. If this is a production deployment then both of these commands will need the --prod flag

Setup of Turborepo and Nodejs Environment

There were a few important steps for me to have the job's environment configured correctly for the monorepo deploys. Turborepo will deal with detecting changes to the codebase, I want to keep yarn cache to speed up builds and the Vercel CLI will need to be accessible on the path.

Turborepo fetch depth

The checkout step needed a custom fetch-depth as seen in the documentation for Using Turbo Repo with Github Actions. It isn't clear how exactly this is used but I expect it will allow Turborepo to detect file changes relative to the current commit.

- uses: actions/checkout@v3
with:
fetch-depth: 2

Nodejs Version and Yarn Cache

Next I needed to configure the setup-node action specific to my stack. This includes using .nvmrc for Nodejs version and caching for yarn.

- uses: actions/setup-node@v3
with:
cache: 'yarn'
node-version-file: '.nvmrc'
- name: Install dependencies
run: yarn

On a side note, Renovate monitors my dependencies in this repo and it looks like it can also automatically create PRs to update the .nvmrc when new versions of Nodejs are released. This is something to look at later.

Vercel CLI

This is a step which I can definitely improve. It is currently using npm to install vercel CLI as a global package. It is slow and not cached. It will do for now.

When I initially set this up, I was running the vercel build without linking each app to the connected vercel project. This caused an issue with the Nodejs functions. Vercel build was not resolving the node_modules in the root of the monorepo, and so they were missing from the deployed function. The repo must be linked to the vercel account as described in this discussion.

- name: Install Vercel CLI
run: npm install --global vercel@latest && vercel link --repo --yes --token $VERCEL_TOKEN

Next is Part 2 CI Build and Deploy