vim 插件的使用
GitHub Actions
简介
概述
- GitHub Actions 是一种 持续集成和持续交付 (CI/CD) 平台,可用于自动执行生成、测试和部署管道。 您可以创建工作流程来构建和测试存储库的每个拉取请求,或将合并的拉取请求部署到生产环境。
- GitHub Actions 不仅仅是 DevOps,还允许您在存储库中发生其他事件时 运行工作流程。 例如,您可以运行工作流程,以便在有人在您的存储库中创建新问题时自动添加相应的标签。
- GitHub 提供 Linux、Windows 和 macOS 虚拟机来运行工作流程,或者您可以在自己的数据中心或云基础架构中托管自己的自托管运行器。
基本概念
- workflow (工作流):持续集成一次运行的过程,就是一个 workflow。是一个 可配置的自动化过程,它将运行一个或多个作业
- 工作流程在存储库的
.github/workflows
目录中定义
- 工作流程在存储库的
- events(事件):事件是存储库中 触发工作流程运行的特定活动。 例如,当有人创建拉取请求、打开议题或将提交推送到存储库时,活动可能源自 GitHub。 此外,还可以通过发布到 REST API 或者手动方式触发工作流按计划运行。
- job (任务/作业):一个 workflow 由一个或多个 jobs 构成,含义是 一次持续集成的运行,可以完成多个任务。 每个步骤要么是一个将要执行的 shell 脚本,要么是一个将要运行的动作。
- action (动作/操作):操作是用于 GitHub Actions 平台的自定义应用程序。可以编写自己的操作,也可以在 GitHub Marketplace 中找到要在工作流程中使用的操作。
- step(步骤):每个 job 由多个 step 构成,一步步完成。
- runners(运行程序):运行程序是触发工作流时运行工作流的服务器。 每个运行器一次可以运行一个作业。 GitHub 提供 Ubuntu Linux、Microsoft Windows 和 macOS 运行器来运行您的工作流程;每个工作流程运行都在新预配的全新虚拟机中执行。
基本操作
查找和自定义操作
浏览 Marketplace 操作
添加操作到工作流程
从 GitHub Marketplace 添加操作
从相同操作添加操作
在工作流文件中通过
{owner}/{repo}@{ref}
或./path/to/dir
语法引用操作```yaml
jobs:
my_first_job:runs-on: ubuntu-latest steps: # This step checks out a copy of your repository. - name: My first step - check out repository uses: actions/checkout@v4 # This step references the directory that contains the action. - name: Use local hello-world-action uses: ./.github/actions/hello-world-action
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
- 从不同仓库添加操作
- 通过 `{owner}/{repo}@{ref}` 语法引用该操作
- 引用 Docker Hub 上的容器
- 如果操作在 Docker Hub 上发布的 Docker 容器图像中定义,必须在工作流文件中通过 `docker://{image}:{tag}` 语法引用该操作。
- 为保护代码和数据,强烈建议先验证 Docker Hub 中 Docker 容器图像的完整性后再将其用于工作流程。
- ```yaml
jobs:
my_first_job:
steps:
- name: My first step
uses: docker://alpine:3.8
对自定义操作使用发行版管理
- 使用标记
- uses: actions/javascript-action@v1.0.1
- 使用 SHA
- uses: actions/javascript-action@a824008085750b8e136effc585c3cd6082bd575f
- 使用分支
- uses: actions/javascript-action@main
对操作使用输入和输出
1 | name: "Example" |
基本功能
变量
1 | steps: |
- 创建名为
POSTGRES_HOST
和POSTGRES_PORT
的自定义变量。可供node client.js
脚本使用
添加脚本
1 | # 使用 run 关键字在运行器上执行 npm install -g bats |
作业间共享
1 | # 创建文件, 将其作为构件上传 |
表达式
可以对工作流和操作中的表达式求值
- 可以使用表达式程序化设置工作流程文件中的环境变量和访问上下文
设置变量
1 | env: |
- 可以使用
boolean
、null
、number
或string
类型
函数
contains(search, item)
:如果search
包含item
,则返回true
startsWith( searchString, searchValue )
:如果searchString
以searchValue
开头endsWith(searchString, searchValue)
:如果searchString
以searchValue
结尾,则返回true
format(string, replaceValue0, replaceValue1, ..., replaceValueN)
:将string
中的值替换为变量replaceValueN
- ```yaml
format(‘Hello {0} {1} {2}’, ‘Mona’, ‘the’, ‘Octocat’)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
- `join( array, optionalSeparator )`:`array` 的值可以是数组,也可以是字符串。`array` 中的所有值都连接成一个字符串。 如果提供 `optionalSeparator`,则它将插入到连接的值之间, 否则使用默认分隔符 `,`
- `toJSON(value)`:对 `value` 返回适合打印的 JSON 表示形式
- `fromJSON(value)`:返回 `value` 的 JSON 对象或 JSON 数据类型
- `hashFiles(path)`:返回与 `path` 模式匹配的文件集的单个哈希
#### 状态函数检查
> 可以将以下状态检查函数用作 `if` 条件中的表达式
- `success()`:当前面的所有步骤都成功时返回 `true`
- `always()`
- 适用于步骤级别或预期即使作业取消仍会运行的任务。 例如,即使作业取消,仍然可以使用 `always` 发送日志
> [!WARNING]
>
> 避免对任何可能出现严重故障的任务(例如获取源)使用 `always`,否则工作流可能会挂起,直到超时。如果要运行作业或步骤且不考虑其成功或失败,请使用推荐的替代方法:`if: ${{ !cancelled() }}`
- `cancelled()`:如果工作流被取消,则返回 `true`
- `failure()`:如果作业的任何先前步骤失败,将返回 `true`。 如果有一系列依赖项作业,则 `failure()` 在任何上级作业失败时返回 `true`
> [!NOTE] - 有条件的失败
>
> - 可以包含一个在失败后运行的步骤的额外条件,但仍必须包含 `failure()` 以覆盖自动应用于不包含状态检查函数的 `if` 条件的默认 `success()` 状态检查。
>
> - ```yaml
> steps:
> ...
> - name: Failing step
> id: demo
> run: exit 1
> - name: The demo step has failed
> if: ${{ failure() && steps.demo.conclusion == 'failure' }}
- ```yaml
对象过滤器
可使用
*
语法来应用筛选器并选择集合中的匹配项
对于
fruits
数组1
2
3
4
5[
{ "name": "apple", "quantity": 1 },
{ "name": "orange", "quantity": 2 },
{ "name": "pear", "quantity": 1 }
]筛选器
fruits.*.name
返回数组[ "apple", "orange", "pear" ]
上下文
上下文是一种访问工作流运行、变量、运行器环境、作业及步骤相关信息的方式。 每个上下文都是一个包含属性的对象,属性可以是字符串或其他对象
github、env、vars、job、jobs、steps、runner、secrets、strategy、matrix、needs、inputs
变量
变量提供了一种存储和重用非敏感配置信息的方法。 可以将任何配置数据(如编译器标志、用户名或服务器名称)存储为变量。 变量在运行工作流的运行器计算机上插值。 在操作或工作流步骤中运行的命令可以创建、读取和修改变量。
可以通过两种方式设置自定义变量。
- 若要定义要在单个工作流中使用的环境变量,可以在工作流文件中使用
env
键。 有关详细信息,请参阅“为单个工作流定义环境变量”。 - 若要跨多个工作流定义配置变量,可以在组织、存储库或环境级别定义它。 有关详细信息,请参阅“为多个工作流定义配置变量”。
工作流 workflow
工作流程是一种可配置的自动化流程,将运行一个或多个作业。工作流由签入存储库的 YAML 文件定义,并将在存储库中的事件触发时运行,也可以手动触发或按定义的计划触发。
工作流在存储库的
.github/workflows
目录中定义,一个存储库可以有多个工作流,每个工作流可以执行一组不同的任务。
触发
workflow 触发器作为可导致工作流运行的事件,可以为:
- 工作流程存储库中发生的事件
- 在 GitHub 之外发生并在 GitHub 上触发
repository_dispatch
事件的事件 - 预定时间
- 手动
事件触发
单个事件
- ```yaml
on: push1
2
3
4
5
- 多个时间
- ```yaml
on: [push, fork]
- ```yaml
活动类型和筛选器用于多个事件
- ```yaml
on:
label:
push:types: - created
page_build:branches: - main
1
2
3
4
5
6
7
8
9
#### 事件活动类型
```yaml
on:
issues:
types:
- opened
- labeled
- ```yaml
[!NOTE]
- 如果指定多个活动类型,则只需要发生其中一种事件活动类型就可触发工作流
- 如果触发工作流的多个事件活动类型同时发生,则将触发多个工作流运行
筛选器
定位拉取请求事件的特定分支
```yaml
on:pull_request:
包括分支
branches: - main # 名为 main 的分支 - 'mona/octocat' # 名为 mona/octocat 的分支 - 'releases/**' # 以 releases/ 开头的分支
排除分支
branches-ignore: - 'mona/octocat' # 名为 mona/octocat 的分支 - 'releases/**-alpha' # 名称匹配 releases/**-alpha 的分支
包括和排除分支
branches: - 'releases/**' # - '!releases/**-alpha'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
- 定位推送事件的特定分支或标记
- ```yaml
on:
push:
branches:
- ...
tags:
- ...
branches-ignore:
- ...
tags-ignore:
- ...
定位拉取请求或推送事件的特定路径
```yaml
on:push: paths: - '**.js' # 推送任何 .js 文件均会触发 paths-ignore: - 'docs/**' # 所有路径均匹配时不触发, 否则触发
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
> [!NOTE]
>
> 如果推送超过 1,000 项提交,或者如果 GitHub 因超时未生成差异,则工作流将始终运行。
- 定位工作流程运行事件的特定分支
- 使用 `workflow_run` 事件时,可以指定触发工作流必须在哪些分支上运行才能触发工作流
- ```yaml
# 仅当名为 Build 的工作流在名称以 releases/ 开头的分支上运行时,具有以下触发器的工作流才会运行
on:
workflow_run:
workflows: ["Build"]
types: [requested]
branches:
- 'releases/**'
定义手动触发工作流的输入
使用
workflow_dispatch
事件时,你可以选择性指定传递到工作流的输入
1 | on: |
手动触发
当工作流配置为在发生
workflow_dispatch
事件时运行时,可以使用 GitHub、GitHub CLI 或 REST API 上的“Actions”选项卡运行工作流
- 要手动运行工作流,必须将工作流配置为在
workflow_dispatch
事件上运行。 - 要触发
workflow_dispatch
事件,工作流必须位于默认分支中
禁用和启用
禁用
启用
触发工作流的事件
可以配置工作流程在 GitHub 上发生特定活动时运行、在预定的时间运行,或者在 GitHub 外部的事件发生时运行
语法和命令
重用
若要使工作流可重用,on
的值必须包括 workflow_call
:
1 | on: |
- 调用
1 | jobs: |
缓存
工作流程运行通常在不同运行之间重新使用相同的输出或下载的依赖项。 例如,
Maven
、Gradle
、npm
和 Yarn 等软件包和依赖项管理工具都会对下载的依赖项保留本地缓存
依赖项
包管理器 | 用于缓存的 setup-*操作 |
---|---|
npm、yarn、pnpm | setup-node |
pip、pipenv、poetry | setup-python |
Gradle、Maven | setup-java |
RubyGems | setup-ruby |
Go | setup-go |
使用 cache 操作
- 输入参数
key
(required) :保存缓存时创建的密钥和用于搜索缓存的密钥。 它可以是变量、上下文值、静态字符串和函数的任何组合path
(required):运行器上用于缓存或还原的路径restore-keys
:包含备用还原键的字符串,每个还原键均放置在一个新行上。 如果key
没有发生缓存命中,则按照提供的顺序依次使用这些还原键来查找和还原缓存enableCrossOsArchive
:启用后,允许 Windows 运行程序独立于创建缓存的操作系统保存或还原缓存
- 输出参数
cache-hit
:表示找到了键的精确匹配项的布尔值
缓存命中/缓存失误
- 当
key
完全匹配现有缓存时,被称为 缓存命中,并且操作会将缓存的文件还原到path
目录。 - 当
key
不匹配现有缓存时,则被称为 缓存失误,在作业成功完成时会自动创建一个新缓存- 发生缓存失误后,还会搜索指定的
restore-keys
以查找任何匹配项
- 发生缓存失误后,还会搜索指定的
示例
1 | name: Caching with npm |
存储构件
构件允许您在作业完成后保留数据,并与同一工作流程中的另一个作业共享该数据。 构件是指在工作流程运行过程中产生的文件或文件集。 例如,在工作流程运行结束后,您可以使用构件保存您的构建和测试输出。 运行中调用的所有操作和工作流都具有对该运行项目的写入权限。
- 常见构件
- 日志文件和核心转储文件
- 测试结果、失败和屏幕截图
- 二进制或压缩文件
- 压力测试性能输出和代码覆盖结果
上传示例
- 创建 Node.js 项目的工作流,该项目在
src
目录中生成代码,在tests
目录中运行测试。 可以假定运行npm test
会生成一个名为code-coverage.html
、存储在output/test/
目录中的代码覆盖率报告 - 工作流上传
dist
目录中的生产工件,但不包括任何 Markdown 文件。 它还将code-coverage.html
报表作为另一个工件上传
1 | name: Node CI |
配置保留期
- 为名为
my-artifact
的工件设置 5 天的自定义保留期
1 | - name: 'Upload Artifact' |
下载构件
actions/download-artifact
操作可用于在工作流运行期间下载以前上传的工件[!NOTE]
只能下载在同一工作流运行期间上传的工作流中的工件
1 | # 指定名称 |
作业间传递数据
可以使用
upload-artifact
和download-artifact
操作在工作流中的作业间共享数据参考:
1 | name: Share data between jobs |
page 作业
- 工作流运行由一个或多个
jobs
组成,默认情况下并行运行。若要按顺序运行作业,可以使用
jobs.<job_id>.needs
关键字定义对其他作业的依赖关系。每个作业在
runs-on
指定的运行器环境中运行。
基本设置
设置作业 ID
使用
jobs.<job_id>
为作业提供唯一标识符。 键job_id
是一个字符串,其值是作业配置数据的映射。 必须将<job_id>
替换为对于jobs
对象的唯一字符串。<job_id>
必须以字母或_
开头,并且只能包含字母数字字符、-
或_
。
1 | jobs: |
设置作业名称
使用
jobs.<job_id>.name
设置作业名称,该名称显示在 GitHub UI 中
设置必备前序作业
- 使用
jobs.<job_id>.needs
标识运行此作业之前必须成功完成的所有作业
- 它可以是一个字符串,也可以是字符串数组
- 如果某个作业失败或跳过,则所有需要它的作业都会被跳过,除非这些作业使用让该作业继续的条件表达式。
1 | # 顺序作业 |
选择作业的运行器
基本设置
使用
jobs.<job_id>.runs-on
定义要运行作业的计算机类型- 目标计算机可以是 GitHub 托管的运行器)、大型运行器 或 自托管运行器。
定义形式:单个字符串、包含字符串的单个变量、字符串数组或变量、使用
group
或labels
键的key:value
对如果指定字符串数组,工作流将在与所有指定
runs-on
值匹配的运行器上执行。 例如,此处的作业将仅在具有标签linux
、x64
和gpu
的自托管运行器上运行runs-on: [self-hosted, linux, x64, gpu]
可以在数组中混合使用字符串和变量
```yaml
on:
workflow_dispatch:inputs: chosen-os: required: true type: choice options: - Ubuntu - macOS
jobs:
test:runs-on: [self-hosted, "${{ inputs.chosen-os }}"] steps: - run: echo Hello world!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
> [!NOTE]
>
> 像 `self-hosted` 这样的简单字符串前后不需要引号,但 `"${{ inputs.chosen-os }}"` 等表达式前后需要引号
- 如果要在多台计算机上运行工作流,请使用 `jobs.<job_id>.strategy`
#### GitHub 托管的运行器
| **操作系统(YAML 工作流标签)** | **说明** |
| :----------------------------------------------------------- | :----------------------------------------------------------- |
| `ubuntu-latest`,`ubuntu-22.04`,`ubuntu-20.04` | `ubuntu-latest` 标签当前使用 Ubuntu 22.04 运行器映像。 |
| `windows-latest`,`windows-2022`,`windows-2019` | `windows-latest` 标签当前使用 Windows Server 2022 运行器映像。 |
| `macos-latest`、`macos-14` [Beta 版本]、`macos-13`、`macos-12`、`macos-11` | `macos-latest` 工作流标签目前使用 macOS 12 运行器映像。 |
> [!NOTE]
>
> `-latest` 运行器映像是 GitHub 提供的最新稳定映像,但可能不是操作系统供应商提供的最新版本的操作系统
#### 选择自托管运行器
> 所有自托管运行器都有 `self-hosted` 标签。 仅使用此标签将选择任何自托管运行器。 选择符合特定条件的运行器,例如操作系统或体系结构,建议提供以 `self-hosted` 开头的标签数组(必须首先列出),然后根据需要包含其他标签。 指定标签数组时,作业将在具有你指定的所有标签的运行器上排队。
#### 在组中选择运行器
> 可以使用 `runs-on` 定位运行器组,以便作业将在属于该组的任何运行器上执行。 若要进行更精细的控制,还可以将运行器组与标签组合在一起。
>
> - 运行器组只能将 大型运行器 或自托管运行器作为成员。
```yaml
name: learn-github-actions
on: [push]
jobs:
check-bats-version:
runs-on:
group: ubuntu-runners
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '14'
- run: npm install -g bats
- run: bats -v
使用条件控制作业执行
可以使用
jobs.<job_id>.if
条件来阻止步骤运行,除非满足条件。 您可以使用任何支持上下文和表达式来创建条件。[!NOTE]
- 跳过的作业将报告其状态为“成功”。 即使是必需检查,也不会阻止拉取请求合并
- 在工作流的某些部分中,不能使用环境变量。 但是,可以使用上下文来访问环境变量的值
1 | # 仅当存储库名为 octo-repo-prod 且位于 octo-org 组织内时,它才会运行 |
环境
使用
jobs.<job_id>.environment
定义作业引用的环境。 在将引用环境的作业发送到运行器之前,必须通过所有部署保护规则
1 | environment: |
设置作业的默认值
使用
defaults
创建将应用于工作流中所有作业的默认设置的map
。 您也可以设置只可用于作业的默认设置
1 | # 设置默认 shell 和工作目录 |
分配权限
可以使用
permissions
修改授予GITHUB_TOKEN
的默认权限,根据需要添加或删除访问权限,以便只授予所需的最低访问权限
定义 GITHUB_TOKEN 范围的访问权限
1 | permissions: |
指定任何作用域后,其他所有未指定的作用域都被设置为
none
可以使用
-all
语法定义所有可用的作用域- ```yaml
permissions: read-all
permissions: write-all
permissions: {} # 禁用所有权限1
2
3
4
5
6
7
8
9
10
11
12
#### 为工作流所有作业设置权限
```yaml
name: "My workflow"
on: [ push ]
permissions: read-all
jobs:
...
- ```yaml
为特定作业设置权限
1 | jobs: |
定义作业的输出
可以使用
jobs.<job_id>.outputs
为作业创建输出的map
。 作业输出可用于所有依赖此作业的下游作业要在依赖的作业中使用作业输出, 可以使用
needs
上下文
1 | jobs: |
actions/checkout
此操作会签出
$GITHUB_WORKSPACE
下的存储库,以便您的工作流程可以访问它[!NOTE]
$GITHUB_WORKSPACE
:运行器上步骤的默认工作目录,以及使用 checkout 操作时存储库的默认位置