工作流语法
你在工作流文件中看到的第一项内容是它的名称,它会显示在仓库的 Actions 下:
name: My first workflow
这个名称后面是触发器。
工作流触发器
触发器是 on
键的值:
on: push
触发器可以包含多个值:
on: [push, pull_request]
许多触发器包含可以配置的其他值:
on:
push:
branches:
- main
- release/**
pull_request:
types: [opened, assigned]
有三种类型的触发器:
-
Webhook 事件
-
定时事件
-
手动事件
Webhook 事件 就是你到目前为止见过的事件。几乎每件事都有对应的 webhook 事件:如果你向 GitHub 推送代码(push
),如果你创建或更新一个拉取请求(pull_request
),或者如果你创建或修改一个问题(issues
)。完整的列表可以参考 GitHub 文档。
定时事件 使用与 cron 作业相同的语法。语法由五个字段组成,分别表示分钟(0-59)、小时(0-23)、日期(1-31)、月份(1-12 或 JAN-DEC)和星期几(0-6 或 SUN-SAT)。你可以使用以下表格中显示的运算符:

以下是一些示例:
on:
schedule:
# Runs at every 15th minute of every day
- cron: '*/15 * * * *'
# Runs every hour from 9am to 5pm
- cron: '0 9-17 * * *'
# Runs every Friday at midnight
- cron: '0 0 * * FRI'
# Runs every quarter (00:00 on day 1 every 3rd month)
- cron: '0 0 1 */3 *'
手动事件 允许你手动触发工作流:
on: workflow_dispatch
你可以配置用户在启动工作流时可以(或必须)指定的输入。以下示例定义了一个名为 homedrive
的变量,你可以在工作流中使用 ${{ github.event.inputs.homedrive }}
表达式来引用它:
on:
workflow_dispatch:
inputs:
homedrive:
description: 'The home drive on the machine'
required: true
default: '/home'
你还可以使用 GitHub API 来触发工作流。为此,你必须定义一个 repository_dispatch
触发器,并指定一个或多个你希望使用的事件名称:
on:
repository_dispatch:
types: [event1, event2]
当发送 HTTP POST 请求时,工作流将被触发。以下是使用 curl
发送 HTTP POST 请求的示例:
curl \
-X POST \
-H "Accept: application/vnd.github.v3+json" \
https://api.github.com/repos/<owner>/<repo>/dispatches \
-d '{"event_type":"event1"}'
以下是使用 JavaScript 的示例(有关 Octokit API 客户端的更多信息,请参见 Octokit.js):
await octokit.request('POST /repos/{owner}/{repo}/dispatches', {
owner: '<owner>',
repo: '<repo>',
event_type: 'event1'
})
通过使用 repository_dispatch
触发器,你可以在任何系统中使用任何 webhook 来触发你的工作流。这帮助你自动化工作流并集成其他系统。
工作流作业
工作流本身在 jobs
部分进行配置。jobs
是一个映射,而不是列表,默认情况下它们是并行运行的。如果你想将它们按顺序链式执行,可以使用 needs
关键字使某个工作依赖于其他工作:
jobs:
job_1:
name: My first job
job_2:
name: My second job
needs: job_1
job_3:
name: My third job
needs: [job_1, job_2]
每个作业都在一个运行器(runner)上执行。运行器可以是自托管的,也可以选择使用云中的运行器。云中为所有平台提供了不同的版本。如果你希望始终使用最新版本,可以使用 ubuntu-latest
、windows-latest
或 macos-latest
。你将在第七章《运行你的工作流》中了解更多关于运行器的内容。
jobs:
job_1:
name: My first job
runs-on: ubuntu-latest
如果你希望使用不同的配置运行工作流,可以使用 矩阵策略(matrix strategy)。工作流将执行所有配置的矩阵值的组合。矩阵中的键可以是任何值,你可以使用 ${{ matrix.key }}
表达式来引用它们:
strategy:
matrix:
os_version: [macos-latest, ubuntu-latest]
node_version: [10, 12, 14]
jobs:
job_1:
name: My first job
runs-on: ${{ matrix.os_version }}
steps:
- uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node_version }}
工作流步骤
一个作业包含一系列步骤,每个步骤可以运行一个命令:
steps:
- name: Install Dependencies
run: npm install
文字块(Literal blocks)允许你运行多行脚本。如果你希望工作流在与默认 shell 不同的 shell 中运行,可以将其与其他值一起配置,例如 working-directory
:
- name: Clean install dependencies and build
run: |
npm ci
npm run build
working-directory: ./temp
shell: bash
以下是可用的 shell:

在非 Windows 系统上,默认的 shell 是 bash,回退为 sh。Windows 上的默认 shell 是 cmd。你也可以使用 command [options] {0}
语法配置自定义 shell:
run: print %ENV
shell: perl {0}
大多数情况下,你会重用步骤。一个可重用的步骤称为 GitHub Action。你可以使用 uses
关键字并按以下语法引用一个 Action:
{owner}/{repo}@{ref}
{owner}/{repo}
是 GitHub 上 Action 的路径。{ref}
引用表示版本:它可以是标签、分支,或是通过其哈希值引用的单个提交。最常见的做法是使用标签进行明确的版本控制,通常包括主要版本和次要版本:
# Reference a version using a label
- uses: actions/checkout@v2
- uses: actions/checkout@v2.2.0
# Reference the current head of a branch
- uses: actions/checkout@main
# Reference a specific commit
- uses: actions/checkout@a81bbbf8298c0fa03ea29cdc473d45769f953675
如果你的 Action 和工作流在同一个仓库中,你可以使用相对路径来引用 Action:
uses: ./.github/actions/my-action
你还可以使用存储在容器注册表中的 Action,例如 Docker Hub 或 GitHub Packages,使用 docker//{image}:{tag}
语法:
uses: docker://alpine:3.8
上下文和表达式语法
当我们查看矩阵策略时,你已经看到了某些表达式。表达式的语法如下:
${{ <expression> }}
表达式可以访问上下文信息,并将其与操作符结合使用。有不同的对象提供上下文,例如 matrix
、github
、env
和 runner
。例如,使用 github.sha
,你可以访问触发工作流的提交 SHA;使用 runner.os
,你可以获取运行器的操作系统,而使用 env
,你可以访问环境变量。有关完整的上下文信息,请访问 GitHub Actions 文档。
你可以使用两种语法来访问上下文属性——字母语法或属性语法,其中属性语法是更常见的:
context['key']
context.key
根据键的格式,你可能需要使用第一个选项。如果键以数字开头或包含特殊字符,可能会需要这样做。
表达式通常用于 if
对象中,以根据不同的条件运行作业:
jobs:
deploy:
if: ${{ github.ref == 'refs/heads/main' }}
runs-on: ubuntu-latest
steps:
- run: echo "Deploying branch $GITHUB_REF"
你可以使用许多预定义的函数,例如 contains(search, item)
:
contains('Hello world!', 'world')
# 返回 true
其他函数示例包括 startsWith()
或 endsWith()
。还有一些特殊函数,可以用来检查当前作业的状态:
steps:
...
- name: The job has succeeded
if: ${{ success() }}
此步骤仅在所有其他步骤成功时执行。下表显示了所有可以用于响应当前作业状态的函数:

除了函数之外,您还可以使用运算符与上下文和函数结合。下表显示了最重要的运算符:

要了解更多关于上下文对象和表达式语法的信息,请访问 GitHub Actions 文档。
工作流命令
要在步骤中与工作流交互,您可以使用工作流命令。工作流命令通常通过 echo
命令传递给进程,并发送类似 ::set-output name={name}::{value}
的字符串给进程。
以下示例设置了一个步骤的输出,并在另一个步骤中访问它。注意如何使用步骤的 ID 来访问输出变量:
- name: Set time
run: |
time=$(date)
echo '::set-output name=MY_TIME::$time'
id: time-gen
- name: Output time
run: echo "It is ${{ steps.time-gen.outputs.MY_TIME }}"
另一个例子是 ::error
命令。它允许您将错误消息写入日志。您还可以选择设置文件名、行号和列号:
::error file={name},line={line},col={col}::{message}
您还可以写入警告和调试消息、将日志行分组或设置环境变量。有关工作流命令的更多详细信息,请访问 GitHub 官方文档。