Edit

Share via


Task types and usage

Azure DevOps Services | Azure DevOps Server 2022 | Azure DevOps Server 2020

Azure Pipelines jobs consist of steps, which can be tasks or scripts. A task is a prepackaged script or procedure that performs an action or uses a set of inputs to define pipeline automation. This article describes pipeline tasks and how to use them. For schema information, see the steps.task definition.

Azure Pipelines includes many built-in tasks that enable fundamental build and deployment scenarios. For a list of available built-in Azure Pipelines tasks, see the Azure Pipelines task reference. You can also install tasks from the Visual Studio Marketplace or create custom tasks.

By default, all steps in a job run in sequence in the same context, whether on the host or in a job container. You can optionally use step targets to control context for individual tasks. To run some tasks in parallel on multiple agents, or without using an agent, see Specify jobs in your pipeline.

Task management

Tasks are available and installed at the Azure DevOps organization level. You can only use tasks and task versions that exist for your organization.

You can disable built-in tasks, Marketplace tasks, or both in Organization Settings > Pipelines > Settings under Task restrictions. If you disable both built-in and Marketplace tasks, only tasks you install by using the Node CLI for Azure DevOps are available.

Disabling Marketplace tasks can help improve pipeline security. Under most circumstances, you shouldn't disable built-in tasks. For more information, see Control available tasks.

Custom tasks

The Visual Studio Marketplace offers many extensions you can install to extend the Azure Pipelines task catalog. You can also create custom tasks. For more information, see Add a custom pipelines task extension.

In YAML pipelines, you refer to tasks by name. If your custom task name matches a built-in task name, the pipeline uses the built-in task. To avoid this situation, you can reference your custom task by using the unique task GUID you assigned when you created the task. For more information, see Understand task.json components.

Task versions

Tasks are versioned, and you must specify the major version of the tasks you use in your pipeline. Specifying the version helps prevent issues when new versions of a task are released.

Pipelines automatically update to use new minor task versions, such as 1.2 to 1.3. Minor task versions are typically backwards compatible, but in some scenarios you might encounter unpredictable errors when a task automatically updates.

If a new major task version such as 2.0 releases, your pipeline continues to use the major version you specified until you edit the pipeline to manually change to the new major version. Build logs provide alerts when new major versions are available. You can only use task versions that exist for your organization.

In YAML, you specify the major version by using @ in the task name. For example, to use version 2 of the PublishTestResults task, specify PublishTestResults@2. You can specify which minor version to use by providing the full task version number after the @, such as GoTool@0.3.1.

Task options

The following properties are available for YAML pipeline task steps. For more information, see the steps.task definition.

Property Type Description
task string Required as first property. Name of the task to run.
inputs string Inputs for the task, using name/value pairs.
condition string Conditions under which the task runs.
continueOnError boolean Whether to continue running even on failure.
displayName string Human-readable name for the task.
enabled boolean Whether to run this task when the job runs.
env string Variables to map into the process environment, using name/value pairs.
name string ID of the step.
retryCountOnTaskFailure string Number of retries if the task fails.
target string Environment to run this task in.
timeoutInMinutes string The maximum time the task can run before being automatically canceled.

Conditions

A task can't determine whether to continue the pipeline job after the task finishes, only provide an ending status such as succeeded or failed. Downstream tasks and jobs can then set a condition based on that status to determine whether to run.

The conditions property specifies conditions under which this task runs. By default, a step runs if nothing in its job failed yet and the step immediately preceding it completed.

You can override or customize these defaults by setting the step to run even if or only if a previous dependency fails or has another outcome. You can also define custom conditions, which are composed of expressions.

Note

Conditions apply to all previous direct and indirect dependencies with the same agent pool. Stages or jobs in different agent pools run concurrently.

Conditions based on previous dependency status include:

  • Succeeded: Run only if all previous dependencies succeed. This behavior is the default if no condition is set in the YAML. To apply this condition, specify condition: succeeded().
  • Succeeded or failed: Run even if a previous dependency fails, unless the run is canceled. To apply this condition, specify condition: succeededOrFailed().
  • Always: Run even if a previous dependency fails, even if the run is canceled. To apply this condition, specify condition: always().
  • Failed: Run only when a previous dependency fails. To apply this condition, specify condition: failed().

In the following YAML example, PublishTestResults@2 runs even if the previous step failed, because of its succeededOrFailed condition.

steps:
- task: UsePythonVersion@0
  inputs:
    versionSpec: '3.x'
    architecture: 'x64'
- task: PublishTestResults@2
  inputs:
    testResultsFiles: "**/TEST-*.xml"
  condition: succeededOrFailed()

Continue on error

The continueOnError property tells the task whether to continue running and report success regardless of failures. If set to true, this property tells the task to ignore a failed status and continue running. Downstream steps and jobs treat the task result as success when they make their run decisions.

Enabled

By default, the task runs whenever the job runs. You can set enabled to false to disable the task. Temporarily disabling the task is useful to remove the task from the process for testing purposes or for specific deployments.

Retry count on task failure

The retryCountOnTaskFailure property specifies the number of times to retry the task if it fails. The default is zero retries.

  • The maximum number of retries allowed is 10.
  • The wait time before retry increases after each failed attempt, following an exponential backoff strategy. The first retry happens after 1 second, the second retry after 4 seconds, and the tenth retry after 100 seconds.
  • Retrying the task doesn't provide idempotency. Side effects of the first try, such as partially creating an external resource, could cause retries to fail.
  • No information about the number of retries is made available to the task.
  • Task failure adds a warning to the task logs indicating that it failed before retrying the task.
  • All retry attempts show in the UI as part of the same task node.

Note

The retryCountOnTaskFailure property requires agent version 2.194.0 or later. On Azure DevOps Server 2022, retries aren't supported for agentless tasks. For more information, see Azure DevOps service update November 16, 2021 - Automatic retries for a task and Azure DevOps service update June 14, 2025 - Retries for server tasks.

Target

Tasks run in an execution context, which is either the agent host or a container. A task can override its context by specifying a target. Available options are host to target the agent host, and any containers defined in the pipeline. In the following example, SampleTask@1 runs on the host and AnotherTask@1 runs in a container.

resources:
  containers:
  - container: pycontainer
    image: python:3.11

steps:
- task: SampleTask@1
  target: host
- task: AnotherTask@1
  target: pycontainer

Timeout

The timeout period begins when the task starts running, and doesn't include the time the task is queued or is waiting for an agent.

Note

Pipelines may specify a job level timeout in addition to a task level timeout. If the job level timeout interval elapses before a task completes, the running job terminates, even if the task is configured with a longer timeout interval. For more information, see Timeouts.

Environment variables

You can use environment variables to map system or user-defined information into the task process.

A YAML pipeline task can specify an env property, which lists name/value strings that represent environment variables.

- task: AzureCLI@2
  env:
    ENV_VARIABLE_NAME: value
    ENV_VARIABLE_NAME2: value
  ...

You can set environment variables by using script steps, or by using scripts in command line, Bash, or PowerShell tasks.

The following example runs a script step that assigns a value to the ENV_VARIABLE_NAME environment variable and echoes the value.

- script: echo "This is " $ENV_VARIABLE_NAME
  env:
    ENV_VARIABLE_NAME: value
  displayName: 'echo environment variable'

The preceding script is functionally the same as running a Bash@3 task with a script input. The following example uses the task syntax.

- task: Bash@3
  inputs:
    script: echo "This is " $ENV_VARIABLE_NAME
  env:
    ENV_VARIABLE_NAME: value
  displayName: 'echo environment variable'

Build tool installer tasks

Build tool installer tasks enable your build pipeline to install and control dependencies. You can use build tool installer tasks to:

  • Install a tool or runtime for a build, including on Microsoft-hosted agents.
  • Validate your app or library against multiple versions of a dependency such as Node.js.

For a list of tool installer tasks, see Tool tasks.

Example: Test and validate an app on multiple versions of Node.js

The following example sets up a build pipeline to run and validate an app on multiple versions of Node.js.

Create an azure-pipelines.yml file that has the following contents in your project's base directory.

pool:
  vmImage: 'windows-latest'

jobs:
- job: NodeJS
  strategy:
    matrix:
      node14:
        nodeVersion: '14.x'
      node16:
        nodeVersion: '16.x'
    maxParallel: 2
  steps:
    - task: NodeTool@0
      displayName: 'Install Node.js $(nodeVersion)'
      inputs:
        versionSpec: '$(nodeVersion)'
        checkLatest: true

    - script: |
        echo Using Node version $(nodeVersion)
        node --version
      displayName: 'Verify Node Installation'

Save and run the pipeline. The job runs twice, one for each version of Node.js you specified in the nodeVersion variable.

The Node.js Tool Installer downloads the Node.js version if it isn't already on the agent. The Command Line script writes the installed version to the command line.

Help and support