Skip to content

Latest commit

 

History

History
416 lines (278 loc) · 13.9 KB

File metadata and controls

416 lines (278 loc) · 13.9 KB
title description ms.assetid ms.topic ms.date monikerRange
Stages in Azure Pipelines
Learn how to organize your jobs into stages, define dependencies, and set conditions. Understand how to implement deployment strategies and use YAML or a Classic pipeline to define stages.
FAAD6503-F8CE-4F5D-8C1E-83AF6E903568
conceptual
02/16/2024
<= azure-devops

Add stages, dependencies, & conditions

[!INCLUDE version-lt-eq-azure-devops]

A stage is a logical boundary in an Azure DevOps pipeline. Stages can be used to group actions in your software development process (for example, build the app, run tests, deploy to preproduction). Each stage contains one or more jobs.

When you define multiple stages in a pipeline, by default, they run one after the other. Stages can also depend on each other. You can use the dependsOn keyword to define dependencies. Stages also can run based on the result of a previous stage with conditions.

To learn how stages work with parallel jobs and licensing, see Configure and pay for parallel jobs.

To find out how stages relate to other parts of a pipeline such as jobs, see Key pipelines concepts.

You can also learn more about how stages relate to parts of a pipeline in the YAML schema stages article.

::: moniker range=">=azure-devops-2019"

You can organize pipeline jobs into stages. Stages are the major divisions in a pipeline: build this app, run these tests, and deploy to preproduction are good examples of stages. They're logical boundaries in your pipeline where you can pause the pipeline and perform various checks.

Every pipeline has at least one stage even if you don't explicitly define it. You can also arrange stages into a dependency graph so that one stage runs before another one. There's a limit of 256 jobs for a stage.

::: moniker-end

::: moniker range="azure-devops-2019"

Note

Support for stages was added in Azure DevOps Server 2019.1.

::: moniker-end

Organize the deployment jobs in your release pipeline into stages. Stages are the major divisions in your release pipeline: run functional tests, deploy to preproduction, and deploy to production are good examples of release stages.

A stage in a release pipeline consists of jobs and tasks.

Approvals and gates, deployment conditions and triggers, and queuing policies control when a release gets deployed to a stage.

stage


Specify stages

::: moniker range="azure-devops-2019"

Note

Support for stages was added in Azure DevOps Server 2019.1.

::: moniker-end

::: moniker range=">=azure-devops-2019"

In the simplest case, you don't need any logical boundaries in your pipeline. In that case, you don't have to explicitly use the stage keyword. You can directly specify the jobs in your YAML file.

# 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"

If you organize your pipeline into multiple stages, you use the stages keyword.

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

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

If you choose to specify a pool at the stage level, then all jobs defined in that stage use that pool unless specified at the job-level.

::: moniker-end

::: moniker range="azure-devops-2019"

Note

In Azure DevOps Server 2019, pools can only be specified at job level.

::: moniker-end

::: moniker range=">=azure-devops-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

The full syntax to specify a stage is:

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]

::: moniker-end

To add a stage to your release pipeline, select the release pipeline in Releases page, select the action to Edit it, and then select the Pipeline tab. While the most important part of defining a stage is the automation tasks, you can also configure several properties and options for a stage in a release pipeline. You can:

  • Edit the name of the stage here if necessary.
  • Designate one user or a group to be the stage owner. Stage owners get notified whenever a deployment to that stage fails. Being a stage owner doesn't automatically come with any permissions.
  • Delete the stage from the pipeline.
  • Change the order of stages.
  • Save a copy of the stage as a stage template.
  • Manage the security settings for the stage.

Defining options and policies


Specify dependencies

::: moniker range="azure-devops-2019"

Note

Support for stages was added in Azure DevOps Server 2019.1.

::: moniker-end

::: moniker range=">=azure-devops-2019"

When you define multiple stages in a pipeline, by default, they run sequentially in the order in which you define them in the YAML file. The exception to this is when you add dependencies. With dependencies, stages run in the order of the dependsOn requirements.

Pipelines must contain at least one stage with no dependencies.

The syntax for defining multiple stages and their dependencies is:

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

Example stages that run sequentially:

# 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:
    ...

Example stages that run in parallel:

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:
    ...

Example of fan-out and fan-in:

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

::: moniker-end

You control the dependencies by setting the triggers on each stage of the release pipeline:

  • Stages run with a trigger or by being manually started.
  • With an After release trigger, a stage starts as soon as the release starts, in parallel with other stages that have After release trigger.
  • With an After stage trigger, a stage will start after all the dependent stages complete. Using this, you can model fan-out and fan-in behavior for stages.

Define conditions

You can specify the conditions under which each stage runs with expressions. By default, a stage runs if it doesn't depend on any other stage, or if all of the stages that it depends on have completed and succeeded. You can customize this behavior by forcing a stage to run even if a previous stage fails or by specifying a custom condition.

If you customize the default condition of the preceding steps for a stage, you remove the conditions for completion and success. So, if you use a custom condition, it's common to use and(succeeded(),custom_condition) to check whether the preceding stage ran successfully. Otherwise, the stage runs regardless of the outcome of the preceding stage.

Note

Conditions for failed ('JOBNAME/STAGENAME') and succeeded ('JOBNAME/STAGENAME') as shown in the following example work only for YAML pipelines.

::: moniker range="azure-devops-2019"

Note

Support for stages was added in Azure DevOps Server 2019.1.

::: moniker-end

::: moniker range=">=azure-devops-2019"

Example to run a stage based upon the status of running a previous stage:

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')

Example of using a custom condition:

stages:
- stage: A

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

::: moniker-end

When you specify After release or After stage triggers, you can also specify the branch filters for the artifacts consumed in the release. Releases will only deploy to a stage when the branch filters are satisfied.


Specify queuing policies

::: moniker range=">= azure-devops-2019" YAML pipelines don't support queuing policies. Each run of a pipeline is independent from and unaware of other runs. In other words, your two successive commits may trigger two pipelines, and both of them will execute the same sequence of stages without waiting for each other. While we work to bring queuing policies to YAML pipelines, we recommend that you use manual approvals in order to manually sequence and control the order the execution if this is of importance. ::: moniker-end

In some cases, you may be able to generate builds faster than they can be deployed. Alternatively, you may configure multiple agents and, for example, be creating releases from the same release pipeline for deployment of different artifacts. In such cases, it's useful to be able to control how multiple releases are queued into a stage. Queuing policies give you that control.

Defining queuing policies

The options you can choose for a queuing policy are:

  • Number of parallel deployments: Use this option if you dynamically provision new resources in your stage and it's physically capable of handling the deployment of multiple releases in parallel, but you want to limit the number of parallel deployments.

  • If you specify a maximum number of deployments, two more options appear:

    • Deploy all in sequence: Use this option if you want to deploy all the releases sequentially into the same shared physical resources. By deploying the builds in turn, one after the other, you ensure that two deployment jobs don't target the same physical resources concurrently, even if there are multiple build and release agents available. You also ensure that predeployment approval requests for the stage are sent out in sequence.

    • Deploy latest and cancel the others: Use this option if you're producing builds faster than releases, and you only want to deploy the latest build.

To understand how these options work, consider a scenario where releases R1, R2, ..., R5 of a single release pipeline get created in quick succession. Assume that the first stage in this pipeline is named QA and has both predeployment and post-deployment approvers defined.

  • If you don't specify a limit for the number of parallel deployments, all five approval requests are sent out as soon as the releases are created. If the approvers approve all of the releases, they'll all be deployed to the QA stage in parallel. (if the QA stage didn't have any predeployment approvers defined, all the five releases will automatically be deployed in parallel to this stage).

  • If you specify a limit and Deploy all in sequence, and the limit has already been reached, the predeployment approval for release R1 will be sent out first. After this approval is completed, the deployment of release R1 to the QA stage begins. Next, a request for post-deployment approval is sent out for release R1. It's only after this post-deployment approval is completed that execution of release R2 begins and its predeployment approval is sent out. The process continues like this for all of the releases in turn.

  • If you specify a limit and Deploy latest and cancel the others, and the limit has already been reached, releases R2, R3, and R4 will be skipped, and the predeployment approval for R5 in the QA stage will be sent out immediately after the post-deployment approval for release R1 is completed.


Specify approvals

::: moniker range="> azure-devops-2019"

You can manually control when a stage should run using approval checks. This is commonly used to control deployments to production environments. Checks are a mechanism available to the resource owner to control if and when a stage in a pipeline can consume a resource. As an owner of a resource, such as an environment, you can define checks that must be satisfied before a stage consuming that resource can start.

Currently, manual approval checks are supported on environments. For more information, see Approvals.

::: moniker-end

::: moniker range="= azure-devops-2019"

Approvals aren't yet supported in YAML pipelines in this version of Azure DevOps Server.

::: moniker-end

You can add manual approvals at the start or end of each stage in the pipeline. For more information, see Release approvals and gates overview.