添加阶段、依赖项和条件

Azure DevOps Services | Azure DevOps Server 2022 - Azure DevOps Server 2019

阶段是指 Azure DevOps 管道中的逻辑边界。 阶段可用于对软件开发流程中的操作进行分组(例如,生成应用、运行测试、部署到预生产环境)。 每个阶段可以包含一个或多个作业。

在管道中定义多个阶段时,默认情况下,它们将依次运行。 阶段也可相互依赖。 可使用 dependsOn 关键字来定义依赖项。 此外,阶段还可根据附带条件的上一阶段的结果来运行。

若要了解阶段如何处理并行作业和许可,请参阅配置并行作业并为其付费

若要了解阶段与管道的其他部分(如作业)的关系,请参阅关键管道概念

还可以在 YAML 架构阶段一文中详细了解阶段与管道的各个部分的关系。

可以将管道作业组织到阶段。 阶段是管道中的主要分支:阶段的典型示例包括“生成此应用”、“运行这些测试”和“部署到预生产环境”。 它们是管道中的逻辑边界,你可在其中暂停管道并执行各种检查。

每个管道至少有一个阶段,即使你未显式定义它,也是如此。 还可以将阶段排列到依赖项关系图中,以便一个阶段先于另一个阶段运行。 一个阶段的作业限制为 256 个。

注意

Azure DevOps Server 2019.1 中添加了对阶段的支持。

指定阶段

注意

Azure DevOps Server 2019.1 中添加了对阶段的支持。

在最简单的情况下,管道中不需要任何逻辑边界。 在这种情况下,无需显式使用 stage 关键字。 可以直接在 YAML 文件中指定作业。

# this has one implicit stage and one implicit job
pool:
  vmImage: 'ubuntu-latest'
steps:
- bash: echo "Hello world"
# this pipeline has one implicit stage
jobs:
- job: A
  steps:
  - bash: echo "A"

- job: B
  steps:
  - bash: echo "B"

如果要将管道组织到多个阶段中,请使用 stages 关键字。

stages:
- stage: A
  jobs:
  - job: A1
  - job: A2

- stage: B
  jobs:
  - job: B1
  - job: B2

如果选择在阶段级别指定 pool,则该阶段中定义的所有作业均会使用该池,除非在作业级别进行指定。

注意

在 Azure DevOps Server 2019 中,只能在作业级别指定池。

stages:
- stage: A
  pool: StageAPool
  jobs:
  - job: A1 # will run on "StageAPool" pool based on the pool defined on the stage
  - job: A2 # will run on "JobPool" pool
    pool: JobPool

用于指定阶段的完整语法为:

stages:
- stage: string  # name of the stage, A-Z, a-z, 0-9, and underscore
  displayName: string  # friendly name to display in the UI
  dependsOn: string | [ string ]
  condition: string
  pool: string | pool
  variables: { string: string } | [ variable | variableReference ] 
  jobs: [ job | templateReference]

指定依赖项

注意

Azure DevOps Server 2019.1 中添加了对阶段的支持。

在管道中定义多个阶段时,默认情况下,它们按照自己在 YAML 文件中的定义顺序依次运行。 添加依赖项时除外。 对于依赖项,阶段按 dependsOn 要求的顺序运行。

管道必须包含至少一个没有依赖项的阶段。

用于定义多个阶段及其依赖项的语法为:

stages:
- stage: string
  dependsOn: string
  condition: string

按顺序运行的示例阶段:

# if you do not use a dependsOn keyword, stages run in the order they are defined
stages:
- stage: QA
  jobs:
  - job:
    ...

- stage: Prod
  jobs:
  - job:
    ...

并行运行的示例阶段:

stages:
- stage: FunctionalTest
  jobs:
  - job:
    ...

- stage: AcceptanceTest
  dependsOn: []    # this removes the implicit dependency on previous stage and causes this to run in parallel
  jobs:
  - job:
    ...

扇出和扇入的示例:

stages:
- stage: Test

- stage: DeployUS1
  dependsOn: Test    # this stage runs after Test

- stage: DeployUS2
  dependsOn: Test    # this stage runs in parallel with DeployUS1, after Test

- stage: DeployEurope
  dependsOn:         # this stage runs after DeployUS1 and DeployUS2
  - DeployUS1
  - DeployUS2

定义条件

可以使用表达式指定每个阶段运行的条件。 默认情况下,如果一个阶段不依赖于任何其他阶段,或者它所依赖的所有阶段都已完成且成功,它就会运行。 可以通过强制阶段运行(即使先前的阶段失败)或通过指定自定义条件来自定义此行为。

如果为某个阶段自定义前面步骤的默认条件,则会删除完成和成功的条件。 因此,如果使用自定义条件,通常会使用 and(succeeded(),custom_condition) 来检查前面的阶段是否成功运行。 否则,无论前面阶段的结果如何,阶段都会运行。

注意

以下示例所示的 failed('JOBNAME/STAGENAME') 和 succeeded('JOBNAME/STAGENAME') 的条件仅适用于 YAML 管道

注意

Azure DevOps Server 2019.1 中添加了对阶段的支持。

基于运行前面阶段的状态运行阶段的示例:

stages:
- stage: A

# stage B runs if A fails
- stage: B
  condition: failed()

# stage C runs if B succeeds
- stage: C
  dependsOn:
  - A
  - B
  condition: succeeded('B')

使用自定义条件的示例:

stages:
- stage: A

- stage: B
  condition: and(succeeded(), eq(variables['build.sourceBranch'], 'refs/heads/main'))

指定队列策略

YAML 管道不支持队列策略。 管道的每个运行都独立于其他运行,并且不知道其他运行。 换句话说,你的两个连续提交可能会触发两个管道,并且它们都将执行相同的阶段序列,而无需相互等待。 虽然我们努力将队列策略引入 YAML 管道,但我们建议你使用手动审批,以便手动排序和控制执行顺序(如果这很重要)。

指定审批

可以使用审批检查手动控制阶段应何时运行。 这通常用于控制向生产环境进行的部署。 检查是资源所有者可用的一种机制,用于控制管道中的阶段是否以及何时可以使用资源。 作为资源(如环境)的所有者,你可以定义在使用该资源的阶段可以启动之前必须满足的检查。

目前,环境支持手动审批检查。 有关详细信息,请参阅审批

在此版本的 Azure DevOps Server 中,YAML 管道尚不支持审批。

添加手动触发器

手动触发的 YAML 管道阶段使你能够拥有统一的管道,而无需始终运行该管道直到完成。

例如,管道可能包括生成、测试、部署到过渡环境以及部署到生产环境的阶段。 你可能希望所有阶段都自动运行,但生产部署除外,你希望在准备就绪时手动触发生产部署。

若要使用此功能,请将 trigger: manual 属性添加到阶段。

在以下示例中,开发阶段会自动运行,而生产阶段需要手动触发。 这两个阶段都运行“Hello World”输出脚本。

stages:
- stage: development
  displayName: Deploy to development
  jobs:
  - job: DeployJob
    steps:
    - script: echo 'hello, world'
      displayName: 'Run script'
- stage: production
  displayName: Deploy to production
  trigger: manual
  jobs:
  - job: DeployJob
    steps:
    - script: echo 'hello, world'
      displayName: 'Run script'

将阶段标记为不可跳过

将阶段标记为 isSkippable: false 以阻止管道用户跳过阶段。 例如,你可能有一个 YAML 模板,该模板会在所有管道中注入执行恶意软件检测的阶段。 如果为此阶段设置 isSkippable: false,则管道将无法跳过恶意软件检测。

在以下示例中,恶意软件检测阶段被标记为不可跳过,这意味着必须在管道运行中执行此阶段。

- stage: malware_detection
  displayName: Malware detection
  isSkippable: false
  jobs:
  - job: check_job
    ...

当阶段不可跳过时,它将显示,并且要运行的阶段配置面板中会有一个禁用复选框。

要运行的阶段以及禁用的阶段的屏幕截图。