GitHub Actions

相关链接: 持续集成持续部署GitHub Actions 文档GitHub Actions 入门教程

持续集成由很多操作组成,包括 抓取代码、构建、测试、打包、发布、部署 等等,GitHub 把这些操作称为 actions。

GitHub Actions入门

GitHub Actions 是 GitHub 的持续集成服务,用来自动化工作流程,其具有功能强大的执行环境。我们可以发现、创建和共享 Actions,还可以组合这些 Actions 自定义 workflow

GitHub 做了一个 官方市场 ,可以发现他人共享的 actions。

关于 GitHub Actions

GitHub Actions使您可以直接在GitHub存储库中创建自定义软件开发生命周期(SDLC)工作流。 我们可以编写单个任务(称为 actions ),并将其组合以创建自定义的自动化工作流程,也可以在存储库中对其进行编辑,以在GitHub上构建,测试,打包,发布或部署任何代码项目。

工作流在Linux,macOS,Windows或GitHub托管服务器上的容器中运行。

默认情况下,fork的存储库中的工作流不运行。

使用限制工作流程运行通知

关于 workflows

借助 workflows ,可以使用各种工具和服务来自动化软件开发生命周期,并在容器中运行。

可以在存储库中创建多个 workflow,需要使用 YAML 语法配置 workflows,且必须将 workflows 放在存储库根目录中的 .github/workflows/ 目录中。

workflow 必须至少具有一个 job,并且 jobs 包含一组执行单个任务的 steps 。Steps 可以运行命令或使用 action。我们可以创建自己的 actions 或使用 GitHub 社区共享的 actions ,并根据需要进行组合。

成功触发 workflow 后,我们将看到 workflow 每一步的构建日志、测试结果、状态。Annotated workflow run image

我们还可以接收有关工作流状态更新的通知,请参阅“ 为通知选择传递方式 ”。

创建一个 workflow 文件

1、在存储库的根目录中,创建一个名为 .github/workflows/ 的目录来存放工作流文件。

2、在 .github/workflows/ 下,为 workflow 添加一个 .yml.yaml 文件,例如 .github/workflows/continuous-integration-workflow.yml

3、使用 GitHub Actions 的 Workflow 语法自定义工作流。

4、将 workflow 文件中的更改提交到要运行 workflow 的分支。

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
name: Greet Everyone
# This workflow is triggered on pushes to the repository(此工作流在推送到存储库时触发)
on: [push]

jobs:
build:
# Job name is Greeting(Job的名称是Greeting)
name: Greeting
# This job runs on Linux(此Job在linux上运行)
runs-on: ubuntu-latest
steps:
# This step uses GitHub's hello-world-javascript-action: https://github.com/actions/hello-world-javascript-action
- name: Hello world
uses: actions/hello-world-javascript-action@v1
with:
who-to-greet: 'Mona the Octocat'
id: hello
# This step prints an output (time) from the previous step's action.(打印上一步操作的输出<时间>)
- name: Echo the greeting's time
run: echo 'The time was ${{ steps.hello.outputs.time }}.'

使用 events 触发 workflow

可以配置的 workflow 启动条件:

  • GitHub 事件。例如当某人将提交推送到存储库、创建问题或拉取请求时。
  • 预定事件开始
  • 发生外部事件

1、要在发生GitHub事件后触发 workflow ,请在 on: 后面添加事件值。例如:

1
2
name: descriptive-workflow-name
on: push # 将更改推送到存储库中的任何分支时,将触发此工作流。

2、要 schedule (计划、安排)一个 workflow ,可以在工作流程文件中使用 POSIX cron syntax。计划工作流程的最短时间间隔是5分钟。例如:此工作流每小时触发一次。

1
2
3
on:
schedule:
- cron: '0 * * * *'

3、要在发生外部事件后触发工作流,可以通过调用 “创建存储库调度事件” REST API端点来调用repository_dispatch webhook事件。

筛选特定的分支,标签和路径

可以将 workflow 设置为仅在某些 branch 上运行。

例如:当在 master 分支上推送 test 目录中的文件或推送到 v1 标签时,此工作流运行。

1
2
3
4
5
6
7
8
9
10
on:
push:
branches:
- master
tags:
- v1
# file paths to consider in the event. Optional; defaults to all.
# 事件中要考虑的文件路径。可选的;默认为全部。
paths:
- 'test/*'

选择虚拟环境

我们可以在GitHub托管的虚拟机上或Docker容器中运行 workflows 。可以为 workflow 中的每个 job 指定虚拟环境,包括系统、工具、程序包和设置。

我们可以从不同类型和版本的虚拟主机中进行选择,包括Linux,Windows和macOS。workflow 中的每个 job 都在相同的虚拟环境中执行,从而允许该 job 中的 actions 使用文件系统共享信息。

指定虚拟主机运行 job :

1
runs-on: ubuntu-18.04

配置 build matrix

要同时跨多个操作系统,平台和语言版本进行测试,可以配置构建矩阵。

定义操作系统矩阵时,必须将必需 runs-on 关键字设置为当前 job 的操作系统,而不是对操作系统名称进行硬编码。可以使用 matrix.os 上下文参数设置 runs-on

例子:此构建矩阵将使用不同版本的 Node.js 和 Ubuntu 系统运行 job 。

1
2
3
4
5
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-16.04, ubuntu-18.04]
node: [6, 8, 10]

配置工作流程

使用环境变量

GitHub为每个GitHub Actions工作流程运行设置 默认环境变量 ,但是您也可以在 workflow 文件中设置自定义环境变量,请查看 环境变量的命名约定

1
2
3
4
5
6
7
steps:
- name: Hello world
env:
FIRST_NAME: Mona
middle_name: The
Last_Name: Octocat
run: echo Hello world $FIRST_NAME $middle_name $Last_Name!

创建和使用加密 Secrets

Secrets 是在存储库中创建的加密环境变量,并且只能由 GitHub Actions 使用。 GitHub 使用 公钥认证加密Poly1305密码算法 在Web浏览器中加密 Secrets。

在 action 中使用 Secrets,必须在 workflow 文件中设置 Secrets 为输入或环境变量。

GitHub 自动修改打印到日志中的 Secrets,但您应避免有意将 Secrets 信息打印到日志中。

Secrets 名称不能包含任何空格。为确保 GitHub 修改日志中的机密,请避免将结构化数据用作 Secrets 值。例如,避免创建包含 JSON 或编码的 Git Blob 的 Secrets。

在存储库主页点击 Settings,在左侧边栏中,点击 Secrets,输入name和value,点击 Add secrets。

image-20191108115243622

除了 GITHUB_TOKEN,当触发一个 fork 存储库的 workflow 时,secrets 不会传递给 runner。

1
2
3
4
5
6
steps:
- name: Hello world action
with: # Set the secret as an input
super_secret: ${{ secrets.SuperSecret }} # 使用secrets上下文访问在存储库中创建的secrets
env: # Set the secret as an environment variable
super_secret: ${{ secrets.SuperSecret }} # 使用secrets上下文访问在存储库中创建的secrets

secrets限制