Skip to main content

GitHub Actions 的工作流语法

工作流程是可配置的自动化过程,由一个或多个作业组成。 您必须创建 YAML 文件来定义工作流程配置。

本文内容

关于工作流程的 YAML 语法

工作流文件使用 YAML 语法,并且必须具有 .yml.yaml 文件扩展名。 如果你不熟悉 YAML 并且想要了解详细信息,请参阅“在五分钟内了解 YAML”。

必须将工作流文件存储在存储库的 .github/workflows 目录中。

name

工作流的名称。 GitHub 在存储库的“操作”选项卡下显示工作流的名称。如果省略 name,GitHub 会显示相对于存储库根目录的工作流文件路径。

run-name

从工作流生成的工作流运行的名称。 GitHub 在存储库的“操作”选项卡上的工作流运行列表中显示工作流运行名称。如果省略了 run-name 或仅为空格,则运行名称将设置为工作流运行的事件特定信息。 例如,对于由 pushpull_request 事件触发的工作流,将其设置为提交消息或拉取请求的标题。

此值可包含表达式,且可引用 githubinputs 上下文。

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 事件具有 createdediteddeleted 活动类型。 如果工作流在 label 事件上触发,则每当创建、编辑或删除标签时,它都会运行。 如果为 created 事件指定 label 活动类型,则工作流将在创建标签时运行,但不会在编辑或删除标签时运行。

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 事件由多种活动触发。 例如,当标签为 createdediteddeleted 时会触发 label。 通过 types 关键词可缩小触发工作流运行的活动类型的范围。 如果只有一种活动类型可触发 Webhook 事件,则不需要 types 关键字。

可以使用事件 types 的数组。 有关每个事件及其活动类型的详细信息,请参阅“触发工作流的事件”。

on:
  label:
    types: [created, edited]

on.<pull_request|pull_request_target>.<branches|branches-ignore>

使用 pull_requestpull_request_target 事件时,可以将工作流配置为仅针对面向特定分支的拉取请求运行。

如果要包含分支名称模式或同时包含和排除分支名称模式,请使用 branches 筛选器。 只希望排除分支名称时,请使用 branches-ignore 筛选器。 不能对工作流中的同一事件同时使用 branchesbranches-ignore 筛选器。

如果你同时定义 branches/branches-ignorepaths/paths-ignore,则工作流将只在这两个筛选器都满足条件时运行。

branchesbranches-ignore 关键词接受使用 ***+?! 等字符匹配多个路径名称的 glob 模式。 如果名称包含其中任一字符,而你想要逐字匹配,则需要使用 \ 转义每个特殊字符。 有关 glob 模式的详细信息,请参阅“GitHub Actions 的工作流语法”。

示例:包括分支

示例:排除分支

当模式与 branches-ignore 模式匹配时,工作流将不会运行。 在 branches-ignore 中定义的模式根据 Git 引用的名称进行评估。 例如,除非拉取请求面向以下内容,否则每当有 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'

示例:包括和排除分支

不能在单个工作流中使用 branchesbranches-ignore 筛选同一事件。 如果要同时包括和排除单个事件的分支模式,请使用 branches 筛选器以及 ! 字符来指示应排除哪些分支或标记。

如果使用字符 ! 定义分支,则还必须至少定义一个没有 ! 字符的分支。 如果只想排除分支,请改用 branches-ignore

您定义模式事项的顺序。

  • 肯定匹配后的匹配否定模式(前缀为 !)将排除 Git 引用。
  • 否定匹配后的匹配肯定模式将再次包含 Git 引用。

以下工作流将在针对面向 releases/10releases/beta/mona 的拉取请求的 pull_request 事件上运行,但不针对面向 releases/10-alphareleases/beta/3-alpha 的拉取请求,由于负模式,!releases/**-alpha 将遵循正模式。

on:
  pull_request:
    branches:
      - 'releases/**'
      - '!releases/**-alpha'

on.push.<branches|tags|branches-ignore|tags-ignore>

使用 push 事件时,可以将工作流配置为在特定分支或标记上运行。

如果要包含分支名称模式或要同时包含和排除分支名称模式,请使用 branches 筛选器。 只希望排除分支名称时,请使用 branches-ignore 筛选器。 不能对工作流中的同一事件同时使用 branchesbranches-ignore 筛选器。

如果要包含标记名称模式或要同时包含和排除标记名称模式,请使用 tags 筛选器。 只需要排除标记名称模式时,请使用 tags-ignore 筛选器。 不能对工作流中的同一事件同时使用 tagstags-ignore 筛选器。

如果仅定义了 tags/tags-ignore 或者仅定义了 branches/branches-ignore,那么对于影响未定义的 Git 引用的事件,工作流将不会运行。如果既未定义 tags/tags-ignore 也未定义 branches/branches-ignore,则工作流将针对影响分支或标记的事件运行。 如果你同时定义 branches/branches-ignorepaths/paths-ignore,则工作流将只在这两个筛选器都满足条件时运行。

branchesbranches-ignoretagstags-ignore 关键词接受使用 ***+?! 等字符匹配多个分支或标记名称的 glob 模式。 如果名称包含其中任一字符,而你想要逐字匹配,则需要使用 \ 转义每个特殊字符。 有关 glob 模式的详细信息,请参阅“GitHub Actions 的工作流语法”。

示例:包括分支和标记

branchestags 中定义的模式根据 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-ignoretags-ignore 模式匹配时,工作流将不会运行。 在 branchestags 中定义的模式根据 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.*

示例:包括和排除分支和标记

不能在一个工作流中使用 branchesbranches-ignore 筛选同一事件。 同样,不能在一个工作流中使用 tagstags-ignore 筛选同一事件。 如果要同时包括和排除一个事件的分支或标记模式,请使用 branchestags 筛选器以及 ! 字符来指示应排除哪些分支或标记。

如果使用字符 ! 定义分支,则还必须至少定义一个没有 ! 字符的分支。 如果只想排除分支,请改用 branches-ignore。 同样,如果使用字符 ! 定义标记,则还必须至少定义一个没有 ! 字符的标记。 如果只想排除标记,请改用 tags-ignore

您定义模式事项的顺序。

  • 肯定匹配后的匹配否定模式(前缀为 !)将排除 Git 引用。
  • 否定匹配后的匹配肯定模式将再次包含 Git 引用。

以下工作流将在推送到 releases/10releases/beta/mona 时运行,但不在推送到 releases/10-alphareleases/beta/3-alpha 时运行,因为否定模式 !releases/**-alpha 遵循肯定模式。

on:
  push:
    branches:
      - 'releases/**'
      - '!releases/**-alpha'

on.<push|pull_request|pull_request_target>.<paths|paths-ignore>

使用 pushpull_request 事件时,可以配置工作流以根据更改的文件路径运行。 路径筛选器不会针对标记的推送进行评估。

如果想要包括文件路径模式或想要同时包括和排除文件路径模式,请使用 paths 筛选器。 如果只想排除文件路径模式,请使用 paths-ignore 筛选器。 不能对工作流中的同一事件同时使用 pathspaths-ignore 筛选器。 如果要同时包括和排除单个事件的路径模式,请使用前缀为 ! 字符的 paths 筛选器来指示应排除哪些路径。

Note

您定义 paths 模式事项的顺序:

  • 肯定匹配后的匹配否定模式(前缀为 !)将排除路径。
  • 否定匹配后的匹配肯定模式将再次包含路径。

如果你同时定义 branches/branches-ignore 筛选器和 paths/paths-ignore 筛选器,则工作流将只在这两个筛选器都满足条件时运行。

pathspaths-ignore 关键字接受使用 *** 通配符匹配多个路径名的 glob 模式。 有关详细信息,请参阅“GitHub Actions 的工作流语法”。

示例:包括路径

如果至少一个路径与 paths 筛选器中的模式匹配,则工作流将运行。 例如,只要推送 JavaScript 文件 (.js),就会运行以下工作流。

on:
  push:
    paths:
      - '**.js'

如果因路径筛选、分支筛选提交消息而跳过某工作流,则与该工作流关联的检查将保持为“挂起”状态。 要求这些检查成功的拉取请求将被阻止合并。

示例:排除路径

当所有路径名称匹配 paths-ignore 中的模式时,工作流不会运行。 如果任何路径名与 paths-ignore 中的模式不匹配,即使某些路径名与模式匹配,工作流也会运行。

具有以下路径筛选器的工作流将仅在 push 事件上运行,这些事件包括至少一个位于存储库根目录的 docs 目录外的文件。

on:
  push:
    paths-ignore:
      - 'docs/**'

示例:包括和排除路径

不能在单个工作流中使用 pathspaths-ignore 筛选同一事件。 如果要同时包括和排除单个事件的路径模式,请使用前缀为 ! 字符的 paths 筛选器来指示应排除哪些路径。

如果使用 ! 字符定义路径,则还必须定义至少一个不带 ! 字符的路径。 如果只想排除路径,请改用 paths-ignore

您定义 paths 模式事项的顺序:

  • 肯定匹配后的匹配否定模式(前缀为 !)将排除路径。
  • 否定匹配后的匹配肯定模式将再次包含路径。

只要 push 事件包括 sub-project 目录或其子目录中的文件,此示例就会运行,除非该文件在 sub-project/docs 目录中。 例如,更改了 sub-project/index.jssub-project/src/index.js 的推送将会触发工作流运行,但只更改 sub-project/docs/readme.md 的推送不会触发。

on:
  push:
    paths:
      - 'sub-project/**'
      - '!sub-project/docs/**'

Git 差异比较

Note

如果推送超过 1,000 项提交,或者如果 GitHub 因超时未生成差异,则工作流将始终运行。

筛选器通过评估更改的文件并针对 paths-ignorepaths 列表运行它们来确定是否应运行工作流。 如果没有更改文件,工作流程将不会运行。

GitHub 会针对推送使用双点差异,针对拉取请求使用三点差异,生成已更改文件列表:

  • 拉取请求: 三点差异比较主题分支的最近版本与其中使用基本分支最新同步主题分支的提交。
  • 推送到现有分支: 双点差异直接相互比较头部和基础 SHA。
  • 推送到新分支: 根据已推送最深提交的上级父项的两点差异。

差异限制为 300 个文件。 如果更改的文件与过滤器返回的前 300 个文件不匹配,工作流程将不会运行。 您可能需要创建更多的特定过滤器,以便工作流程自动运行。

有关详细信息,请参阅“关于比较拉取请求中的分支”。

on.schedule

可以使用 on.schedule 定义工作流的时间计划。 可使用 POSIX cron 语法将工作流计划为在特定的 UTC 时间运行。 预定的工作流程在默认或基础分支的最新提交上运行。 您可以运行预定工作流程的最短间隔是每 5 分钟一次。

此示例在每天 5:30 和 17:30 UTC 触发工作流程:

on:
  schedule:
    # * is a special character in YAML so you have to quote this string
    - cron:  '30 5,17 * * *'

多个 schedule 事件可以触发单个工作流。 你可以通过 github.event.schedule 上下文访问触发工作流的计划事件。 此示例触发工作流在每周一至周四 5:30 UTC 运行,但在周一和周三跳过 Not on Monday or Wednesday 步骤。

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 参数,则对布尔值、数字和字符串来说,输入的默认值依次为 false0""

在被调用的工作流中,可以使用 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 关键字定义输入,则为必需项。 此参数的值是指定输入的数据类型的字符串。 其必须是 booleannumberstring

on.workflow_call.outputs

被调用工作流程的输出映射。 调用的工作流程输出可用于调用方工作流程中的所有下游作业。 每个输出都有一个标识符、一个可选 description, 和一个 value.。必须将 value 设置为被调用工作流内作业中的输出值。

在下面的示例中,为此可重用工作流定义了两个输出:workflow_output1workflow_output2。 这些是映射到称为 job_output1job_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 上下文来引用机密。

Note

如果要将机密传递给嵌套的可重用工作流,则必须再次使用 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 事件时,可以指定触发工作流必须在哪些分支上运行才能触发工作流。

branchesbranches-ignore 筛选器接受使用 ***+?! 等字符匹配多个分支名称的 glob 模式。 如果名称包含其中任一字符,而你想要逐字匹配,则需要使用 \ 转义每个特殊字符。 有关 glob 模式的详细信息,请参阅“GitHub Actions 的工作流语法”。

例如,仅当名为 Build 的工作流在名称以 releases/ 开头的分支上运行时,具有以下触发器的工作流才会运行:

on:
  workflow_run:
    workflows: ["Build"]
    types: [requested]
    branches:
      - 'releases/**'

仅当名为 Build 的工作流不在名为 canary 的分支上运行时,具有以下触发器的工作流才会运行:

on:
  workflow_run:
    workflows: ["Build"]
    types: [requested]
    branches-ignore:
      - "canary"

不能对工作流中的同一事件同时使用 branchesbranches-ignore 筛选器。 如果要同时包括和排除单个事件的分支模式,请使用 branches 筛选器以及 ! 字符来指示应排除哪些分支。

您定义模式事项的顺序。

  • 肯定匹配后的匹配否定模式(前缀为 !)将排除分支。
  • 否定匹配后的匹配肯定模式将再次包含分支。

例如,当名为 Build 的工作流在名为 releases/10releases/beta/mona 但不在名为 releases/10-alphareleases/beta/3-alphamain 的分支上运行时,具有以下触发器的工作流将运行。

on:
  workflow_run:
    workflows: ["Build"]
    types: [requested]
    branches:
      - 'releases/**'
      - '!releases/**-alpha'

on.workflow_dispatch

使用 workflow_dispatch 事件时,你可以选择性指定传递到工作流的输入。

此触发器仅当工作流文件位于默认分支时接收事件。

on.workflow_dispatch.inputs

触发的工作流在 inputs 上下文中接收输入。 有关详细信息,请参阅“上下文。”

Note

  • 工作流还将接收 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

此参数的值是指定输入的数据类型的字符串。 这必须是 booleanchoicenumberenvironmentstring

permissions

可以使用 permissions 修改授予 GITHUB_TOKEN 的默认权限,根据需要添加或删除访问权限,以便只授予所需的最低访问权限。 有关详细信息,请参阅“自动令牌身份验证”。

可以使用 permissions 作为顶级密钥,以应用于工作流中的所有作业或特定作业。 当你在特定作业中添加 permissions 密钥时,该作业中使用 GITHUB_TOKEN 的所有操作和运行命令都将获得你指定的访问权限。 有关详细信息,请参阅 jobs.<job_id>.permissions

对于下表中显示的每个可用权限,可以分配以下访问级别之一:read(如果适用)、writenonewrite 包括 read。 如果指定其中任何权限的访问,则所有未指定的权限都将设置为 none

可用的权限以及每个权限允许执行的操作的详细信息:

权限允许操作使用 GITHUB_TOKEN
actions使用 GitHub Actions。 例如,actions: write 允许操作取消工作流运行。 有关详细信息,请参阅“GitHub 应用程序所需的权限”。
attestations使用项目证明。 例如,attestations: write 允许一个操作为生成生成项目证明。 有关详细信息,请参阅“使用项目证明确立生成的来源”。
checks使用检查运行和检查套件。 例如,checks: write 允许操作创建检查运行。 有关详细信息,请参阅“GitHub 应用程序所需的权限”。
contents处理存储库的内容。 例如,contents: read 允许操作列出提交,contents: write 允许操作创建发布。 有关详细信息,请参阅“GitHub 应用程序所需的权限”。
deployments处理部署。 例如,deployments: write 允许操作创建新部署。 有关详细信息,请参阅“GitHub 应用程序所需的权限”。
discussions使用 GitHub Discussions。 例如,discussions: write 允许操作关闭或删除讨论。 有关详细信息,请参阅“使用 GraphQL API for Discussions”。
id-token提取 OpenID Connect (OIDC) 令牌。 这需要 id-token: write。 有关详细信息,请参阅“关于使用 OpenID Connect 进行安全强化”。
issues处理问题。 例如,issues: write 允许操作向问题添加注释。 有关详细信息,请参阅“GitHub 应用程序所需的权限”。
packages使用 GitHub Packages。 例如,packages: write 允许操作在 GitHub Packages 上上传和发布包。 有关详细信息,请参阅“关于 GitHub Packages 的权限”。
pages使用 GitHub Pages。 例如,pages: write 允许操作请求 GitHub Pages 生成。 有关详细信息,请参阅“GitHub 应用程序所需的权限”。
pull-requests处理拉取请求。 例如,pull-requests: write 允许操作向拉取请求添加标签。 有关详细信息,请参阅“GitHub 应用程序所需的权限”。
repository-projects使用 GitHub 项目(经典)。 例如,repository-projects: write 允许操作向项目添加列(经典)。 有关详细信息,请参阅“GitHub 应用程序所需的权限”。
security-events使用 GitHub 代码扫描和 Dependabot 警报。 例如,security-events: read 允许操作列出存储库的 Dependabot 警报,security-events: write 允许操作更新代码扫描警报的状态。 有关详细信息,请参阅“GitHub 应用所需的权限”中的“‘代码扫描警报’的存储库权限”和“‘Dependabot 警报’的存储库权限”。
statuses处理提交状态。 例如,statuses:read 允许操作列出给定引用的提交状态。 有关详细信息,请参阅“GitHub 应用程序所需的权限”。

定义 GITHUB_TOKEN 范围的访问权限

可以通过将 readwritenone 指定为 permissions 键中可用权限的值来定义 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-allwrite-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>.envjobs.<job_id>.steps[*].env

env 映射中的变量不能根据映射中的其他变量进行定义。

当多个环境变量使用相同的名称定义时,GitHub 会使用最特定的变量。 例如,步骤中定义的环境变量在步骤执行时将覆盖名称相同的作业和工作流环境变量。 为作业定义的环境变量在作业执行时将覆盖名称相同的工作流变量。

env 的示例

env:
  SERVER: production

defaults

使用 defaults 创建将应用于工作流中所有作业的默认设置的 map。 您也可以设置只可用于作业的默认设置。 有关详细信息,请参阅 jobs.<job_id>.defaults

使用相同名称定义了多个默认设置时,GitHub 会使用最具体的默认设置。 例如,在作业中定义的默认设置将覆盖在工作流程中定义的同名默认设置。

defaults.run

你可以使用 defaults.run 为工作流中的所有 run 步骤提供默认的 shellworking-directory 选项。 你也可以为只可用于作业的 run 设定默认设置。 有关详细信息,请参阅 jobs.<job_id>.defaults.run。 您不能在此关键词中使用上下文或表达式。

使用相同名称定义了多个默认设置时,GitHub 会使用最具体的默认设置。 例如,在作业中定义的默认设置将覆盖在工作流程中定义的同名默认设置。

示例:设置默认 shell 和工作目录

defaults:
  run:
    shell: bash
    working-directory: ./scripts

defaults.run.shell

使用 shell 为步骤定义 shell。 此关键字可以引用多个上下文。 有关详细信息,请参阅“上下文”。

支持的平台shell 参数说明内部运行命令
Linux/macOSunspecified非 Windows 平台上的默认 shell。 请注意,这与显式指定 bash 时运行的命令不同。 如果在路径中找不到 bash,则将其视为 shbash -e {0}
Allbash非 Windows 平台上回退到 sh 的默认 shell。 指定 Windows 上的 bash shell 时,将使用 Git for Windows 随附的 bash shel。bash --noprofile --norc -eo pipefail {0}
全部pwshPowerShell Core。 GitHub 将扩展名 .ps1 追加到你的脚本名称。pwsh -command ". '{0}'"
Allpython执行 python 命令。python {0}
Linux/macOSsh未提供 shell 且在路径中找不到 bash 时的非 Windows 平台的后退行为。sh -e {0}
WindowscmdGitHub 将扩展名 .cmd 追加到你的脚本名称并替换 {0}%ComSpec% /D /E:ON /V:OFF /S /C "CALL "{0}""
Windowspwsh这是 Windows 上使用的默认 shell。 PowerShell Core。 GitHub 将扩展名 .ps1 追加到你的脚本名称。 如果自承载 Windows 运行器未安装 PowerShell Core,则改用 PowerShell Desktop。pwsh -command ". '{0}'"
WindowspowershellPowerShell 桌面。 GitHub 将扩展名 .ps1 追加到你的脚本名称。powershell -command ". '{0}'"

使用相同名称定义了多个默认设置时,GitHub 会使用最具体的默认设置。 例如,在作业中定义的默认设置将覆盖在工作流程中定义的同名默认设置。

defaults.run.working-directory

使用 working-directory 为步骤定义用于 shell 的工作目录。 此关键字可以引用多个上下文。 有关详细信息,请参阅“上下文”。

Tip

在运行 shell 之前,请确保你分配的 working-directory 在运行器上存在。 使用相同名称定义了多个默认设置时,GitHub 会使用最具体的默认设置。 例如,在作业中定义的默认设置将覆盖在工作流程中定义的同名默认设置。

concurrency

使用 concurrency 以确保只有使用相同并发组的单一作业或工作流才会同时运行。 并发组可以是任何字符串或表达式。 表达式只能使用 githubinputsvars 上下文。 有关表达式的详细信息,请参阅“对工作流和操作中的表达式求值”。

你还可以在作业级别指定 concurrency。 有关详细信息,请参阅 jobs.<job_id>.concurrency

这意味着一个并发组中最多只能有一个正在运行的作业和一个待处理的作业。 当并发作业或工作流排队时,如果存储库中使用同一并发组的其他作业或工作流正在运行,则排队的作业或工作流将为 pending。 将取消同一并发组中的任何现有 pending 作业或工作流(如果存在)并取消新的列队作业或工作流。

若还要取消同一并发组中任何当前正在运行的作业或工作流,请指定 cancel-in-progress: true。 若要有条件地取消同一并发组中当前正在运行的作业或工作流,可以将 cancel-in-progress 指定为具有任何允许的表达式上下文的表达式。

Note

  • 并发组名称不区分大小写。 例如,prodProd 将被视为同一个并发组。
  • 对于使用并发组的作业或工作流运行,无法保证排序。 同一并发组中的作业或工作流运行按任意顺序进行处理。

示例:使用并发和默认行为

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 密钥与 cancel-in-progress 选项设置为 true

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.<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_jobmy_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(如果适用)、writenonewrite 包括 read。 如果指定其中任何权限的访问,则所有未指定的权限都将设置为 none

可用的权限以及每个权限允许执行的操作的详细信息:

权限允许操作使用 GITHUB_TOKEN
actions使用 GitHub Actions。 例如,actions: write 允许操作取消工作流运行。 有关详细信息,请参阅“GitHub 应用程序所需的权限”。
attestations使用项目证明。 例如,attestations: write 允许一个操作为生成生成项目证明。 有关详细信息,请参阅“使用项目证明确立生成的来源”。
checks使用检查运行和检查套件。 例如,checks: write 允许操作创建检查运行。 有关详细信息,请参阅“GitHub 应用程序所需的权限”。
contents处理存储库的内容。 例如,contents: read 允许操作列出提交,contents: write 允许操作创建发布。 有关详细信息,请参阅“GitHub 应用程序所需的权限”。
deployments处理部署。 例如,deployments: write 允许操作创建新部署。 有关详细信息,请参阅“GitHub 应用程序所需的权限”。
discussions使用 GitHub Discussions。 例如,discussions: write 允许操作关闭或删除讨论。 有关详细信息,请参阅“使用 GraphQL API for Discussions”。
id-token提取 OpenID Connect (OIDC) 令牌。 这需要 id-token: write。 有关详细信息,请参阅“关于使用 OpenID Connect 进行安全强化”。
issues处理问题。 例如,issues: write 允许操作向问题添加注释。 有关详细信息,请参阅“GitHub 应用程序所需的权限”。
packages使用 GitHub Packages。 例如,packages: write 允许操作在 GitHub Packages 上上传和发布包。 有关详细信息,请参阅“关于 GitHub Packages 的权限”。
pages使用 GitHub Pages。 例如,pages: write 允许操作请求 GitHub Pages 生成。 有关详细信息,请参阅“GitHub 应用程序所需的权限”。
pull-requests处理拉取请求。 例如,pull-requests: write 允许操作向拉取请求添加标签。 有关详细信息,请参阅“GitHub 应用程序所需的权限”。
repository-projects使用 GitHub 项目(经典)。 例如,repository-projects: write 允许操作向项目添加列(经典)。 有关详细信息,请参阅“GitHub 应用程序所需的权限”。
security-events使用 GitHub 代码扫描和 Dependabot 警报。 例如,security-events: read 允许操作列出存储库的 Dependabot 警报,security-events: write 允许操作更新代码扫描警报的状态。 有关详细信息,请参阅“GitHub 应用所需的权限”中的“‘代码扫描警报’的存储库权限”和“‘Dependabot 警报’的存储库权限”。
statuses处理提交状态。 例如,statuses:read 允许操作列出给定引用的提交状态。 有关详细信息,请参阅“GitHub 应用程序所需的权限”。

定义 GITHUB_TOKEN 范围的访问权限

可以通过将 readwritenone 指定为 permissions 键中可用权限的值来定义 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-allwrite-all 访问:

permissions: read-all
permissions: write-all

可以使用以下语法来禁用所有可用权限的权限:

permissions: {}

更改分支存储库中的权限

可以使用 permissions 密钥添加和删除分叉存储库的读取权限,但通常不能授予其写入权限。 此行为的例外情况是,管理员用户已在 GitHub Actions 设置中选择了“通过拉取请求向工作流发送写入令牌”选项。 有关详细信息,请参阅“管理存储库的 GitHub Actions 设置”。

示例:为工作流中的一个作业设置 GITHUB_TOKEN 权限

本示例显示为将仅应用到作业 staleGITHUB_TOKEN 设置的权限。 为 issuespull-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 等待 job1job2 完成。

此示例中的作业按顺序运行:

  1. job1
  2. job2
  3. job3

示例:不要求成功的依赖项作业

jobs:
  job1:
  job2:
    needs: job1
  job3:
    if: ${{ always() }}
    needs: [job1, job2]

在此示例中,job3 使用 always() 条件表达式,确保始终在 job1job2 完成(无论是否成功)后运行。 有关详细信息,请参阅“对工作流和操作中的表达式求值”。

jobs.<job_id>.if

可以使用 jobs.<job_id>.if 条件来阻止步骤运行,除非满足条件。 您可以使用任何支持上下文和表达式来创建条件。 有关此键支持哪些上下文的详细信息,请参阅“访问有关工作流运行的上下文信息”。

Note

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 组织内时,它才会运行。 否则,作业将被标记为“跳过”。

YAML
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 定义要运行作业的计算机类型。

  • 可以提供以下形式的 runs-on

    • 单个字符串
    • 包含字符串的单个变量
    • 字符串数组、包含字符串的变量或两者的组合
    • 使用 grouplabels 键的 key: value
  • 如果指定字符串数组,工作流将在与所有指定 runs-on 值匹配的运行器上执行。 例如,此处的作业将仅在具有标签 linuxx64gpu 的自托管运行器上运行:

    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

Note

self-hosted 这样的简单字符串前后不需要引号,但 "${{ inputs.chosen-os }}" 等表达式前后需要引号。

选择 GitHub 托管的运行器

如果使用 GitHub 托管的运行器,每个作业将在 runs-on 指定的运行器映像的新实例中运行。

使用 GitHub 托管的运行器时,运行时的值是运行器标签或运行器组名称。 标准 GitHub 托管的运行器的标签如下表所示。

有关详细信息,请参阅“关于 GitHub 托管的运行程序”。

用于公共存储库的 GitHub 托管的标准运行器

对于公共存储库,使用下表所示工作流标签的作业可在具有关联规范的虚拟机上运行。 可以在公共存储库上免费且无限制地使用这些运行器。

虚拟机 处理器 (CPU) 内存 (RAM) 存储 (SSD) 工作流标签
Linux 4 16 GB 14 GB ubuntu-latestubuntu-24.04ubuntu-22.04ubuntu-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-latestmacos-14macos-15 [公共预览版]

适用于专用存储库的标准 GitHub 托管的运行器

对于专用存储库,使用下表所示工作流标签的工作可在具有关联规范的虚拟机上运行。 这些运行程序使用 GitHub 帐户分配的免费分钟数,然后按每分钟费率收费。 有关详细信息,请参阅“关于 GitHub Actions 的计费”。

虚拟机 处理器 (CPU) 内存 (RAM) 存储 (SSD) 工作流标签
Linux 2 7 GB 14 GB ubuntu-latestubuntu-24.04ubuntu-22.04ubuntu-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-latestmacos-14macos-15 [公共预览版]

除了标准 GitHub 托管的运行器之外,GitHub 还在 GitHub Team 和 GitHub Enterprise Cloud 计划中为客户提供一系列具有更多高级功能的托管虚拟机,如更多核心和磁盘空间、GPU 支持的计算机以及 RAM 支持的计算机。 有关详细信息,请参阅“关于较大的运行器”。

Note

-latest 运行器映像是 GitHub 提供的最新稳定映像,但可能不是操作系统供应商提供的最新版本的操作系统。

Warning

Beta 版映像和已弃用的映像“按原样”、“含全部错误”和“按可用性”提供,不包含在服务级别协议和保证之内。 客户支持可能不会涵盖 Beta 版映像。

示例:指定操作系统

runs-on: ubuntu-latest

有关详细信息,请参阅“使用 GitHub 托管的运行器”。

选择自托管运行器

要为作业指定自托管运行器,请在工作流文件中使用自托管运行器标签配置 runs-on

自托管运行器可能具有 self-hosted 标签。 设置自托管运行器时,默认情况下,我们将包含标签 self-hosted。 可以传递 --no-default-labels 标志以防止应用自托管标签。 标签可用于为运行器创建目标选项(例如,操作系统或体系结构),建议提供以 self-hosted 开头的标签数组(必须首先列出),然后根据需要包含其他标签。 指定标签数组时,作业将在具有你指定的所有标签的运行器上排队。

请注意,Actions Runner Controller 不支持多个标签,并且不支持 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 键将 grouplabels 组合在一起,以便将作业路由到具有匹配标签的组内的任何可用运行器:

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 提供,也可以作为具有 nameurl 的环境对象提供。 URL 将映射到部署 API 中的 environment_url。 有关部署 API 的详细信息,请参阅“存储库的 REST API 终结点”。

Note

在将引用环境的作业发送到运行器之前,必须通过所有部署保护规则。 有关详细信息,请参阅“管理部署环境”。

使用单一环境名称的示例

environment: staging_environment

使用环境名称和 URL 的示例

environment:
  name: production_environment
  url: https://github.com

url 的值可以是一个表达式。 允许的表达式上下文:githubinputsvarsneedsstrategymatrixjobrunnerenvsteps。 有关表达式的详细信息,请参阅“对工作流和操作中的表达式求值”。

将输出用作 URL 的示例

environment:
  name: production_environment
  url: ${{ steps.step_id.outputs.url_output }}

name 的值可以是一个表达式。 允许的表达式上下文:githubinputsvarsneedsstrategymatrix。 有关表达式的详细信息,请参阅“对工作流和操作中的表达式求值”。

示例:使用表达式作为环境名称

environment:
  name: ${{ github.ref_name }}

jobs.<job_id>.concurrency

可以使用 jobs.<job_id>.concurrency 确保只有使用相同并发组的单一作业或工作流才会同时运行。 并发组可以是任何字符串或表达式。 允许的表达式上下文:githubinputsvarsneedsstrategymatrix。 有关表达式的详细信息,请参阅“对工作流和操作中的表达式求值”。

还可以在工作流级别指定 concurrency。 有关详细信息,请参阅 concurrency

这意味着一个并发组中最多只能有一个正在运行的作业和一个待处理的作业。 当并发作业或工作流排队时,如果存储库中使用同一并发组的其他作业或工作流正在运行,则排队的作业或工作流将为 pending。 将取消同一并发组中的任何现有 pending 作业或工作流(如果存在)并取消新的列队作业或工作流。

若还要取消同一并发组中任何当前正在运行的作业或工作流,请指定 cancel-in-progress: true。 若要有条件地取消同一并发组中当前正在运行的作业或工作流,可以将 cancel-in-progress 指定为具有任何允许的表达式上下文的表达式。

Note

  • 并发组名称不区分大小写。 例如,prodProd 将被视为同一个并发组。
  • 对于使用并发组的作业或工作流运行,无法保证排序。 同一并发组中的作业或工作流运行按任意顺序进行处理。

示例:使用并发和默认行为

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 密钥与 cancel-in-progress 选项设置为 true

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。 可以设置用于整个工作流或单个步骤的变量。 有关详细信息,请参阅 envjobs.<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 步骤提供默认的 shellworking-directory

你可以为作业中的所有 run 步骤提供默认的 shellworking-directory 选项。 你也可以为整个工作流的 run 设置默认设置。 有关详细信息,请参阅 defaults.run

这些值可以在级别 jobs.<job_id>.defaults.runjobs.<job_id>.steps[*].run 覆盖。

使用相同名称定义了多个默认设置时,GitHub 会使用最具体的默认设置。 例如,在作业中定义的默认设置将覆盖在工作流程中定义的同名默认设置。

jobs.<job_id>.defaults.run.shell

使用 shell 为步骤定义 shell。 此关键字可以引用多个上下文。 有关详细信息,请参阅“上下文”。

支持的平台shell 参数说明内部运行命令
Linux/macOSunspecified非 Windows 平台上的默认 shell。 请注意,这与显式指定 bash 时运行的命令不同。 如果在路径中找不到 bash,则将其视为 shbash -e {0}
Allbash非 Windows 平台上回退到 sh 的默认 shell。 指定 Windows 上的 bash shell 时,将使用 Git for Windows 随附的 bash shel。bash --noprofile --norc -eo pipefail {0}
全部pwshPowerShell Core。 GitHub 将扩展名 .ps1 追加到你的脚本名称。pwsh -command ". '{0}'"
Allpython执行 python 命令。python {0}
Linux/macOSsh未提供 shell 且在路径中找不到 bash 时的非 Windows 平台的后退行为。sh -e {0}
WindowscmdGitHub 将扩展名 .cmd 追加到你的脚本名称并替换 {0}%ComSpec% /D /E:ON /V:OFF /S /C "CALL "{0}""
Windowspwsh这是 Windows 上使用的默认 shell。 PowerShell Core。 GitHub 将扩展名 .ps1 追加到你的脚本名称。 如果自承载 Windows 运行器未安装 PowerShell Core,则改用 PowerShell Desktop。pwsh -command ". '{0}'"
WindowspowershellPowerShell 桌面。 GitHub 将扩展名 .ps1 追加到你的脚本名称。powershell -command ". '{0}'"

使用相同名称定义了多个默认设置时,GitHub 会使用最具体的默认设置。 例如,在作业中定义的默认设置将覆盖在工作流程中定义的同名默认设置。

jobs.<job_id>.defaults.run.working-directory

使用 working-directory 为步骤定义用于 shell 的工作目录。 此关键字可以引用多个上下文。 有关详细信息,请参阅“上下文”。

Tip

在运行 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/heroku@1.0.0

示例:使用机密

无法直接在 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/checkout@v4.2.0
  # Reference a branch
  - uses: actions/checkout@main

示例:使用公共操作

{owner}/{repo}@{ref}

您可以指定公共 GitHub 仓库中的分支、引用或 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/aws@v2.0.1

示例:在子目录中使用公共操作

{owner}/{repo}/{path}@{ref}

公共 GitHub 仓库中特定分支、引用或 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 中枢操作

docker://{image}:{tag}

发布于 Docker 中心的 Docker 映像。

jobs:
  my_first_job:
    steps:
      - name: My first step
        uses: docker://alpine:3.8

示例:使用 GitHub Packages Container registry

docker://{host}/{image}:{tag}

GitHub Packages Container registry 中的公共 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

示例:在不同于工作流程的私有仓库中使用操作

您的工作流程必须检出私有仓库,并在本地引用操作。 生成 personal access token 并将令牌添加为机密。 有关详细信息,请参阅“管理个人访问令牌”和“在 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 而不是 personal access token,以确保即使 personal access token 所有者离开,工作流也能继续运行。 有关详细信息,请参阅“使用 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-directoryjobs.<job_id>.defaults.run.working-directory

还可以使用 run 步骤来运行脚本。 有关详细信息,请参阅“添加脚本到工作流程”。

jobs.<job_id>.steps[*].shell

你可以使用 shell 关键字,覆盖运行器操作系统中的默认 Shell 设置,以及作业的默认值。 你可以使用内置的 shell 关键字,也可以自定义 shell 选项集。 内部运行的 shell 命令执行一个临时文件,其中包含 run 关键字中指定的命令。

支持的平台shell 参数说明内部运行命令
Linux/macOSunspecified非 Windows 平台上的默认 shell。 请注意,这与显式指定 bash 时运行的命令不同。 如果在路径中找不到 bash,则将其视为 shbash -e {0}
Allbash非 Windows 平台上回退到 sh 的默认 shell。 指定 Windows 上的 bash shell 时,将使用 Git for Windows 随附的 bash shel。bash --noprofile --norc -eo pipefail {0}
全部pwshPowerShell Core。 GitHub 将扩展名 .ps1 追加到你的脚本名称。pwsh -command ". '{0}'"
Allpython执行 python 命令。python {0}
Linux/macOSsh未提供 shell 且在路径中找不到 bash 时的非 Windows 平台的后退行为。sh -e {0}
WindowscmdGitHub 将扩展名 .cmd 追加到你的脚本名称并替换 {0}%ComSpec% /D /E:ON /V:OFF /S /C "CALL "{0}""
Windowspwsh这是 Windows 上使用的默认 shell。 PowerShell Core。 GitHub 将扩展名 .ps1 追加到你的脚本名称。 如果自承载 Windows 运行器未安装 PowerShell Core,则改用 PowerShell Desktop。pwsh -command ". '{0}'"
WindowspowershellPowerShell 桌面。 GitHub 将扩展名 .ps1 追加到你的脚本名称。powershell -command ". '{0}'"

另外,可以为作业中的所有 run 步骤或整个工作流中的所有 run 步骤指定默认 Shell。 有关详细信息,请参阅 defaults.run.shelljobs.<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 -eshbash 强制实施快速失败行为。 指定 shell: bash 时,-o pipefail 还应用于强制提前退出生成非零退出状态的管道。
    • 你可以通过向 shell 选项提供模板字符串来完全控制 shell 参数。 例如,bash {0}
    • sh 类 shell 使用脚本中最后执行的命令退出代码退出,也是操作的默认行为。 运行程序将根据此退出代码将步骤的状态报告为失败/成功。
  • powershell/pwsh

    • 可能时的快速失败行为。 对于 pwshpowershell 内置 shell,我们将在脚本内容前面追加 $ErrorActionPreference = 'stop'
    • 我们追加 if ((Test-Path -LiteralPath variable:\LASTEXITCODE)) { exit $LASTEXITCODE } 到 Powershell 脚本,以便操作状态反映脚本的最后一个退出代码。
    • 用户始终可以选择退出,方法是不使用内置 shell,并按需提供 pwsh -File {0}powershell -Command "& '{0}'" 等自定义 shell 选项。
  • cmd

    • 除了编写脚本来检查每个错误代码并相应地响应之外,似乎没有办法完全选择快速失败行为。 由于我们默认不能实际提供该行为,因此您需要将此行为写入脚本。
    • cmd.exe 在退出时带有其执行的最后一个程序的错误等级,并且会将错误代码返回到运行器。 此行为在内部与之前的 shpwsh 默认行为一致,并且是 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_namemiddle_namelast_name)。 这些输入变量将作为 INPUT_FIRST_NAMEINPUT_MIDDLE_NAMEINPUT_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

string 定义 Docker 容器的输入。 GitHub 在容器启动时将 args 传递到容器的 ENTRYPOINT。 此参数不支持 array of strings。 包含空格的单个参数应该用双引号 "" 括起来。

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,请使用按偏好排序的指南:

  1. 在操作的自述文件中记录必要的参数,并在 CMD 指令的中忽略它们。
  2. 使用默认值,允许不指定任何 args 即可使用操作。
  3. 如果操作显示 --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

设置供步骤在运行器环境中使用的变量。 也可以设置用于整个工作流或某个作业的变量。 有关详细信息,请参阅 envjobs.<job_id>.env

当多个环境变量使用相同的名称定义时,GitHub 会使用最特定的变量。 例如,步骤中定义的环境变量在步骤执行时将覆盖名称相同的作业和工作流环境变量。 为作业定义的环境变量在作业执行时将覆盖名称相同的工作流变量。

公共操作可在自述文件中指定预期的变量。 如果要设置机密或敏感值(如密码或令牌),则必须使用 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 托管运行器的“使用限制、计费和管理”和针对自托管运行器使用限制的“关于自托管运行程序”。

Note

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]

将针对变量的每个可能组合运行作业。 在此示例中,工作流将运行六个作业,其中一个作业用于每个 osversion 变量组合。

默认情况下,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.versionmatrix.os 来访问作业正在使用的 versionos 的当前值。 有关详细信息,请参阅“访问有关工作流运行的上下文信息”。

示例:使用单维矩阵

可以指定单个变量来创建单维矩阵。

例如,以下工作流使用值 [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 版本

工作流将运行六个作业,其中针对每个 osversion 变量组合提供一个作业。 每个作业都会将 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 }}

矩阵中的变量配置可以是 objectarray

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

将生成具有以下矩阵组合的六个作业:

  • {fruit: apple, animal: cat, color: pink, shape: circle}
  • {fruit: apple, animal: dog, color: green, shape: circle}
  • {fruit: pear, animal: cat, color: pink}
  • {fruit: pear, animal: dog, color: green}
  • {fruit: banana}
  • {fruit: banana, animal: cat}

遵循以下逻辑:

  • {color: green} 添加到所有原始矩阵组合,因为它可以添加,而不会覆盖原始组合的任何部分。
  • {color: pink, animal: cat} 仅将 color:pink 添加到包含 animal: cat 的原始矩阵组合中。 这会覆盖上一个 include 条目添加的 color: green
  • {fruit: apple, shape: circle} 仅将 shape: circle 添加到包含 fruit: apple 的原始矩阵组合中。
  • {fruit: banana} 添加到任何原始矩阵组合时都会覆盖值,因此会将其作为其他矩阵组合进行添加。
  • {fruit: banana, animal: cat} 添加到任何原始矩阵组合时都会覆盖值,因此会将其作为其他矩阵组合进行添加。 它不会添加到 {fruit: banana} 矩阵组合中,因为该组合不是原始矩阵组合之一。

示例:扩展配置

例如,以下工作流将运行四个作业,其中针对每个 osnode 变量组合提供一个作业。 当对应于 windows-latestos 值和 16node 值的作业运行时,作业中将包含一个被称为 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 个作业,矩阵中每个 osversion 的组合一个作业,再加上一个用于 windows-latestos 值和 17version 值的作业。

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。 排除的配置必须是部分匹配项,才能将其排除。 例如,以下工作流将运行 9 个作业:每 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 }}

Note

所有 include 组合会在 exclude 之后处理。 这允许你使用 include 添加回以前排除的组合。

jobs.<job_id>.strategy.fail-fast

你可以使用 jobs.<job_id>.strategy.fail-fastjobs.<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-errortrue,即使具有 jobs.<job_id>.continue-on-error: true 的作业失败,矩阵中的其他作业也将继续运行。

可以同时使用 jobs.<job_id>.strategy.fail-fastjobs.<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

Note

如果工作流使用 Docker 容器操作、作业容器或服务容器,则必须使用 Linux 运行器:

  • 如果您要使用 GitHub 托管的运行器,则必须使用 Ubuntu 运行器。
  • 如果您要使用自托管运行器,则必须使用 Linux 机器作为运行器,并且必须安装 Docker。

使用 jobs.<job_id>.container 创建用于运行作业中尚未指定容器的任何步骤的容器。 如有步骤同时使用脚本和容器操作,则容器操作将运行为同一网络上使用相同卷挂载的同级容器。

若不设置 container,所有步骤将直接在 runs-on 指定的主机上运行,除非步骤引用已配置为在容器中运行的操作。

Note

用于容器中的 run 步骤的默认 shell 是 sh,而不是 bash。 这可以使用 jobs.<job_id>.defaults.runjobs.<job_id>.steps[*].shell 进行替代。

示例:在容器中运行作业

YAML
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 设置 usernamepasswordmap。 凭据是你将提供给 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 选项”。

Warning

不支持 --network--entrypoint 选项。

jobs.<job_id>.services

Note

如果工作流使用 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 设置 usernamepasswordmap。 凭据是你将提供给 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 选项”。

Warning

--network 选项不受支持。

jobs.<job_id>.uses

要作为作业运行的可重用工作流程文件的位置和版本。 使用以下语法之一:

  • {owner}/{repo}/.github/workflows/{filename}@{ref} 用于公共和专用存储库中的可重用工作流。
  • ./.github/workflows/{filename} 用于同一存储库中的可重用工作流。

在第一个选项中,{ref} 可以是 SHA、发布标记或分支名称。 如果发布标记和分支具有相同的名称,则发布标记优先于分支名称。 出于稳定性和安全性考虑,使用提交 SHA 是最稳妥的选项。 有关详细信息,请参阅“GitHub Actions 的安全强化”。

如果使用第二个语法选项(不带 {owner}/{repo}@{ref}),则调用的工作流来自与调用方工作流相同的提交。 不允许使用 refs/headsrefs/tags 等引用前缀。 您不能在此关键词中使用上下文或表达式。

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 类型匹配。

允许的表达式上下文:githubneeds

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> 定义的机密名称匹配。

允许的表达式上下文:githubneedssecrets

筛选器模式速查表

您可以在路径、分支和标记过滤器中使用特殊字符。

  • *:匹配零个或多个字符,但不匹配 / 字符。 例如,Octo* 匹配 Octocat
  • **:匹配零个或多个任意字符。
  • ?:匹配零个或一个前面的字符。
  • +:匹配一个或多个前面的字符。
  • [] 匹配列在括号中或包含在范围内的一个字母数字字符。 范围只能包括 a-zA-Z0-9。 例如,范围 [0-9a-z] 匹配任何数字或小写字母。 例如,[CB]at 匹配 CatBat,而 [1-2]00 匹配 100200
  • !:在模式开始时,它将否定以前的正模式。 如果不是第一个字符,它就没有特殊的意义。

字符 *[! 是 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
'**'匹配所有分支和标记名称。 这是不使用 branchestags 筛选器时的默认行为。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/**/*.mddocs 目录下任意位置带有 .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