Skip to content

CI Host Azure DevOps

Scott Singleton edited this page May 10, 2026 · 1 revision

CI Host: Azure DevOps

AzureDevOpsHost resolves automatically when TF_BUILD=True (the canonical Azure DevOps Pipelines marker). Inherits the common CiHost surface (CI Host Integrations) and adds ADO-specific properties and commands.

Detection

if (CiHost is AzureDevOpsHost ado)
{
    // ADO Pipelines specifics
}

Read-only properties

Property Env var
BuildId BUILD_BUILDID
BuildNumber BUILD_BUILDNUMBER
DefinitionName BUILD_DEFINITIONNAME
Reason BUILD_REASON (Manual / IndividualCI / BatchedCI / Schedule / PullRequest)
RepositoryName BUILD_REPOSITORY_NAME
RepositoryUri BUILD_REPOSITORY_URI
SourceBranch BUILD_SOURCEBRANCH
SourceBranchName BUILD_SOURCEBRANCHNAME
SourceVersion BUILD_SOURCEVERSION (commit SHA)
SourcesDirectory BUILD_SOURCESDIRECTORY
ArtifactStagingDirectory BUILD_ARTIFACTSTAGINGDIRECTORY
AgentName AGENT_NAME
AgentOs AGENT_OS
CollectionUri SYSTEM_TEAMFOUNDATIONCOLLECTIONURI
TeamProject SYSTEM_TEAMPROJECT
PullRequestId SYSTEM_PULLREQUEST_PULLREQUESTID
PullRequestTargetBranch SYSTEM_PULLREQUEST_TARGETBRANCH

Derived helper:

ado.IsPullRequest    // true when SYSTEM_PULLREQUEST_PULLREQUESTID is non-empty

Emit commands

ado.OpenGroup("Build");              // ##[group]Build
ado.CloseGroup();                    // ##[endgroup]
ado.LogWarning("careful");           // ##vso[task.logissue type=warning]careful
ado.LogError("oops");                // ##vso[task.logissue type=error]oops
ado.SetVariable("MyVar", "value");   // ##vso[task.setvariable variable=MyVar]value

LogError marks the run with the issue (visible in the build summary). Multiple errors aggregate.

ADO-specific extras

ado.SetSecretVariable("Token", value);   // marked as secret; ADO redacts in logs
ado.UpdateBuildNumber("1.2.3-rc.1");     // overrides the auto-assigned build number
ado.UploadArtifact("/path/to/file");     // attaches as an artifact on the run

SetSecretVariable adds ;issecret=true to the task.setvariable command. Subsequent steps that reference $(Token) will receive the value, but it's redacted from logs by ADO itself.

Recipes

Override the build number from git

Target ResolveBuildNumber => _ => _.Executes(() =>
{
    var bn = $"1.0.0-{Git.Branch}-{Git.Commit[..7]}";
    if (CiHost is AzureDevOpsHost ado) ado.UpdateBuildNumber(bn);
    BuildNumber = bn;
});

Upload artifacts after pack

Target UploadArtifacts => _ => _
    .DependsOn(nameof(Pack))
    .Executes(() =>
    {
        if (CiHost is not AzureDevOpsHost ado) return;
        Artifacts.GlobFiles("*.nupkg").ForEach(f => ado.UploadArtifact(f.Value));
    });

(For first-class artifact upload that also works in non-ADO contexts, prefer the actions/upload-artifact-equivalent in the pipeline YAML; this command is the inline fallback.)

Pass a typed secret to a downstream step

Target ProvisionToken => _ => _.Executes(() =>
{
    var token = ResolveTokenFromKeyVault();    // returns a Secret
    if (CiHost is AzureDevOpsHost ado)
        ado.SetSecretVariable("DownstreamToken", token.Reveal());
});

Secret.Reveal is internal-only — the wrapper for that secret type, not the build script, makes the call. In a real script you'd use a wrapper that takes a Secret and emits the right commands; for now SetSecretVariable takes a string for parity with the underlying ADO command.

See also

Clone this wiki locally