添加阶段、依赖项和条件

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

阶段是指 Azure DevOps 管道中的逻辑边界。 在软件开发过程中,将动作分组到不同阶段,例如构建应用、运行测试和部署到预生产环境。 每个阶段可以包含一个或多个作业。

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

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

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

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

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

即使未显式定义管道,每个管道至少有一个阶段。 还可以将阶段排列到依赖项关系图中,以便一个阶段先于另一个阶段运行。 一个阶段最多可以有 256 个作业。

指定阶段

最简单的情况是,管道中不需要逻辑边界。 对于这些方案,可以直接在 YAML 文件中指定作业,而无需关键字 stages 。 例如,如果你有一个简单的管道来生成和测试小型应用程序,而无需单独的环境或部署步骤,则可以直接定义所有作业,而无需使用阶段。

pool:
  vmImage: 'ubuntu-latest'

jobs:
- job: BuildAndTest
  steps:
  - script: echo "Building the application"
  - script: echo "Running tests"

此管道有一个隐式阶段和两个任务。 stages关键字未使用,因为只有一个阶段。

jobs:
- job: Build
  steps:
  - bash: echo "Building"

- job: Test
  steps:
  - bash: echo "Testing"

若要将管道组织到多个阶段,请使用 stages 关键字。 此 YAML 定义了一个管道,其中包含两个阶段,其中每个阶段包含多个作业,每个作业都有要执行的特定步骤。

stages:
- stage: A
  displayName: "Stage A - Build and Test"
  jobs:
  - job: A1
    displayName: "Job A1 - build"
    steps:
    - script: echo "Building the application in Job A1"
      displayName: "Build step"
  - job: A2
    displayName: "Job A2 - Test"
    steps:
    - script: echo "Running tests in Job A2"
      displayName: "Test step"

- stage: B
  displayName: "Stage B - Deploy"
  jobs:
  - job: B1
    displayName: "Job B1 - Deploy to Staging"
    steps:
    - script: echo "Deploying to staging in Job B1"
      displayName: "Staging deployment step"
  - job: B2
    displayName: "Job B2 - Deploy to Production"
    steps:
    - script: echo "Deploying to production in Job B2"
      displayName: "Production deployment step"

如果在阶段级别指定pool,则该阶段中的所有作业都使用该池,除非在作业级别指定该池。

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

指定依赖项

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

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

有关如何定义阶段的详细信息,请参阅 YAML 架构中的阶段

以下示例阶段按顺序运行。 如果不使用 dependsOn 关键字,则分阶段按定义的顺序运行。

stages:
- stage: Build
  displayName: "Build Stage"
  jobs:
  - job: BuildJob
    steps:
    - script: echo "Building the application"
      displayName: "Build Step"

- stage: Test
  displayName: "Test Stage"
  jobs:
  - job: TestJob
    steps:
    - script: echo "Running tests"
      displayName: "Test Step"

并行运行的示例阶段:

stages:
- stage: FunctionalTest
  displayName: "Functional Test Stage"
  jobs:
  - job: FunctionalTestJob
    steps:
    - script: echo "Running functional tests"
      displayName: "Run Functional Tests"

- stage: AcceptanceTest
  displayName: "Acceptance Test Stage"
  dependsOn: [] # Runs in parallel with FunctionalTest
  jobs:
  - job: AcceptanceTestJob
    steps:
    - script: echo "Running acceptance tests"
      displayName: "Run Acceptance Tests"

扇出和扇入行为的示例:

stages:
- stage: Test

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

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

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

定义条件

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

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

注意

以下示例所示的 FAILED(‘JOBNAME/STAGENAME’) 和 SUCCEEDED(‘JOBNAME/STAGENAME’) 的条件仅适用于 YAML 管道

示例:根据前一阶段的运行状态来运行某一阶段。

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 管道,但我们建议你使用手动审批,以便手动排序和控制执行顺序(如果这很重要)。

指定审批

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

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

添加手动触发器

手动触发的 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
    ...

当某个阶段不可跳过时,它会在运行阶段配置面板中显示一个已禁用的复选框。

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