
搭一个 Hexo 博客不难,难的是「每次写完还要本地 hexo generate 再手动推一堆静态文件」。把构建交给 GitHub Actions 后,工作流就变成:写文章 → git push → 几十秒后自动上线,本地连 node_modules 都不用装。这篇记录一套能直接抄的配置,以及我自己踩到的几个坑。
为什么用 Actions,而不是本地 hexo deploy
传统做法是本地构建好,再用 hexo-deployer-git 把 public/ 推到 gh-pages 分支。问题是:
- 换台电脑就得重新装环境;
- 构建产物进了 git 历史,仓库越来越臃肿;
- 忘了构建直接推源码,线上就不更新。
交给 Actions 后,仓库里只放源码,构建在云端干净环境里跑,产物直接交给 GitHub Pages,不落进 git 历史。这是目前的主流做法。
一份能直接用的工作流
在仓库根目录建 .github/workflows/pages.yml:
1 | name: Deploy Hexo site to Pages |
关键点:
- 用官方的
configure-pages/upload-pages-artifact/deploy-pages三件套,不用自己折腾gh-pages分支。 permissions三行必须有,否则deploy-pages没权限。build和deploy拆成两个 job,部署单独跑、状态更清晰。
坑一:项目站的子路径
如果你的仓库不是 用户名.github.io,而是普通仓库(比如 blogs),站点会发布在子路径 https://用户名.github.io/blogs/ 下。这时 _config.yml 必须同时设对两项:
1 | url: https://用户名.github.io/blogs |
root 没设的话,CSS、JS、图片全会去根路径找,结果就是「页面能打开但样式全丢」。设好后构建产物里的链接会变成 /blogs/css/style.css,本地 hexo server 也会跑在 localhost:4000/blogs/。
坑二:npm ci 需要 lockfile
工作流里用了 npm ci(比 npm install 更快、更可复现),但它**强依赖 package-lock.json**。Hexo 脚手架默认可能给的是 yarn.lock,于是 Actions 直接报错。本地补一条即可:
1 | npm install --package-lock-only # 只生成 package-lock.json |
把 package-lock.json 提交进仓库,cache: npm 的缓存也才能命中。
坑三:第一次必须手动开 Pages 开关
工作流写好推上去,第一次大概率还是失败,错误卡在 Setup Pages 这一步。原因是仓库还没启用 Pages:
- 打开仓库 Settings → Pages;
- Build and deployment → Source 选 GitHub Actions;
- 回 Actions 页面 Re-run jobs 重跑。
这一步只需做一次,之后每次 push 就全自动了。
坑四:GitHub 偷偷塞进来的 Jekyll 工作流
这个最隐蔽。当你在网页上启用 Pages 时,GitHub 有时会自动帮你提交一个 Jekyll 工作流(jekyll-gh-pages.yml)。于是仓库里同时有两个工作流都监听 push 且都往 Pages 部署:
- 你的 Hexo 工作流——正常构建;
- 自动塞进来的 Jekyll 工作流——把 Hexo 源码当 Jekyll 编译,必然失败,还和 Hexo 抢同一个
github-pages部署。
表现就是:明明 Hexo 构建成功了,线上内容却时好时坏、或者总有一条红叉。解决很简单——删掉那个 Jekyll 工作流:
1 | git rm .github/workflows/jekyll-gh-pages.yml |
日常发文流程
配好之后,写博客就只剩三步:
1 | npx hexo new "文章标题" # 生成 source/_posts/文章标题.md |
剩下的构建和发布,交给 Actions 就行。
小结
- 用官方 Pages Actions 三件套,源码归源码、产物归 Pages;
- 项目站记得
url+root一起设子路径; npm ci配package-lock.json;- 第一次手动把 Pages 的 Source 设成 GitHub Actions;
- 留意并删掉 GitHub 自动塞的 Jekyll 工作流。
这套跑通之后,博客就真正变成「写完即发」了。