前言

之前部署 Hexo 博客都是本地构建静态文件,然后手动推送到 GitHub Pages。这种方式有几个问题:

  • 源码只在本地,存在丢失风险
  • 换电脑需要重新配置环境
  • 每次更新都需要手动执行部署命令

本文介绍如何使用 GitHub Actions 实现自动部署,解决这些问题。

准备工作

1. 两个仓库

我们将使用两个 GitHub 仓库:

  • 源码仓库:存放 Hexo 源码(可以私有)
  • Pages 仓库:存放生成的静态文件(必须公开)

例如:

  • 源码:https://github.com/CeRu-007/hexo-cerublog
  • Pages:https://github.com/CeRu-007/CeRu-007.github.io

2. 创建源码仓库

在 GitHub 上创建新仓库,用于存放 Hexo 源码。

配置源码仓库

1. 初始化 Git 并推送

在博客根目录执行:

1
2
3
4
5
6
git init
git add .
git commit -m "Initial commit: Hexo blog source code"
git branch -M main
git remote add origin https://github.com/CeRu-007/hexo-cerublog.git
git push -u origin main

2. 配置 .gitignore

确保 .gitignore 文件包含以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
.DS_Store
Thumbs.db
db.json
*.log
node_modules/
public/
.deploy*/
_multiconfig.yml
.sass-cache/
.deploy_git/
.idea/
.vscode/
*.swp
*.swo
*~

这样可以避免推送不必要的文件:

3. 处理主题(Git Submodule)

如果主题是通过 git clone 安装的(如 Butterfly),需要添加为 Git Submodule:

1
2
3
4
git submodule add https://github.com/jerryc127/hexo-theme-butterfly.git themes/butterfly
git add .gitmodules
git commit -m "Add butterfly theme as submodule"
git push

为什么要用 Submodule?

  • 记录主题的具体版本,确保一致性
  • 不存储主题完整代码,节省空间
  • GitHub Actions 会自动拉取子模块

创建 GitHub Actions 工作流

1. 创建工作流文件

在项目根目录创建 .github/workflows/deploy.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
name: Hexo Deploy

on:
push:
branches:
- main
workflow_dispatch:

jobs:
build-and-deploy:
runs-on: ubuntu-latest

steps:
- name: Checkout source
uses: actions/checkout@v4
with:
submodules: true

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'

- name: Install dependencies
run: |
npm install -g hexo-cli
npm install

- name: Generate static files
run: hexo generate

- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v3
with:
personal_token: ${{ secrets.HEXO }}
external_repository: CeRu-007/CeRu-007.github.io
publish_dir: ./public
publish_branch: gh-pages
force_orphan: true

关键配置说明:

  • submodules: true:自动拉取主题子模块
  • external_repository:指定 Pages 仓库地址
  • personal_token:使用 Personal Access Token(HEXO)用于跨仓库部署
  • publish_branch:部署到 gh-pages 分支

注意: 这里必须使用 personal_token 而不是 github_token,因为 github_token 不能跨仓库推送。

2. 提交工作流文件

1
2
3
git add .github/workflows/deploy.yml
git commit -m "Add GitHub Actions workflow for auto deployment"
git push

配置 GitHub Personal Access Token

由于要跨仓库部署,需要创建 Personal Access Token。

1. 创建 Token

  1. 访问 https://github.com/settings/tokens
  2. 点击 Generate new token (classic)
  3. 填写信息:
    • Note: Hexo Deploy
    • Expiration: 选择过期时间
    • 勾选权限:repo(完整的仓库访问权限)
  4. 点击 Generate token
  5. 复制生成的 token(只显示一次)

2. 添加 Secret

  1. 进入源码仓库:Settings → Secrets and variables → Actions
  2. 点击 New repository secret
  3. 填写:
    • Name: HEXO
    • Value: 粘贴刚才复制的 token
  4. 点击 Add secret

配置 GitHub Pages

进入 Pages 仓库(CeRu-007/CeRu-007.github.io):

  • 点击 SettingsPages
  • Build and deployment 部分:
    • Source: Deploy from a branch
    • Branch: gh-pages(第一次部署后会自动创建)
    • Folder: / (root)
  • 点击 Save

测试自动部署

现在推送代码就会自动触发部署:

1
2
3
git add .
git commit -m "测试自动部署"
git push

查看部署状态:https://github.com/CeRu-007/hexo-cerublog/actions

工作流程

自动部署的完整流程:

  1. 推送代码到源码仓库的 main 分支
  2. GitHub Actions 自动触发
  3. 拉取源码和主题子模块
  4. 安装依赖
  5. 生成静态文件
  6. 部署到 Pages 仓库的 gh-pages 分支
  7. GitHub Pages 自动更新网站

优势对比

之前的方式

❌ 源码只在本地,容易丢失
❌ 换电脑需要重新配置
❌ 每次手动执行 hexo deploy
❌ 无法查看历史修改

现在的方式

✅ 源码备份在 GitHub,安全可靠
✅ 随时随地 git clone 即可工作
✅ 推送代码自动部署
✅ 完整的 Git 历史记录
✅ 多设备协作方便

常见问题

Q: 源码仓库可以是私有的吗?

A: 可以。源码仓库私有不影响自动部署,只有 Pages 仓库需要公开。

Q: 为什么不用同一个仓库?

A: 分开更清晰:

  • 源码仓库:只存放源代码
  • Pages 仓库:只存放静态文件
  • 便于管理和协作

Q: 如何更新主题?

A: 更新子模块:

1
2
3
4
5
6
cd themes/butterfly
git pull
cd ../..
git add themes/butterfly
git commit -m "Update theme"
git push

Q: 如何在其他电脑上工作?

A: 克隆源码仓库:

1
2
3
git clone --recursive https://github.com/CeRu-007/hexo-cerublog.git
cd hexo-cerublog
npm install

Q: 为什么使用 personal_token 而不是 github_token?

A: 因为我们要跨仓库部署(从源码仓库部署到 Pages 仓库),而 github_token 是 GitHub 自动生成的,只能访问当前仓库,无法跨仓库推送。personal_token 是你创建的 Personal Access Token,拥有完整的仓库访问权限,可以跨仓库操作。

🔧 故障排查:主题中的图片无法加载

问题描述

如果主题作为 Git Submodule 后,发现主题中的某些图片无法加载,可能是因为这些图片是在本地添加的新文件,没有包含在子模块的原始代码中。

原因分析

主题作为 Git Submodule 时,GitHub Actions 只会拉取子模块的原始代码(即官方仓库的内容),不会包含你在本地添加的新文件。

解决方案

将主题中新增的图片文件复制到博客的 source/img/ 目录下:

1
2
3
4
5
6
7
8
9
10
# 复制主题中的图片到 source/img/
cp themes/butterfly/source/img/7.jpg source/img/7.jpg
cp themes/butterfly/source/img/8.jpg source/img/8.jpg
cp themes/butterfly/source/img/9.jpg source/img/9.jpg
cp themes/butterfly/source/img/10.jpg source/img/10.jpg

# 添加到 Git 仓库
git add source/img/7.jpg source/img/8.jpg source/img/9.jpg source/img/10.jpg
git commit -m "Add missing images to source/img"
git push

预防措施

  • 对于主题中新增的图片、自定义样式等文件,建议放在 source/ 目录下,而不是直接修改主题目录
  • 如果必须修改主题文件,考虑创建一个子主题或者 fork 主题仓库

总结

通过 GitHub Actions 实现自动部署,大大简化了博客的维护工作。现在只需要专注于写文章,推送代码后一切自动完成。

同时,源码备份在 GitHub 上,再也不用担心数据丢失了!