一个基于 GitHub Actions 部署 Hexo 博客的 workflow
本文最后更新于 2026年4月28日 下午
TL;DR
一套直接使用原始的 git方式管理,部署 hexo 博客的 workflow,实现静态托管的仓库不止托管网页内容,同时可以保存博客仓库所有信息。
为什么要这样
起因是水群看到的一个说法:



其实看完就大概能懂了,这个道理还挺简单的,熟悉 GitHub Actions 以及 CI/CD 工作流的人都能很轻松想到,不过可惜我太菜了看完才想到。
总之实现一下。
实现
在我的博客托管仓库新建一个分支 Blog-Source,里面的内容和我本地的博客文件夹完全一致。
在本地的文件夹创建一个本地的 git 仓库,通过 git workflow 来管理博客,抛弃原先的 hexo workflow 如 hexo deploy等。
新建一个 GitHub Actions,位于 ./.github/workflows/下,内容:
代码
name: Deploy to GitHub Pages
on:
push:
branches:
- Blog-Source
workflow_dispatch:
jobs:
build-and-deploy:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '22'
cache: 'npm'
- run: npm ci
- run: npx hexo generate
- uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./public
publish_branch: main
force_orphan: false
之后,就可以做到在 Blog-Source 分支的提交,都会触发自动博客的部署。
这样的好处有很多:
- 博客的托管仓库拥有了保存博客内容的功能,而不只是一堆编译后的 HTML 文件;
- 可以随时随地修改博客,比如其实上面这一大段是我拿手机在外面,通过 GitHub APP 写的,提交之后,CI 流水线可以直接帮我部署好。
下面是我开始设计的一套 workflow,但是发现非常垃圾,遂抛弃之(心疼我烧的 token)。
下面是一些当时有的没的的记录,择日分析掉。
今天先试了一下一套新的hexo博客部署的workflow,择日开源,先列TODO:
把这套框架开源,剥除掉里面和我自己博客有关的内容 以及和特定hexo主题有关的内容 以及不跨平台的内容
在开源的同时肯定要写README,所以在写文档的同时搞懂这些东西
我发现不能在博客的main分支写README不然每次部署会被覆盖,所以打算把当前的repo的分支结构改成一个空空如也的main,里面只有一个README,然后别的分支再负责各自的事情,即:把当前的main分支变成gh-pages分支,然后再开一个新的main分支,作为主分支但是什么也不放,只放一个README,试试效果
remote: Enumerating objects: 310, done.
remote: Counting objects: 100% (49/49), done.
remote: Compressing objects: 100% (37/37), done.
remote: Total 310 (delta 16), reused 16 (delta 5), pack-reused 261 (from 1)
Receiving objects: 100% (310/310), 9.18 MiB | 518.00 KiB/s, done.这一块的时候太慢了,需要解决
询问并发修改博客内容和博客框架配置的时候,两个action会不会冲突,经常看到有失败,这个是否有影响
建立docs-archive分支的目的:
- 让托管的仓库拥有保存文档原件的功能;
- 可以在网页端直接修改markdown文档,随后action会自动执行部署的workflow。
但是有这么一个问题:假设我在网页端改完了 / 新建了某个文件,结果我会发现:
- 在目前的这套本地的workflow下,我无法获取远端自己创建 / 修改的文档;
- 因而,如果本地的文档想要更新,会不可避免地覆盖之前远程修改 / 创建的内容。
这个问题其实是两套workflow的冲突:
- 在远程修改文件,本质是通过传统的git方式,改了某个markdown文件,然后add commit push(不过这三套操作在网页端基本是融为一体的),再触发由GitHub Action构建的CI/CD流水线,触发部署;
- 在本地的
./source/_posts文件夹内修改文件,走的是hexo的那一套,使用的是当前魔改过的npm run publish,但是本质上还是hexo CLI 命令的组合。总而言之,是本地的文档其实是没有使用git进行管理的!这些文件夹内根本就没有.git目录,将本地部署到远程依赖的还是hexo的那一套操作。 - 其实我有解决方案:
- 就是把自己的
./source/_posts文件夹抽出来,不参与之前的hexo式的workflow,而是使用git的方式,直接push到docs-archive分支; - 同理,对博客配置的修改也可以把
hexo-source分支的内容抽离下来,每次执行单独的push即可; - 剩下的部分,交给GitHub的CI/CD流水线执行
- 就是把自己的
- 这样看,现在的workflow其实还得改,但是我又感觉这样略麻烦,因为之前基本是一个一键的
hexo clean && hexo generate && hexo deploy就能解决所有操作,现在却要分成两个git仓库还得分开push,不知道有没有什么更好的方案。
得改一下.github/workflows/docs-archive.yml 的 docs-archive.yml的名字,可以改成docs-deploy.yml的名字,但是我不知道这会不会和我之前说的“询问并发修改博客内容和博客框架配置的时候,两个action会不会冲突,经常看到有失败,这个是否有影响”冲突?我觉得是不是应该分两个GitHub Action的yml文件好一点?
还有,我现在应该还有机会回滚到最开始的那种workflow吧?只需要在main分支reset到之前,然后继续使用之前hexo deploy的那一套workflow就好了吧?
npm run preview
本地预览:clean -> generate -> server
npm run build
本地构建验证:clean -> generate
npm run publish:posts
把 source/_posts 同步到 docs-archive
然后由 GitHub Actions 自动发布博客
npm run publish:source
把当前 Hexo 框架、主题、配置、脚本同步到 hexo-source
然后由 GitHub Actions 自动发布博客
npm run publish
先 publish:source,再 publish:posts
适合你既改了博客框架又改了文章的情况4/27日凌晨11点左右,和Kisechan交流了一下,发现自己设计的这套workflow被他平时用的那一套workflow完全爆杀,打算直接转而投向他那种了。
上面的所有东西可以当作作废。
TODO: 让那个会话的gpt总结一下我本来的设计,直接写在这里,让llm原汁原味概括一下就行。
日后自己再在这里补充一下kisechan的这一套workflow吧,说实话为什么我意识到他完全爆杀我,是因为我发现上面说的那些问题都可以被他这套workflow解决掉,所以这里我要自己写一下为什么我认为他这里完全爆杀我,从上面的几个问题出发就好了。