In this article

Build variables

12/13/2018

10 minutes to read

Contributors

In this article

Azure Pipelines | TFS 2018 | TFS 2017 | TFS 2015

Note

In Microsoft Team Foundation Server (TFS) 2018 and previous versions,
build and release pipelines are called definitions,
service connections are called service endpoints,
stages are called environments,
and jobs are called phases.

Variables give you a convenient way to get key bits of data into various parts of the pipeline.
As the name suggests, the contents of a variable may change from run to run or job to job of your pipeline.
Some variables are predefined by the system, and you are free to add your own as well.

Working with variables

Variables add a layer of indirection to your pipeline.
Almost any place where a pipeline requires a text string or a number, you can use a variable instead of hard-coding a value.
The system will replace the variable with its current value during the pipeline's execution.

Variable names consist of letters, numbers, ., and _ characters.
How you reference a variable depends on context.
The following table indicates how you can reference a variable called Build.DefinitionName in each context.

System-defined variables

Some variables are automatically inserted by the system.
As a pipeline author or end user, you cannot set the contents of such variables.
See the comprehensive lists of build variables and release variables to learn which ones are available.

System.AccessToken

Secret variables such as System.AccessToken have special behavior.
Secrets aren't available to scripts and tasks by default.
You must explicitly allow secret variables on a pipeline-by-pipeline basis.
This reduces the chances for a malicious script or task to steal the credentials they contain.

In YAML, you must explicitly map System.AccessToken into the pipeline using a
variable. You can do this at the step or task level:

steps:
- bash: echo This is a script that could use $SYSTEM_ACCESSTOKEN
env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
- powershell: Write-Host "This is a script that could use $env:SYSTEM_ACCESSTOKEN"
env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)

You can allow scripts and tasks to access System.AccessToken at the job level.

Navigate to the job

Under Additional options, check the Allow scripts to access the OAuth token box.

Checking this box also leaves the credential set in Git so that you can run
pushes and pulls in your scripts.

User-defined variables

Some build templates automatically create variables for you.
For example, when you create a new .NET app build, BuildConfiguration and BuildPlatform are automatically defined for you.
You are free to define additional variables in your pipelines.
Both of these are considered user-defined variables.

Counters

You can create a counter that is automatically incremented by one in each execution of your pipeline. You can optionally provide a seed value for the counter if you need to start at a specific number. The counter can be assigned to a variable and then referenced in task inputs or scripts as you would any other variable.

variables:
major: 2
minor: 1
# creates a counter called versioncounter and seeds it at 100 and then assigns the value to a variable named patch.
patch: $[counter('versioncounter', 100)]
# use the patch variable as part of your pipeline naming scheme
name: $(Date:yyyyMMdd).$(patch)
pool:
vmImage: 'ubuntu-16.04'
steps:
# use the variables as part of your versioning for your nuget package
- script: |
dotnet pack /p:PackageVersion=$(major).$(minor).$(patch)

Set a job-scoped variable from a script

To set a variable from a script, you use a command syntax and print to stdout.
This does not update the environment variables, but it does make the new
variable available to downstream steps within the same job.

Set an output (multi-job) variable

If you want to make a variable available to future jobs, you must mark it as
an output variable using isOutput=true. Then you can map it into future
jobs using $[] syntax and including the step name which set the variable.

Secret variables

Important: By default with GitHub repositories, secret variables associated with your build pipeline are not made available to pull request builds of forks. See Validate contributions from forks.

Secret variables are encrypted at rest with a 2048-bit RSA key.
They are automatically masked out of any log output from the pipeline.
Unlike a normal variable, they are not automatically decrypted into environment variables for scripts.
You can explicitly map them in, though:

Important: By default with GitHub repositories, secret variables associated with your build pipeline are not made available to pull request builds of forks. See Validate contributions from forks.

Secret variables are encrypted at rest with a 2048-bit RSA key.
They are automatically masked out of any log output from the pipeline.
Unlike a normal variable, they are not automatically decrypted into environment variables for scripts.
They are automatically decrypted for use as inputs to your build tasks.
You can also pass them explicitly into a script from your build task (for example as $(password)).

Allow at queue time

You can choose which variables are allowed to be set at queue time and which are fixed by the pipeline author.
If a variable appears in the variables block of a YAML file, it is fixed and cannot be overridden at queue time.
To allow a variable to be set at queue time, make sure it doesn't appear in the variables block of a pipeline or job.

You can choose which variables are allowed to be set at queue time and which are fixed by the pipeline author.
Continuing the .NET example from above, BuildConfiguration can be settable at queue time for CI builds.
This way, developers can choose whether to create Debug or Release builds depending on their needs.
However, on your official builds, BuildConfiguration should not be settable at queue time so that you don't accidentally ship Debug binaries.

Define and modify your variables in a script

To define or modify a variable from a script, use the task.setvariable logging command.
Note that the updated variable value is scoped to the job being executed, and does not flow across jobs or stages.
Variable names are transformed to uppercase, and the characters "." and " " are replaced by "_".

For example, Agent.WorkFolder becomes AGENT_WORKFOLDER.
On Windows, you access this as %AGENT_WORKFOLDER or $env:AGENT_WORKFOLDER.
On Linux and macOS, you use $AGENT_WORKFOLDER.

@echo off
set sauceArgument=%~1
set secretSauceArgument=%~2
@echo No problem reading %sauceArgument% or %SAUCE%
@echo But I cannot read %SECRET_SAUCE%
@echo But I can read %secretSauceArgument% (but the log is redacted so I do not spoil
the secret)

Param(
[string]$sauceArgument,
[string]$secretSauceArgument
)
Write-Host No problem reading $env:SAUCE or $sauceArgument
Write-Host But I cannot read $env:SECRET_SAUCE
Write-Host But I can read $secretSauceArgument "(but the log is redacted so I do not
spoil the secret)"