【Hexo自动部署】优雅的使用 Github Actions 进行 Hexo 静态博客的持续集成与部署-腾讯云开发者社区-腾讯云

前言

作为技术博主,博客的高效维护与部署一直是我关注的重点。近期在维护博客时,我遇到了两个核心问题:

  1. 内容管理混乱:草稿箱文件堆积,缺乏分类标准,甚至因误操作破坏了原有配置;
  2. 兼容性局限:计划将文章同步至 FastGPT 等 AI 知识库时,发现官方推荐的 Hexo 部署方案(源码与静态文件混存)中,冗余的 public 目录会干扰 RAG 系统提取内容,且源码与发布产物耦合易引发冲突。

为解决这些问题,我采用了源码与发布分离的部署架构:将 Markdown 源文件单独存放在一个仓库,通过 GitHub Actions 自动在另一个仓库构建并发布静态文件。这种方式的优劣对比如下:

方案 优点 缺点
官方混仓部署 支持本地手动 / 自动发布,预览方便,配置简单 仓库体积大,源码与产物混合,不利于二次利用
本文分离部署 源码纯净、产物独立,兼容 AI 知识库,自动构建 本地预览需搭测试环境,配置较复杂(双仓库 + 鉴权)

部署核心思路

核心逻辑:当源码仓库收到推送时,GitHub Actions 自动将源文件检出到 source/_posts,并从 _hexo 目录复制配置文件还原 Hexo 环境,最终执行构建与发布。

文件结构设计(源码仓库):

1
2
3
4
5
6
7
8
|-- _hexo/ # Hexo 核心配置目录 
| |-- _config.yml # Hexo 主配置
| |-- _config.next.yml # NexT 主题配置
| |-- package.json # Node 环境依赖
| |-- scaffolds/ # 文章模板(draft/page/post.md)
| |-- static/ # 静态资源(头像、支付码等)
|-- .github/workflows/ # GitHub Actions 工作流配置
|-- .obsidian/ # Obsidian 编辑器配置(可选)

详细部署步骤

1. 生成 SSH 密钥对(用于仓库间鉴权)

需要生成一对 SSH 密钥,用于源码仓库向发布仓库推送构建结果:

1
ssh-keygen -t rsa -C "<github 注册邮箱>"

执行后会在以下路径生成两个文件:

  • 私钥:~/.ssh/id_rsa(Linux/Mac)或 C:\Users\<用户名>\.ssh\id_rsa(Windows)
  • 公钥:~/.ssh/id_rsa.pub(同上路径)

注意:.ssh为隐藏目录,需要修改系统设置显示此文件夹

2. 准备两个仓库

仓库 1:源码仓库(存放 Markdown 与配置)

  • 新建仓库(例如命名为 hexo-source
  • 进入仓库设置:Settings → Secrets and variables → Actions → New repository secret
  • 添加一个名为 HEXO_DEPLOY_KEY 的密钥,值为私钥 id_rsa 的内容(用记事本打开复制)

仓库 2:发布仓库(存放静态文件,用于 GitHub Pages)

  • 仓库名必须为 <你的 GitHub 用户名>.github.io(固定格式,否则 GitHub Pages 无法生效)
  • 权限需设为公开,并开启 Discussions 功能(进入仓库设置 → Features 勾选)
  • 配置部署密钥:Settings → Deploy keys → Add deploy key
    • Title 填 HEXO_DEPLOY_PUB
    • Key 填入公钥 id_rsa.pub 的内容,并勾选 Allow write access(允许推送权限)

3. 配置 Hexo 环境文件

在源码仓库中创建 _hexo 目录,放入以下核心文件(可从本地 Hexo 环境中复制, 参考Hexo-博客配置):

  • _config.yml:Hexo 主配置(需修改部署相关配置,见步骤 4)
  • _config.next.yml:NexT 主题配置(其他主题同理)
  • package.json:依赖配置(需包含 hexohexo-deployer-git 等核心依赖)
  • scaffolds/:文章模板(draft.md/page.md/post.md
  • 静态资源:如头像(avatar.jpg)、关于页(about.md)等,按实际需求存放

4. 配置部署与工作流文件

① Hexo 部署配置(_hexo/_config.yml

在配置文件中添加部署规则,指向发布仓库:

1
2
3
4
5
6
7
8
# Deployment
## Docs: https://hexo.io/docs/deployment.html
deploy:
- type: git
repo: git@github.com:<username>/<username>.github.io.git
branch: master
name: <username>
email: <email>

② GitHub Actions 工作流(.github/workflows/hexo-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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
name: hexo-deploy  # 工作流名称

# 触发条件:向 master 分支推送时执行
on:
push:
branches: ["master"]

jobs:
build:
runs-on: ubuntu-latest # 使用 Ubuntu 环境
steps:
# 1. 配置时区(避免时间显示异常)
- name: Setup Timezone
uses: szenius/set-timezone@v2.0
with:
timezoneLinux: "Asia/Shanghai"

# 2. 拉取源码仓库内容到 source/_posts
- uses: actions/checkout@v3
with:
path: source/_posts

# 3. 安装 Node.js(需与本地开发环境版本一致,这里用 20.x)
- name: Use Node.js 20
uses: actions/setup-node@v4
with:
node-version: '20'

# 4. 缓存 NPM 依赖(加速构建)
- name: Cache NPM dependencies
uses: actions/cache@v4
with:
path: node_modules
key: ${{ runner.OS }}-npm-cache
restore-keys: |
${{ runner.OS }}-npm-cache

# 5. 配置 SSH 密钥(用于向发布仓库推送)
- name: Setup Git
env:
ACTION_DEPLOY_KEY: ${{ secrets.HEXO_DEPLOY_KEY }} # 引用源码仓库的私钥
run: |
mkdir -p ~/.ssh/
echo "$ACTION_DEPLOY_KEY" > ~/.ssh/id_rsa
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_rsa # 严格权限,否则 SSH 会拒绝使用
ssh-keyscan github.com >> ~/.ssh/known_hosts # 信任 GitHub 主机

# 6. 拉取主题(以 NexT 为例,其他主题修改仓库地址即可)
- name: Use Themes
uses: actions/checkout@v3
with:
repository: next-theme/hexo-theme-next
path: themes/next

# 7. 还原 Hexo 环境(从 _hexo 目录复制配置文件)
- name: Setup Hexo
run: |
npm install -g hexo-cli # 全局安装 Hexo 命令行工具
# 复制核心配置文件
cp source/_posts/_hexo/_config.yml .
cp source/_posts/_hexo/_config.next.yml .
cp source/_posts/_hexo/package.json .
# 复制文章模板
mkdir scaffolds
cp source/_posts/_hexo/scaffolds/* scaffolds/
# 复制静态页面(关于页、分类页等,按实际需求调整)
mkdir -p source/about source/categories source/tags source/images
cp source/_posts/_hexo/about.md source/about/index.md
cp source/_posts/_hexo/categories.md source/categories/index.md
cp source/_posts/_hexo/tags.md source/tags/index.md
cp source/_posts/_hexo/*.jpg source/images/ # 复制图片资源
# 安装依赖
npm install

# 8. 缓存部署目录(加速后续构建)
- name: Cache Deploy
uses: actions/cache@v4
with:
path: .deploy_git
key: ${{ runner.OS }}-deploy-cache
restore-keys: |
${{ runner.OS }}-deploy-cache

# 9. 构建并发布
- name: Deploy
run: |
cd .deploy_git && git pull # 拉取最新发布内容,避免冲突
cd ..
hexo clean # 清理缓存
hexo generate # 生成静态文件
hexo deploy # 部署到发布仓库

验证与使用

  1. 将上述文件提交到源码仓库的 master 分支,GitHub Actions 会自动触发工作流;
  2. 进入源码仓库的 Actions 标签页,查看工作流执行状态,若显示绿色对勾则部署成功;
  3. 访问 https://<你的用户名>.github.io,即可看到最新发布的博客。

注意事项

  1. 私钥 HEXO_DEPLOY_KEY 是敏感信息,切勿泄露或提交到仓库;
  2. 发布仓库名必须严格为 <用户名>.github.io,否则 GitHub Pages 无法正常访问;
  3. 若主题是自定义修改过的,建议将主题 fork 到自己的仓库,再在工作流中拉取自己的 fork 版本;
  4. 本地预览时,可在源码仓库中手动搭建 Hexo 环境(复制 _hexo 目录文件,执行 hexo server)。

参考

Hexo官方提供的Github Actions部署示例

由于没有自己的云服务器,所以我之前选择博客工具的时候排除了Typora、Wordpress…转而选择了 Hexo,但其实相较于前者,Hexo 的云端写作体验一直很糟糕。   随着近两年 CI/CD、DevOps 这些概念的流行,很多工具都火了起来,像 Jenkins、Github的好基友Travis等等,但这些都不太适用我们的情况,Jenkins 也需要自己的服务器,而TravisCI我也测试了一下,本来是适用的,也很方便,但是官方宣布后续不再免费,只赠送 10000 积分用完即止,开通付费版则要 69刀/月 [俺支持不起,倒不如整一个云服务器,大佬请随意!]。   但是我偶然了解到全球最大的同性交友网站丢出了一个重磅炸弹-Github Actions,我发现利用此功能可以完美解决 Hexo 静态博客自动部署的问题,并且免费版每月赠送2000分钟的时长,完美!

  本篇博文就来浅谈一下 Github Actions 的原理,以及使用他简单实现 Hexo 静态博客的自动部署(即每次我们 push 源代码后,自动生成静态文件,并上传到我们的仓库或者云存储中;Github 本身可以开启运行结果邮件通知功能,有条件的也可以设置 WebHooks 来进行通知。),好了那么话不多说,我们直接开始,欢迎大佬批评指正。

Github Actions

简介

  前面我们有提到 CI/CD、DevOps 这些名词,其实就是我们一般开发完成后,需要进行测试、打包、发布等操作,这些动作其实都是可以自动完成的,之前提到的 Jenkins 就可以做到,但是需要有自己的服务器。

  而 Github Actions 服务,就是用来帮助我们完成这些动作,他既可以使用自己的服务器也可以使用 Github 的服务器(支持多种环境与语言)。

使用

  Github Actions 和其他工具一样,通过脚本文件来进行一系列复杂的操作,他也有自己的语法规则-官方文档。

  由于很多操作在不同项目里面是类似的,完全可以共享。GitHub 注意到了这一点,想出了一个很妙的点子,允许开发者把每个操作写成独立的脚本文件,存放到代码仓库,使得其他开发者可以引用,官方市场、github/actions 仓库。

  其他基础使用,推荐查看阮一峰老师的介绍。

原理(个人了解)

  其实 Github Actions 就是当我们完成触发条件后(例如:push/pull等),Github 通过我们编写的脚本文件把应该在本地运行的命令,放到他的服务器(也可以设置自己的服务器)上自动运行,大大减少我们的操作。

  经过博主的测试,Github 提供的服务器上预装了多种语言及一些常见的运行环境等,所以我们编写脚本其实很简单,只需按语法要求添加以下固定内容即可:

  • 提供脚本基本信息
  • 指定运行环境、触发条件
  • 编写任务、步骤、动作

  添加这些内容后,当匹配触发条件时,Github 就会读取我们的脚本文件,在服务器上的指定环境中运行我们预先写好的任务、步骤、动作。

好了,经过这些简单的了解后,我们开始配置 Github Actions吧。

Hexo 静态博客自动部署

建立博客源代码仓库

  因为我们需要 Hexo 源代码才能生成静态文件,所以我们需要建立一个私有仓库来保存我们的源代码,当然如果你觉得麻烦也可以建立一个分支来保存,此处就不介绍了。

Ps: 如果您还不会搭建 Hexo 博客,可以参考本站之前的 Hexo 搭建教学。

  • 具体操作如图所示

  仓库建立后,我们可以先把自己的源代码通过 Git 提交上去,这里就不介绍了,也可以参考之前的博客搭建教学。

Ps: 如果碰到 Github 连线失败的情况,建议禁用代理 git config --global --unset http.proxy,或者直接使用 open ssh 进行连线推送。

Hexo 简单配置与介绍

Github 的链接形式

  Github 这种网站的代码仓库地址常见有三种形式,适用于不同的情况,下面简单介绍一下。

  • 普通链接,一般在使用账号密码登录后或者ssh传输时使用。

代码语言:javascript

AI代码解释

复制

1
2
3
// 这种地址可以直接在仓库中复制
https://github.com/pandaoh/biugle.git
git@github.com:pandaoh/biugle.git
  • 账号密码链接,这种适用于自己调用 Github 的数据或者当 Api 使用等情形。

代码语言:javascript

AI代码解释

复制

1
https://{username}:{password}@github.com/pandaoh/biugle.git
  • token 链接,在 Github Settings 中生成 token 后,可以直接放到仓库地址中,这样就可以直接访问有权限的仓库,方便我们自动部署。

代码语言:javascript

AI代码解释

复制

1
https://{token}@github.com/pandaoh/biugle.git
生成 Github Token

  了解完 Github 这些链接形式后,我们就可以开始配置了,因为我们决定使用 Token 这种链接形式来进行连线推送等操作,所以首先就是生成 Github Token

  • 打开我们自己的 Github Settings,选择 Developer settings => Personal access tokens

  • 生成 token 后,此信息只会展示一次,我们先保存下来,因安全问题后文我统一将此 token 称为 $GH_TOKEN
修改 config.yml

  大部分人之前应该都是在本地进行博客编写,所以连接 Github 的方式应该都是使用的 ssh,那么前面我们为了方便后续自动部署,需要把 config.yml 文件中的 deploy->repository->github 值改成 token url 的形式。

代码语言:javascript

AI代码解释

复制

1
2
3
4
5
6
deploy:
- type: git
repository:
github: https://{$GH_TOKEN}@github.com/pandaoh/pandaoh.github.io.git,master
...
// 注意此处的 {$GH_TOKEN} 请替换成我们之前生成的 token 内容,此仓库地址是我们博客静态文件最终存放的仓库地址,即搭建教学中开通 Github Pages 服务的那个仓库地址。

添加 GitHub Actions 脚本

  配置完 Hexo,我们开始编写 Github 的脚本文件,GitHub Actions 的配置文件叫做 workflow 文件,存放在源代码仓库的 .github/workflows 目录。   workflow 文件采用 YAML 格式,文件名可以任意取,但是后缀名统一为 .yml,比如 test.yml。一个库可以有多个 workflow 文件。   GitHub 在我们完成预设触发条件时,只要发现 .github/workflows 目录里面有 .yml 文件,就会自动读取运行该文件。

添加步骤
  • 我们可以直接手动建立此文件,或者通过源代码仓库点击 Actions => 选择 Setup Node创建,但最终同样都需 push 到远端源代码仓库中。

参数介绍

建议阅读完前面给出的官方文档再来进行此处的了解 ^_^

  • 建立文件后,我们修改其配置如下。

代码语言:javascript

AI代码解释

复制

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
40
41
42
43
44
45
46
47
48
name: DoubleAm's Blog CI/CD # 脚本 workflow 名称

on:
push:
branches: [main, master] # 当监测 main,master 的 push
paths: # 监测所有 source 目录下的文件变动,所有 yml,json 后缀文件的变动。
- '*.json'
- '**.yml'
- '**/source/**'

jobs:
blog: # 任务名称
timeout-minutes: 30 # 设置 30 分钟超时
runs-on: ubuntu-latest # 指定最新 ubuntu 系统
steps:
- uses: actions/checkout@v2 # 拉取仓库代码
- uses: actions/setup-node@v2 # 设置 node.js 环境
- name: Cache node_modules # 缓存 node_modules,提高编译速度,毕竟每月只有 2000 分钟。
uses: actions/cache@v2 # 亲测 Github 服务器编译速度比我自己电脑都快,如果每次构建按5分钟计算,我们每个月可以免费部署 400 次,Github yyds!!!
env:
cache-name: cache-node-modules
with:
path: ~/.npm
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
${{ runner.os }}-
- name: Init Node.js # 安装源代码所需插件
run: |
npm install
echo "init node successful"
- name: Install Hexo-cli # 安装 Hexo
run: |
npm install -g hexo-cli --save
echo "install hexo successful"
- name: Build Blog # 编译创建静态博客文件
run: |
hexo clean
hexo g
echo "build blog successful"
- name: Deploy DoubleAm's Blog # 设置 git 信息并推送静态博客文件
run: |
git config --global user.name "doubleam"
git config --global user.email "admin@biugle.cn"
hexo deploy

- run: echo "Deploy Successful!"

验证结果

Hexo 与 Github Actions 均配置完成后,我们将这两个文件变动都推送至源代码仓库中。

推送内容

完成以上操作后,我们每修改并 push 一次监测的文件,就可以触发脚本运行。

查看 Github Actions 运行日志与结果

触发后我们可以查看运行日志与结果,如下图所示。

  • 基础日志

  • 详细日志

添加 WebHooks 通知

  脚本运行完成一般都有邮件通知,但如果我们需要在 push 后添加其他通知,例如钉钉机器人、QQ等,我们可以添加 WebHooks 来进行通知。

  • 可以直接在仓库添加 WebHooks,选择触发条件后,输入接口地址【POST】与 Secret (可选),Github 会在我们完成触发条件时,携带此次操作的信息数据包请求一次这个 POST 接口,至于后面的处理就可以自定义啦。