使用 Halo CLI + GitHub Actions 持续部署主题

32 阅读

适合哪些场景?

在开始之前,请先确认这个方案是否适合你。它主要面向以下两类用户:

  1. 自研自用:主题由你自己开发并用于自己的网站,希望在每次推送代码后,主题能自动构建并更新到线上站点,省去手动上传的步骤。

  2. 开发测试:主题计划分享给他人使用,但需要在自己的站点上持续验证最新构建产物的效果。

如果你只是使用他人开发的主题,通过控制台的应用市场一键更新即可,不需要本文介绍的方案。

准备工作

  • 主题代码已托管在 GitHub 仓库

  • 主题具备完整的构建流程(例如使用 pnpm build 输出 dist/*.zip

  • Halo 站点可以通过公网访问,并已生成 API Token

推荐在主题的 package.json 的 build 脚本中引入 @halo-dev/theme-package-cli,自动构建一个 zip 包,并输出到 dist 目录,示例:

{
  "scripts": {
    "build": "vite build && npx @halo-dev/theme-package-cli"
  }
}

生成 API Token:

在 Halo 控制台进入个人中心 → 个人令牌,创建一个新的 Token,包含 主题管理 权限,并将其保存到 GitHub 仓库的 Settings → Secrets and variables → Actions 中,变量名设置为 HALO_TOKEN

注意:此操作需要升级到 Halo 2.24,否则 主题管理 权限可能无法调用升级主题的接口。

工作流说明

整个 CI/CD 流程分为以下几步:

  1. 推送代码到 main 分支

  2. GitHub Actions 自动触发,检出代码

  3. 使用短 commit SHA 更新 theme.yaml 中的版本号,便于追踪每次构建

  4. 安装依赖并执行构建,输出主题 zip 包

  5. 将构建产物上传为 Artifact 归档备份

  6. 安装 Halo CLI,使用 Bearer Token 完成登录认证

  7. 调用 halo theme upgrade 将新构建的主题包推送到 Halo 站点

GitHub Actions 配置

在仓库根目录创建 .github/workflows/deploy.yml 文件,内容如下:

name: Deploy theme

on:
  push:
    branches:
      - main
    paths:
      - "**"
      - "!**.md"

permissions:
  contents: read

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v6

      - name: Setup pnpm
        uses: pnpm/action-setup@v5
        with:
          run_install: false

      - name: Setup Node.js
        uses: actions/setup-node@v6
        with:
          node-version: "24"
          cache: "pnpm"

      # 更新主题版本号,便于在控制台中识别当前运行的具体版本
      - name: Update theme version
        run: |
          SHORT_SHA="${GITHUB_SHA::7}"
          sed -i "s/^  version: .*/  version: 0.0.0-${SHORT_SHA}/" theme.yaml
          grep '^  version:' theme.yaml

      - name: Install dependencies
        run: pnpm install

      - name: Build distribution
        run: pnpm build

      - name: Upload artifact
        uses: actions/upload-artifact@v7
        with:
          # 替换为你的主题名称(metadata.name)
          name: theme-foo
          path: dist/*.zip
          retention-days: 7

      - name: Install Halo CLI
        run: npm install -g @halo-dev/cli

      - name: Upgrade theme via Halo CLI
        env:
          HALO_CLI_CONFIG_DIR: ${{ runner.temp }}/halo-cli
          HALO_TOKEN: ${{ secrets.HALO_TOKEN }}
          # 替换为你的主题名称(metadata.name)
          THEME_NAME: theme-foo
          # 替换为你的 Halo 站点地址
          HALO_URL: https://www.halo.run
        run: |
          THEME_ZIP="$(echo dist/*.zip)"

          if [ ! -f "$THEME_ZIP" ]; then
            echo "Theme zip file not found in dist/"
            exit 1
          fi

          halo auth login \
            --profile ci \
            --url "$HALO_URL" \
            --auth-type bearer \
            --token "$HALO_TOKEN"

          halo theme upgrade "$THEME_NAME" \
            --profile ci \
            --file "$THEME_ZIP"

需要注意的是,此 Workflow 配置并不是固定的,这篇文章也只是提供一个思路,你可以根据自身需求进行调整,比如改为只有在创建新的 tag 时才部署。

需要根据实际情况修改的配置

配置项 说明
HALO_URL 替换为你的 Halo 站点地址,例如 https://www.example.com
THEME_NAME 替换为你的主题名称,需与 theme.yaml 中的 metadata.name 字段一致
path: dist/*.zip 如果你的构建产物路径不同,请相应修改
node-version 根据项目实际要求调整 Node.js 版本
version 中的前缀 0.0.0 随意填写,构建的时候会追加短 commit SHA 作为后缀

注意事项

  • HALO_TOKEN 是敏感信息,务必通过 GitHub Secrets 传入,不要硬编码在工作流文件中

  • 工作流中使用了 HALO_CLI_CONFIG_DIR 将 CLI 的配置目录隔离到 runner 临时目录,避免影响其他环境

  • 每次部署都会用 commit SHA 更新版本号,方便在控制台中识别当前运行的具体版本

  • 如果主题尚未安装到 Halo,需要先手动安装一次,后续再通过此工作流进行升级


评论