Restent's Notebook

  • · 技术

    用 GitHub Actions 替代 Vercel CI

    受不了了!这就用 GitHub Actions 构建站点内容,再上传到 Vercel(擦汗)


    问 题 描 述

    前几天将博客部署回了 Vercel。本地 Vercel CLI 初始化项目、Vercel CI 构建并部署完网站之后,打开链接一看:捏妈滴,我 CSS 哪里去了?用 Devtools Network 一看,CSS 文件 404 Not Found,连带着几个 JavaScript chunks......

    这个问题并不是前几天部署回去的时候遇到的,而是我很久之前、还没改回 Cloudflare Workers Site 的时候就遇到了这个问题:不管是什么项目,只要用了 Vercel CI 部署,CSS 和随机几个 JavaScript chunks 总会不翼而飞,给我干成了流汗黄豆 😅。

    不过解决办法其实是有的。正如标题所言,我先用 GitHub Actions 构建完站点内容,再上传到 Vercel,而不是让 Vercel CI 一条龙服务解决。嗯,就这么简单。

    CI 构建:从 Vercel CI 到 GitHub Actions

    很久很久之前,GitHub Organization 想要使用 Vercel CI 必须得买 Team Plan,所以大家都会通过 GitHub Actions 使用 Vercel CI。

    Vercel Action(amondnet/vercel-action)便是其中一个例子。它其实就是一个 GitHub Actions 特供的 Vercel CLI,区别仅仅在于:

    • 本地的 Vercel CLI 读取 .vercel 文件夹内的 project.json 获取 orgIDprojectID,以便上传内容到 Vercel CI 进行构建;
    • Vercel Action 受限于 orgIDprojectID 明文存储在 project.json 里、不能直接上传到 repo;同时,Vercel Action 不能直接访问你的 Vercel 账号,就像你本地安装了 Vercel CLI 也得执行 vercel login。所以,你必须得在 repo Secrets 里填写 VERCEL_TOKEN, VERCEL_ORG_IDVERCEL_PROJECT_ID,供 Vercel Action 使用。

    但是最上面已经提到了,Vercel CI 给我造成了不小的麻烦,所以我的网站不会再交给 Vercel CI 构建,而是交给 GitHub Actions。或许我可以将 Vercel 项目的根目录设置在 .output/public,这样在 GitHub Actions 构建完站点内容之后,我就可以通过 Vercel Action 上传到 Vercel 了。如果你是这么想的话,那你就大错特错了:Vercel 会自动检测你的项目框架(比如我是 Nuxt,那么它识别出来之后自动给你选择 Nuxt 的预设),而它在给你套上预设之后会出现什么就不好说了。

    不过,Vercel 虽然没有制作 Official Action,但是他们给出了一个与 GitHub Actions 一起使用的 方案。这是他们给出的一个 Action 配置文件:

    name: Vercel Production Deployment
    env:
      VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
      VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
    on:
      push:
        branches:
          - main
    jobs:
      Deploy-Production:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v2
          - name: Install Vercel CLI
            run: npm install --global vercel@latest
          - name: Pull Vercel Environment Information
            run: vercel pull --yes --environment=production --token=${{ secrets.VERCEL_TOKEN }}
          - name: Build Project Artifacts
            run: vercel build --prod --token=${{ secrets.VERCEL_TOKEN }}
          - name: Deploy Project Artifacts to Vercel
            run: vercel deploy --prebuilt --prod --token=${{ secrets.VERCEL_TOKEN }}
    

    好像根本看不懂它在讲什么?别急,我来告诉你:

    • 第一,env 项指定需要用到的 VERCEL_ORG_IDVERCEL_PROJECT_ID 、并从对应名称的 Secret 读取;
    • 第二,喜闻乐见的 checkout;
    • 第三,全局安装 Vercel CLI;
    • 第四,使用 VERCEL_TOKEN 拉取你的项目环境信息;
    • 第五,使用 VERCEL_TOKEN 在本地(即 GitHub Actions)构建你的站点内容;
    • 第六,使用 VERCEL_TOKEN 将构建好的内容上传到 Vercel。
      • 由于这一步标注了 --prebuilt,所以上传到 Vercel 后不会再让 CI 构建、而是直接 deploy。

    现在你估计看懂了:这就是把 Vercel CI 的构建步骤交给 GitHub Actions 了。而且经过 GitHub Actions 构建之后,上面提到的 CSS 和随即几个 JavaScript chunks 不翼而飞 也不会出现了。

    实战

    假设我正要部署我手头上的 Nuxt 3 项目,包管理器就用我最近换的 Bun。

    添加 Secrets

    上面已经说到,Vercel Action 本质上就是一个 Vercel CLI,而这个 Action 代码也需要用到 Vercel CLI。所以你必须得在 repo Secrets 里添加 VERCEL_TOKEN, VERCEL_ORG_IDVERCEL_PROJECT_ID

    VERCEL_ORG_IDVERCEL_PROJECT_ID 就在上面提到的、你的项目根目录的 .vercel/project.json 里,分别对应 orgIDprojectID;至于 VERCEL_TOKEN,懒得一步步教了,自己查一下怎么开一个(

    编写 Action 配置文件

    在项目根目录下创建 .github/workflows 目录,再在这个目录下创建一个 deploy.yml,写入下述内容:

    name: Deploy site
    env:
      VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
      VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
    
    on:
      push:
        branches:
          - main
    jobs:
      CI:
        runs-on: ubuntu-latest
        steps:
          - name: Checkout
            uses: actions/checkout@master
          - name: Setup bun
            uses: oven-sh/setup-bun@v1
            with:
              bun-version: latest
          - name: Install Vercel CLI
            run: bun install --global vercel@latest
          - name: Pull Vercel Environment Information
            run: vercel pull --yes --environment=production --token=${{ secrets.VERCEL_TOKEN }}
          - name: Build Project Artifacts
            run: vercel build --prod --token=${{ secrets.VERCEL_TOKEN }}
          - name: Deploy Project Artifacts to Vercel
            run: vercel deploy --prebuilt --prod --token=${{ secrets.VERCEL_TOKEN }}
    

    对的,就是这么简单。除了 Bun / npm / pnpm / yarn 这种包管理器需要你自行配置,其余用 Vercel CLI 就可以搞定了。

    将这个配置文件推到 GitHub 上,并且 Vercel 的项目设置保持原来用 Vercel CI 构建的配置,如果顺利跑完的话就可以收工了。


© 2019 - 2024 Restent Ou

Powered by Nuxt