Azure Pipelines definitions
The Azure Pipelines YAML the repository carries, read as Azure writes it: what starts a run, the stages and jobs it declares, the pool each job lands on and how long it may run, and every task a step reaches for with the version it asks for, alongside the macro, template and runtime expressions a script interpolates. Names and shapes only, never a secret, an input value or a variable value.
| Facts key | azure |
| Version | v1 |
| Script | azure.py |
| Timeout | 60 seconds |
Inputs
| Input | Description | Default | Environment |
|---|---|---|---|
pipelines | Comma separated globs matched against every file in the working directory and against bare file names, naming the pipeline definitions to read. Azure has no fixed location for them, so if your repository keeps them elsewhere, name them here. Anything matched that is not YAML is still left out. | azure-pipelines*.yml,azure-pipelines*.yaml | GUARDRAIL_INPUT_PIPELINES |
When a guardrail declares an input with the same name, it passes its value through. That means you set these values in the guardrail's configuration in buildnote.json.
A guardrail asks for these facts by name and reads them back by the same name:
{
"collect": ["azure"]
}azure = guardrail.facts("azure")Facts
These are the fields of the document azure collects. In a path, [] means each entry of the list before it, and [path] means a key of the object before it.
| Fact | Meaning |
|---|---|
source | report when a pipeline definition was read, none when there was none. |
reason | Why nothing was read, present only when source is none. |
reports | Every definition that was read, in path order. |
reports[].path | Path of the definition, relative to the directory the CLI runs in. |
reports[].modified | When it was last written, ISO 8601. |
reports[].format | Always azure. |
pipelines | The pipelines themselves, one entry per file that was read. |
pipelines[].path | Path of the file, relative to the directory the CLI runs in. |
pipelines[].name | The name the pipeline gives its runs, exactly as written, or null. |
pipelines[].triggers | Which of trigger, pr, schedules and resources the file declares. A file declaring none of them runs only when somebody starts it. |
pipelines[].variables | Names of the variables the pipeline declares, whether written as a mapping, as name entries, or as a group or template it pulls in. Names only, never values. |
pipelines[].stages | The stages the file declares, in the order it declares them. Empty for a pipeline written as jobs or steps alone. |
pipelines[].jobs | Every job in the file, whatever it is nested under: the jobs of each stage in order, then the top level jobs, and a pipeline written as bare steps as the one job it is. |
pipelines[].jobs[].id | The job or deployment key, or the stage's name for a stage that declares neither, or null. |
pipelines[].jobs[].displayName | Display name the job gives itself, or null. |
pipelines[].jobs[].stage | The stage the job sits in, or null for a job declared outside one. |
pipelines[].jobs[].pool | The pool the job asks for, exactly as written: a name, or a mapping naming a vmImage or an agent pool. |
pipelines[].jobs[].hostedImage | The vmImage the job asks for, or null when it names none. |
pipelines[].jobs[].selfHosted | false when the job names a vmImage, which is one of Microsoft's hosted agents, and null when it names a pool Azure does not say is hosted or names no pool at all. |
pipelines[].jobs[].timeoutInMinutes | The declared timeoutInMinutes, exactly as written, or null when the job declares none and takes the organisation's own limit. |
pipelines[].jobs[].environment | The environment a deployment job targets, exactly as written, or null. An environment is what carries an approval check. |
pipelines[].jobs[].dependsOn | Jobs this one waits for, by name. |
pipelines[].jobs[].condition | The raw condition guarding the job, or null. |
pipelines[].jobs[].template | The template this job comes from instead of declaring steps, exactly as written, or null. |
pipelines[].jobs[].steps | The steps the job declares, in order. |
pipelines[].jobs[].steps[].displayName | Display name of the step, or null. |
pipelines[].jobs[].steps[].task | The task the step runs, exactly as written with its version, or null for a step that only runs a script. |
pipelines[].jobs[].steps[].taskName | The part of task before the @, or null. |
pipelines[].jobs[].steps[].taskVersion | What follows the @ in task, which for an Azure task is a major version rather than a revision anybody can pin further, or null. |
pipelines[].jobs[].steps[].template | The template the step pulls in instead of running something itself, exactly as written, or null. |
pipelines[].jobs[].steps[].script | The script body the step runs, whether written as script, bash, pwsh or powershell, truncated to 2000 characters, or null. |
pipelines[].jobs[].steps[].shell | The shell keyword the body was written under, bash, pwsh or powershell, or null for a plain script step taking the agent's default. |
pipelines[].jobs[].steps[].inputKeys | Names of the inputs the step passes to the task. Names only, never values. |
pipelines[].jobs[].steps[].macros | Every $( ) macro appearing in the script body, read from the whole body before it was truncated. A macro is substituted into the script before it runs, which is the script injection surface. |
pipelines[].jobs[].steps[].templateExpressions | Every ${{ }} template expression appearing in the script body, which Azure resolves when the pipeline is compiled. |
pipelines[].jobs[].steps[].runtimeExpressions | Every $[ ] runtime expression appearing in the script body, which Azure resolves when the run starts. |
stages | Every stage declared across the files that were read. |
counts.pipelines | Files that were read. |
counts.jobs | Jobs across every file. |
counts.steps | Steps across every job. |
unparsed | Files that matched but were not read, because their YAML uses something outside the subset the collector can represent. A file listed here is not an empty file: nothing was read from it, so draw no verdict about it. |
unparsed[].path | Path of the file that was not read. |
unparsed[].reason | The construct that could not be represented, and the line it is on. |
If a collector can't finish, it prints what it gathered so far along with an incomplete key that says why. Facts after the point where it stopped are missing, so a check that depends on them should read incomplete first.
Example facts
Here are the facts the azure collector gathers from an example project:
{
"source": "report",
"reports": [
{
"path": "azure-pipelines.yml",
"modified": "2026-03-04T10:15:00Z",
"format": "azure"
}
],
"pipelines": [
{
"path": "azure-pipelines.yml",
"name": "build",
"triggers": [
"trigger",
"pr"
],
"variables": [
"gradleOptions"
],
"stages": [
"build"
],
"jobs": [
{
"id": "check",
"displayName": "Build and test",
"stage": "build",
"pool": {
"vmImage": "ubuntu-latest"
},
"hostedImage": "ubuntu-latest",
"selfHosted": false,
"timeoutInMinutes": 15,
"environment": null,
"dependsOn": [],
"condition": null,
"template": null,
"steps": [
{
"displayName": null,
"task": "JavaToolInstaller@0",
"taskName": "JavaToolInstaller",
"taskVersion": "0",
"template": null,
"script": null,
"shell": null,
"inputKeys": [
"versionSpec",
"jdkArchitectureOption",
"jdkSourceOption"
],
"macros": [],
"templateExpressions": [],
"runtimeExpressions": []
},
{
"displayName": "Build",
"task": null,
"taskName": null,
"taskVersion": null,
"template": null,
"script": "./gradlew check",
"shell": "bash",
"inputKeys": [],
"macros": [],
"templateExpressions": [],
"runtimeExpressions": []
}
]
}
]
}
],
"stages": [
"build"
],
"counts": {
"pipelines": 1,
"jobs": 1,
"steps": 2
},
"unparsed": []
}Collected for
| Guardrail | Category | Inputs |
|---|---|---|
azure/job-timeout-set | azure | pipelines |