使用 GitHub Actions 自动部署

2022-05-31

GitHub Actions 是 GitHub 的线上持续集成 (CI) 服务,它提供了非常丰富的操作,能够在线上自动化地完成许多繁琐的操作。

Action 基本配置

GitHub 的 Action 配置文件放在项目下的 .github/workflows 目录中,我们可以新建一个 yaml 文件,例如 gh-pages.yml

一般一个 .yml 文件就是一次 CI 的工作流程,而一个 workflow 下可能有多个 jobstepaction,它们是逐级包含的关系。

 

Action 配置大致可以分为三个主要的字段:nameonjob

Name 字段

第一个字段是 name,它指定这个工作流程的名字,如果这个字段留空则默认为文件名。

name: Github Pages

On 字段

第二个字段是 on,它指明了触发这个工作流程的条件。

on:
  push:
    branches:
      - main

上面的配置说明只有动作为 push 而且对象分支是 main 才会触发这个工作流程。如果要配置多个触发动作,可以这样写:

on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main

上面代码指定,push 事件或 pull_request 事件都可以触发这个工作流程。

如果你需要在触发动作后输入参数,请使用 workflow_dispatch 字段。

Job 字段

job 字段是最为重要的字段,这里记录了所有工作流程的步骤和动作。

  1. needs 字段控制多个 job 之间的依赖和执行的顺序,假设 deploy 需要在 build 之后,那么应该这样写:

    jobs:
      build:
      deploy:
    	needs: build
    
  2. runs-on 字段指明这个工作运行的平台,假设这个工作需要运行在最新的 Ubuntu 环境下。

    jobs:
      deploy:
    	 runs-on: ubuntu-latest
    
  3. steps 字段是动作的具体执行,每个 job 都可以包含一至多个 step,每个 step 都可以有如下的字段:

    • jobs.<job_id>.steps.name:步骤名。
    • jobs.<job_id>.steps.run:该步骤运行的命令。
    • jobs.<job_id>.steps.env:该步骤所需的环境变量。

GitHub Page 的自动部署

我的需求是当我向 Hugo 项目仓库提交修改后,Action 能自动构建网页,并刷新 Algolia 索引,最后将产生的静态文件分发至指定的 GitHub Page 仓库。

准备工作

由于 GitHub 仓库可能是公开的,所以我们要先将一些应用的 TOKEN 写入仓库中的私密变量中。

在仓库的 setting -> security -> secrets and variables -> action 下可以新建私密变量。这里我建了两个变量,分别是用于仓库提交的 HUGO_DEPLOY_TOKEN 和用于更新搜索索引的 ALGOLIA_ADMIN_KEY

私密变量

这两个私密变量将会在下面的 steps 中使用。

注意这里的 HUGO_DEPLOY_TOKEN 并非由项目仓库产生,而是在你的 GitHub Page 仓库中获得,以获得对其推送的权限,这里只是记录在你的项目仓库中而已。

具体步骤

我希望工作流程在 pushpull_request 后被触发,所以 on 字段很容易写。

on:
  push:
    branches:
      - main  # Set a branch to deploy
  pull_request:
    branches:
      - main
  workflow_dispatch:

接下来是 steps 的统一配置:

runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
        with:
          submodules: true  # Fetch Hugo themes (true OR recursive)
          fetch-depth: 0    # Fetch all history for .GitInfo and .Lastmod

这里我指定了最新的 Ubuntu 为工作的虚拟容器,并且设置了主题子模块的检索。

下面是设置 Hugo 并构建网页

  - name: Setup Hugo
	uses: peaceiris/actions-hugo@v2
	with:
	  hugo-version: 'latest'
	  extended: true

  - name: Build
	run: |
		npm install --legacy-peer-deps
		npm run build

这里使用的 Hugo 版本是最新的 extended 版,因为 extended 版本对 scss 的支持较好。

刷新 Algolia 的搜索索引

  - name: Update Algolia Index (zh_cn)
	env:
	  ALGOLIA_APP_ID: RHHT49UC27
	  ALGOLIA_ADMIN_KEY: ${{ secrets.ALGOLIA_ADMIN_KEY }}
	  ALGOLIA_INDEX_NAME: 'zh_cn_index'
	  ALGOLIA_INDEX_FILE: './public/index.json'
	run: |
	  npm run algolia

最后只要将构建好的文件发布至 GitHub Page 仓库即可

  - name: Deploy
	uses: peaceiris/actions-gh-pages@v3
	with:
	  personal_token: ${{ secrets.HUGO_DEPLOY_TOKEN }}
	  external_repository: sheffeyg/sheffeyg.github.io
	  publish_branch: gh-pages  # 推送到 gh-pages 分支
	  publish_dir: ./public     # Hugo 的生成目录
	  destination_dir: ./docs   # Page 的目标目录,默认为根目录
	  # cname: github.com       # 第三方域名
	  # commit_message: ${{ github.event.head_commit.message }}
	  allow_empty_commit: true

这里的 publish_dir 是构建后源文件的存储目录,而 destination_dir 是在目标仓库中部署的路径,默认的部署路径是目的仓库的根目录,在仓库仓库的 setting -> pages 设置项中可以将该目录改为 ./doc,gh-pages 将以该路径作为根路径进行渲染。

[ Code ]