从“手工作坊”到“自动化工厂”:我的 Hexo 博客 CI/CD 踩坑与实践实录
从“手工作坊”到“自动化工厂”:我的 Hexo 博客 CI/CD 踩坑与实践实录
作为一个计算机科学与技术专业的大四学生,折腾个人博客似乎是大学生涯的“必修课”。在此之前,我的 Hexo 博客(搭载了好看的 Butterfly 主题)一直采用的是最原始的本地部署方式:每次写完文章,都要在本地终端敲下 hexo clean && hexo g -d。
虽然命令不复杂,但这存在几个致命痛点:
- 重度依赖本地环境:万一电脑重装系统,或者换了台电脑,又得重新配置 Node.js 和一大堆依赖,简直是场灾难。
- 缺乏版本控制:只有生成的静态网页托管在云端,博客的 Markdown 源码如果忘记备份,一旦硬盘损坏,心血全部白费。
- 不够“运维”:作为一个未来想从事运维(DevOps)方向的人,怎么能忍受这种纯手工的低效操作呢?
为了解决这些问题,我决定引入现代软件工程的基础设施——CI/CD(持续集成与持续部署),把发布的脏活累活全部交给 GitHub Actions。这篇文章记录了我的整个折腾过程以及踩过的那些“大坑”。
一、 架构设计:双分支策略
在开始之前,我们需要对 GitHub 仓库的结构进行改造。采取“源码与产物分离”的原则:
hexo-source分支:用来存放博客的所有原材料(Markdown 文章、主题文件、_config.yml、package.json等)。这是我们平时打交道的分支。main分支:用来存放 Hexo 编译后生成的纯静态 HTML/CSS/JS 文件。GitHub Pages 直接读取这个分支对外展示。
二、 核心图纸:编写 GitHub Actions 工作流
在博客根目录下创建 .github/workflows/deploy.yml 文件。这就好比给 GitHub 机器人写了一份 SOP(标准作业程序)。
YAML
1 | name: Hexo Blog CI/CD |
当这套流程跑通后,我只需要执行 git push,剩下的机器会自动帮我完成。
三、 血泪踩坑记(重点)
你以为写完脚本就万事大吉了?实际上,我在跑这套流水线时经历了无数个报错和“白屏”,以下是排查和解决的过程:
坑 1:GitHub 机器人权限不足 (Failed in 10s)
一开始跑流水线,只用了 10 秒就亮起了红灯报错。
- 原因:GitHub 默认的安全策略限制了 Action 的写权限,机器人没法把代码推送到
main分支。 - 解决:进入仓库
Settings->Actions->General,滚动到底部将Workflow permissions改为 Read and write permissions。
坑 2:网页部署成功,但打开是白屏!
Actions 一路绿灯,打开博客却是一片空白,查看网页源码发现也是空的。
- 原因 1:主题变成“空壳”。因为 Butterfly 主题本身是一个 Git 仓库,直接丢进源码里会被识别为 Submodule(子模块)。如果没有配置
.gitmodules,云端拉下来的主题文件夹就是空的。- 解决:进入本地
themes/Butterfly,删掉隐藏的.git文件夹,将其降维成普通文件夹,然后重新git add并推送。
- 解决:进入本地
- 原因 2:缺少渲染器插件。本地偷偷装过 Pug 和 Stylus 渲染器,但没写进配置里,导致云端机器人不会翻译主题模板。
- 解决:执行
npm install hexo-renderer-pug hexo-renderer-stylus --save,强制将其写入package.json,一起推送到云端。
- 解决:执行
坑 3:本地 Git 一直报错 Connection was reset
代码修好了,却死活推不上 GitHub。
原因:本地网络环境问题,Git 客户端迷路了,没走本机的代理端口。
解决:给 Git 配置本地代理。由于我的代理软件端口是 7897,执行以下命令精准放行:
Bash
1
2git config --global http.proxy http://127.0.0.1:7897
git config --global https.proxy http://127.0.0.1:7897
坑 4:所有文章的发布时间都变成了“今天”
好不容易看到界面了,结果发现所有历史文章的日期全变了。
- 原因:由于 Hexo 默认读取文件的“创建时间”作为文章日期。在 GitHub Actions 启动的全新虚拟机里,源码文件都是“刚刚”拉取下载的,所以全变成了今天。
- 解决:在前面的
deploy.yml脚本中,给 checkout 步骤加上fetch-depth: 0拉取完整历史。当然,最稳妥的办法还是在每篇 Markdown 文件的头部(Front-matter)老老实实写上date: YYYY-MM-DD。
四、 总结
将博客从手动挡升级到自动挡,虽然中间踩了不少坑,但也让我真切体会到了自动化运维的魅力。现在,无论我是在图书馆的电脑上,还是用平板,只要能访问 GitHub,就能随时修改发布我的文章。
这也算是我迈向专业开发/运维道路上的一个小小里程碑。技术折腾不止,期待未来能在服务器、网络和架构上探索更多有趣的玩法!
