「GitHub Actions」- 持续集成服务(学习笔记)

更新日期:2021年04月20日

问题描述

GitHub Actions 是 GitHub 的持续集成服务,类似与 Jenkins、Travis CI、GOCD 等等工具,都是为了完成自动化任务。于 2018 年 10 月推出,正式版于 2019 年 11 月正式推出。

最近(04/09/2021)还火了一把:黑客用 GitHub Action 服务器挖矿,三天跑了 3 万个任务,代码惊现中文……啊哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈

该笔记将记录:如何使用 GitHub Actions 服务来构建自己的应用,以及常见问题处理。

解决方案

快速入门

1)在项目目录中,创建 .github/workflows/example.yml 文件。

2)并将如下内容写入 example.yaml 文件(如下为官方示例,同时我们也进行简单补充):

name: learn-github-actions
on: [push]
jobs:
  check-bats-version:
    runs-on: ubuntu-latest
    steps:
      # 拉取代码(GitHub Action 不会自动拉取仓库代码,因此基本每个 Workflow 中都有该 Action)
      - uses: actions/checkout@v2
      # 安装 NodeJS 环境(其他 Action 可以参考 Actions Marketplace 页面)
      - uses: actions/setup-node@v1
      - run: npm install -g bats
      - run: bats -v

3)最后提交代码,然后就能够在仓库主页的 Actions 中看到 CI 的执行过程。

解释说明

1)runs-on: ubuntu-latest,表示使用 GitHub 提供的 ubuntu-latest 主机。目前(02/02/2021)指向 18.04 TLS 版本,预装 Docker-Moby 19.03.14、Pip3 9.0.1、Docker Compose 1.27.4、jq 1.5 等等很多应用。在安装必要应用前,建议阅读官方文档(参考 virtual-environments/Ubuntu1804-README.md at main 文档),因为多数常见应用已预装,无需我们再次安装。

2)指令 run 与 uses 不能出现在同个字典中,否则提示 a step cannot have both the `uses` and `run` keys 错误。

# 这是错误的写法
- uses: actions/checkout@v2
  run: npm install -g bats

相关文档

快速入门,参考文档:Introduction to GitHub Actions - GitHub Docs(该文档足够用于快速入门)
全部指令,参考官方:Workflow syntax for GitHub Actions - GitHub Docs
Actions Marketplace:GitHub Marketplace · Actions to improve your workflow

uraimo/run-on-arch-action - 构建非 x86 应用。

定义 Job 执行顺序(依赖)

参考 jobs.<job_id>.needs 指令。

敏感信息管理(Secret)

私密(Secret)信息管理,参考 Encrypted secrets - GitHub Docs 文档。如下为学习笔记:

功能说明

敏感信息可以保存在 Organization, Repository, Repository Environments 中。

在 Organization 中,定义 Secret 可以用于所有 Repository,还可以通过访问控制来允许特定 Repository 访问 Organization 的 Secret。

在 Repository 中,创建的 Secret 仅能在当前仓库中中使用。

在 Repository Environments 中,可以允许要求的 Reviewer 访问 Secret。但是,无法在 Workflow 的 Job 中使用,要经过同义后才能使用。

对于同名的 Secret,最低级的优先级最高,即:Repository Environments > Repository > Organization

创建 Secret 信息

如何在 GitHub 中创建,参考 Creating encrypted secrets for xxxx 文档,该已经文档描述如何在 Organization, Repository, Repository Environments 中创建 Secret 信息。

使用 Secret 信息

在 Workflow 中,可以如下方式引用 Secret 信息:

steps:
  - shell: bash
    env:
      SUPER_SECRET: ${{ secrets.SuperSecret }}
    run: |
      example-command "$SUPER_SECRET"
  - name: Hello world action
    with: # Set the secret as an input
      super_secret: ${{ secrets.SuperSecret }}
    env: # Or as an environment variable
      super_secret: ${{ secrets.SuperSecret }}

更多的使用方法,参考 Using encrypted secrets in a workflow 文档。

注意事项

1)官方不建议在 Secret 中使用结构化数据,比如 JSON,这是为了确保 GitHub 处理日志中的私密信息。

添加 Runner 主机

问题描述

最开始,我们使用 GitHub Action 提供的免费主机,来完成构建任务。但是,默认的 Linux 主机每月仅有 3000 分钟,这对于我们来说是不够的,我们需要完成更多的构建任务。

好在 GitHub Action 允许添加自己的主机。因此,我们能够将自己的主机作为 GitHub Action 节点,来完成构建任务。

该部分笔记将记录:如何完成该设置,以及常见问题处理方法(参考 About self-hosted runners - GitHub Docs 文档)。

解决方案

1)我们使用组织仓库,需要在组织内的项目能够使用该节点进行构建。因此:Organization => Settings => Actions => Self-hosted runners => Add new
2)此时,会显示添加 Runner 的命令,按照要求执行即可。注意,不能使用 Root 用户运行,否则提示 Must not run with sudo 信息;
3)然后,在 <workflow>.yml 中,通过 runs-on: [self-hosted, linux, ARM64] 来选择节点。

如果遇到 No runner matching the specified labels was found: self-hosted. 错误,则会有如下愿意:
1)通过 runs-on 标签,未能找到匹配的主机
2)受到设置的限制,某些仓库无法在该 Runner 中执行构建。需要进行如下设置:

Actions => Self-hosted runners => Runner groups => ... => Edit name and repository access => Allow public repositories

我们的 Workflow 脚本(仅供参考)

我们的需求比较简单:
1)在特定分支构建 Docker 镜像,并推送 DockerHub 仓库;
2)此外,我们使用 Docker Buildx 来构建多架构镜像;

下面是我们使用的 Workflow 脚本:

name: Build Docker Images

on:
  push:
    branches:
      - master
      - main
      - 'v*'

jobs:
  build:
    runs-on: [self-hosted, Linux]
    defaults:
      run:
        shell: bash
    steps:
      - name: "Checking out code"
        uses: actions/checkout@v2
        with:
          submodules: recursive
      - name: "Login to DockerHub"
        uses: docker/login-action@v1
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_PASSWORD }}
      - name: "Set up QEMU"
        uses: docker/setup-qemu-action@v1
        with:
          image: tonistiigi/binfmt:master
      - name: "Set up Docker Buildx"
        uses: docker/setup-buildx-action@v1
      - name: "Building docker images"
        run: |
          image="k4nzdroid/$(basename ${GITHUB_REPOSITORY})"
          
          tag=${GITHUB_REF#refs/heads/}
          if [ "$tag" = 'master' || "$tag" = 'main' ]; then
              tag=lable
          fi
          
          docker buildx build \
              --output "type=image,push=true" \
              --file "Dockerfile" \
              --tag "${image}:${tag}" \
              --platform "linux/amd64" \
              "."

参考文献

博客园/你知道什么是 GitHub Action 么?
GitHub Actions 入门教程
virtual-environments/Ubuntu1804-README.md at main · actions/virtual-environments
Encrypted secrets - GitHub Docs
Adding self-hosted runners - GitHub Docs
Self-hosted runners are not visible to GitHub Actions workflows in public repositories by default: "No runner matching the specified labels was found:" - Code to Cloud / GitHub Actions - GitHub Support Community
Workflow syntax for GitHub Actions - GitHub Docs


ToC

问题描述

解决方案

快速入门

解释说明

相关文档

定义 Job 执行顺序(依赖)

敏感信息管理(Secret)

功能说明

创建 Secret 信息

使用 Secret 信息

注意事项

添加 Runner 主机

问题描述

解决方案

我们的 Workflow 脚本(仅供参考)

参考文献