Deploying to vercel from codeberg

4 min read

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:

  1. Keep the usage of woodpecker light, ideally under 2 minutes from push to deployment.
  2. Be able to have a develop branch that would deploy to a preview environment, and use the main 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
  1. 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
  1. Specify that this file should only run when pushing to the develop branch.
when:
  branch: develop
  1. 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.