一个基于 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/下,内容:

代码YML · 31 行
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解决掉,所以这里我要自己写一下为什么我认为他这里完全爆杀我,从上面的几个问题出发就好了。