跳至主要内容

GitHub Actions 的工作流语法

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

本文内容

关于工作流的 YAML 语法

工作流文件使用 YAML 语法,并且必须具有 .yml.yaml 文件扩展名。如果您不熟悉 YAML 并想了解更多信息,请参阅“在 Y 分钟内学习 YAML”。

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

name

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

run-name

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

此值可以包含表达式,并可以引用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事件,则只要创建、编辑或删除标签,它就会运行。如果为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 事件都由不止一种类型的活动触发。例如,当标签被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中定义的模式将针对 Git ref 的名称进行评估。例如,以下工作流将在针对以下内容的pull_request事件发生时运行:

  • 名为main的分支(refs/heads/main
  • 名为mona/octocat的分支(refs/heads/mona/octocat
  • 名称以releases/开头的分支,例如releases/10refs/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-alpharefs/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 ref。
  • 负匹配之后的匹配正模式将再次包含 Git ref。

以下工作流将在针对releases/10releases/beta/monapull_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 ref 的事件运行。如果既没有定义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/10refs/heads/releases/10
  • 名为v2的标签(refs/tags/v2
  • 名称以v1.开头的标签,例如v1.9.1refs/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-alpharefs/heads/releases/beta/3-alpha
  • 名为v2的标签(refs/tags/v2
  • 名称以v1.开头的标签,例如v1.9refs/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 ref。
  • 负匹配之后的匹配正模式将再次包含 Git ref。

以下工作流将在推送到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过滤器来指示要排除哪些路径。

注意

定义paths模式的顺序很重要

  • 正匹配后的匹配负模式(以!为前缀)将排除该路径。
  • 负匹配后的匹配正模式将再次包含该路径。

如果同时定义了branches/branches-ignorepaths/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 diff 比较

注意

如果您推送超过 1,000 次提交,或者由于超时而 GitHub 未生成 diff,则工作流将始终运行。

过滤器通过评估更改的文件并将它们与paths-ignorepaths列表运行来确定是否应运行工作流。如果没有更改任何文件,则工作流将不会运行。

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关键字定义了输入,则需要此参数。此参数的值是一个字符串,指定输入的数据类型。这必须是以下之一:booleannumberstring

on.workflow_call.outputs

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

在下面的示例中,为这个可重用工作流定义了两个输出: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上下文来引用密钥。

注意

如果您正在将密钥传递给嵌套的可重用工作流,则必须再次使用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 的工作流语法”。

例如,具有以下触发器的 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"

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

定义模式的顺序很重要。

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

例如,具有以下触发器的 workflow 将在名为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

触发的 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

此参数的值是一个字符串,指定输入的数据类型。这必须是以下之一: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 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密钥中指定readwritenone作为可用权限的值来定义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 / macOS未指定非 Windows 平台上的默认 shell。请注意,这会运行与显式指定bash时不同的命令。如果路径中找不到bash,则将其视为shbash -e {0}
所有平台bash非 Windows 平台上的默认 shell,并回退到sh。在 Windows 上指定 bash shell 时,将使用 Git for Windows 附带的 bash shell。bash --noprofile --norc -eo pipefail {0}
所有平台pwshPowerShell Core。GitHub 会将扩展名.ps1附加到您的脚本名称。pwsh -command ". '{0}'"
所有平台python执行 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 Desktop。GitHub 会将扩展名.ps1附加到您的脚本名称。powershell -command ". '{0}'".

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

defaults.run.working-directory

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

提示

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

concurrency

使用concurrency确保一次只有一个使用相同并发组的作业或工作流运行。并发组可以是任何字符串或表达式。表达式只能使用githubinputsvars上下文。有关表达式的更多信息,请参阅"在工作流和操作中评估表达式"。

您也可以在作业级别指定concurrency。有关更多信息,请参阅jobs.<job_id>.concurrency

这意味着并发组中最多只能同时存在一个正在运行的作业和一个挂起的作业。当并发作业或工作流排队时,如果存储库中使用相同并发组的另一个作业或工作流正在进行中,则排队的作业或工作流将处于pending状态。如果存在,则并发组中任何现有的pending作业或工作流都将被取消,新的排队作业或工作流将取代其位置。

要取消并发组中任何当前正在运行的作业或工作流,请指定cancel-in-progress: true。要根据条件取消并发组中当前正在运行的作业或工作流,您可以将cancel-in-progress指定为包含任何允许的表达式上下文的表达式。

注意

  • 并发组名称不区分大小写。例如,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密钥与设置为truecancel-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_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 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密钥中指定readwritenone作为可用权限的值来定义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权限

此示例显示为GITHUB_TOKEN设置的权限,这些权限仅适用于名为stale的作业。为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条件来阻止作业运行,除非满足某个条件。您可以使用任何受支持的上下文和表达式来创建条件。有关此键中支持哪些上下文的更多信息,请参见“访问有关工作流运行的上下文信息”。

注意

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

注意

简单字符串(如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-latestubuntu-24.04ubuntu-22.04ubuntu-20.04
Windows 4 16 GB 14 GB windows-latestwindows-2022windows-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-latestwindows-2022windows-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 加速的机器和 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-16coreruns-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 端点”。

注意

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

示例:使用单个环境名称

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指定为包含任何允许的表达式上下文的表达式。

注意

  • 并发组名称不区分大小写。例如,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密钥与设置为truecancel-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) }}'
Actions 不保证矩阵作业的运行顺序。确保输出名称唯一,否则最后运行的矩阵作业将覆盖输出值。

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 / macOS未指定非 Windows 平台上的默认 shell。请注意,这会运行与显式指定bash时不同的命令。如果路径中找不到bash,则将其视为shbash -e {0}
所有平台bash非 Windows 平台上的默认 shell,并回退到sh。在 Windows 上指定 bash shell 时,将使用 Git for Windows 附带的 bash shell。bash --noprofile --norc -eo pipefail {0}
所有平台pwshPowerShell Core。GitHub 会将扩展名.ps1附加到您的脚本名称。pwsh -command ". '{0}'"
所有平台python执行 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 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,则将其视为shbash -e {0}
所有平台bash非 Windows 平台上的默认 shell,并回退到sh。在 Windows 上指定 bash shell 时,将使用 Git for Windows 附带的 bash shell。bash --noprofile --norc -eo pipefail {0}
所有平台pwshPowerShell Core。GitHub 会将扩展名.ps1附加到您的脚本名称。pwsh -command ". '{0}'"
所有平台python执行 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 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 -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,并提供自定义 shell 选项,例如:pwsh -File {0}powershell -Command "& '{0}'",具体取决于需要。
  • 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

一个字符串,定义 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,请按优先级顺序使用以下指南

  1. 在操作的 README 中记录必需的参数,并从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 将使用最具体的变量。例如,在步骤中定义的环境变量将在作业和工作流环境变量执行期间覆盖同名的作业和工作流环境变量。作业中定义的环境变量将在作业执行期间覆盖同名的工作流变量。

公共操作可以在 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]

每个可能的变量组合都将运行一个作业。在此示例中,工作流将运行六个作业,每个作业对应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 }}

矩阵中的变量配置可以是对象数组

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条目添加的颜色: 绿色
  • {水果: 苹果, 形状: 圆形}仅将形状: 圆形添加到包含水果: 苹果的原始矩阵组合中。
  • {水果: 香蕉}无法添加到任何原始矩阵组合中而不会覆盖值,因此它被添加为附加矩阵组合。
  • {水果: 香蕉, 动物: 猫}无法添加到任何原始矩阵组合中而不会覆盖值,因此它被添加为附加矩阵组合。它不会添加到{水果: 香蕉}矩阵组合中,因为该组合不是原始矩阵组合之一。

示例:扩展配置

例如,以下工作流程将运行四个作业,每个作业对应osnode的一个组合。当os值为windows-latestnode值为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个作业,每个作业对应矩阵中osversion的一个组合,再加上一个os值为windows-latestversion值为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-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-errormatrix.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.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选项”。

警告

不支持--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设置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 选项”。

警告

不支持--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之类的 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定义的类型匹配。

允许的表达式上下文: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