文章

GitHub Actions 小记

概述

GitHub Actions 是一个用来自动化软件开发工作流的工具。它的用途包括但不限于 CI/CD、生成文档、自动发布 Release、操作 Issue 等。它类似于 GitLab CI/CD、Jenkins 等 CI/CD 工具,有丰富的文档和社区支持,很适合用来入门。接下来我简单讲述一个最简单的构建 Go Web 应用并发布 docker 镜像到 DockerHub 的过程。

配置 GitHub Actions 需要一个 yaml 文件。一般有以下几个部分:

  • name 这个 action 的名称
  • on 触发条件
  • jobs 要运行的任务

触发条件

有很多事件可以触发工作流运行,详情可以看 Events that trigger workflows - GitHub Docs。列举几个常用的:

  • push:tags 标签触发,可以在 push 标签的时候触发构建、创建 Release 等
  • push:branches 某分支触发,可以在测试期间实现 push 代码后自动构建并部署
  • workflow_dispatch 在网页上手动触发

示例如下:

on:
  push:
    tags:
      - "v*"
  workflow_dispatch:

任务

一个工作流(workflow)可以有多个任务(job),每个任务又有多个步骤(step)。

一般来说,需要定义任务运行的环境和其步骤。步骤中又可以使用 action,或运行指定的指令等。一个简单的示例如下:

jobs:
  docker:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
	  - name: Login to DockerHub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}
      - name: Run Make
        run: make build-docker

runs-on 定义了这个job 的运行环境(操作系统和架构),完整的列表可以看这里

steps 定义了这个job 要执行的步骤。示例中的 actions/checkout@v4 docker/login-action@v3 均为预先写好的 action,是可以复用的一小段步骤。更多的 action 可以在 GitHub Marketplace 中找到。

对于预先写好的 action,一般会提供一些参数供你定义,使用 with 关键字即可传入这些参数。你也可以运行一些简单的命令,使用 run 关键字即可。

一开始理解“步骤”可能会比较模糊,你可以这么想:

  • 每个 job 会给你分配一台空白的机器,拥有一个空白的目录
  • 每个 step 相当于在这个空白机器上运行一条命令(或对于actions 来说是一个脚本)

因此你会在一个 job 的开头看到一些拉取代码,配置环境的 actions,然后再对代码进行运行单测、编译、发布等等。

Secrets

在运行工作流的过程中,可能会遇到一些需要传入敏感信息(例如上面的 dockerhub 的账号密码等)的情况,把这些敏感信息写在 yaml 明文里是不安全的,因此 GitHub 提供了 Secrets 功能。可以在项目中配置 secrets,并在工作流的 yaml 中通过 ${{ secrets.XXX }} 获取。

完整例子

这是我的 Go Web 应用脚手架的 workflow,完整文件可以见 这里

name: release

on:
  push:
    tags:
      - "*"

permissions:
  contents: write

jobs:
  goreleaser:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0
      - run: git fetch --force --tags
      - uses: actions/setup-go@v4
        with:
          go-version: stable
      - name: Docker Login
        uses: docker/login-action@v3.0.0
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}
      - uses: goreleaser/goreleaser-action@v5
        with:
          distribution: goreleaser
          version: latest
          args: release --clean
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

可以看到这个 workflow 的基础信息:名叫 release,在推送 tag 的时候触发。同时他定义了一个 job,叫 goreleaser ,有若干步骤。

  • 检出代码,相当于把代码拉取到构建机器。
  • 配置 Go 环境。
  • 登录到 DockerHub
  • 运行 goreleaser

GoReleaser 是一个 Go 的构建发布工具,能够把 Go 应用程序发布到 GitHub、DockerHub 等等,同时由于 Go 的跨平台特性,通过 GoReleaser 构建发布的二进制、镜像等也能支持多个平台。

配置好后,当 push 一个 tag 到 GitHub 时,这个 workflow 会自动运行,并发布。其效果如 Release v0.1.1 · LeslieLeung/gin-application-template · GitHub

Ref

License:  CC BY 4.0