关于工作流的 YAML 语法
工作流文件使用 YAML 语法,并且必须具有 .yml
或 .yaml
文件扩展名。如果您不熟悉 YAML 并想了解更多信息,请参阅“在 Y 分钟内学习 YAML”。
您必须将工作流文件存储在存储库的 .github/workflows
目录中。
name
工作流的名称。GitHub 会在您的存储库的“Actions”选项卡下显示您的工作流名称。如果您省略 name
,GitHub 将显示相对于存储库根目录的工作流文件路径。
run-name
工作流运行的名称,由工作流生成。GitHub 会在你的仓库“Actions”选项卡的工作流运行列表中显示工作流运行名称。如果省略run-name
或仅包含空格,则运行名称将设置为工作流运行的特定于事件的信息。例如,对于由push
或pull_request
事件触发的 workflow,它将设置为提交消息或拉取请求的标题。
此值可以包含表达式,并可以引用github
和inputs
上下文。
run-name
示例
run-name: Deploy to ${{ inputs.deploy_target }} by @${{ github.actor }}
on
要自动触发工作流,请使用on
定义哪些事件可以导致工作流运行。有关可用事件的列表,请参阅“触发工作流的事件”。
您可以定义可以触发工作流的单个或多个事件,或设置时间表。您还可以将工作流的执行限制为仅针对特定文件、标签或分支更改发生。这些选项将在以下部分中介绍。
使用单个事件
例如,具有以下on
值的工作流将在向工作流存储库中的任何分支推送时运行
on: push
使用多个事件
您可以指定单个事件或多个事件。例如,具有以下on
值的工作流将在向存储库中的任何分支推送时运行,或在有人分叉存储库时运行
on: [push, fork]
如果指定多个事件,则只需要发生其中一个事件即可触发工作流。如果你的工作流的多个触发事件同时发生,则会触发多个工作流运行。
使用活动类型
某些事件具有活动类型,可以让你更好地控制工作流何时运行。使用on.<event_name>.types
定义将触发工作流运行的事件活动类型。
例如,issue_comment
事件具有created
、edited
和deleted
活动类型。如果你的工作流触发label
事件,则只要创建、编辑或删除标签,它就会运行。如果为label
事件指定created
活动类型,则在创建标签时你的工作流将运行,但在编辑或删除标签时不会运行。
on:
label:
types:
- created
如果指定多个活动类型,则只需要发生其中一个事件活动类型即可触发工作流。如果你的工作流的多个触发事件活动类型同时发生,则会触发多个工作流运行。例如,以下工作流在打开或标记问题时触发。如果打开了一个带有两个标签的问题,则将启动三个工作流运行:一个用于打开的问题事件,两个用于两个标记的问题事件。
on:
issues:
types:
- opened
- labeled
有关每个事件及其活动类型的更多信息,请参阅“触发工作流的事件”。
使用过滤器
某些事件具有过滤器,可以让你更好地控制工作流何时运行。
例如,push
事件具有branches
过滤器,该过滤器会导致你的工作流仅在向与branches
过滤器匹配的分支推送时运行,而不是在任何推送时运行。
on:
push:
branches:
- main
- 'releases/**'
结合使用活动类型和过滤器以及多个事件
如果为事件指定活动类型或过滤器,并且你的工作流触发多个事件,则必须分别配置每个事件。必须为所有事件附加冒号(:
),包括没有配置的事件。
例如,具有以下on
值的工作流将在以下情况下运行:
- 创建标签
- 向存储库中的
main
分支推送 - 向启用了 GitHub Pages 的分支推送
on:
label:
types:
- created
push:
branches:
- main
page_build:
on.<event_name>.types
使用on.<event_name>.types
定义将触发工作流运行的活动类型。大多数 GitHub 事件都由不止一种类型的活动触发。例如,当标签被created
、edited
或deleted
时,label
事件会被触发。types
关键字使你能够缩小导致工作流运行的活动范围。当只有一个活动类型触发 webhook 事件时,types
关键字是不必要的。
您可以使用事件types
数组。有关每个事件及其活动类型的更多信息,请参阅“触发工作流的事件”。
on:
label:
types: [created, edited]
on.<pull_request|pull_request_target>.<branches|branches-ignore>
使用pull_request
和pull_request_target
事件时,您可以配置工作流,使其仅针对目标为特定分支的拉取请求运行。
当要包含分支名称模式或同时包含和排除分支名称模式时,请使用branches
过滤器。当只想排除分支名称模式时,请使用branches-ignore
过滤器。您不能在工作流中对同一事件同时使用branches
和branches-ignore
过滤器。
如果同时定义branches
/branches-ignore
和paths
/paths-ignore
,则只有当两个过滤器都满足时,工作流才会运行。
branches
和branches-ignore
关键字接受使用诸如*
、**
、+
、?
、!
等字符的 glob 模式,以匹配多个分支名称。如果名称包含任何这些字符,并且你想要精确匹配,则需要使用\
转义每个特殊字符。有关 glob 模式的更多信息,请参阅“GitHub Actions 的工作流语法”。
示例:包含分支
branches
中定义的模式将针对 Git ref 的名称进行评估。例如,以下工作流将在针对以下内容的pull_request
事件发生时运行:
- 名为
main
的分支(refs/heads/main
) - 名为
mona/octocat
的分支(refs/heads/mona/octocat
) - 名称以
releases/
开头的分支,例如releases/10
(refs/heads/releases/10
)
on:
pull_request:
# Sequence of patterns matched against refs/heads
branches:
- main
- 'mona/octocat'
- 'releases/**'
如果由于分支筛选、路径筛选或提交消息而跳过了工作流,则与该工作流关联的检查将保持“待定”状态。需要这些检查才能成功才能合并的拉取请求将被阻止合并。
示例:排除分支
当模式与branches-ignore
模式匹配时,工作流将不会运行。branches-ignore
中定义的模式将针对 Git ref 的名称进行评估。例如,以下工作流将在发生pull_request
事件时运行,除非拉取请求的目标是:
- 名为
mona/octocat
的分支(refs/heads/mona/octocat
) - 名称与
releases/**-alpha
匹配的分支,例如releases/beta/3-alpha
(refs/heads/releases/beta/3-alpha
)
on:
pull_request:
# Sequence of patterns matched against refs/heads
branches-ignore:
- 'mona/octocat'
- 'releases/**-alpha'
示例:包含和排除分支
您不能使用branches
和branches-ignore
来筛选单个工作流中的同一事件。如果要同时包含和排除单个事件的分支模式,请使用branches
过滤器以及!
字符来指示应排除哪些分支。
如果使用!
字符定义分支,则还必须定义至少一个没有!
字符的分支。如果只想排除分支,请改用branches-ignore
。
定义模式的顺序很重要。
- 正匹配之后的匹配负模式(以
!
为前缀)将排除 Git ref。 - 负匹配之后的匹配正模式将再次包含 Git ref。
以下工作流将在针对releases/10
或releases/beta/mona
的pull_request
事件上运行,但不会针对针对releases/10-alpha
或releases/beta/3-alpha
的拉取请求运行,因为负模式!releases/**-alpha
位于正模式之后。
on:
pull_request:
branches:
- 'releases/**'
- '!releases/**-alpha'
on.push.<branches|tags|branches-ignore|tags-ignore>
使用push
事件时,您可以配置工作流以在特定分支或标签上运行。
当要包含分支名称模式或同时包含和排除分支名称模式时,请使用branches
过滤器。当只想排除分支名称模式时,请使用branches-ignore
过滤器。您不能在工作流中对同一事件同时使用branches
和branches-ignore
过滤器。
当要包含标签名称模式或同时包含和排除标签名称模式时,请使用tags
过滤器。当只想排除标签名称模式时,请使用tags-ignore
过滤器。您不能在工作流中对同一事件同时使用tags
和tags-ignore
过滤器。
如果仅定义tags
/tags-ignore
或仅定义branches
/branches-ignore
,则工作流不会针对影响未定义 Git ref 的事件运行。如果既没有定义tags
/tags-ignore
也没有定义branches
/branches-ignore
,则工作流将针对影响分支或标签的事件运行。如果同时定义branches
/branches-ignore
和paths
/paths-ignore
,则只有当两个过滤器都满足时,工作流才会运行。
branches
、branches-ignore
、tags
和tags-ignore
关键字接受使用诸如*
、**
、+
、?
、!
等字符的 glob 模式,以匹配多个分支或标签名称。如果名称包含任何这些字符,并且你想要精确匹配,则需要使用\
来*转义*每个特殊字符。有关 glob 模式的更多信息,请参阅“GitHub Actions 的工作流语法”。
示例:包含分支和标签
branches
和tags
中定义的模式将针对 Git ref 的名称进行评估。例如,以下工作流将在向以下内容推送push
事件时运行:
- 名为
main
的分支(refs/heads/main
) - 名为
mona/octocat
的分支(refs/heads/mona/octocat
) - 名称以
releases/
开头的分支,例如releases/10
(refs/heads/releases/10
) - 名为
v2
的标签(refs/tags/v2
) - 名称以
v1.
开头的标签,例如v1.9.1
(refs/tags/v1.9.1
)
on:
push:
# Sequence of patterns matched against refs/heads
branches:
- main
- 'mona/octocat'
- 'releases/**'
# Sequence of patterns matched against refs/tags
tags:
- v2
- v1.*
示例:排除分支和标签
当模式与branches-ignore
或tags-ignore
模式匹配时,工作流将不会运行。branches
和tags
中定义的模式将针对 Git ref 的名称进行评估。例如,以下工作流将在发生push
事件时运行,除非push
事件的目标是:
- 名为
mona/octocat
的分支(refs/heads/mona/octocat
) - 名称与
releases/**-alpha
匹配的分支,例如releases/beta/3-alpha
(refs/heads/releases/beta/3-alpha
) - 名为
v2
的标签(refs/tags/v2
) - 名称以
v1.
开头的标签,例如v1.9
(refs/tags/v1.9
)
on:
push:
# Sequence of patterns matched against refs/heads
branches-ignore:
- 'mona/octocat'
- 'releases/**-alpha'
# Sequence of patterns matched against refs/tags
tags-ignore:
- v2
- v1.*
示例:包含和排除分支和标签
您不能使用branches
和branches-ignore
来筛选单个工作流中的同一事件。同样,您不能使用tags
和tags-ignore
来筛选单个工作流中的同一事件。如果要同时包含和排除单个事件的分支或标签模式,请使用branches
或tags
过滤器以及!
字符来指示应排除哪些分支或标签。
如果使用!
字符定义分支,则还必须定义至少一个不使用!
字符的分支。如果只想排除分支,请改用branches-ignore
。同样,如果使用!
字符定义标签,则还必须定义至少一个不使用!
字符的标签。如果只想排除标签,请改用tags-ignore
。
定义模式的顺序很重要。
- 正匹配之后的匹配负模式(以
!
为前缀)将排除 Git ref。 - 负匹配之后的匹配正模式将再次包含 Git ref。
以下工作流将在推送到releases/10
或releases/beta/mona
时运行,但不会在推送到releases/10-alpha
或releases/beta/3-alpha
时运行,因为负模式!releases/**-alpha
位于正模式之后。
on:
push:
branches:
- 'releases/**'
- '!releases/**-alpha'
on.<push|pull_request|pull_request_target>.<paths|paths-ignore>
使用push
和pull_request
事件时,您可以配置工作流,使其根据更改的文件路径运行。对于标签推送,不会评估路径过滤器。
当您要包含文件路径模式或同时包含和排除文件路径模式时,请使用paths
过滤器。当您只想排除文件路径模式时,请使用paths-ignore
过滤器。您不能在一个工作流中对同一事件同时使用paths
和paths-ignore
过滤器。如果您想对单个事件同时包含和排除路径模式,请使用以!
字符为前缀的paths
过滤器来指示要排除哪些路径。
注意
定义paths
模式的顺序很重要
- 正匹配后的匹配负模式(以
!
为前缀)将排除该路径。 - 负匹配后的匹配正模式将再次包含该路径。
如果同时定义了branches
/branches-ignore
和paths
/paths-ignore
,则只有当这两个过滤器都满足条件时,工作流才会运行。
paths
和paths-ignore
关键字接受使用*
和**
通配符匹配多个路径名称的 glob 模式。有关更多信息,请参阅“GitHub Actions 的工作流语法”。
示例:包含路径
如果至少有一条路径与paths
过滤器中的模式匹配,则工作流将运行。例如,以下工作流将在您推送 JavaScript 文件 (.js
) 时运行。
on:
push:
paths:
- '**.js'
如果由于路径过滤、分支过滤或提交消息而跳过了工作流,则与该工作流关联的检查将保持“挂起”状态。需要这些检查才能成功才能合并的拉取请求将被阻止合并。
示例:排除路径
当所有路径名称都与paths-ignore
中的模式匹配时,工作流将不会运行。如果任何路径名称与paths-ignore
中的模式不匹配,即使某些路径名称与这些模式匹配,工作流也会运行。
具有以下路径过滤器的的工作流仅在push
事件包含存储库根目录中docs
目录之外的至少一个文件时才会运行。
on:
push:
paths-ignore:
- 'docs/**'
示例:包含和排除路径
您不能使用paths
和paths-ignore
来过滤单个工作流中的同一事件。如果您想对单个事件同时包含和排除路径模式,请使用以!
字符为前缀的paths
过滤器来指示要排除哪些路径。
如果使用!
字符定义路径,则还必须定义至少一条不使用!
字符的路径。如果只想排除路径,请改用paths-ignore
。
定义paths
模式的顺序很重要
- 正匹配后的匹配负模式(以
!
为前缀)将排除该路径。 - 负匹配后的匹配正模式将再次包含该路径。
此示例在push
事件包含sub-project
目录或其子目录中的文件时运行,除非该文件位于sub-project/docs
目录中。例如,更改sub-project/index.js
或sub-project/src/index.js
的推送将触发工作流运行,但仅更改sub-project/docs/readme.md
的推送不会触发。
on:
push:
paths:
- 'sub-project/**'
- '!sub-project/docs/**'
Git diff 比较
注意
如果您推送超过 1,000 次提交,或者由于超时而 GitHub 未生成 diff,则工作流将始终运行。
过滤器通过评估更改的文件并将它们与paths-ignore
或paths
列表运行来确定是否应运行工作流。如果没有更改任何文件,则工作流将不会运行。
GitHub 使用两点 diff(用于推送)和三点 diff(用于拉取请求)生成更改文件的列表。
- **拉取请求:**三点 diff 是主题分支的最新版本与主题分支上次与基分支同步的提交之间的比较。
- **对现有分支的推送:**两点 diff 直接比较头和基 SHA。
- **对新分支的推送:**针对推送的最深提交的祖先的父级的两点 diff。
diff 限制为 300 个文件。如果更改的文件未在过滤器返回的前 300 个文件中匹配,则工作流将不会运行。您可能需要创建更具体的过滤器,以便工作流会自动运行。
有关更多信息,请参阅“关于比较拉取请求中的分支”。
on.schedule
您可以使用on.schedule
为您的工作流定义时间表。您可以使用POSIX cron 语法安排工作流在特定的 UTC 时间运行。计划的工作流在默认分支或基分支上的最新提交上运行。您可以运行计划的工作流的最短间隔为每 5 分钟一次。
此示例每天 UTC 时间 5:30 和 17:30 触发工作流
on:
schedule:
# * is a special character in YAML so you have to quote this string
- cron: '30 5,17 * * *'
单个工作流可以由多个schedule
事件触发。您可以通过github.event.schedule
上下文访问触发工作流的调度事件。此示例触发工作流在每周一至周四 UTC 时间 5:30 运行,但在周一和周三跳过“不在周一或周三”步骤。
on:
schedule:
- cron: '30 5 * * 1,3'
- cron: '30 5 * * 2,4'
jobs:
test_schedule:
runs-on: ubuntu-latest
steps:
- name: Not on Monday or Wednesday
if: github.event.schedule != '30 5 * * 1,3'
run: echo "This step will be skipped on Monday and Wednesday"
- name: Every time
run: echo "This step will always run"
有关 cron 语法的更多信息,请参阅“触发工作流的事件”。
on.workflow_call
使用on.workflow_call
定义可重用工作流的输入和输出。您还可以映射可用于被调用工作流的密钥。有关可重用工作流的更多信息,请参阅“重用工作流”。
on.workflow_call.inputs
使用workflow_call
关键字时,您可以选择指定从调用者工作流传递到被调用工作流的输入。有关workflow_call
关键字的更多信息,请参阅“触发工作流的事件”。
除了可用的标准输入参数外,on.workflow_call.inputs
还需要一个type
参数。有关更多信息,请参阅on.workflow_call.inputs.<input_id>.type
。
如果没有设置default
参数,则输入的默认值为布尔值的false
、数字的0
和字符串的""
。
在被调用工作流中,您可以使用inputs
上下文来引用输入。有关更多信息,请参阅“访问有关工作流运行的上下文信息”。
如果调用者工作流传递的输入未在被调用工作流中指定,则会导致错误。
on.workflow_call.inputs
示例
on:
workflow_call:
inputs:
username:
description: 'A username passed from the caller workflow'
default: 'john-doe'
required: false
type: string
jobs:
print-username:
runs-on: ubuntu-latest
steps:
- name: Print the input name to STDOUT
run: echo The username is ${{ inputs.username }}
有关更多信息,请参阅“重用工作流”。
on.workflow_call.inputs.<input_id>.type
如果为on.workflow_call
关键字定义了输入,则需要此参数。此参数的值是一个字符串,指定输入的数据类型。这必须是以下之一:boolean
、number
或string
。
on.workflow_call.outputs
被调用工作流的输出映射。被调用工作流输出可用于调用者工作流中的所有下游作业。每个输出都有一个标识符、一个可选的description
和一个value
。value
必须设置为被调用工作流中作业的输出值。
在下面的示例中,为这个可重用工作流定义了两个输出:workflow_output1
和workflow_output2
。它们映射到名为job_output1
和job_output2
的输出,这两个输出都来自名为my_job
的作业。
on.workflow_call.outputs
示例
on:
workflow_call:
# Map the workflow outputs to job outputs
outputs:
workflow_output1:
description: "The first job output"
value: ${{ jobs.my_job.outputs.job_output1 }}
workflow_output2:
description: "The second job output"
value: ${{ jobs.my_job.outputs.job_output2 }}
有关如何引用作业输出的信息,请参阅jobs.<job_id>.outputs
。有关更多信息,请参阅“重用工作流”。
on.workflow_call.secrets
可在被调用工作流中使用的密钥映射。
在被调用工作流中,您可以使用secrets
上下文来引用密钥。
注意
如果您正在将密钥传递给嵌套的可重用工作流,则必须再次使用jobs.<job_id>.secrets
来传递密钥。有关更多信息,请参阅“重用工作流”。
如果调用者工作流传递了被调用工作流中未指定的密钥,则会导致错误。
on.workflow_call.secrets
示例
on:
workflow_call:
secrets:
access-token:
description: 'A token passed from the caller workflow'
required: false
jobs:
pass-secret-to-action:
runs-on: ubuntu-latest
steps:
# passing the secret to an action
- name: Pass the received secret to an action
uses: ./.github/actions/my-action
with:
token: ${{ secrets.access-token }}
# passing the secret to a nested reusable workflow
pass-secret-to-workflow:
uses: ./.github/workflows/my-workflow
secrets:
token: ${{ secrets.access-token }}
on.workflow_call.secrets.<secret_id>
与密钥关联的字符串标识符。
on.workflow_call.secrets.<secret_id>.required
指定是否必须提供密钥的布尔值。
on.workflow_run.<branches|branches-ignore>
使用workflow_run
事件时,可以指定触发工作流必须在其上运行的分支,以便触发您的工作流。
branches
和branches-ignore
过滤器接受使用*
、**
、+
、?
、!
等字符的 glob 模式,以匹配多个分支名称。如果名称包含任何这些字符,并且您想要精确匹配,则需要使用\
转义每个特殊字符。有关 glob 模式的更多信息,请参阅“GitHub Actions 的工作流语法”。
例如,具有以下触发器的 workflow 仅在名为Build
的工作流在名称以releases/
开头的分支上运行时才会运行。
on:
workflow_run:
workflows: ["Build"]
types: [requested]
branches:
- 'releases/**'
具有以下触发器的 workflow 仅在名为Build
的工作流在名称不为canary
的分支上运行时才会运行。
on:
workflow_run:
workflows: ["Build"]
types: [requested]
branches-ignore:
- "canary"
您不能在工作流中的同一事件中同时使用branches
和branches-ignore
过滤器。如果您想要同时包含和排除单个事件的分支模式,请使用branches
过滤器以及!
字符来指示应排除哪些分支。
定义模式的顺序很重要。
- 正则匹配后的否定模式(以
!
为前缀)将排除该分支。 - 否定匹配后的正则匹配将再次包含该分支。
例如,具有以下触发器的 workflow 将在名为Build
的工作流在名为releases/10
或releases/beta/mona
的分支上运行时运行,但不会在releases/10-alpha
、releases/beta/3-alpha
或main
上运行。
on:
workflow_run:
workflows: ["Build"]
types: [requested]
branches:
- 'releases/**'
- '!releases/**-alpha'
on.workflow_dispatch
使用workflow_dispatch
事件时,您可以选择指定传递给工作流的输入。
此触发器仅在工作流文件位于默认分支上时接收事件。
on.workflow_dispatch.inputs
触发的 workflow 在inputs
上下文中接收输入。有关更多信息,请参阅“上下文”。
注意
- workflow 还将在
github.event.inputs
上下文中接收输入。inputs
上下文和github.event.inputs
上下文中的信息相同,除了inputs
上下文将布尔值保留为布尔值,而不是将其转换为字符串。choice
类型解析为字符串,并且是一个可选择的选项。 inputs
的顶级属性的最大数量为 10。inputs
的最大有效负载为 65,535 个字符。
on.workflow_dispatch.inputs
示例
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 }}
on.workflow_dispatch.inputs.<input_id>.required
指定是否必须提供输入的布尔值。
on.workflow_dispatch.inputs.<input_id>.type
此参数的值是一个字符串,指定输入的数据类型。这必须是以下之一:boolean
、choice
、number
、environment
或string
。
permissions
您可以使用permissions
修改授予GITHUB_TOKEN
的默认权限,根据需要添加或删除访问权限,以便您只允许最低限度的必要访问权限。有关更多信息,请参阅“自动令牌身份验证”。
您可以将permissions
用作顶级密钥(应用于工作流中的所有作业),也可以在特定作业中使用。当您在特定作业中添加permissions
密钥时,在该作业中使用GITHUB_TOKEN
的所有操作和运行命令都将获得您指定的访问权限。有关更多信息,请参阅jobs.<job_id>.permissions
。
对于下表中显示的每个可用权限,您可以分配一个访问级别:read
(如果适用)、write
或none
。write
包含read
。如果您指定了这些权限中的任何一个的访问权限,则所有未指定的权限都将设置为none
。
可用的权限以及每个权限允许操作执行的操作的详细信息
权限 | 允许使用GITHUB_TOKEN 的操作执行以下操作 |
---|---|
actions | 使用 GitHub Actions。例如,actions: write 允许操作取消工作流运行。有关更多信息,请参阅“GitHub Apps所需的权限”。 |
attestations | 使用工件证明。例如,attestations: write 允许操作为构建生成工件证明。有关更多信息,请参阅“使用工件证明来建立构建来源” |
checks | 使用检查运行和检查套件。例如,checks: write 允许操作创建一个检查运行。有关更多信息,请参阅“GitHub Apps所需的权限”。 |
contents | 使用仓库的内容。例如,contents: read 允许操作列出提交,而contents: write 允许操作创建发布。有关更多信息,请参阅“GitHub Apps所需的权限”。 |
deployments | 使用部署。例如,deployments: write 允许操作创建一个新的部署。有关更多信息,请参阅“GitHub Apps所需的权限”。 |
discussions | 使用 GitHub Discussions。例如,discussions: write 允许操作关闭或删除讨论。有关更多信息,请参阅“使用 GraphQL API 进行讨论” |
id-token | 获取 OpenID Connect (OIDC) 令牌。这需要id-token: write 。有关更多信息,请参阅“关于使用 OpenID Connect 加强安全性” |
issues | 使用问题。例如,issues: write 允许操作向问题添加评论。有关更多信息,请参阅“GitHub Apps所需的权限”。 |
packages | 使用 GitHub Packages。例如,packages: write 允许操作上传和发布 GitHub Packages 上的软件包。有关更多信息,请参阅“关于 GitHub Packages 的权限”。 |
pages | 使用 GitHub Pages。例如,pages: write 允许操作请求 GitHub Pages 构建。有关更多信息,请参阅“GitHub Apps所需的权限”。 |
pull-requests | 使用拉取请求。例如,pull-requests: write 允许操作向拉取请求添加标签。有关更多信息,请参阅“GitHub Apps所需的权限”。 |
repository-projects | 使用 GitHub 项目(经典版)。例如,repository-projects: write 允许操作向项目(经典版)添加列。有关更多信息,请参阅“GitHub Apps所需的权限”。 |
security-events | 使用 GitHub 代码扫描和 Dependabot 警报。例如,security-events: read 允许操作列出仓库的 Dependabot 警报,而security-events: write 允许操作更新代码扫描警报的状态。有关更多信息,请参阅““代码扫描警报”的仓库权限”和““Dependabot 警报”的仓库权限”在“GitHub Apps所需的权限”中。 |
statuses | 使用提交状态。例如,statuses:read 允许操作列出给定引用的提交状态。有关更多信息,请参阅“GitHub Apps所需的权限”。 |
定义GITHUB_TOKEN
作用域的访问权限
您可以通过在permissions
密钥中指定read
、write
或none
作为可用权限的值来定义GITHUB_TOKEN
将允许的访问权限。
permissions:
actions: read|write|none
attestations: read|write|none
checks: read|write|none
contents: read|write|none
deployments: read|write|none
id-token: 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
。
您可以使用以下语法为所有可用权限定义read-all
或write-all
访问权限。
permissions: read-all
permissions: write-all
您可以使用以下语法禁用所有可用权限的权限。
permissions: {}
更改派生仓库中的权限
您可以使用permissions
密钥为派生仓库添加和删除读取权限,但通常您不能授予写入访问权限。此行为的例外情况是管理员用户已在 GitHub Actions 设置中选择了“将写入令牌发送到来自拉取请求的工作流”选项。有关更多信息,请参阅“管理仓库的 GitHub Actions 设置”。
设置工作流中所有作业的GITHUB_TOKEN
权限
您可以在工作流的顶层指定permissions
,以便该设置应用于工作流中的所有作业。
示例:为整个工作流设置GITHUB_TOKEN
权限
此示例显示为GITHUB_TOKEN
设置的权限,这些权限将应用于工作流中的所有作业。所有权限都被授予读取访问权限。
name: "My workflow"
on: [ push ]
permissions: read-all
jobs:
...
env
一个map
,其中包含工作流中所有作业步骤可用的变量。您还可以设置仅对单个作业的步骤或单个步骤可用的变量。有关更多信息,请参阅jobs.<job_id>.env
和jobs.<job_id>.steps[*].env
。
env
映射中的变量不能根据映射中的其他变量定义。
当使用相同的名称定义多个环境变量时,GitHub 将使用最具体的变量。例如,在步骤中定义的环境变量将在作业和工作流环境变量执行期间覆盖同名的作业和工作流环境变量。作业中定义的环境变量将在作业执行期间覆盖同名的工作流变量。
env
示例
env:
SERVER: production
defaults
使用defaults
创建一个map
,其中包含将应用于工作流中所有作业的默认设置。您还可以设置仅对作业可用的默认设置。有关更多信息,请参阅jobs.<job_id>.defaults
。
当使用相同的名称定义多个默认设置时,GitHub 将使用最具体的默认设置。例如,在作业中定义的默认设置将覆盖在工作流中定义的同名默认设置。
defaults.run
您可以使用defaults.run
为工作流中的所有run
步骤提供默认的shell
和working-directory
选项。您还可以设置仅对作业可用的run
默认设置。有关更多信息,请参阅jobs.<job_id>.defaults.run
。您不能在此关键字中使用上下文或表达式。
当使用相同的名称定义多个默认设置时,GitHub 将使用最具体的默认设置。例如,在作业中定义的默认设置将覆盖在工作流中定义的同名默认设置。
示例:设置默认 shell 和工作目录
defaults:
run:
shell: bash
working-directory: ./scripts
defaults.run.shell
使用shell
为步骤定义shell
。此关键字可以引用多个上下文。有关更多信息,请参阅"上下文"。
支持的平台 | shell 参数 | 描述 | 内部运行的命令 |
---|---|---|---|
Linux / macOS | 未指定 | 非 Windows 平台上的默认 shell。请注意,这会运行与显式指定bash 时不同的命令。如果路径中找不到bash ,则将其视为sh 。 | bash -e {0} |
所有平台 | bash | 非 Windows 平台上的默认 shell,并回退到sh 。在 Windows 上指定 bash shell 时,将使用 Git for Windows 附带的 bash shell。 | bash --noprofile --norc -eo pipefail {0} |
所有平台 | pwsh | PowerShell Core。GitHub 会将扩展名.ps1 附加到您的脚本名称。 | pwsh -command ". '{0}'" |
所有平台 | python | 执行 python 命令。 | python {0} |
Linux / macOS | sh | 如果未提供 shell 并且路径中找不到bash ,则非 Windows 平台的回退行为。 | sh -e {0} |
Windows | cmd | GitHub 会将扩展名.cmd 附加到您的脚本名称并替换为{0} 。 | %ComSpec% /D /E:ON /V:OFF /S /C "CALL "{0}"" . |
Windows | pwsh | 这是 Windows 上使用的默认 shell。PowerShell Core。GitHub 会将扩展名.ps1 附加到您的脚本名称。如果您的自托管 Windows 运行器未安装 *PowerShell Core*,则将改为使用 *PowerShell Desktop*。 | pwsh -command ". '{0}'" . |
Windows | powershell | PowerShell Desktop。GitHub 会将扩展名.ps1 附加到您的脚本名称。 | powershell -command ". '{0}'" . |
当使用相同的名称定义多个默认设置时,GitHub 将使用最具体的默认设置。例如,在作业中定义的默认设置将覆盖在工作流中定义的同名默认设置。
defaults.run.working-directory
使用working-directory
为步骤的shell
定义工作目录。此关键字可以引用多个上下文。有关更多信息,请参阅"上下文"。
提示
在运行 shell 之前,请确保您分配的working-directory
在运行器上存在。当使用相同的名称定义多个默认设置时,GitHub 将使用最具体的默认设置。例如,在作业中定义的默认设置将覆盖在工作流中定义的同名默认设置。
concurrency
使用concurrency
确保一次只有一个使用相同并发组的作业或工作流运行。并发组可以是任何字符串或表达式。表达式只能使用github
、inputs
和vars
上下文。有关表达式的更多信息,请参阅"在工作流和操作中评估表达式"。
您也可以在作业级别指定concurrency
。有关更多信息,请参阅jobs.<job_id>.concurrency
。
这意味着并发组中最多只能同时存在一个正在运行的作业和一个挂起的作业。当并发作业或工作流排队时,如果存储库中使用相同并发组的另一个作业或工作流正在进行中,则排队的作业或工作流将处于pending
状态。如果存在,则并发组中任何现有的pending
作业或工作流都将被取消,新的排队作业或工作流将取代其位置。
要取消并发组中任何当前正在运行的作业或工作流,请指定cancel-in-progress: true
。要根据条件取消并发组中当前正在运行的作业或工作流,您可以将cancel-in-progress
指定为包含任何允许的表达式上下文的表达式。
注意
- 并发组名称不区分大小写。例如,
prod
和Prod
将被视为同一个并发组。 - 使用并发组的作业或工作流运行的顺序不受保证。相同并发组中的作业或工作流运行将以任意顺序处理。
示例:使用并发和默认行为
GitHub Actions 的默认行为是允许多个作业或工作流运行同时运行。concurrency
关键字允许您控制工作流运行的并发性。
例如,您可以立即在定义触发条件的位置之后使用concurrency
关键字来限制特定分支的整个工作流运行的并发性
on:
push:
branches:
- main
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
您还可以通过在作业级别使用concurrency
关键字来限制工作流内作业的并发性
on:
push:
branches:
- main
jobs:
job-1:
runs-on: ubuntu-latest
concurrency:
group: example-group
cancel-in-progress: true
示例:并发组
并发组提供了一种管理和限制共享相同并发密钥的工作流运行或作业执行的方法。
concurrency
密钥用于将工作流或作业分组到并发组中。当您定义concurrency
密钥时,GitHub Actions 确保一次只有一个具有该密钥的工作流或作业运行。如果新的工作流运行或作业以相同的concurrency
密钥启动,GitHub Actions 将取消任何已使用该密钥运行的工作流或作业。concurrency
密钥可以是硬编码字符串,也可以是包含上下文变量的动态表达式。
您可以在工作流中定义并发条件,以便工作流或作业成为并发组的一部分。
这意味着当工作流运行或作业启动时,GitHub 将取消在同一并发组中已在进行中的任何工作流运行或作业。这在您希望防止某些工作流或作业(例如用于部署到登台环境的工作流或作业)的并行运行的情况下非常有用,以防止可能导致冲突或消耗比必要更多资源的操作。
在此示例中,job-1
是名为staging_environment
的并发组的一部分。这意味着,如果触发了job-1
的新运行,则将取消在staging_environment
并发组中已在进行中的同一作业的任何运行。
jobs:
job-1:
runs-on: ubuntu-latest
concurrency:
group: staging_environment
cancel-in-progress: true
或者,在您的工作流中使用动态表达式(例如concurrency: ci-${{ github.ref }}
)意味着工作流或作业将成为名为ci-
(后跟触发工作流的分支或标签的引用)的并发组的一部分。在此示例中,如果在以前的运行仍在进行中时将新的提交推送到主分支,则以前的运行将被取消,新的运行将开始。
on:
push:
branches:
- main
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
示例:使用并发取消任何正在进行的作业或运行
要在 GitHub Actions 中使用并发来取消任何正在进行的作业或运行,您可以将concurrency
密钥与设置为true
的cancel-in-progress
选项一起使用。
concurrency:
group: ${{ github.ref }}
cancel-in-progress: true
请注意,在此示例中,如果没有定义特定的并发组,GitHub Actions 将取消作业或工作流的 *任何* 正在进行的运行。
示例:使用回退值
如果使用仅为特定事件定义的属性构建组名,则可以使用回退值。例如,github.head_ref
仅在pull_request
事件中定义。如果您的工作流响应除pull_request
事件之外的其他事件,则需要提供回退以避免语法错误。以下并发组仅在pull_request
事件中取消正在进行的作业或运行;如果github.head_ref
未定义,则并发组将回退到运行 ID,该 ID 保证对运行唯一且已定义。
concurrency:
group: ${{ github.head_ref || github.run_id }}
cancel-in-progress: true
示例:仅取消当前工作流的正在进行的作业或运行
如果存储库中有多个工作流,则并发组名称必须在工作流之间唯一,以避免取消其他工作流的正在进行的作业或运行。否则,任何先前正在进行或挂起的作业都将被取消,无论工作流如何。
要仅取消同一工作流的正在进行的运行,可以使用github.workflow
属性来构建并发组。
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
示例:仅取消特定分支上的正在进行的作业
如果您只想取消某些分支上的正在进行的作业,而不想取消其他分支上的作业,则可以使用带有cancel-in-progress
的条件表达式。例如,如果您只想取消开发分支上的正在进行的作业,而不想取消发布分支上的作业,则可以这样做。
要仅在未在发布分支上运行时取消同一工作流的正在进行的运行,您可以将cancel-in-progress
设置为类似于以下内容的表达式。
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ !contains(github.ref, 'release/')}}
在此示例中,对release/1.2.3
分支的多次推送不会取消正在进行的运行。对其他分支(例如main
)的推送将取消正在进行的运行。
jobs
一个工作流运行由一个或多个jobs
组成,默认情况下这些jobs
并行运行。要顺序运行作业,您可以使用jobs.<job_id>.needs
关键字定义对其他作业的依赖关系。
每个作业都在由runs-on
指定的运行器环境中运行。
只要您在工作流使用限制范围内,就可以运行无限数量的作业。更多信息,请参见关于 GitHub 托管运行器的“使用限制、计费和管理”以及关于自托管运行器使用限制的“关于自托管运行器”。
如果您需要查找工作流运行中运行的作业的唯一标识符,可以使用 GitHub API。更多信息,请参见“GitHub Actions 的 REST API 端点”。
jobs.<job_id>
使用jobs.<job_id>
为您的作业提供唯一的标识符。键job_id
是一个字符串,其值是作业配置数据的映射。您必须将<job_id>
替换为jobs
对象中唯一的字符串。<job_id>
必须以字母或_
开头,并且只能包含字母数字字符、-
或_
。
示例:创建作业
在此示例中,创建了两个作业,它们的job_id
值分别为my_first_job
和my_second_job
。
jobs:
my_first_job:
name: My first job
my_second_job:
name: My second job
jobs.<job_id>.name
使用jobs.<job_id>.name
为作业设置名称,该名称将显示在 GitHub UI 中。
jobs.<job_id>.permissions
对于特定作业,您可以使用jobs.<job_id>.permissions
修改授予GITHUB_TOKEN
的默认权限,根据需要添加或删除访问权限,以便您只允许最低限度的必要访问权限。更多信息,请参见“自动令牌身份验证”。
如果需要,您可以通过在作业定义中指定权限,为每个作业的GITHUB_TOKEN
配置不同的权限集。或者,您可以为工作流中的所有作业指定权限。有关在工作流级别定义权限的信息,请参见permissions
。
对于下表中显示的每个可用权限,您可以分配一个访问级别:read
(如果适用)、write
或none
。write
包含read
。如果您指定了这些权限中的任何一个的访问权限,则所有未指定的权限都将设置为none
。
可用的权限以及每个权限允许操作执行的操作的详细信息
权限 | 允许使用GITHUB_TOKEN 的操作执行以下操作 |
---|---|
actions | 使用 GitHub Actions。例如,actions: write 允许操作取消工作流运行。有关更多信息,请参阅“GitHub Apps所需的权限”。 |
attestations | 使用工件证明。例如,attestations: write 允许操作为构建生成工件证明。有关更多信息,请参阅“使用工件证明来建立构建来源” |
checks | 使用检查运行和检查套件。例如,checks: write 允许操作创建一个检查运行。有关更多信息,请参阅“GitHub Apps所需的权限”。 |
contents | 使用仓库的内容。例如,contents: read 允许操作列出提交,而contents: write 允许操作创建发布。有关更多信息,请参阅“GitHub Apps所需的权限”。 |
deployments | 使用部署。例如,deployments: write 允许操作创建一个新的部署。有关更多信息,请参阅“GitHub Apps所需的权限”。 |
discussions | 使用 GitHub Discussions。例如,discussions: write 允许操作关闭或删除讨论。有关更多信息,请参阅“使用 GraphQL API 进行讨论” |
id-token | 获取 OpenID Connect (OIDC) 令牌。这需要id-token: write 。有关更多信息,请参阅“关于使用 OpenID Connect 加强安全性” |
issues | 使用问题。例如,issues: write 允许操作向问题添加评论。有关更多信息,请参阅“GitHub Apps所需的权限”。 |
packages | 使用 GitHub Packages。例如,packages: write 允许操作上传和发布 GitHub Packages 上的软件包。有关更多信息,请参阅“关于 GitHub Packages 的权限”。 |
pages | 使用 GitHub Pages。例如,pages: write 允许操作请求 GitHub Pages 构建。有关更多信息,请参阅“GitHub Apps所需的权限”。 |
pull-requests | 使用拉取请求。例如,pull-requests: write 允许操作向拉取请求添加标签。有关更多信息,请参阅“GitHub Apps所需的权限”。 |
repository-projects | 使用 GitHub 项目(经典版)。例如,repository-projects: write 允许操作向项目(经典版)添加列。有关更多信息,请参阅“GitHub Apps所需的权限”。 |
security-events | 使用 GitHub 代码扫描和 Dependabot 警报。例如,security-events: read 允许操作列出仓库的 Dependabot 警报,而security-events: write 允许操作更新代码扫描警报的状态。有关更多信息,请参阅““代码扫描警报”的仓库权限”和““Dependabot 警报”的仓库权限”在“GitHub Apps所需的权限”中。 |
statuses | 使用提交状态。例如,statuses:read 允许操作列出给定引用的提交状态。有关更多信息,请参阅“GitHub Apps所需的权限”。 |
定义GITHUB_TOKEN
作用域的访问权限
您可以通过在permissions
密钥中指定read
、write
或none
作为可用权限的值来定义GITHUB_TOKEN
将允许的访问权限。
permissions:
actions: read|write|none
attestations: read|write|none
checks: read|write|none
contents: read|write|none
deployments: read|write|none
id-token: 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
。
您可以使用以下语法为所有可用权限定义read-all
或write-all
访问权限。
permissions: read-all
permissions: write-all
您可以使用以下语法禁用所有可用权限的权限。
permissions: {}
更改派生仓库中的权限
您可以使用permissions
密钥为派生仓库添加和删除读取权限,但通常您不能授予写入访问权限。此行为的例外情况是管理员用户已在 GitHub Actions 设置中选择了“将写入令牌发送到来自拉取请求的工作流”选项。有关更多信息,请参阅“管理仓库的 GitHub Actions 设置”。
示例:设置工作流中一个作业的GITHUB_TOKEN
权限
此示例显示为GITHUB_TOKEN
设置的权限,这些权限仅适用于名为stale
的作业。为issues
和pull-requests
权限授予写入访问权限。所有其他权限将没有访问权限。
jobs:
stale:
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
steps:
- uses: actions/stale@v5
jobs.<job_id>.needs
使用jobs.<job_id>.needs
标识在该作业运行之前必须成功完成的任何作业。它可以是字符串或字符串数组。如果作业失败或被跳过,则所有需要它的作业都将被跳过,除非作业使用导致作业继续的条件表达式。如果运行包含一系列相互依赖的作业,则从失败或跳过点开始,依赖链中的所有作业都将应用失败或跳过。如果您希望即使依赖的作业没有成功也运行作业,请在jobs.<job_id>.if
中使用always()
条件表达式。
示例:需要成功的依赖作业
jobs:
job1:
job2:
needs: job1
job3:
needs: [job1, job2]
在此示例中,job1
必须成功完成才能开始job2
,而job3
等待job1
和job2
都完成。
此示例中的作业顺序运行
job1
job2
job3
示例:不需要成功的依赖作业
jobs:
job1:
job2:
needs: job1
job3:
if: ${{ always() }}
needs: [job1, job2]
在此示例中,job3
使用always()
条件表达式,以便在job1
和job2
完成后始终运行,无论它们是否成功。更多信息,请参见“在工作流和操作中评估表达式”。
jobs.<job_id>.if
您可以使用jobs.<job_id>.if
条件来阻止作业运行,除非满足某个条件。您可以使用任何受支持的上下文和表达式来创建条件。有关此键中支持哪些上下文的更多信息,请参见“访问有关工作流运行的上下文信息”。
注意
jobs.<job_id>.if
条件在应用jobs.<job_id>.strategy.matrix
之前进行评估。
当您在if
条件中使用表达式时,您可以选择省略${{ }}
表达式语法,因为 GitHub Actions 会自动将if
条件评估为表达式。但是,此例外并非在所有地方都适用。
当表达式以!
开头时,您必须始终使用${{ }}
表达式语法或使用''
、""
或()
进行转义,因为!
是 YAML 格式中的保留符号。例如
if: ${{ ! startsWith(github.ref, 'refs/tags/') }}
更多信息,请参见“在工作流和操作中评估表达式”。
示例:仅为特定存储库运行作业
此示例使用if
来控制production-deploy
作业何时运行。它仅在存储库名为octo-repo-prod
且位于octo-org
组织内时运行。否则,该作业将标记为已跳过。
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
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>.runs-on
使用jobs.<job_id>.runs-on
定义要在其上运行作业的机器类型。
- 目标机器可以是GitHub 托管运行器、更大运行器或自托管运行器。
- 您可以根据分配给运行器的标签、其组成员身份或两者的组合来定位运行器。
-
您可以将
runs-on
提供为- 单个字符串
- 包含字符串的单个变量
- 字符串数组、包含字符串的变量或两者的组合
- 使用
group
或labels
键的key: value
对
-
如果您指定字符串或变量数组,您的工作流将在与所有指定的
runs-on
值匹配的任何运行器上执行。例如,这里作业将只在具有标签linux
、x64
和gpu
的自托管运行器上运行runs-on: [self-hosted, linux, x64, gpu]
更多信息,请参见“选择自托管运行器”。
-
您可以在数组中混合字符串和变量。例如
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!
-
如果您想在多台机器上运行工作流,请使用
jobs.<job_id>.strategy
。
注意
简单字符串(如self-hosted
)不需要引号,但表达式(如"${{ inputs.chosen-os }}"
)需要引号。
选择 GitHub 托管运行器
如果您使用 GitHub 托管运行器,则每个作业都在runs-on
指定的运行器映像的新实例中运行。
当您使用 GitHub 托管运行器时,runs-on
的值是运行器标签或运行器组的名称。标准 GitHub 托管运行器的标签显示在下表中。
更多信息,请参见“关于 GitHub 托管运行器”。
公共存储库的标准 GitHub 托管运行器
对于公共存储库,使用下表中所示工作流标签的作业将在具有关联规格的虚拟机上运行。在公共存储库上使用这些运行器是免费且无限的。
虚拟机 | 处理器 (CPU) | 内存 (RAM) | 存储 (SSD) | 工作流标签 |
---|---|---|---|---|
Linux | 4 | 16 GB | 14 GB |
ubuntu-latest 、ubuntu-24.04 、ubuntu-22.04 、ubuntu-20.04 |
Windows | 4 | 16 GB | 14 GB |
windows-latest 、windows-2022 、windows-2019 |
macOS | 3 | 14 GB | 14 GB |
macos-12
|
macOS | 4 | 14 GB | 14 GB |
macos-13
|
macOS | 3 (M1) | 7 GB | 14 GB |
macos-latest 、macos-14 、macos-15 [公开预览] |
私有存储库的标准 GitHub 托管运行器
对于私有存储库,使用下表中所示工作流标签的作业将在具有关联规格的虚拟机上运行。这些运行器使用您的 GitHub 帐户分配的免费分钟数,然后按分钟费率收费。更多信息,请参见“关于 GitHub Actions 的计费”。
虚拟机 | 处理器 (CPU) | 内存 (RAM) | 存储 (SSD) | 工作流标签 |
---|---|---|---|---|
Linux | 2 | 7 GB | 14 GB |
ubuntu-latest 、ubuntu-24.04 、ubuntu-22.04 、ubuntu-20.04 |
Windows | 2 | 7 GB | 14 GB |
windows-latest 、windows-2022 、windows-2019 |
macOS | 3 | 14 GB | 14 GB |
macos-12
|
macOS | 4 | 14 GB | 14 GB |
macos-13
|
macOS | 3 (M1) | 7 GB | 14 GB |
macos-latest 、macos-14 、macos-15 [公开预览] |
除了标准的 GitHub 托管运行器外,GitHub 还为使用 GitHub Team 和 GitHub Enterprise Cloud 计划的客户提供一系列具有高级功能的托管虚拟机——例如,更多核心和磁盘空间、GPU 加速的机器和 ARM 架构的机器。更多信息,请参阅“关于大型运行器”。
注意
-latest
运行器镜像是 GitHub 提供的最新稳定镜像,可能不是操作系统供应商提供的最新操作系统版本。
警告
Beta 版和已弃用的镜像按“现状”、“包含所有缺陷”和“按可用性”提供,不包含在服务等级协议和保修范围内。Beta 版镜像可能不包含在客户支持范围内。
示例:指定操作系统
runs-on: ubuntu-latest
更多信息,请参阅“使用 GitHub 托管运行器”。
选择自托管运行器
要为您的作业指定自托管运行器,请在您的工作流文件中使用自托管运行器标签配置runs-on
。
自托管运行器可能具有self-hosted
标签。设置自托管运行器时,默认情况下我们将包含标签self-hosted
。您可以传入--no-default-labels
标志以防止应用自托管标签。标签可用于为运行器创建目标选项,例如操作系统或架构,我们建议提供一个以self-hosted
开头的标签数组(此标签必须列在首位),然后根据需要包含其他标签。当您指定一个标签数组时,作业将排队到具有您指定的所有标签的运行器上。
请注意,Actions 运行器控制器不支持多个标签,也不支持self-hosted
标签。
示例:使用标签进行运行器选择
runs-on: [self-hosted, linux]
更多信息,请参阅“关于自托管运行器”和“在工作流中使用自托管运行器”。
选择组中的运行器
您可以使用runs-on
来定位运行器组,以便作业将在该组的任何运行器上执行。为了更精细的控制,您还可以将运行器组与标签结合使用。
示例:使用组控制作业运行位置
在此示例中,Ubuntu 运行器已添加到名为ubuntu-runners
的组中。runs-on
密钥将作业发送到ubuntu-runners
组中任何可用的运行器。
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
示例:组合组和标签
组合组和标签时,运行器必须同时满足这两个要求才能有资格运行作业。
在此示例中,名为ubuntu-runners
的运行器组中填充了 Ubuntu 运行器,这些运行器还被分配了标签ubuntu-20.04-16core
。runs-on
密钥组合了group
和labels
,以便作业被路由到组内任何具有匹配标签的可用运行器。
name: learn-github-actions
on: [push]
jobs:
check-bats-version:
runs-on:
group: ubuntu-runners
labels: ubuntu-20.04-16core
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>.environment
使用jobs.<job_id>.environment
定义作业引用的环境。
您可以仅提供环境name
,也可以提供包含name
和url
的环境对象。URL 映射到部署 API 中的environment_url
。有关部署 API 的更多信息,请参阅“存储库的 REST API 端点”。
注意
在将引用环境的作业发送到运行器之前,必须通过所有部署保护规则。更多信息,请参阅“管理部署环境”。
示例:使用单个环境名称
environment: staging_environment
示例:使用环境名称和 URL
environment:
name: production_environment
url: https://github.com
url
的值可以是表达式。允许的表达式上下文:github
、inputs
、vars
、needs
、strategy
、matrix
、job
、runner
、env
和steps
。有关表达式的更多信息,请参阅“在工作流和操作中评估表达式”。
示例:使用输出作为 URL
environment:
name: production_environment
url: ${{ steps.step_id.outputs.url_output }}
name
的值可以是表达式。允许的表达式上下文:github
、inputs
、vars
、needs
、strategy
和matrix
。有关表达式的更多信息,请参阅“在工作流和操作中评估表达式”。
示例:使用表达式作为环境名称
environment:
name: ${{ github.ref_name }}
jobs.<job_id>.concurrency
您可以使用jobs.<job_id>.concurrency
来确保一次只运行一个使用相同并发组的作业或工作流。并发组可以是任何字符串或表达式。允许的表达式上下文:github
、inputs
、vars
、needs
、strategy
和matrix
。有关表达式的更多信息,请参阅“在工作流和操作中评估表达式”。
您也可以在工作流级别指定concurrency
。更多信息,请参阅concurrency
。
这意味着并发组中最多只能同时存在一个正在运行的作业和一个挂起的作业。当并发作业或工作流排队时,如果存储库中使用相同并发组的另一个作业或工作流正在进行中,则排队的作业或工作流将处于pending
状态。如果存在,则并发组中任何现有的pending
作业或工作流都将被取消,新的排队作业或工作流将取代其位置。
要取消并发组中任何当前正在运行的作业或工作流,请指定cancel-in-progress: true
。要根据条件取消并发组中当前正在运行的作业或工作流,您可以将cancel-in-progress
指定为包含任何允许的表达式上下文的表达式。
注意
- 并发组名称不区分大小写。例如,
prod
和Prod
将被视为同一个并发组。 - 使用并发组的作业或工作流运行的顺序不受保证。相同并发组中的作业或工作流运行将以任意顺序处理。
示例:使用并发和默认行为
GitHub Actions 的默认行为是允许多个作业或工作流运行同时运行。concurrency
关键字允许您控制工作流运行的并发性。
例如,您可以立即在定义触发条件的位置之后使用concurrency
关键字来限制特定分支的整个工作流运行的并发性
on:
push:
branches:
- main
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
您还可以通过在作业级别使用concurrency
关键字来限制工作流内作业的并发性
on:
push:
branches:
- main
jobs:
job-1:
runs-on: ubuntu-latest
concurrency:
group: example-group
cancel-in-progress: true
示例:并发组
并发组提供了一种管理和限制共享相同并发密钥的工作流运行或作业执行的方法。
concurrency
密钥用于将工作流或作业分组到并发组中。当您定义concurrency
密钥时,GitHub Actions 确保一次只有一个具有该密钥的工作流或作业运行。如果新的工作流运行或作业以相同的concurrency
密钥启动,GitHub Actions 将取消任何已使用该密钥运行的工作流或作业。concurrency
密钥可以是硬编码字符串,也可以是包含上下文变量的动态表达式。
您可以在工作流中定义并发条件,以便工作流或作业成为并发组的一部分。
这意味着当工作流运行或作业启动时,GitHub 将取消在同一并发组中已在进行中的任何工作流运行或作业。这在您希望防止某些工作流或作业(例如用于部署到登台环境的工作流或作业)的并行运行的情况下非常有用,以防止可能导致冲突或消耗比必要更多资源的操作。
在此示例中,job-1
是名为staging_environment
的并发组的一部分。这意味着,如果触发了job-1
的新运行,则将取消在staging_environment
并发组中已在进行中的同一作业的任何运行。
jobs:
job-1:
runs-on: ubuntu-latest
concurrency:
group: staging_environment
cancel-in-progress: true
或者,在您的工作流中使用动态表达式(例如concurrency: ci-${{ github.ref }}
)意味着工作流或作业将成为名为ci-
(后跟触发工作流的分支或标签的引用)的并发组的一部分。在此示例中,如果在以前的运行仍在进行中时将新的提交推送到主分支,则以前的运行将被取消,新的运行将开始。
on:
push:
branches:
- main
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
示例:使用并发取消任何正在进行的作业或运行
要在 GitHub Actions 中使用并发来取消任何正在进行的作业或运行,您可以将concurrency
密钥与设置为true
的cancel-in-progress
选项一起使用。
concurrency:
group: ${{ github.ref }}
cancel-in-progress: true
请注意,在此示例中,如果没有定义特定的并发组,GitHub Actions 将取消作业或工作流的 *任何* 正在进行的运行。
示例:使用回退值
如果使用仅为特定事件定义的属性构建组名,则可以使用回退值。例如,github.head_ref
仅在pull_request
事件中定义。如果您的工作流响应除pull_request
事件之外的其他事件,则需要提供回退以避免语法错误。以下并发组仅在pull_request
事件中取消正在进行的作业或运行;如果github.head_ref
未定义,则并发组将回退到运行 ID,该 ID 保证对运行唯一且已定义。
concurrency:
group: ${{ github.head_ref || github.run_id }}
cancel-in-progress: true
示例:仅取消当前工作流的正在进行的作业或运行
如果存储库中有多个工作流,则并发组名称必须在工作流之间唯一,以避免取消其他工作流的正在进行的作业或运行。否则,任何先前正在进行或挂起的作业都将被取消,无论工作流如何。
要仅取消同一工作流的正在进行的运行,可以使用github.workflow
属性来构建并发组。
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
示例:仅取消特定分支上的正在进行的作业
如果您只想取消某些分支上的正在进行的作业,而不想取消其他分支上的作业,则可以使用带有cancel-in-progress
的条件表达式。例如,如果您只想取消开发分支上的正在进行的作业,而不想取消发布分支上的作业,则可以这样做。
要仅在未在发布分支上运行时取消同一工作流的正在进行的运行,您可以将cancel-in-progress
设置为类似于以下内容的表达式。
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ !contains(github.ref, 'release/')}}
在此示例中,对release/1.2.3
分支的多次推送不会取消正在进行的运行。对其他分支(例如main
)的推送将取消正在进行的运行。
jobs.<job_id>.outputs
您可以使用jobs.<job_id>.outputs
为作业创建输出的map
。作业输出可用于依赖此作业的所有下游作业。有关定义作业依赖项的更多信息,请参阅jobs.<job_id>.needs
。
输出是 Unicode 字符串,最大可达 1 MB。工作流运行中的所有输出总计最大可达 50 MB。
包含表达式的作业输出在每个作业结束时在运行器上进行评估。包含密钥的输出在运行器上被屏蔽,不会发送到 GitHub Actions。
如果由于输出可能包含密钥而被跳过,您将看到以下警告消息:“跳过输出{output.Key}
,因为它可能包含密钥。”有关如何处理密钥的更多信息,请参考示例:屏蔽密钥并在作业或工作流之间传递密钥。
要在依赖作业中使用作业输出,您可以使用needs
上下文。更多信息,请参阅“访问有关工作流运行的上下文信息”。
示例:定义作业输出
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"
在矩阵作业中使用作业输出
矩阵可用于生成多个不同名称的输出。使用矩阵时,作业输出将从矩阵内的所有作业中组合。
jobs:
job1:
runs-on: ubuntu-latest
outputs:
output_1: ${{ steps.gen_output.outputs.output_1 }}
output_2: ${{ steps.gen_output.outputs.output_2 }}
output_3: ${{ steps.gen_output.outputs.output_3 }}
strategy:
matrix:
version: [1, 2, 3]
steps:
- name: Generate output
id: gen_output
run: |
version="${{ matrix.version }}"
echo "output_${version}=${version}" >> "$GITHUB_OUTPUT"
job2:
runs-on: ubuntu-latest
needs: [job1]
steps:
# Will show
# {
# "output_1": "1",
# "output_2": "2",
# "output_3": "3"
# }
- run: echo '${{ toJSON(needs.job1.outputs) }}'
jobs.<job_id>.env
作业中所有步骤都可用的变量的map
。您可以为整个工作流或单个步骤设置变量。更多信息,请参阅env
和jobs.<job_id>.steps[*].env
。
当使用相同的名称定义多个环境变量时,GitHub 将使用最具体的变量。例如,在步骤中定义的环境变量将在作业和工作流环境变量执行期间覆盖同名的作业和工作流环境变量。作业中定义的环境变量将在作业执行期间覆盖同名的工作流变量。
jobs.<job_id>.env
示例
jobs:
job1:
env:
FIRST_NAME: Mona
jobs.<job_id>.defaults
使用jobs.<job_id>.defaults
创建将应用于作业中所有步骤的默认设置的map
。您也可以为整个工作流设置默认设置。更多信息,请参阅defaults
。
当使用相同的名称定义多个默认设置时,GitHub 将使用最具体的默认设置。例如,在作业中定义的默认设置将覆盖在工作流中定义的同名默认设置。
jobs.<job_id>.defaults.run
使用jobs.<job_id>.defaults.run
为作业中的所有run
步骤提供默认的shell
和working-directory
。
您可以为作业中的所有run
步骤提供默认的shell
和working-directory
选项。您也可以为整个工作流的run
设置默认设置。更多信息,请参阅defaults.run
。
这些可以在jobs.<job_id>.defaults.run
和jobs.<job_id>.steps[*].run
级别被覆盖。
当使用相同的名称定义多个默认设置时,GitHub 将使用最具体的默认设置。例如,在作业中定义的默认设置将覆盖在工作流中定义的同名默认设置。
jobs.<job_id>.defaults.run.shell
使用shell
为步骤定义shell
。此关键字可以引用多个上下文。有关更多信息,请参阅"上下文"。
支持的平台 | shell 参数 | 描述 | 内部运行的命令 |
---|---|---|---|
Linux / macOS | 未指定 | 非 Windows 平台上的默认 shell。请注意,这会运行与显式指定bash 时不同的命令。如果路径中找不到bash ,则将其视为sh 。 | bash -e {0} |
所有平台 | bash | 非 Windows 平台上的默认 shell,并回退到sh 。在 Windows 上指定 bash shell 时,将使用 Git for Windows 附带的 bash shell。 | bash --noprofile --norc -eo pipefail {0} |
所有平台 | pwsh | PowerShell Core。GitHub 会将扩展名.ps1 附加到您的脚本名称。 | pwsh -command ". '{0}'" |
所有平台 | python | 执行 python 命令。 | python {0} |
Linux / macOS | sh | 如果未提供 shell 并且路径中找不到bash ,则非 Windows 平台的回退行为。 | sh -e {0} |
Windows | cmd | GitHub 会将扩展名.cmd 附加到您的脚本名称并替换为{0} 。 | %ComSpec% /D /E:ON /V:OFF /S /C "CALL "{0}"" . |
Windows | pwsh | 这是 Windows 上使用的默认 shell。PowerShell Core。GitHub 会将扩展名.ps1 附加到您的脚本名称。如果您的自托管 Windows 运行器未安装 *PowerShell Core*,则将改为使用 *PowerShell Desktop*。 | pwsh -command ". '{0}'" . |
Windows | powershell | PowerShell Desktop。GitHub 会将扩展名.ps1 附加到您的脚本名称。 | powershell -command ". '{0}'" . |
当使用相同的名称定义多个默认设置时,GitHub 将使用最具体的默认设置。例如,在作业中定义的默认设置将覆盖在工作流中定义的同名默认设置。
jobs.<job_id>.defaults.run.working-directory
使用working-directory
为步骤的shell
定义工作目录。此关键字可以引用多个上下文。有关更多信息,请参阅"上下文"。
提示
在运行 shell 之前,请确保您分配的working-directory
在运行器上存在。当使用相同的名称定义多个默认设置时,GitHub 将使用最具体的默认设置。例如,在作业中定义的默认设置将覆盖在工作流中定义的同名默认设置。
示例:为作业设置默认的run
步骤选项
jobs:
job1:
runs-on: ubuntu-latest
defaults:
run:
shell: bash
working-directory: ./scripts
jobs.<job_id>.steps
一个作业包含一系列称为steps
的任务。步骤可以运行命令、运行设置任务或在您的仓库、公共仓库或在 Docker 注册表中发布的动作中运行操作。并非所有步骤都运行操作,但所有操作都作为步骤运行。每个步骤在运行器环境中的自己的进程中运行,并可以访问工作区和文件系统。由于步骤在其自己的进程中运行,因此环境变量的更改不会在步骤之间保留。GitHub 提供内置步骤来设置和完成作业。
GitHub 仅显示前 1,000 个检查,但是,只要您在工作流使用限制内,您可以运行无限数量的步骤。有关更多信息,请参阅针对 GitHub 托管运行器的“使用限制、计费和管理”以及针对自托管运行器的“关于自托管运行器”以了解自托管运行器的使用限制。
jobs.<job_id>.steps
示例
name: Greeting from Mona
on: push
jobs:
my-job:
name: My Job
runs-on: ubuntu-latest
steps:
- name: Print a greeting
env:
MY_VAR: Hi there! My name is
FIRST_NAME: Mona
MIDDLE_NAME: The
LAST_NAME: Octocat
run: |
echo $MY_VAR $FIRST_NAME $MIDDLE_NAME $LAST_NAME.
jobs.<job_id>.steps[*].id
步骤的唯一标识符。您可以使用id
在上下文中引用步骤。有关更多信息,请参阅“访问有关工作流运行的上下文信息”。
jobs.<job_id>.steps[*].if
您可以使用if
条件来阻止步骤运行,除非满足某个条件。您可以使用任何受支持的上下文和表达式来创建条件。有关此密钥中支持哪些上下文的更多信息,请参阅“访问有关工作流运行的上下文信息”。
当您在if
条件中使用表达式时,您可以选择省略${{ }}
表达式语法,因为 GitHub Actions 会自动将if
条件评估为表达式。但是,此例外并非在所有地方都适用。
当表达式以!
开头时,您必须始终使用${{ }}
表达式语法或使用''
、""
或()
进行转义,因为!
是 YAML 格式中的保留符号。例如
if: ${{ ! startsWith(github.ref, 'refs/tags/') }}
更多信息,请参见“在工作流和操作中评估表达式”。
示例:使用上下文
仅当事件类型为pull_request
且事件操作为unassigned
时,此步骤才会运行。
steps:
- name: My first step
if: ${{ github.event_name == 'pull_request' && github.event.action == 'unassigned' }}
run: echo This event is a pull request that had an assignee removed.
示例:使用状态检查函数
只有在作业的上一步失败时,my backup step
才会运行。有关更多信息,请参阅“在工作流和操作中评估表达式”。
steps:
- name: My first step
uses: octo-org/action-name@main
- name: My backup step
if: ${{ failure() }}
uses: actions/[email protected]
示例:使用密钥
不能直接在if:
条件中引用密钥。相反,请考虑将密钥设置为作业级别的环境变量,然后引用环境变量以有条件地运行作业中的步骤。
如果未设置密钥,则引用密钥的表达式的返回值(例如,示例中的${{ secrets.SuperSecret }}
)将为空字符串。
name: Run a step if a secret has been set
on: push
jobs:
my-jobname:
runs-on: ubuntu-latest
env:
super_secret: ${{ secrets.SuperSecret }}
steps:
- if: ${{ env.super_secret != '' }}
run: echo 'This step will only run if the secret has a value set.'
- if: ${{ env.super_secret == '' }}
run: echo 'This step will only run if the secret does not have a value set.'
有关更多信息,请参阅“访问有关工作流运行的上下文信息”和“在 GitHub Actions 中使用密钥”。
jobs.<job_id>.steps[*].name
要在 GitHub 上显示的步骤名称。
jobs.<job_id>.steps[*].uses
选择要作为作业中步骤的一部分运行的操作。操作是可重用的代码单元。您可以使用与工作流相同的仓库中定义的操作、公共仓库中的操作或已发布的 Docker 容器映像中的操作。
我们强烈建议您通过指定 Git ref、SHA 或 Docker 标记来包含您正在使用的操作的版本。如果您没有指定版本,它可能会破坏您的工作流,或者在操作所有者发布更新时导致意外行为。
- 使用已发布操作版本的提交 SHA 对稳定性和安全性最安全。
- 如果操作发布主要版本标记,则您应该期望收到关键修复和安全补丁,同时仍保留兼容性。请注意,此行为取决于操作作者的决定。
- 使用操作的默认分支可能很方便,但是,如果有人发布具有重大更改的新主要版本,您的工作流可能会中断。
某些操作需要您必须使用with
关键字设置的输入。查看操作的自述文件以确定所需的输入。
操作是 JavaScript 文件或 Docker 容器。如果您正在使用的操作是 Docker 容器,则必须在 Linux 环境中运行作业。有关更多详细信息,请参阅runs-on
。
示例:使用版本化的操作
steps:
# Reference a specific commit
- uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3
# Reference the major version of a release
- uses: actions/checkout@v4
# Reference a specific version
- uses: actions/[email protected]
# Reference a branch
- uses: actions/checkout@main
示例:使用公共操作
{owner}/{repo}@{ref}
您可以在公共 GitHub 仓库中指定分支、ref 或 SHA。
jobs:
my_first_job:
steps:
- name: My first step
# Uses the default branch of a public repository
uses: actions/heroku@main
- name: My second step
# Uses a specific version tag of a public repository
uses: actions/[email protected]
示例:在子目录中使用公共操作
{owner}/{repo}/{path}@{ref}
公共 GitHub 仓库中特定分支、ref 或 SHA 的子目录。
jobs:
my_first_job:
steps:
- name: My first step
uses: actions/aws/ec2@main
示例:在与工作流相同的仓库中使用操作
./path/to/dir
包含工作流仓库中操作的目录的路径。您必须在使用操作之前检出您的仓库。
示例仓库文件结构
|-- hello-world (repository)
| |__ .github
| └── workflows
| └── my-first-workflow.yml
| └── actions
| |__ hello-world-action
| └── action.yml
该路径相对于默认工作目录(github.workspace
、$GITHUB_WORKSPACE
)。如果操作将仓库检出到与工作流不同的位置,则必须更新用于本地操作的相对路径。
示例工作流文件
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
示例:使用 Docker Hub 操作
docker://{image}:{tag}
在Docker Hub上发布的 Docker 映像。
jobs:
my_first_job:
steps:
- name: My first step
uses: docker://alpine:3.8
示例:使用 GitHub Packages 容器注册表
docker://{host}/{image}:{tag}
GitHub Packages 容器注册表中的公共 Docker 映像。
jobs:
my_first_job:
steps:
- name: My first step
uses: docker://ghcr.io/OWNER/IMAGE_NAME
示例:使用 Docker 公共注册表操作
docker://{host}/{image}:{tag}
公共注册表中的 Docker 映像。此示例使用 gcr.io
中的 Google Container Registry。
jobs:
my_first_job:
steps:
- name: My first step
uses: docker://gcr.io/cloud-builders/gradle
示例:在与工作流不同的私有仓库中使用操作
您的工作流必须检出私有仓库并本地引用操作。生成个人访问令牌并将令牌添加为密钥。有关更多信息,请参阅“管理您的个人访问令牌”和“在 GitHub Actions 中使用密钥”。
将示例中的PERSONAL_ACCESS_TOKEN
替换为您密钥的名称。
jobs:
my_first_job:
steps:
- name: Check out repository
uses: actions/checkout@v4
with:
repository: octocat/my-private-repo
ref: v1.0
token: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
path: ./.github/actions/my-private-repo
- name: Run my action
uses: ./.github/actions/my-private-repo/my-action
或者,使用 GitHub App 代替个人访问令牌,以确保即使个人访问令牌所有者离开,您的工作流也能继续运行。有关更多信息,请参阅“在 GitHub Actions 工作流中使用 GitHub App 进行身份验证的 API 请求”。
jobs.<job_id>.steps[*].run
使用操作系统的 shell 运行不超过 21,000 个字符的命令行程序。如果您不提供name
,则步骤名称将默认为run
命令中指定的文本。
默认情况下,使用非登录 shell 运行命令。您可以选择不同的 shell 并自定义用于运行命令的 shell。有关更多信息,请参阅jobs.<job_id>.steps[*].shell
。
每个run
关键字都代表运行器环境中的一个新进程和 shell。当您提供多行命令时,每一行都在同一个 shell 中运行。例如
-
单行命令
- name: Install Dependencies run: npm install
-
多行命令
- name: Clean install dependencies and build run: | npm ci npm run build
jobs.<job_id>.steps[*].working-directory
使用working-directory
关键字,您可以指定运行命令的工作目录。
- name: Clean temp directory
run: rm -rf *
working-directory: ./temp
或者,您可以为作业中的所有run
步骤或整个工作流中的所有run
步骤指定默认工作目录。有关更多信息,请参阅“defaults.run.working-directory
”和“jobs.<job_id>.defaults.run.working-directory
”。
您还可以使用run
步骤来运行脚本。有关更多信息,请参阅“向工作流添加脚本”。
jobs.<job_id>.steps[*].shell
您可以使用shell
关键字覆盖运行器操作系统和作业默认值中的默认 shell 设置。您可以使用内置shell
关键字,也可以定义自定义的 shell 选项集。内部运行的 shell 命令执行包含run
关键字中指定的命令的临时文件。
支持的平台 | shell 参数 | 描述 | 内部运行的命令 |
---|---|---|---|
Linux / macOS | 未指定 | 非 Windows 平台上的默认 shell。请注意,这会运行与显式指定bash 时不同的命令。如果路径中找不到bash ,则将其视为sh 。 | bash -e {0} |
所有平台 | bash | 非 Windows 平台上的默认 shell,并回退到sh 。在 Windows 上指定 bash shell 时,将使用 Git for Windows 附带的 bash shell。 | bash --noprofile --norc -eo pipefail {0} |
所有平台 | pwsh | PowerShell Core。GitHub 会将扩展名.ps1 附加到您的脚本名称。 | pwsh -command ". '{0}'" |
所有平台 | python | 执行 python 命令。 | python {0} |
Linux / macOS | sh | 如果未提供 shell 并且路径中找不到bash ,则非 Windows 平台的回退行为。 | sh -e {0} |
Windows | cmd | GitHub 会将扩展名.cmd 附加到您的脚本名称并替换为{0} 。 | %ComSpec% /D /E:ON /V:OFF /S /C "CALL "{0}"" . |
Windows | pwsh | 这是 Windows 上使用的默认 shell。PowerShell Core。GitHub 会将扩展名.ps1 附加到您的脚本名称。如果您的自托管 Windows 运行器未安装 *PowerShell Core*,则将改为使用 *PowerShell Desktop*。 | pwsh -command ". '{0}'" . |
Windows | powershell | PowerShell Desktop。GitHub 会将扩展名.ps1 附加到您的脚本名称。 | powershell -command ". '{0}'" . |
或者,您可以为作业中的所有run
步骤或整个工作流中的所有run
步骤指定默认 shell。有关更多信息,请参阅“defaults.run.shell
”和“jobs.<job_id>.defaults.run.shell
”。
示例:使用 Bash 运行命令
steps:
- name: Display the path
shell: bash
run: echo $PATH
示例:使用 Windows cmd
运行命令
steps:
- name: Display the path
shell: cmd
run: echo %PATH%
示例:使用 PowerShell Core 运行命令
steps:
- name: Display the path
shell: pwsh
run: echo ${env:PATH}
示例:使用 PowerShell Desktop 运行命令
steps:
- name: Display the path
shell: powershell
run: echo ${env:PATH}
示例:运行内联 Python 脚本
steps:
- name: Display the path
shell: python
run: |
import os
print(os.environ['PATH'])
自定义 shell
您可以使用command [options] {0} [more_options]
将shell
值设置为模板字符串。GitHub 将字符串的第一个空格分隔的词解释为命令,并在{0}
处插入临时脚本的文件名。
例如
steps:
- name: Display the environment variables and their values
shell: perl {0}
run: |
print %ENV
使用的命令(此示例中的perl
)必须安装在运行器上。
有关 GitHub 托管运行器上包含的软件的信息,请参阅“使用 GitHub 托管运行器”。
退出代码和错误操作偏好
对于内置 shell 关键字,我们提供以下由 GitHub 托管运行器执行的默认值。运行 shell 脚本时,您应该使用这些指南。
-
bash
/sh
- 默认情况下,使用
set -e
对sh
和bash
强制执行快速失败行为。当指定shell: bash
时,还会应用-o pipefail
以强制从生成非零退出状态的管道提前退出。 - 您可以通过向 shell 选项提供模板字符串来完全控制 shell 参数。例如,
bash {0}
。 - 类似
sh
的 shell 使用在脚本中执行的最后一个命令的退出代码退出,这也是操作的默认行为。运行器将根据此退出代码将步骤的状态报告为失败/成功。
- 默认情况下,使用
-
powershell
/pwsh
- 尽可能使用快速失败机制。对于
pwsh
和powershell
内置 shell,我们将$ErrorActionPreference = 'stop'
添加到脚本内容的开头。 - 我们将
if ((Test-Path -LiteralPath variable:\LASTEXITCODE)) { exit $LASTEXITCODE }
添加到 PowerShell 脚本中,以便操作状态反映脚本的最后退出代码。 - 用户始终可以选择不使用内置 shell,并提供自定义 shell 选项,例如:
pwsh -File {0}
或powershell -Command "& '{0}'"
,具体取决于需要。
- 尽可能使用快速失败机制。对于
-
cmd
- 除了编写脚本检查每个错误代码并相应地做出响应之外,似乎没有办法完全启用快速失败行为。因为我们实际上无法默认提供该行为,所以您需要将此行为写入您的脚本中。
cmd.exe
将以其执行的最后一个程序的错误级别退出,并将错误代码返回给运行程序。此行为与之前的sh
和pwsh
默认行为在内部一致,并且是cmd.exe
的默认行为,因此此行为保持不变。
jobs.<job_id>.steps[*].with
操作定义的输入参数的map
。每个输入参数都是一个键值对。输入参数设置为环境变量。变量名前缀为INPUT_
并转换为大写。
为 Docker 容器定义的输入参数必须使用args
。更多信息,请参见“jobs.<job_id>.steps[*].with.args
”。
jobs.<job_id>.steps[*].with
示例
定义了hello_world
操作定义的三个输入参数(first_name
、middle_name
和last_name
)。这些输入变量将作为INPUT_FIRST_NAME
、INPUT_MIDDLE_NAME
和INPUT_LAST_NAME
环境变量供hello-world
操作访问。
jobs:
my_first_job:
steps:
- name: My first step
uses: actions/hello_world@main
with:
first_name: Mona
middle_name: The
last_name: Octocat
jobs.<job_id>.steps[*].with.args
一个字符串
,定义 Docker 容器的输入。容器启动时,GitHub 将args
传递到容器的ENTRYPOINT
。此参数不支持字符串数组
。包含空格的单个参数应用双引号""
括起来。
jobs.<job_id>.steps[*].with.args
示例
steps:
- name: Explain why this job ran
uses: octo-org/action-name@main
with:
entrypoint: /bin/echo
args: The ${{ github.event_name }} event triggered this step.
args
用于替换Dockerfile
中的CMD
指令。如果在Dockerfile
中使用CMD
,请按优先级顺序使用以下指南
- 在操作的 README 中记录必需的参数,并从
CMD
指令中省略它们。 - 使用允许在不指定任何
args
的情况下使用操作的默认值。 - 如果操作公开
--help
标志或类似内容,请将其用作默认值以使您的操作具有自文档功能。
jobs.<job_id>.steps[*].with.entrypoint
覆盖Dockerfile
中的 Docker ENTRYPOINT
,或者如果尚未指定,则设置它。与具有 shell 和 exec 形式的 Docker ENTRYPOINT
指令不同,entrypoint
关键字只接受一个定义要运行的可执行文件的字符串。
jobs.<job_id>.steps[*].with.entrypoint
示例
steps:
- name: Run a custom command
uses: octo-org/action-name@main
with:
entrypoint: /a/different/executable
entrypoint
关键字旨在与 Docker 容器操作一起使用,但您也可以将其与未定义任何输入的 JavaScript 操作一起使用。
jobs.<job_id>.steps[*].env
设置步骤要在运行程序环境中使用的变量。您还可以为整个工作流程或作业设置变量。更多信息,请参见env
和jobs.<job_id>.env
。
当使用相同的名称定义多个环境变量时,GitHub 将使用最具体的变量。例如,在步骤中定义的环境变量将在作业和工作流环境变量执行期间覆盖同名的作业和工作流环境变量。作业中定义的环境变量将在作业执行期间覆盖同名的工作流变量。
公共操作可以在 README 文件中指定预期的变量。如果您正在设置秘密或敏感值(例如密码或令牌),则必须使用secrets
上下文设置秘密。更多信息,请参见“访问有关工作流运行的上下文信息”。
jobs.<job_id>.steps[*].env
示例
steps:
- name: My first action
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
FIRST_NAME: Mona
LAST_NAME: Octocat
jobs.<job_id>.steps[*].continue-on-error
防止步骤失败时作业失败。设置为true
允许步骤失败时作业通过。
jobs.<job_id>.steps[*].timeout-minutes
在终止进程之前运行步骤的最大分钟数。
不支持小数。timeout-minutes
必须是正整数。
jobs.<job_id>.timeout-minutes
在 GitHub 自动取消作业之前允许作业运行的最大分钟数。默认值:360
如果超时超过运行程序的作业执行时间限制,则将在达到执行时间限制时取消作业。有关作业执行时间限制的更多信息,请参阅有关 GitHub 托管运行程序的“使用限制、计费和管理”和有关自托管运行程序使用限制的“关于自托管运行程序”。
注意
GITHUB_TOKEN
在作业完成或最长 24 小时后过期。对于自托管运行程序,如果作业超时超过 24 小时,令牌可能是限制因素。有关GITHUB_TOKEN
的更多信息,请参见“自动令牌身份验证”。
jobs.<job_id>.strategy
使用jobs.<job_id>.strategy
为您的作业使用矩阵策略。矩阵策略允许您在一个作业定义中使用变量来自动创建多个基于变量组合的作业运行。例如,您可以使用矩阵策略在多种语言版本或多个操作系统上测试您的代码。更多信息,请参见“在工作流中运行作业的变体”。
jobs.<job_id>.strategy.matrix
使用jobs.<job_id>.strategy.matrix
定义不同作业配置的矩阵。在您的矩阵中,定义一个或多个变量,后跟一个值数组。例如,以下矩阵有一个名为version
的变量,其值为[10, 12, 14]
,还有一个名为os
的变量,其值为[ubuntu-latest, windows-latest]
jobs:
example_matrix:
strategy:
matrix:
version: [10, 12, 14]
os: [ubuntu-latest, windows-latest]
每个可能的变量组合都将运行一个作业。在此示例中,工作流将运行六个作业,每个作业对应os
和version
变量的一个组合。
默认情况下,GitHub 将根据运行程序的可用性最大化并行运行的作业数量。矩阵中变量的顺序决定了创建作业的顺序。您定义的第一个变量将是工作流运行中创建的第一个作业。例如,上面的矩阵将按以下顺序创建作业
{version: 10, os: ubuntu-latest}
{version: 10, os: windows-latest}
{version: 12, os: ubuntu-latest}
{version: 12, os: windows-latest}
{version: 14, os: ubuntu-latest}
{version: 14, os: windows-latest}
每个工作流运行最多生成 256 个作业。此限制适用于 GitHub 托管运行程序和自托管运行程序。
您定义的变量成为matrix
上下文中的属性,您可以在工作流文件的其他区域引用该属性。在此示例中,您可以使用matrix.version
和matrix.os
来访问作业正在使用的version
和os
的当前值。更多信息,请参见“访问有关工作流运行的上下文信息”。
示例:使用单维矩阵
您可以指定单个变量来创建单维矩阵。
例如,以下工作流定义了值为[10, 12, 14]
的变量version
。工作流将运行三个作业,每个值一个作业。每个作业都将通过matrix.version
上下文访问version
值,并将该值作为node-version
传递给actions/setup-node
操作。
jobs:
example_matrix:
strategy:
matrix:
version: [10, 12, 14]
steps:
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.version }}
示例:使用多维矩阵
您可以指定多个变量来创建多维矩阵。每个可能的变量组合都将运行一个作业。
例如,以下工作流指定了两个变量
- 在
os
变量中指定的两个操作系统 - 在
version
变量中指定的三个 Node.js 版本
工作流将运行六个作业,每个作业对应os
和version
变量的一个组合。每个作业都将runs-on
值设置为当前os
值,并将当前version
值传递给actions/setup-node
操作。
jobs:
example_matrix:
strategy:
matrix:
os: [ubuntu-22.04, ubuntu-20.04]
version: [10, 12, 14]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.version }}
矩阵中的变量配置可以是对象
的数组
。
matrix:
os:
- ubuntu-latest
- macos-latest
node:
- version: 14
- version: 20
env: NODE_OPTIONS=--openssl-legacy-provider
此矩阵生成 4 个具有相应上下文的作业。
- matrix.os: ubuntu-latest
matrix.node.version: 14
- matrix.os: ubuntu-latest
matrix.node.version: 20
matrix.node.env: NODE_OPTIONS=--openssl-legacy-provider
- matrix.os: macos-latest
matrix.node.version: 14
- matrix.os: macos-latest
matrix.node.version: 20
matrix.node.env: NODE_OPTIONS=--openssl-legacy-provider
示例:使用上下文创建矩阵
您可以使用上下文创建矩阵。有关上下文的更多信息,请参见“访问有关工作流运行的上下文信息”。
例如,以下工作流在repository_dispatch
事件上触发,并使用来自事件有效负载的信息来构建矩阵。当使用如下所示的有效负载创建存储库分派事件时,矩阵version
变量的值将为[12, 14, 16]
。有关repository_dispatch
触发器的更多信息,请参见“触发工作流的事件”。
{
"event_type": "test",
"client_payload": {
"versions": [12, 14, 16]
}
}
on:
repository_dispatch:
types:
- test
jobs:
example_matrix:
runs-on: ubuntu-latest
strategy:
matrix:
version: ${{ github.event.client_payload.versions }}
steps:
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.version }}
jobs.<job_id>.strategy.matrix.include
使用jobs.<job_id>.strategy.matrix.include
扩展现有矩阵配置或添加新配置。include
的值是一个对象列表。
对于include
列表中的每个对象,如果键值对不会覆盖任何原始矩阵值,则会将其添加到每个矩阵组合中。如果对象无法添加到任何矩阵组合中,则会创建一个新的矩阵组合。请注意,原始矩阵值不会被覆盖,但添加的矩阵值可能会被覆盖。
例如,这个矩阵
strategy:
matrix:
fruit: [apple, pear]
animal: [cat, dog]
include:
- color: green
- color: pink
animal: cat
- fruit: apple
shape: circle
- fruit: banana
- fruit: banana
animal: cat
将产生六个作业,具有以下矩阵组合:
{水果: 苹果, 动物: 猫, 颜色: 粉红色, 形状: 圆形}
{水果: 苹果, 动物: 狗, 颜色: 绿色, 形状: 圆形}
{水果: 梨, 动物: 猫, 颜色: 粉红色}
{水果: 梨, 动物: 狗, 颜色: 绿色}
{水果: 香蕉}
{水果: 香蕉, 动物: 猫}
遵循以下逻辑:
{颜色: 绿色}
被添加到所有原始矩阵组合中,因为它可以在不覆盖原始组合任何部分的情况下添加。{颜色: 粉红色, 动物: 猫}
仅将颜色:粉红色
添加到包含动物: 猫
的原始矩阵组合中。这将覆盖先前include
条目添加的颜色: 绿色
。{水果: 苹果, 形状: 圆形}
仅将形状: 圆形
添加到包含水果: 苹果
的原始矩阵组合中。{水果: 香蕉}
无法添加到任何原始矩阵组合中而不会覆盖值,因此它被添加为附加矩阵组合。{水果: 香蕉, 动物: 猫}
无法添加到任何原始矩阵组合中而不会覆盖值,因此它被添加为附加矩阵组合。它不会添加到{水果: 香蕉}
矩阵组合中,因为该组合不是原始矩阵组合之一。
示例:扩展配置
例如,以下工作流程将运行四个作业,每个作业对应os
和node
的一个组合。当os
值为windows-latest
且node
值为16
的作业运行时,作业中将包含一个名为npm
的附加变量,其值为6
。
jobs:
example_matrix:
strategy:
matrix:
os: [windows-latest, ubuntu-latest]
node: [14, 16]
include:
- os: windows-latest
node: 16
npm: 6
runs-on: ${{ matrix.os }}
steps:
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- if: ${{ matrix.npm }}
run: npm install -g npm@${{ matrix.npm }}
- run: npm --version
示例:添加配置
例如,此矩阵将运行10个作业,每个作业对应矩阵中os
和version
的一个组合,再加上一个os
值为windows-latest
且version
值为17
的作业。
jobs:
example_matrix:
strategy:
matrix:
os: [macos-latest, windows-latest, ubuntu-latest]
version: [12, 14, 16]
include:
- os: windows-latest
version: 17
如果未指定任何矩阵变量,则将运行include
下的所有配置。例如,以下工作流程将运行两个作业,每个作业对应一个include
条目。这允许您在没有完全填充的矩阵的情况下利用矩阵策略。
jobs:
includes_only:
runs-on: ubuntu-latest
strategy:
matrix:
include:
- site: "production"
datacenter: "site-a"
- site: "staging"
datacenter: "site-b"
jobs.<job_id>.strategy.matrix.exclude
要删除矩阵中定义的特定配置,请使用jobs.<job_id>.strategy.matrix.exclude
。被排除的配置只需要部分匹配即可被排除。例如,以下工作流程将运行九个作业:12个配置中的每一个都对应一个作业,减去一个与{os: macos-latest, version: 12, environment: production}
匹配的被排除的作业,以及两个与{os: windows-latest, version: 16}
匹配的被排除的作业。
strategy:
matrix:
os: [macos-latest, windows-latest]
version: [12, 14, 16]
environment: [staging, production]
exclude:
- os: macos-latest
version: 12
environment: production
- os: windows-latest
version: 16
runs-on: ${{ matrix.os }}
注意
所有include
组合都在exclude
之后处理。这允许您使用include
添加先前被排除的组合。
jobs.<job_id>.strategy.fail-fast
您可以使用jobs.<job_id>.strategy.fail-fast
和jobs.<job_id>.continue-on-error
来控制如何处理作业失败。
jobs.<job_id>.strategy.fail-fast
应用于整个矩阵。如果jobs.<job_id>.strategy.fail-fast
设置为true
或其表达式计算结果为true
,则如果矩阵中的任何作业失败,GitHub 将取消矩阵中所有正在进行和排队的作业。此属性默认为true
。
jobs.<job_id>.continue-on-error
应用于单个作业。如果jobs.<job_id>.continue-on-error
为true
,则即使具有jobs.<job_id>.continue-on-error: true
的作业失败,矩阵中的其他作业也将继续运行。
您可以同时使用jobs.<job_id>.strategy.fail-fast
和jobs.<job_id>.continue-on-error
。例如,以下工作流程将启动四个作业。对于每个作业,continue-on-error
由matrix.experimental
的值确定。如果任何具有continue-on-error: false
的作业失败,则所有正在进行或排队的作业都将被取消。如果具有continue-on-error: true
的作业失败,则其他作业不会受到影响。
jobs:
test:
runs-on: ubuntu-latest
continue-on-error: ${{ matrix.experimental }}
strategy:
fail-fast: true
matrix:
version: [6, 7, 8]
experimental: [false]
include:
- version: 9
experimental: true
jobs.<job_id>.strategy.max-parallel
默认情况下,GitHub 将根据运行程序的可用性最大化并行运行的作业数量。要设置使用matrix
作业策略时可以同时运行的作业的最大数量,请使用jobs.<job_id>.strategy.max-parallel
。
例如,以下工作流程将一次最多运行两个作业,即使有运行程序可以一次运行所有六个作业。
jobs:
example_matrix:
strategy:
max-parallel: 2
matrix:
version: [10, 12, 14]
os: [ubuntu-latest, windows-latest]
jobs.<job_id>.continue-on-error
防止作业失败时工作流程运行失败。设置为true
允许在该作业失败时工作流程运行通过。
示例:防止特定失败的矩阵作业导致工作流程运行失败
您可以允许作业矩阵中的特定作业失败而不会导致工作流程运行失败。例如,如果您只想允许将node
设置为15
的实验性作业失败而不会导致工作流程运行失败。
runs-on: ${{ matrix.os }}
continue-on-error: ${{ matrix.experimental }}
strategy:
fail-fast: false
matrix:
node: [13, 14]
os: [macos-latest, ubuntu-latest]
experimental: [false]
include:
- node: 15
os: ubuntu-latest
experimental: true
jobs.<job_id>.container
注意
如果您的工作流程使用 Docker 容器操作、作业容器或服务容器,则必须使用 Linux 运行程序。
- 如果您使用的是 GitHub 托管的运行程序,则必须使用 Ubuntu 运行程序。
- 如果您使用的是自托管运行程序,则必须使用 Linux 机器作为您的运行程序,并且必须安装 Docker。
使用jobs.<job_id>.container
创建一个容器来运行作业中尚未指定容器的任何步骤。如果您有同时使用脚本和容器操作的步骤,则容器操作将作为同一网络上的兄弟容器以相同的卷挂载运行。
如果不设置container
,则所有步骤都将直接在runs-on
指定的宿主机上运行,除非步骤引用配置为在容器中运行的操作。
注意
容器内run
步骤的默认 shell 为sh
而不是bash
。这可以使用jobs.<job_id>.defaults.run
或jobs.<job_id>.steps[*].shell
覆盖。
示例:在容器内运行作业
name: CI on: push: branches: [ main ] jobs: container-test-job: runs-on: ubuntu-latest container: image: node:18 env: NODE_ENV: development ports: - 80 volumes: - my_docker_volume:/volume_mount options: --cpus 1 steps: - name: Check for dockerenv file run: (ls /.dockerenv && echo Found dockerenv) || (echo No dockerenv)
name: CI
on:
push:
branches: [ main ]
jobs:
container-test-job:
runs-on: ubuntu-latest
container:
image: node:18
env:
NODE_ENV: development
ports:
- 80
volumes:
- my_docker_volume:/volume_mount
options: --cpus 1
steps:
- name: Check for dockerenv file
run: (ls /.dockerenv && echo Found dockerenv) || (echo No dockerenv)
仅指定容器镜像时,可以省略image
关键字。
jobs:
container-test-job:
runs-on: ubuntu-latest
container: node:18
jobs.<job_id>.container.image
使用jobs.<job_id>.container.image
定义用作运行操作的容器的 Docker 镜像。该值可以是 Docker Hub 镜像名称或注册表名称。
jobs.<job_id>.container.credentials
如果镜像的容器注册表需要身份验证才能拉取镜像,则可以使用jobs.<job_id>.container.credentials
设置username
和password
的map
。凭据与您提供给docker login
命令的值相同。
示例:为容器注册表定义凭据
container:
image: ghcr.io/owner/image
credentials:
username: ${{ github.actor }}
password: ${{ secrets.github_token }}
jobs.<job_id>.container.env
使用jobs.<job_id>.container.env
设置容器中环境变量的map
。
jobs.<job_id>.container.ports
使用jobs.<job_id>.container.ports
设置要在容器上公开的端口的array
。
jobs.<job_id>.container.volumes
使用jobs.<job_id>.container.volumes
设置容器要使用的卷的array
。您可以使用卷在服务或作业中的其他步骤之间共享数据。您可以指定命名的 Docker 卷、匿名的 Docker 卷或宿主机上的绑定装载。
要指定卷,请指定源路径和目标路径。
<source>:<destinationPath>
.
<source>
是卷名或宿主机上的绝对路径,<destinationPath>
是容器中的绝对路径。
示例:在容器中挂载卷
volumes:
- my_docker_volume:/volume_mount
- /data/my_data
- /source/directory:/destination/directory
jobs.<job_id>.container.options
使用jobs.<job_id>.container.options
配置其他 Docker 容器资源选项。有关选项列表,请参阅“docker create
选项”。
警告
不支持--network
和--entrypoint
选项。
jobs.<job_id>.services
注意
如果您的工作流程使用 Docker 容器操作、作业容器或服务容器,则必须使用 Linux 运行程序。
- 如果您使用的是 GitHub 托管的运行程序,则必须使用 Ubuntu 运行程序。
- 如果您使用的是自托管运行程序,则必须使用 Linux 机器作为您的运行程序,并且必须安装 Docker。
用于为工作流程中的作业托管服务容器。服务容器可用于创建数据库或缓存服务(如 Redis)。运行程序会自动创建一个 Docker 网络并管理服务容器的生命周期。
如果将作业配置为在容器中运行,或者您的步骤使用容器操作,则无需映射端口即可访问服务或操作。Docker 会自动公开同一 Docker 用户定义的桥接网络上容器之间的所有端口。您可以直接通过其主机名引用服务容器。主机名会自动映射到您在工作流程中为服务配置的标签名称。
如果将作业配置为直接在运行程序机器上运行,并且您的步骤不使用容器操作,则必须将任何必需的 Docker 服务容器端口映射到 Docker 宿主机(运行程序机器)。您可以使用 localhost 和映射的端口访问服务容器。
有关服务容器网络的更多信息,请参阅“关于服务容器”。
示例:使用 localhost
此示例创建两个服务:nginx 和 redis。当您指定容器端口但未指定主机端口时,容器端口会随机分配到主机上的空闲端口。GitHub 会在${{job.services.<service_name>.ports}}
上下文中设置分配的主机端口。在此示例中,您可以使用${{ job.services.nginx.ports['80'] }}
和 ${{ job.services.redis.ports['6379'] }}
上下文访问服务主机端口。
services:
nginx:
image: nginx
# Map port 8080 on the Docker host to port 80 on the nginx container
ports:
- 8080:80
redis:
image: redis
# Map random free TCP port on Docker host to port 6379 on redis container
ports:
- 6379/tcp
steps:
- run: |
echo "Redis available on 127.0.0.1:${{ job.services.redis.ports['6379'] }}"
echo "Nginx available on 127.0.0.1:${{ job.services.nginx.ports['80'] }}"
jobs.<job_id>.services.<service_id>.image
用作运行操作的服务容器的 Docker 镜像。该值可以是 Docker Hub 镜像名称或注册表名称。
如果将jobs.<job_id>.services.<service_id>.image
分配为空字符串,则服务将不会启动。您可以使用此方法设置条件服务,类似于以下示例。
services:
nginx:
image: ${{ options.nginx == true && 'nginx' || '' }}
jobs.<job_id>.services.<service_id>.credentials
如果镜像的容器注册表需要身份验证才能拉取镜像,则可以使用jobs.<job_id>.container.credentials
设置username
和password
的map
。凭据与您提供给docker login
命令的值相同。
jobs.<job_id>.services.<service_id>.credentials
示例
services:
myservice1:
image: ghcr.io/owner/myservice1
credentials:
username: ${{ github.actor }}
password: ${{ secrets.github_token }}
myservice2:
image: dockerhub_org/myservice2
credentials:
username: ${{ secrets.DOCKER_USER }}
password: ${{ secrets.DOCKER_PASSWORD }}
jobs.<job_id>.services.<service_id>.env
在服务容器中设置环境变量的map
。
jobs.<job_id>.services.<service_id>.ports
设置要在服务容器上公开的端口的array
。
jobs.<job_id>.services.<service_id>.volumes
为服务容器设置要使用的卷的array
。您可以使用卷在服务或作业中的其他步骤之间共享数据。您可以指定命名 Docker 卷、匿名 Docker 卷或主机上的绑定挂载。
要指定卷,请指定源路径和目标路径。
<source>:<destinationPath>
.
<source>
是卷名或宿主机上的绝对路径,<destinationPath>
是容器中的绝对路径。
jobs.<job_id>.services.<service_id>.volumes
示例
volumes:
- my_docker_volume:/volume_mount
- /data/my_data
- /source/directory:/destination/directory
jobs.<job_id>.services.<service_id>.options
其他 Docker 容器资源选项。有关选项列表,请参阅“docker create
选项”。
警告
不支持--network
选项。
jobs.<job_id>.uses
要作为作业运行的可重用工作流文件的路径和版本。使用以下语法之一
- 对于公共和私有存储库中的可重用工作流,使用
{owner}/{repo}/.github/workflows/{filename}@{ref}
。 - 对于同一存储库中的可重用工作流,使用
./.github/workflows/{filename}
。
在第一个选项中,{ref}
可以是 SHA、发行版标签或分支名称。如果发行版标签和分支具有相同的名称,则发行版标签优先于分支名称。使用提交 SHA 是确保稳定性和安全性的最安全选项。有关更多信息,请参阅“GitHub Actions 的安全加固”。
如果您使用第二个语法选项(不带{owner}/{repo}
和 @{ref}
),则调用的工作流与调用工作流来自相同的提交。不允许使用refs/heads
和refs/tags
之类的 ref 前缀。您不能在此关键字中使用上下文或表达式。
jobs.<job_id>.uses
示例
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
有关更多信息,请参阅“重用工作流”。
jobs.<job_id>.with
当作业用于调用可重用工作流时,您可以使用with
提供传递给调用的工作流的输入映射。
您传递的任何输入都必须与调用的工作流中定义的输入规范匹配。
与jobs.<job_id>.steps[*].with
不同,您使用jobs.<job_id>.with
传递的输入在调用的工作流中不可作为环境变量使用。您可以改为使用inputs
上下文引用输入。
jobs.<job_id>.with
示例
jobs:
call-workflow:
uses: octo-org/example-repo/.github/workflows/called-workflow.yml@main
with:
username: mona
jobs.<job_id>.with.<input_id>
由输入的字符串标识符及其值组成的一对。标识符必须与调用的工作流中由on.workflow_call.inputs.<inputs_id>
定义的输入名称匹配。值的数据类型必须与调用的工作流中由on.workflow_call.inputs.<input_id>.type
定义的类型匹配。
允许的表达式上下文:github
和needs
。
jobs.<job_id>.secrets
当作业用于调用可重用工作流时,您可以使用secrets
提供传递给调用的工作流的密钥映射。
您传递的任何密钥都必须与调用的工作流中定义的名称匹配。
jobs.<job_id>.secrets
示例
jobs:
call-workflow:
uses: octo-org/example-repo/.github/workflows/called-workflow.yml@main
secrets:
access-token: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
jobs.<job_id>.secrets.inherit
使用inherit
关键字将调用工作流的所有密钥传递给调用的工作流。这包括调用工作流可以访问的所有密钥,即组织、存储库和环境密钥。可以使用inherit
关键字在同一组织内的存储库之间或同一企业内的组织之间传递密钥。
jobs.<job_id>.secrets.inherit
示例
on:
workflow_dispatch:
jobs:
pass-secrets-to-workflow:
uses: ./.github/workflows/called-workflow.yml
secrets: inherit
on:
workflow_call:
jobs:
pass-secret-to-action:
runs-on: ubuntu-latest
steps:
- name: Use a repo or org secret from the calling workflow.
run: echo ${{ secrets.CALLING_WORKFLOW_SECRET }}
jobs.<job_id>.secrets.<secret_id>
由密钥的字符串标识符及其值组成的一对。标识符必须与调用的工作流中由on.workflow_call.secrets.<secret_id>
定义的密钥名称匹配。
允许的表达式上下文:github
、needs
和secrets
。
筛选器模式速查表
您可以在路径、分支和标签筛选器中使用特殊字符。
*
:匹配零个或多个字符,但不匹配/
字符。例如,Octo*
匹配Octocat
。**
:匹配零个或多个任意字符。?
:匹配前面字符的零个或一个。+
:匹配前面字符的一个或多个。[]
:匹配括号中列出的或包含在范围内的任一字母数字字符。范围只能包含a-z
、A-Z
和0-9
。例如,范围[0-9a-z]
匹配任何数字或小写字母。例如,[CB]at
匹配Cat
或Bat
,[1-2]00
匹配100
和200
。!
:在模式开头时,使其否定之前的正模式。如果不是第一个字符,则没有特殊含义。
字符*
、[
和!
是 YAML 中的特殊字符。如果您以*
、[
或!
开头模式,则必须将模式括在引号中。此外,如果您使用包含[
和/或]
的模式的流序列,则必须将模式括在引号中。
# Valid
paths:
- '**/README.md'
# Invalid - creates a parse error that
# prevents your workflow from running.
paths:
- **/README.md
# Valid
branches: [ main, 'release/v[0-9].[0-9]' ]
# Invalid - creates a parse error
branches: [ main, release/v[0-9].[0-9] ]
有关分支、标签和路径筛选器语法的更多信息,请参阅on.<push>.<branches|tags>
、on.<pull_request>.<branches|tags>
和on.<push|pull_request>.paths
。
匹配分支和标签的模式
模式 | 描述 | 示例匹配项 |
---|---|---|
feature/* | * 通配符匹配任何字符,但不匹配斜杠 (/ )。 | feature/my-branch feature/your-branch |
feature/** | ** 通配符匹配任何字符,包括分支和标签名称中的斜杠 (/ )。 | feature/beta-a/my-branch feature/your-branch feature/mona/the/octocat |
main releases/mona-the-octocat | 匹配分支或标签名称的确切名称。 | main releases/mona-the-octocat |
'*' | 匹配所有不包含斜杠 (/ ) 的分支和标签名称。* 字符是 YAML 中的特殊字符。当您以* 开头模式时,必须使用引号。 | main releases |
'**' | 匹配所有分支和标签名称。当您不使用branches 或tags 筛选器时,这是默认行为。 | all/the/branches every/tag |
'*feature' | * 字符是 YAML 中的特殊字符。当您以* 开头模式时,必须使用引号。 | mona-feature feature ver-10-feature |
v2* | 匹配以v2 开头的分支和标签名称。 | v2 v2.0 v2.9 |
v[12].[0-9]+.[0-9]+ | 匹配所有具有主版本 1 或 2 的语义版本控制分支和标签。 | v1.10.1 v2.0.0 |
匹配文件路径的模式
路径模式必须与整个路径匹配,并从存储库的根目录开始。
模式 | 匹配说明 | 示例匹配项 |
---|---|---|
'*' | * 通配符匹配任何字符,但不匹配斜杠 (/ )。* 字符是 YAML 中的特殊字符。当您以* 开头模式时,必须使用引号。 | README.md server.rb |
'*.jsx?' | ? 字符匹配前面字符的零个或一个。 | page.js page.jsx |
'**' | ** 通配符匹配任何字符,包括斜杠 (/ )。当您不使用path 筛选器时,这是默认行为。 | all/the/files.md |
'*.js' | * 通配符匹配任何字符,但不匹配斜杠 (/ )。匹配存储库根目录中的所有.js 文件。 | app.js index.js |
'**.js' | 匹配存储库中的所有.js 文件。 | index.js js/index.js src/js/app.js |
docs/* | 存储库根目录中docs 目录根目录下的所有文件。 | docs/README.md docs/file.txt |
docs/** | 存储库根目录中/docs 目录中的任何文件。 | docs/README.md docs/mona/octocat.txt |
docs/**/*.md | docs 目录下任何带有.md 后缀的文件。 | docs/README.md docs/mona/hello-world.md docs/a/markdown/file.md |
'**/docs/**' | 存储库中任何位置的docs 目录下的任何文件。 | docs/hello.md dir/docs/my-file.txt space/docs/plan/space.doc |
'**/README.md' | 存储库中任何位置的README.md文件。 | README.md js/README.md |
'**/*src/**' | 存储库中任何位置带有src 后缀的文件夹中的任何文件。 | a/src/app.js my-src/code/js/app.js |
'**/*-post.md' | 存储库中任何位置带有-post.md 后缀的文件。 | my-post.md path/their-post.md |
'**/migrate-*.sql' | 存储库中任何位置带有migrate- 前缀和.sql 后缀的文件。 | migrate-10909.sql db/migrate-v1.0.sql db/sept/migrate-v1.sql |
'*.md' '!README.md' | 在模式前使用感叹号 (! ) 表示否定。当文件匹配某个模式同时也匹配文件中稍后定义的否定模式时,该文件将不被包含。 | hello.md 不匹配 README.md docs/hello.md |
'*.md' '!README.md' README* | 模式按顺序检查。否定先前模式的模式将重新包含文件路径。 | hello.md README.md README.doc |