Deploying to vercel from codeberg
When I first began migrating repositories from GitHub to Codeberg, the first thing I noticed was that vercel does not support codeberg as a git integration. I like vercel for a lot of reasons, but most of all the ability to preview a build of the site without deploying it to production. Additionally, if something does go seriously wrong, I can always rollback to a previous deployment that was working while I troubleshoot the cause. Using the command line tool for vercel I was able to still deploy just fine but I risked the codebase getting out of sync with the deployments.
Through my previous project, setting up mdbook with woodpecker ci and codeberg pages, I had access to the hosted woodpecker instance on Codeberg. I wanted to try to get vercel to deploy using woodpecker instead of having to manually do it from the command line. This would ensure that the code displayed in the repo on Codeberg was always in sync with what was actually displayed to users on the site.
Implementation
I had two main objectives when starting this feature:
- Keep the usage of woodpecker light, ideally under 2 minutes from push to deployment.
- Be able to have a
develop
branch that would deploy to a preview environment, and use themain
branch to deploy to production when it was pushed to or when a PR was merged into it.
I was able to implement this through having two separate configurations inside a single woodpecker directory.
.woodpecker
├── .deploy.yml
└── .preview.yml
The preview.yml
file looks like this, and is quite minimal. It essentially replicates the process that I was manually doing on the command line.
clone:
git:
image: woodpeckerci/plugin-git
when:
branch: develop
steps:
build:
image: node
secrets: [vercel_token]
environment:
VERCEL_ORG_ID:
from_secret: vercel_org_id
VERCEL_PROJECT_ID:
from_secret: vercel_project_id
commands:
- npm install --global vercel@latest
- vercel deploy --token=$vercel_token
- Clone the git repository (woodpecker will actually perform this automatically, however if I want to do any customization down the line doesn’t hurt to have this here).
clone:
git:
image: woodpeckerci/plugin-git
- Specify that this file should only run when pushing to the
develop
branch.
when:
branch: develop
- Use the nodejs image and specify three secrets total. Two of which, vercel_org_id and vercel_project_id, are environment variables, and vercel_token is used as an argument in the cli syntax. I used this guide on integrating vercel with github actions as a reference point, and then just had to translate the syntax into what woodpecker expected.
steps:
build:
image: node
secrets: [vercel_token]
environment:
VERCEL_ORG_ID:
from_secret: vercel_org_id
VERCEL_PROJECT_ID:
from_secret: vercel_project_id
commands:
- npm install --global vercel@latest
- vercel deploy --token=$vercel_token
The only difference between the preview version and the deploy version is that the deploy file uses --prod
after vercel deploy
. This will mean that whenever the main branch receives a push or has a branch merged into it, the resulting code will be deployed to markpitblado.me
instead of just the vercel preview domains.
Minimizing woodpecker ci usage
One of the key discoveries was getting vercel to handle the compute for the npm install
and npm run build
instead of the woodpecker worker. This can be done by setting both of those commands explicitly in the vercel project settings and then making sure to expose all of the code to vercel (and not just the code in the output directory, which in this case would be _site
.) At the time of writing, woodpecker-ci is taking about 90 seconds to deploy the site to vercel. This includes both installing all the dependencies and building the site on the vercel side.
Overall thoughts
I am really happy with how this turned out. I was able to meet both of the objectives that I had when I started, and I no longer feel like I have sacrificed any functionality by moving from GitHub to Codeberg for my site. As a reminder, if you would like to request access to the woodpecker ci for codeberg, you should do so here.