一键部署 Hexo 博客到 GitHub Pages

Hexo 是一个快速、简洁且高效的博客框架,只需一条指令即可部署到 GitHub Pages, Heroku 或其他平台1

如果没有什么特殊的需求,将生成的静态网页托管到 GitHub Pages 是一个不错的选择。目前 Hexo 官方提供了2种方式一键部署到 GitHub Pages:

这两种方式对应了不同的使用场景,第一种方式适合博客源代码没有托管在 GitHub 的场景,第二种相反。博主选择了将博客源代码托管到了 GitHub,所以很自然的选择了第二种方式实现一键部署的需求,接下来具体看看如何利用 CI/CD 工具实现远程一键部署 Hexo 博客到 GitHub Pages。

一键部署博客

博主在几年前就接触了 Hexo 博客,当时 GitHub Actions 的正式版才推出不久(2019/11/13)2,参考了韩骏大佬的博客3使用了 AppVeyor 作为 CI/CD 工具,只可惜其免费版本不支持私有仓库。博客源代码仓库包含了非公开的配置信息(服务的tokensecret)以及加密文章的原文、草稿箱的草稿,因此源代码仓库设置为私有是必要的。而 GitHub Actions 作为 GitHub 自家的产品,对于当前的使用场景即使是私有仓库也完美支持。有一点需要注意的是对于私有仓库 GitHub Actions 有额度限制,不过即使是最低级别的 GitHub Free 也有相当可观的额度,具体可以查阅官方文档

选定 GitHub Actions 作为 CI/CD 工具后查阅 Hexo 官方给定的文档发现其设定是博客源代码与 GitHub Pages 储存在同一个仓库通过分支进行区分,但将 GitHub Pages 所在的仓库设置为私有需要订阅更高级别的产品4,这显然与我们的需求不符。

GitHub Pages is available in public repositories with GitHub Free and GitHub Free for organizations, and in public and private repositories with GitHub Pro, GitHub Team, GitHub Enterprise Cloud, and GitHub Enterprise Server. For more information, see "GitHub’s products."

通过查阅 Hexo 官方配置文件中复用的 Action peaceiris/actions-gh-pages@v3文档发现,经过简单配置和修改就可以实现我们的需求。

By default, your files are published to the repository which is running this action. If you want to publish to another repository on GitHub, set the environment variable external_repository to <username>/<external-repository>.

先分别贴上原版的配置文件和修改后的配置文件:

  • 原版配置文件

    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
    name: Pages

    on:
    push:
    branches:
    - main # default branch

    jobs:
    pages:
    runs-on: ubuntu-latest
    permissions:
    contents: write
    steps:
    - uses: actions/checkout@v3
    with:
    token: ${{ secrets.GITHUB_TOKEN }}
    # If your repository depends on submodule, please see: https://github.com/actions/checkout
    submodules: recursive
    - name: Use Node.js 16.x
    uses: actions/setup-node@v2
    with:
    node-version: '16'
    - name: Cache NPM dependencies
    uses: actions/cache@v2
    with:
    path: node_modules
    key: ${{ runner.OS }}-npm-cache
    restore-keys: |
    ${{ runner.OS }}-npm-cache
    - name: Install Dependencies
    run: npm install
    - name: Build
    run: npm run build
    - name: Deploy
    uses: peaceiris/actions-gh-pages@v3
    with:
    github_token: ${{ secrets.GITHUB_TOKEN }}
    publish_dir: ./public
  • 修改后的配置文件

    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
    name: Deploy GitHub Pages

    on:
    push:
    branches:
    - main # default branch

    jobs:
    deploy-gh-pages:
    runs-on: ubuntu-latest
    permissions:
    contents: write
    steps:
    - uses: actions/checkout@v3
    with:
    token: ${{ secrets.GITHUB_TOKEN }}
    # If your repository depends on submodule, please see: https://github.com/actions/checkout
    submodules: recursive
    - name: Install pandoc
    run: sudo apt-get install pandoc
    - name: Use Node.js 19.x
    uses: actions/setup-node@v2
    with:
    node-version: '19'
    - name: Cache NPM dependencies
    uses: actions/cache@v2
    with:
    path: node_modules
    key: ${{ runner.OS }}-npm-cache
    restore-keys: |
    ${{ runner.OS }}-npm-cache
    - name: Install Dependencies
    run: npm install
    - name: Build
    run: npm run build
    - name: Deploy
    uses: peaceiris/actions-gh-pages@v3
    with:
    deploy_key: ${{ secrets.ACTIONS_DEPLOY_KEY }}
    external_repository: username/external-repository
    publish_dir: ./public
    user_name: 'github-actions[bot]'
    user_email: 'github-actions[bot]@users.noreply.github.com'
    commit_message: ${{ github.event.head_commit.message }}

与原版的配置文件对比只修改了以下3个方面:

  1. 安装 pandoc
    1
    2
    3
    # line 19
    - name: Install pandoc
    run: sudo apt-get install pandoc
    • 与此文无关,因渲染器改为了hexo-renderer-pandoc
  2. 修改 Node.js 主版本:
    1
    2
    3
    4
    5
    # line 21
    - name: Use Node.js 19.x
    uses: actions/setup-node@v2
    with:
    node-version: '19'
    • 在本地使用node --version查看即可
  3. 配置peaceiris/actions-gh-pages@v3的传入参数:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    # line 36
    - name: Deploy
    uses: peaceiris/actions-gh-pages@v3
    with:
    deploy_key: ${{ secrets.ACTIONS_DEPLOY_KEY }}
    external_repository: username/external-repository
    publish_dir: ./public
    user_name: 'github-actions[bot]'
    user_email: 'github-actions[bot]@users.noreply.github.com'
    commit_message: ${{ github.event.head_commit.message }}
    • 删除github_token:对于external_repository使用external_repositorypersonal_token代替
    • 增加deploy_key:生成SSH Key Pair,在 GitHub Pages 仓库使用公钥设置Deploy keys并确保勾选Allow write access,在博客源代码仓库的Actions secrets and variables设置项使用私钥设置Secrets。配置文件里的ACTIONS_DEPLOY_KEY就是之前设置Secrets填的名字
    • 增加external_repository:GitHub Pages 仓库username/external-repository
    • 增加user_name:配置 GitHub Pages 仓库的 commit 用户为github-actions[bot]
    • 增加user_email:配置 GitHub Pages 仓库的 commit 用户邮箱为github-actions[bot]邮箱
    • 增加commit_message:配置 GitHub Pages 仓库的 commit message 为触发该 GitHub Actions 事件源的头部 commit message

修改完配置文件后将配置文件存放到博客源代码仓库的.github/workflows/filename.yml,以后有提交 push 到该仓库的main分支便可触发该配置文件对应的工作流完成 GitHub Pages 的自动部署。

一键推送源码

至此似乎已经大功告成,但博主觉得已经完成建站进入正常更新状态的博客,每次更新还需要git addgit commitgit push三个步骤才能完成博客更新还是略微麻烦,有没有办法能实现一键推送博客源代码?

使用 Hexo Deployer

Hexo Deployer是 Hexo 自带的部署工具,通过编写安装各种各样的 Hexo 插件,可以通过hexo deploy命令将 Hexo 博客一键部署到各种类型的托管服务,Hexo Deployer提供了 API 供开发者开发第三方插件实现该功能。

虽然 Hexo 官方的本意是部署博客,但似乎可以借助这个功能实现我们一键推送源码的需求,于是博主根据 hexo-deployer-git 编写了一个 Hexo 插件 hexo-auto-push-git

  1. 安装

    1
    $ npm install https://github.com/ChiuJun/hexo-auto-push-git.git --save-dev

  2. 配置

    1
    2
    3
    4
    5
    # You can use this:
    deploy:
    type: git
    branch: [branch]
    message: [message]
  3. 使用

    1
    $ hexo deploy

使用 alias shell

修改完博客配置希望看看效果,每次都要输入一串命令

1
$ hexo clean && hexo g && hexo s

想到可以用alias简化操作,突然想到alias也可以完成我们一键推送源码的需求

1
2
3
4
alias hexo_test="hexo clean && hexo generate && hexo server"
alias hexot=hexo_test
alias hexo_post_article_to_source_repo="git add -A && git commit -m \"docs: site updated `date \"+%Y-%m-%d %H:%M:%S\"`\" && git push -u origin HEAD:main"
alias hexop=hexo_post_article_to_source_repo

将后面两行alias命令添加到所使用 shell 的配置文件中,使用source命令更新下配置文件便可以使用别名hexop一键推送源码

1
$ hexop
至此,我们已经完成了一键推送源码以及一键部署博客,以后便可以愉快的写博客了!


  1. Hexo (2023a) Home page , Hexo. Available at: https://hexo.io/zh-cn/ (Accessed: 08 July 2023).↩︎

  2. Niyogi, S. (2019) New from universe 2019: Github for mobile, GitHub Archive Program, and more, The GitHub Blog. Available at: https://github.blog/2019-11-13-universe-day-one/#github-actions (Accessed: 08 July 2023).↩︎

  3. Han, J. (2017) Hexo的版本控制与持续集成, formulahendry. Available at: https://formulahendry.github.io/2016/12/04/hexo-ci/ (Accessed: 08 July 2023).↩︎

  4. GitHub, Inc. (no date) About GitHub Pages, GitHub Docs. Available at: https://docs.github.com/en/pages/getting-started-with-github-pages/about-github-pages (Accessed: 09 July 2023).↩︎