When I relaunched my personal site, I wanted to keep both the Astro -based site and its Sanity CMS in a single monorepo and host them each under a separate Vercel project instance. Since I trigger deploys via git commits to the same repo, this meant Vercel should ideally only redeploy an app if it was actually updated.
Initial setup
I used Yarn workspaces and created two directories under the apps directory. One for the Astro site and one for the CMS.
On Vercel, I added each app as a project and linked both to the same git repo. For each project, you can provide a relative path (from your repo root) to its apps directory under the General / Root Directory setting, so that it knows what part of a monorepo to use.
Here's what that looks like for the Astro site:
Next up was getting Vercel to only redeploy an app that had actually changed. In the Vercel dashboard, there's a project Git setting called ' Ignored Build Step '. If you list a shell command here, the build process will only continue if it returns an exit code of 1 after it's run:
Skipping builds using git diff
Initially, I used
git diff
to see if a commit modified files for a given app by scoping it to its directory. So for the Astro site that would be
git diff --quiet HEAD^ HEAD ./apps/site
.
This returns 1 as needed to trigger a build process if that app has changes in a git commit. However, if you make changes across multiple apps, Vercel would only use the most recent commit to decide what to rebuild.
Better: Skipping builds using turbo-ignore
The solution to this problem came via a
tip on Twitter
from person at Vercel: Use
turbo-ignore
, part of the
Turborepo
build system.
When paired with Vercel hosting, it can identify if a given workspace (app) has been modified since the last successful deploy based on the Turborepo dependency graph.
I didn't actually have any build dependencies between the two apps, so the required
turbo.json
needed for a
basic Turborepo setup
was pretty straightforward:
{
"$schema": "https://turbo.build/schema.json",
"pipeline": {
"build": {
"outputs": ["dist/**"]
},
"dev": {
"cache": false
}
}
Now I could set each of my Ignored Build Step settings to just
npx turbo-ignore
.
Any new git push to the repo will only trigger a build/redeploy for an app if it's been updated, no matter how many git commits ago.
A nice little added bonus was that you can even set up caching between your local and remote builds to speed up your build process.
Check out the entire setup for this on GitHub .
If you found this post useful, please consider following me on Twitter for more like it.