使用 GitHub Actions 实现博客自动化部署

blog-deploy

TL;DR

最近把博客渲染、部署的工作从我很久前自己写的 blog-deploy 迁移到了 Hugo,原因是前者功能太简单了,而又无心再去维护。顺便又优化了下博客样式,加入了近年来流行的暗色元素。

由于我的博客是全权托管在 GitHub 上的,以前 repo 全部都是公开的,后来不想这样了,因为有些还没写完的文章我不想那么早 push 上去就被别人看到(内容需要沉淀才会有价值),但是为了在多个设备间同步又必须 push。所以我把博客的 repo 设置为了私有。但是随之而来的是私有 repo 不能用免费的 Travis,不能享有免费的 Pages 服务。

所以我选择了使用如下方式:

  • 原文仓库私有
  • 单独开一个公开 repo 作为 Pages,部署在 gh-pages 分支
  • 文章发布时针对性渲染,Hugo 里对应的就是 draft: true

GitHub Actions

上面说了那么多,现在进入主题。GitHub Actions 是 GitHub 最近一段时间(被巨硬收购后)推出的一款持续集成服务。它相对于 Travis CI 来说有更高的可玩性,更重要的是他对私有仓库免费!

一切准备就绪后,在 GitHub 创建两个 repo:

  • blog:私有,用于放置 Hugo 和博客文章等文件;
  • blog-pages:公开,放置 Hugo 渲染出的博客静态文件;

创建部署密钥

由于我们需要使用 GitHub Actions 实现自动化部署,所以需要给予对 blog-pages 仓库的写权限,这里我使用的是 GitHub 的 Deploy keys 功能。

使用如下指令可以创建部署密钥,执行后会在当前目录生成 gh-pagesgh-pages.pub 两个文件,前者是私钥,后者为公钥。

ssh-keygen -t rsa -b 4096 -C "noreply@github.com" -f gh-pages -N ""

然后打开 blog-pages 仓库页面,找到顶部导航中的 Settings,点击后选择 Deploy keys,点击 Add deploy key 贴入公钥文件的内容。

还需要在 blog 这个私有仓库的 Settings - Secrets - New secret 界面添加私钥。其中 Name 一栏我叫 ACTIONS_DEPLOY_KEY,你也可以改别的,但是要同样替换掉下面 GitHub Actions 配置里的名字。

添加 GitHub Actions 配置

blog 仓库根目录创建 .github/workflows/deploy.yaml 文件,后面的 deploy.yaml 文件名你可以自定义。

name: Build and Deploy
on:
  push:
    branches:
      - master
jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@master
      - name: Clone theme
        run: |
          git clone --depth 1 https://github.com/sxyazi/hugo-theme-lavias.git themes/hugo-theme-lavias
      - name: Cache Hugo
        id: cache-hugo
        uses: actions/cache@v3
        with:
          path: /tmp/hugo
          key: ${{ runner.os }}-hugo
      - name: Setup Hugo
        if: steps.cache-hugo.outputs.cache-hit != 'true'
        run: |
          wget https://github.com/gohugoio/hugo/releases/download/v0.102.2/hugo_extended_0.102.2_Linux-64bit.tar.gz -O hugo.tar.gz
          tar fxz hugo.tar.gz -C /tmp && chmod u+x /tmp/hugo
      - name: Build
        run: |
          /tmp/hugo --minify
      - name: Deploy
        uses: peaceiris/actions-gh-pages@v3
        with:
          # cname: sxyz.blog
          publish_dir: public
          force_orphan: true
          deploy_key: ${{ secrets.ACTIONS_DEPLOY_KEY }}
          external_repository: sxyazi/blog-pages

你需要将 external_repository 的值修改成你的公有仓库的名字。如果你有绑定域名的需要,把上面代码中的 cname 项解除注释改成你自己的域名就可以了,域名 DNS 需要 CNAME 解析到 <USERNAME>.github.io<USERNAME> 是你的 GitHub 用户名。

把上面文件发布到 GitHub 上,就会自动开始部署。如果构建流程没有报错的话,就代表博客已经成功部署了一次了。下次再去修改博客里的任何文件时就都会再重复这一自动步骤了。