背景
之前每次更新博客都要手动执行 hexo clean && hexo deploy,需要本地安装 Node.js 和项目依赖,换台电脑就很不方便。将部署流程整合到 GitHub Actions 后,只需要把文章推送到仓库,CI 会自动构建并部署到 GitHub Pages。
整体架构
1 | 本地推送代码到 hexo 分支 |
配置步骤
第一步:创建 workflow 文件
在仓库根目录创建 .github/workflows/main.yml:
1 | name: Deploy Hexo Blog |
第二步:创建 Personal Access Token
由于源仓库(hexo_source_file)和部署目标仓库(lixiandea.github.io)是两个不同的仓库,GitHub Actions 默认的 GITHUB_TOKEN 只能访问当前仓库,无法跨仓库推送。因此需要创建 Personal Access Token(PAT)。
- 打开 https://github.com/settings/tokens
- 点击 Generate new token (classic)
- 勾选
repo权限(完整的仓库访问权限) - 设置过期时间(建议选择较长的周期,避免频繁更换)
- 生成并复制 token
第三步:配置 Repository Secret
将 PAT 存储为仓库的 Secret,避免在代码中暴露:
- 打开源仓库 → Settings → Secrets and variables → Actions
- 点击 New repository secret
- Name 填
DEPLOY_TOKEN - Value 粘贴刚才的 token
- 保存
第四步:推送代码触发部署
将 workflow 文件推送到 hexo 分支,GitHub Actions 会自动运行:
1 | git add .github/workflows/main.yml |
可以在仓库的 Actions 页面查看运行状态。
关键问题与解决
主题的 submodule 问题
我的 Butterfly 主题是通过 git submodule 引入的,但 .gitmodules 文件丢失导致 submodule 引用损坏。在 CI 环境中克隆代码后 themes/butterfly/ 目录为空,hexo generate 会报 No layout 错误。
解决方案:将主题目录添加到 .gitignore,在 workflow 中动态克隆:
1 | - name: Clone Butterfly theme |
本地开发时也需要保留主题文件,所以 .gitignore 中添加:
1 | themes/butterfly/ |
本地已有主题目录不会被删除,只是不再被 git 跟踪。
为什么不用 hexo deploy
hexo deploy 需要配置 git 凭据才能推送到远程仓库。在 GitHub Actions 中配置 git 认证比较麻烦,需要手动设置 user.name、user.email,还要处理 HTTPS 或 SSH 认证。
peaceiris/actions-gh-pages 封装了这些逻辑:
- 自动配置 git 用户信息
- 通过
personal_token认证 - 支持
commit_message自定义(如使用源仓库的 commit message) - 自动处理强制推送和清理
为什么 GITHUB_TOKEN 不够用
GITHUB_TOKEN 是 GitHub Actions 自动生成的令牌,但它的权限仅限于当前仓库。我的场景是:
- 源仓库:
lixiandea/hexo_source_file(私有) - 目标仓库:
lixiandea/lixiandea.github.io(公开)
从源仓库推送到目标仓库属于跨仓库操作,必须使用有 repo 权限的 PAT。
最终效果
配置完成后,工作流变成:
1 | 1. 本地写文章 / 修改博客 |
不再需要本地执行 hexo deploy,也不需要在每台电脑上安装 Node.js 环境。只需要一个能 push 代码的终端即可。
总结
| 步骤 | 说明 |
|---|---|
| 创建 workflow 文件 | .github/workflows/main.yml,监听 hexo 分支推送 |
| 创建 PAT | GitHub Settings → Developer settings → Personal access tokens |
| 配置 Secret | 仓库 Settings → Secrets → Actions → DEPLOY_TOKEN |
| 推送触发 | 代码推送到 hexo 分支后自动构建部署 |
核心依赖:peaceiris/actions-gh-pages 处理跨仓库推送部署。