GitHub Action 实现 Hexo 博客持续集成

无需配置 Hexo 环境~ 在任何可以打开网页的设备上即可编辑你的 Hexo 博客并部署!

你要先清楚某些东西…

  • 在私有仓库下使用 GitHub Action 是不完全免费的。 对于免费用户,你每个月只能使用 GitHub Action 工作 2000 min。这个数据计算方法特别有意思,详见 GitHub

据我多次测试,对于我的博客,GitHub Action 每次部署大概要耗时 1 min。 假设你每次提交需要耗时 2 min,这意味着你如果使用私有仓库存放后续操作中的源码,你每个月只能提交 1000 次博客。折算下来,也就是说,你每天只能提交 33 次博客。

需要特别说明的,上面的时间计算是在 Linux 环境下的计算。如果你在后续操作中使用的 Operating system 是 Windows 或 macOS ,则 GitHub Action 记录的时间分别是你实际使用时间的 2 倍和 10 倍。

话说,如果你能做到每天提交 33 次博客,请务必留个联系方式让我认识一下。没别的意思,就是想瞻仰一下劳模的风采。

  • 在测试过程中,我发现即使使用 Linux 作为 Operating system, GitHub Action 实际工作时间也和 GitHub 计费时间并不相同。 同时,我在 GitHub Action 界面发现如下文字:
This is the workflow execution time which may be different than the billed time.
  • 如果你需要自定义域名,你的CNAME文件应放在 Hexo 源码仓库的 source 文件夹下。
  • hexo-action@v1.0.0 会自动删除项目仓库下的.deploy_git文件。即每次提交源码后,部署 Hexo 的那个仓库的所有历史提交将会被清空。这个问题在 hexo-action@1.0.1 被修复。我认为这个修复是不合理的。
  • 如果需要添加额外的 node module,则在package.json中添加相应依赖。

默认已满足的条件

  • 已注册 GitHub 账号
  • 已有一个部署到 GitHub 且工作正常的 Hexo 博客
  • 有一定动手能力

接下来,让我们开始……

方法一


部署集成环境

  1. GitHub 建立一个新的仓库,公有还是私有,取决于你的选择。建议此时生成 SSH 密匙简化后续提交过程。

特别提醒,对于 GitHub 免费用户,私有仓库每个月的数据传输上限为 1GB。 <===该部分内容源自 GitHub 文档,但是实际操作中并未发现该现象,目前还在考证中。 GitHub Actions 部署时使用的数据不会计入数据传输上限。

  1. 在博客源码中新建.github/workflows/hexo.yml文件,在文件添加如下内容:
name: Deploy # workflow 名字

on:
  [push] # 触发事件

jobs:
  build: # Job 1 ID
    runs-on: ubuntu-latest # 设定运行环境为最新版 Ubuntu,如果你有把握的话,你也可以改成其它运行环境。参见文末备注。
    name: Deploy blog.
    steps:
    - name: Checkout # Step 1 获取源码
      uses: actions/checkout@v1 # 使用 actions/checkout@v1
      with: # 条件
        submodules: true ## Checkout private submodules(themes or something else).参见文末备注。

    # Caching dependencies to speed up workflows. (GitHub will remove any cache entries that have not been accessed in over 7 days.) 缓存压缩 node_modules,不用每次下载,使用时解压,可以加快工作流的执行过程,超过 7 天没有使用将删除压缩包。
    - name: Cache node modules # Step 2
      uses: actions/cache@v1
      id: cache
      with:
        path: node_modules
        key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
        restore-keys: |
          ${{ runner.os }}-node-          
    - name: Install Dependencies # Step 3 
      if: steps.cache.outputs.cache-hit != 'true' # 如果变量 cache-hit 不等于 true
      run: npm install # 安装 NPM 相关依赖

    # Deploy hexo blog website.
    - name: Deploy # Step 4
      id: deploy
      uses: sma11black/hexo-action@v1.0.1
      with:
        deploy_key: ${{ secrets.DEPLOY_KEY }}
        user_name: your github name #你 GitHub 用户名。如果去除该行则使用 bot。去除该行是不推荐行为。
        user_email: yourgithubemail@example.com #你 GitHub 邮箱。如果去除该行则使用 bot。去除该行是不推荐行为。
        commit_msg: ${{ github.event.head_commit.message }} #Hexo 部署博客的自动提交备注

部分内容需要根据你实际情况修改为相应内容

  1. push 你的博客源码到刚刚新建的仓库。

建议在 push 前进行一次 hexo clean。且在每一次hexo g后准备 push,都应该进行一次 hexo clean

  1. 输入如下命令再生成一对 SSH 密匙。
ssh-keygen -t rsa -f ~/.ssh/id_rsa_a -C "example@example.com"

如果你使用的是未预安装 OpenSSH 软件的 Linux 发行版,你需要先安装 OpenSSH 再进行如下步骤。 命令中的邮箱填自己 GitHub 的邮箱。此时会在本地生成一对公匙和私匙。

  1. 打开你 GitHub 存放源码的那个仓库,转到Settings > Secrets,创建一个名为DEPLOY_KEYSecret,复制上面生成的私匙内容。复制内容应该包含私匙开始的—–BEGIN OPENSSH PRIVATE KEY—– 和结束的 —–END OPENSSH PRIVATE KEY—–

  2. 打开你部署博客的那个仓库,即仓库名为 yourgithubname.github.io 的那个仓库,转到Settings > Deploy Keys,输入上面生成的公匙,勾选 “Allow write access”并确定。

  3. 享受你的 GitHub CI 吧~

备注内容(可以不看)

  • 其他可选的运行环境请参见 GitHub
  • 关于 Submodules 参见 GitHub

方法二

  1. 打开 github.com

  2. Settings - Developer settings - Personal access tokens - Generate new token 中创建密钥,勾选 Repo,拉到最下面,Generate token,接着将生成的 Token 保存下来(Token 只会出现一次,请务必妥善保管)

  3. 在你 Hexo 博客文件仓库/分支所在的仓库 的 Settings - Secrets - Add a new secret 创建俩个变量分别是 GH_REFGH_TOKEN。 GH_REF 内容为你 GitHub Pages 仓库的地址(不需要包含 https) GH_TOKEN 内容为上面所获取的 Token。

如果你对自动部署细节不感兴趣,可以直接跳转 成品 复制并根据自己情况修改即可。

配置内容

1.名称(这个随意取)

name: Hexo Blog Deploy

2.指定触发 workflow 的事件,这里选择的是推送至指定分支的事件

on:
  push: # 这里是推送事件
    branches:
      - master # 这里指定了推送的分支

3.设置时区,这里设置的是上海的

env:
  TZ: Asia/Shanghai

4.指定 workflow 所运行的系统,此处设置的是最新 Ubuntu。

blog-cicd:
  name: Hexo build
  runs-on: ubuntu-latest

5.检出代码,设置 Node 环境

- name: Checkout codes
  uses: actions/checkout@v2

- name: Setup node
  uses: actions/setup-node@v1.1.0
  with:
    node-version: "12.x" # Node 的版本

6.同步子模块。如果没有使用子模块的话,这一步可以忽略。

- name: Checkout submodules
  run: |
    auth_header="$(git config --local --get http.https://github.com/.extraheader)"
    git submodule sync --recursive
    git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive --depth=1    

7.缓存 .npm 目录,加快构建速度

- name: Cache Node Dependencies # Npm 缓存,这一步报错的话,把这部分删掉即可
  id: cache
  uses: actions/cache@v1
  with:
    path: .npm
    key: ${{runner.OS}}-npm-caches-${{ hashFiles('package-lock.json') }}

8.安装依赖。我建议,如果可以,请每次都执行以下步骤。

- name: Install dependencies
  run: |
    npm install hexo-cli -g
    npm install    

9.生成文件。

- name: Generate files
  run: |
    hexo clean && hexo generate    

10.将 GitHub Pages 仓库克隆下来,并将 .git 目录移动到生成文件的文件夹文件夹中(这样可以保留之前的 commit 记录),然后再将其推送到 GitHub Pages

- name: Deploy blog
  run: |
    git clone "https://${{ secrets.GH_REF }}" deploy_git
    mv ./deploy_git/.git ./public/
    cd ./public
    git config --local user.email "your@email" # 你的邮箱
    git config --local user.name "yourname" # 你的用户名
    git add .
    git commit -m "GitHub Actions Auto Builder at $(date +'%Y-%m-%d %H:%M:%S')"
    git push --force "https://${{ secrets.GH_TOKEN }}@${{ secrets.GH_REF }}" master:master    

成品

最后的 workflow

name: Blog Deploy

on:
  push:
    branches:
      - master

env:
  TZ: Asia/Shanghai

jobs:
  blog-cicd:
    name: Hexo build and deploy
    runs-on: ubuntu-latest

    steps:
      - name: Checkout codes
        uses: actions/checkout@v2

      - name: Setup node
        uses: actions/setup-node@v1.1.0
        with:
          node-version: "12.x"

# 若需要同步子模块的话,将下面的注释删掉即可
#
#      - name: Checkout submodules
#        run: |
#          auth_header="$(git config --local --get http.https://github.com/.extraheader)"
#          git submodule sync --recursive
#          git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive --depth=1

      - name: Cache Node Dependencies # Npm 缓存,这一步报错的话,把这部分删掉即可
        id: cache
        uses: actions/cache@v1
        with:
          path: .npm
          key: ${{runner.OS}}-npm-caches-${{ hashFiles('package-lock.json') }}

      - name: Install dependencies
        run: |
          npm install hexo-cli -g
          npm install          

      - name: Generate files
        run: |
          hexo clean && hexo generate          

      - name: Deploy blog
        run: |
          git clone "https://${{ secrets.GH_REF }}" deploy_git
          mv ./deploy_git/.git ./public/
          cd ./public
          git config --local user.email "your@email" # 你的邮箱
          git config --local user.name "yourname" # 你的用户名
          git add .
          git commit -m "GitHub Actions Auto Builder at $(date +'%Y-%m-%d %H:%M:%S')"
          git push --force "https://${{ secrets.GH_TOKEN }}@${{ secrets.GH_REF }}" master:master          

我的配置文件

如果你还是无法理解的话,可以直接复制我的配置文件,然后修改用户名和邮箱为自己 GitHub 的用户名和邮箱。

Note:请注意修改 Clone themes 中的主题链接为你所用的主题的 URL

name: GitHub Auto Buider For Blog

on:
  push:
    branches:
      - master
  schedule:
    - cron: '0 21 * * *'

env:
  TZ: Asia/Shanghai

jobs:
  blog-cicd:
    name: Hexo build and deploy
    runs-on: ubuntu-latest

    steps:
      - name: Checkout codes
        uses: actions/checkout@v2

      - name: Setup node
        uses: actions/setup-node@v1.1.0
        with:
          node-version: "12.x"

      - name: Clone themes
        run: |
          git clone -b dev https://github.com/YunYouJun/hexo-theme-yun.git themes/yun          

      - name: Cache Node Dependencies
        id: cache
        uses: actions/cache@v1
        with:
          path: .npm
          key: ${{runner.OS}}-npm-caches-${{ hashFiles('package-lock.json') }}

      - name: Install dependencies
        run: |
          npm install hexo-cli -g
          npm install
          npm audit fix          

      - name: Generate files
        run: |
          hexo clean && hexo generate          

      - name: Deploy blog
        run: |
          git clone "https://${{ secrets.GH_REF }}" deploy_git
          mv ./deploy_git/.git ./public/
          cd ./public
          git config --local user.email "xxxx" # 你的邮箱
          git config --local user.name "RimuruW" # 你的用户名
          git add .
          git commit -m "GitHub Actions Auto Builder at $(date +'%Y-%m-%d %H:%M:%S')"
          git push --force "https://${{ secrets.GH_TOKEN }}@${{ secrets.GH_REF }}" master:master          

参考文档:

Built with Hugo
主题 StackJimmy 设计