GitHub Actions

GitHub Actions 文档 - GitHub 文档

简介

概述

  • 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 操作

image-20240314164011584

添加操作到工作流程

  • 从 GitHub Marketplace 添加操作

    • GithubMarketplace
  • 从相同操作添加操作

    • 在工作流文件中通过 {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
2
3
4
5
6
7
8
9
10
name: "Example"
description: "Receives file and generates output"
inputs:
file-path: # id of input
description: "Path to test script"
required: true
default: "test-file.js"
outputs:
results-file: # id of output
description: "Path to results file"

基本功能

变量

1
2
3
4
5
6
steps:
- name: Connect to PostgreSQL
run: node client.js
env:
POSTGRES_HOST: postgres
POSTGRES_PORT: 5432
  • 创建名为 POSTGRES_HOSTPOSTGRES_PORT 的自定义变量。可供 node client.js 脚本使用

添加脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 使用 run 关键字在运行器上执行 npm install -g bats
jobs:
example-job:
runs-on: ubuntu-latest
steps:
- run: npm install -g bats

# 将存储库签出到运行器后, 可使用 run 关键字运行脚本
jobs:
example-job:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./scripts
steps:
- name: Check out the repository to the runner
uses: actions/checkout@v4
- name: Run a script
run: ./my-script.sh
- name: Run another script
run: ./my-other-script.sh

作业间共享

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 创建文件, 将其作为构件上传
jobs:
example-job:
name: Save output
runs-on: ubuntu-latest
steps:
- shell: bash
run: |
expr 1 + 1 > output.log
- name: Upload output file
uses: actions/upload-artifact@v4
with:
name: output-log-file
path: output.log

# 从单独工作流中下载工件
jobs:
example-job:
runs-on: ubuntu-latest
steps:
- name: Download a single artifact
uses: actions/download-artifact@v4
with:
name: output-log-file

表达式

可以对工作流和操作中的表达式求值

  • 可以使用表达式程序化设置工作流程文件中的环境变量和访问上下文

设置变量

1
2
3
4
5
6
7
8
9
10
11
12
13
env:
MY_ENV_VAR: ${{ <expression> }}

# 示例
env:
myNull: ${{ null }}
myBoolean: ${{ false }}
myIntegerNumber: ${{ 711 }}
myFloatNumber: ${{ -9.2 }}
myHexNumber: ${{ 0xff }}
myExponentialNumber: ${{ -2.99e-2 }}
myString: Mona the Octocat
myStringInBraces: ${{ 'It''s open source!' }}
  • 可以使用 booleannullnumberstring 类型

函数

  • contains(search, item):如果 search 包含 item,则返回 true

  • startsWith( searchString, searchValue ):如果 searchStringsearchValue 开头

  • endsWith(searchString, searchValue):如果 searchStringsearchValue 结尾,则返回 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' }}

对象过滤器

可使用 * 语法来应用筛选器并选择集合中的匹配项

  • 对于 fruits 数组

    1
    2
    3
    4
    5
    [
    { "name": "apple", "quantity": 1 },
    { "name": "orange", "quantity": 2 },
    { "name": "pear", "quantity": 1 }
    ]
  • 筛选器 fruits.*.name 返回数组 [ "apple", "orange", "pear" ]

上下文

上下文是一种访问工作流运行、变量、运行器环境、作业及步骤相关信息的方式。 每个上下文都是一个包含属性的对象,属性可以是字符串或其他对象

githubenvvarsjobjobsstepsrunnersecretsstrategymatrixneedsinputs

变量

变量提供了一种存储和重用非敏感配置信息的方法。 可以将任何配置数据(如编译器标志、用户名或服务器名称)存储为变量。 变量在运行工作流的运行器计算机上插值。 在操作或工作流步骤中运行的命令可以创建、读取和修改变量。

可以通过两种方式设置自定义变量。

工作流 workflow

工作流程是一种可配置的自动化流程,将运行一个或多个作业。工作流由签入存储库的 YAML 文件定义,并将在存储库中的事件触发时运行,也可以手动触发或按定义的计划触发。

工作流在存储库的 .github/workflows 目录中定义,一个存储库可以有多个工作流,每个工作流可以执行一组不同的任务。

触发

workflow 触发器作为可导致工作流运行的事件,可以为:

  • 工作流程存储库中发生的事件
  • 在 GitHub 之外发生并在 GitHub 上触发 repository_dispatch 事件的事件
  • 预定时间
  • 手动

事件触发

  • 单个事件

    • ```yaml
      on: push
      1
      2
      3
      4
      5

      - 多个时间

      - ```yaml
      on: [push, fork]
  • 活动类型和筛选器用于多个事件

    • ```yaml
      on:
      label:
      types:
        - created
      
      push:
      branches:
        - main
      
      page_build:
      1
      2
      3
      4
      5
      6
      7
      8
      9

      #### 事件活动类型

      ```yaml
      on:
      issues:
      types:
      - opened
      - labeled

[!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
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
on:
workflow_dispatch:
inputs:
logLevel:
description: 'Log level'
required: true
default: 'warning'
type: choice
options:
- info
- warning
- debug
print_tags:
description: 'True to print to STDOUT'
required: true
type: boolean
tags:
description: 'Test scenario tags'
required: true
type: string
environment:
description: 'Environment to run tests against'
type: environment
required: true

jobs:
print-tag:
runs-on: ubuntu-latest
if: ${{ inputs.print_tags }}
steps:
- name: Print the input tag to STDOUT
run: echo The tags are ${{ inputs.tags }}

手动触发

当工作流配置为在发生 workflow_dispatch 事件时运行时,可以使用 GitHub、GitHub CLI 或 REST API 上的“Actions”选项卡运行工作流

  • 要手动运行工作流,必须将工作流配置为在 workflow_dispatch 事件上运行。
  • 要触发 workflow_dispatch 事件,工作流必须位于默认分支中

禁用和启用

禁用

工作流的屏幕截图。 标有水平烤肉串图标的“显示工作流选项”按钮和“禁用工作流”菜单项以深橙色边框标出。

启用

“Actions”页的屏幕截图。 在左侧边栏中,工作流名称用深橙色边框突出显示。

触发工作流的事件

可以配置工作流程在 GitHub 上发生特定活动时运行、在预定的时间运行,或者在 GitHub 外部的事件发生时运行

触发工作流的事件

语法和命令

重用

若要使工作流可重用,on 的值必须包括 workflow_call

1
2
on:
workflow_call:
  • 调用
1
2
3
4
5
6
7
jobs:
call-workflow-1-in-local-repo:
uses: octo-org/this-repo/.github/workflows/workflow-1.yml@172239021f7ba04fe7327647b213799853a9eb89
call-workflow-2-in-local-repo:
uses: ./.github/workflows/workflow-2.yml
call-workflow-in-another-repo:
uses: octo-org/another-repo/.github/workflows/workflow.yml@v1

缓存

工作流程运行通常在不同运行之间重新使用相同的输出或下载的依赖项。 例如,MavenGradlenpm 和 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
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
name: Caching with npm
on: push
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Cache node modules
id: cache-npm
uses: actions/cache@v3
env:
cache-name: cache-node-modules
with:
# npm cache files are stored in `~/.npm` on Linux/macOS
path: ~/.npm
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
${{ runner.os }}-

- if: ${{ steps.cache-npm.outputs.cache-hit != 'true' }}
name: List the state of node modules
continue-on-error: true
run: npm list

- name: Install dependencies
run: npm install

- name: Build
run: npm run build

- name: Test
run: npm test

存储构件

构件允许您在作业完成后保留数据,并与同一工作流程中的另一个作业共享该数据。 构件是指在工作流程运行过程中产生的文件或文件集。 例如,在工作流程运行结束后,您可以使用构件保存您的构建和测试输出。 运行中调用的所有操作和工作流都具有对该运行项目的写入权限。

  • 常见构件
    • 日志文件和核心转储文件
    • 测试结果、失败和屏幕截图
    • 二进制或压缩文件
    • 压力测试性能输出和代码覆盖结果

上传示例

  • 创建 Node.js 项目的工作流,该项目在 src 目录中生成代码,在 tests 目录中运行测试。 可以假定运行 npm test 会生成一个名为 code-coverage.html、存储在 output/test/ 目录中的代码覆盖率报告
  • 工作流上传 dist 目录中的生产工件,但不包括任何 Markdown 文件。 它还将 code-coverage.html 报表作为另一个工件上传
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
name: Node CI

on: [push]

jobs:
build_and_test:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: npm install, build, and test
run: |
npm install
npm run build --if-present
npm test
- name: Archive production artifacts
uses: actions/upload-artifact@v4
with:
name: dist-without-markdown
path: |
dist
!dist/**/*.md
- name: Archive code coverage results
uses: actions/upload-artifact@v4
with:
name: code-coverage-report
path: output/test/code-coverage.html

配置保留期

  • 为名为 my-artifact 的工件设置 5 天的自定义保留期
1
2
3
4
5
6
- name: 'Upload Artifact'
uses: actions/upload-artifact@v4
with:
name: my-artifact
path: my_file.txt
retention-days: 5

下载构件

  • actions/download-artifact 操作可用于在工作流运行期间下载以前上传的工件

    [!NOTE]

    只能下载在同一工作流运行期间上传的工作流中的工件

1
2
3
4
5
6
7
8
9
# 指定名称
- name: Download a single artifact
uses: actions/download-artifact@v4
with:
name: my-artifact

# 未指定名称则下载所有构件
- name: Download all workflow run artifacts
uses: actions/download-artifact@v4

作业间传递数据

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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
name: Share data between jobs

on: [push]

jobs:
job_1:
name: Add 3 and 7
runs-on: ubuntu-latest
steps:
# 执行数学计算并将结果保存到名为 math-homework.txt 的文本文件
- shell: bash
run: |
expr 3 + 7 > math-homework.txt
# 使用 upload-artifact 操作上传构件名称为 homework_pre 的 math-homework.txt 文件
- name: Upload math result for job 1
uses: actions/upload-artifact@v4
with:
name: homework_pre
path: math-homework.txt

job_2:
name: Multiply by 9
needs: job_1
runs-on: windows-latest
steps:
# 下载在上一个作业中上传的 homework_pre 构件。 默认情况下,download-artifact 操作会将工件下载到该步骤执行的工作区目录中。 可以使用 path 输入参数指定不同的下载目录。
- name: Download math result for job 1
uses: actions/download-artifact@v4
with:
name: homework_pre
# 读取 math-homework.txt 文件中的值,执行数学计算,并再次将结果保存到 math-homework.txt,覆盖其内容
- shell: bash
run: |
value=`cat math-homework.txt`
expr $value \* 9 > math-homework.txt
# 上传 math-homework.txt 文件。 由于构件在 v4 中被视为不可变,因此构件会作为名称传递不同的输入 homework_final
- name: Upload math result for job 2
uses: actions/upload-artifact@v4
with:
name: homework_final
path: math-homework.txt

job_3:
name: Display results
needs: job_2
runs-on: macOS-latest
steps:
# 从作业 2 下载 homework_final 构件
- name: Download math result for job 2
uses: actions/download-artifact@v4
with:
name: homework_final
# 将数学方程式的结果打印到日志中
- name: Print the final result
shell: bash
run: |
value=`cat math-homework.txt`
echo The result is $value

page 作业

  • 工作流运行由一个或多个 jobs 组成,默认情况下并行运行。
  • 若要按顺序运行作业,可以使用 jobs.<job_id>.needs 关键字定义对其他作业的依赖关系。

  • 每个作业在 runs-on 指定的运行器环境中运行。

基本设置

设置作业 ID

使用 jobs.<job_id> 为作业提供唯一标识符。 键 job_id 是一个字符串,其值是作业配置数据的映射。 必须将 <job_id> 替换为对于 jobs 对象的唯一字符串。 <job_id> 必须以字母或 _ 开头,并且只能包含字母数字字符、-_

1
2
3
4
5
jobs:
my_first_job:
name: My first job
my_second_job:
name: My second job

设置作业名称

使用 jobs.<job_id>.name 设置作业名称,该名称显示在 GitHub UI 中

设置必备前序作业

  • 使用 jobs.<job_id>.needs 标识运行此作业之前必须成功完成的所有作业
    • 它可以是一个字符串,也可以是字符串数组
  • 如果某个作业失败或跳过,则所有需要它的作业都会被跳过,除非这些作业使用让该作业继续的条件表达式。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 顺序作业
jobs:
job1:
job2:
needs: job1
job3:
needs: [job1, job2]

# 始终执行
jobs:
job1:
job2:
needs: job1
job3:
if: ${{ always() }} # if ${{ !cancelled() }}
needs: [job1, job2]

选择作业的运行器

基本设置

  • 使用 jobs.<job_id>.runs-on 定义要运行作业的计算机类型

  • 定义形式:单个字符串、包含字符串的单个变量、字符串数组或变量、使用 grouplabels 键的 key:value

    • 如果指定字符串数组,工作流将在与所有指定 runs-on 值匹配的运行器上执行。 例如,此处的作业将仅在具有标签 linuxx64gpu 的自托管运行器上运行

      • 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
2
3
4
5
6
7
8
9
10
11
12
13
14
# 仅当存储库名为 octo-repo-prod 且位于 octo-org 组织内时,它才会运行
# 否则,job将被标记为“跳过”
name: example-workflow
on: [push]
jobs:
production-deploy:
if: github.repository == 'octo-org/octo-repo-prod'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '14'
- run: npm install -g bats

环境

使用 jobs.<job_id>.environment 定义作业引用的环境。 在将引用环境的作业发送到运行器之前,必须通过所有部署保护规则

1
2
3
environment:
name: production_environment
url: https://github.com

设置作业的默认值

使用 defaults 创建将应用于工作流中所有作业的默认设置的 map。 您也可以设置只可用于作业的默认设置

1
2
3
4
5
# 设置默认 shell 和工作目录
defaults:
run:
shell: bash
working-directory: ./scripts

分配权限

可以使用 permissions 修改授予 GITHUB_TOKEN 的默认权限,根据需要添加或删除访问权限,以便只授予所需的最低访问权限

定义 GITHUB_TOKEN 范围的访问权限

1
2
3
4
5
6
7
8
9
10
11
12
13
14
permissions:
actions: read|write|none
checks: read|write|none
contents: read|write|none
deployments: read|write|none
id-token: read|write|none
issues: read|write|none
discussions: read|write|none
packages: read|write|none
pages: read|write|none
pull-requests: read|write|none
repository-projects: read|write|none
security-events: read|write|none
statuses: read|write|none
  • 指定任何作用域后,其他所有未指定的作用域都被设置为 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:
      ...

为特定作业设置权限

1
2
3
4
5
6
7
8
9
10
jobs:
stale:
runs-on: ubuntu-latest

permissions:
issues: write
pull-requests: write

steps:
- uses: actions/stale@v5

定义作业的输出

可以使用 jobs.<job_id>.outputs 为作业创建输出的 map。 作业输出可用于所有依赖此作业的下游作业

要在依赖的作业中使用作业输出, 可以使用 needs 上下文

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
jobs:
job1:
runs-on: ubuntu-latest
# Map a step output to a job output
outputs:
output1: ${{ steps.step1.outputs.test }}
output2: ${{ steps.step2.outputs.test }}
steps:
- id: step1
run: echo "test=hello" >> "$GITHUB_OUTPUT"
- id: step2
run: echo "test=world" >> "$GITHUB_OUTPUT"
job2:
runs-on: ubuntu-latest
needs: job1
steps:
- env:
OUTPUT1: ${{needs.job1.outputs.output1}}
OUTPUT2: ${{needs.job1.outputs.output2}}
run: echo "$OUTPUT1 $OUTPUT2"

actions/checkout

  • 此操作会签出 $GITHUB_WORKSPACE 下的存储库,以便您的工作流程可以访问它

  • [!NOTE]

    $GITHUB_WORKSPACE:运行器上步骤的默认工作目录,以及使用 checkout 操作时存储库的默认位置