跳至主要内容

控制工作流和作业的并发性

一次运行一个作业。

概述

默认情况下,GitHub Actions 允许同一工作流中的多个作业、同一存储库中的多个工作流运行以及存储库所有者帐户中的多个工作流运行同时运行。这意味着多个工作流运行、作业或步骤可以同时运行。

GitHub Actions 还允许您控制工作流运行的并发性,以便您可以确保在特定上下文中一次仅运行一个运行、一个作业或一个步骤。这在以下情况下非常有用:控制帐户或组织的资源,因为同时运行多个工作流、作业或步骤可能会导致冲突或消耗比预期更多的 Actions 分钟和存储空间。

例如,能够并发运行工作流意味着,如果多个提交依次快速推送到存储库,则每次推送都可能触发单独的工作流运行,并且这些运行将并发执行。

在不同场景中使用并发

您可以使用 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)的推送将取消正在进行的运行。

监控您组织或企业中的当前作业

要识别并发或排队中的任何约束,您可以检查当前在您组织或企业的 GitHub 托管运行器上处理了多少个作业。有关更多信息,请参阅“监控您的当前作业”。