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
...
当某个阶段不可跳过时,它会在运行阶段配置面板中显示一个已禁用的复选框。