Azure DevOps YAML files have different output variables and conditions for different stages, jobs, and tasks.

Application of stage, job, task and condition in YAML

  • Introduction
  • Resource preparation
  • structural relationship
  • Code writing (task)
    • Define variables within task
    • task condition gets variable value
    • task code explanation
    • Test task code
  • Code writing (job)
    • job variable definition
    • Get job variable value
    • job condition
    • job code explanation
    • Test job code
  • Code writing (stage)
    • stage code display
    • Variable definitions
    • Get variable value
    • Code explanation
    • code testing

Content introduction

Some friends may be confused after reading the title, what on earth is this about? OK, now let’s give an overview.
In the DevOps YAML file, we have dependencies between some tasks, or between jobs, and between stages. For example, if I get an output variable of the previous job to be 0, we need to execute job1, but if the output variable value is 1. This is another result. We need to execute job2 and skip job1. The same goes for tasks and stages. What we are going to talk about today is how to implement this process.

Resource preparation

We need an Azure Devops account
A compilation machine (self host agent/agent machine provided by Microsoft)
An organization, an AzureRepos warehouse

Structural relationship

stage -> job -> step -> task
stage: The largest, also called stage, we can understand it as compilation stage, testing stage and deployment stage.
job: Job, each stage may require many jobs to complete the tasks of this stage.
step: steps. Each job may require many steps to complete the job.
task: Task, in fact, it is not necessarily a task, but also script, bash… these are all tasks

Code writing (task)

First let’s do the tasks. In fact, the compiler will execute each step of the task in the order in which you write the tasks in YAML. We log in to the Azure DevOps portal.
Then we click pipelines -> create pipelines to start creating our first pipeline.

Then we select the first Azure Repos Git

Then we can select a warehouse, and then we can click directly to start using the pipeline

In this way, we can write the content ourselves:
What we came up with is as follows
Trigger conditions, agent pool
Here I am using the one provided by Microsoft. These can be left as default.

Then we paste the following code onto our own Yaml.

# Starter pipeline
# Start with a minimal pipeline that you can customize to build and deploy your code.
# Add steps that build, run tests, deploy, and more:
# https://aka.ms/yaml

trigger:
- main

pool:
  vmImage: ubuntu-latest
 
jobs:
- job:
  steps:
  -powershell:
      echo "##vso[task.setvariable variable=taskvar;isOutput=true]task test"
    name: varls

  - script: echo okokok
    condition: eq(variables['varls.taskvar'],'task')
    displayName: dev

  - script: |
      echo $(varls.taskvar)
    condition: eq(variables['varls.taskvar'],'task test')
    displayName: test
  
  

One of the main things to pay attention to here is defining output parameters and obtaining output variables.
Because in the same job, tasks are executed sequentially and can be obtained directly. If they are not in the same job, you need to use (depend on).

Define variables within task

- powershell:
      echo "##vso[task.setvariable variable=taskvar;isOutput=true]task test"

The variable name is taskvar, and the variable value is “task test”
The most important of these are the parameters:
isOutput=true
This proves that this variable is an output variable.
task.setvariable variable This is the fixed format for task definition variables.

task condition gets variable value

I didn’t find this acquisition variable on the official website, but based on my understanding, I can write it out and acquire the task variables in the same job.
variables[varls.taskvar’]
where variables are all fixed variables.
Then we get and use

task name. variable name

to get the variable value.
condition eq(variable value, target value)

task code explanation

-powershell:
      echo "##vso[task.setvariable variable=taskvar;isOutput=true]task test"
    name: varls

An output variable named taskvar is defined with the value: ‘task test’
The task name is varls

================================================== =====

-script: echo okokok
    condition: eq(variables['varls.taskvar'],'task')
    displayName: dev

First print okokok and see if it can be entered into this task.
The condition then takes the variable value and compares it to task’.
task test is not equal to task
Therefore, this task will not be performed
Similarly, the task name is dev

================================================== =====

-script: |
      echo $(varls.taskvar)
    condition: eq(variables['varls.taskvar'],'task test')
    displayName: test

Same as above.
According to what we said, he should skip dev and run the test task directly.

Test task code

Then let’s try running:

We can click on test:

ok, no problem.

Code writing (job)

In fact, the difference between jobs and tasks is that there is no direct dependency between different jobs. We need to use depend on to connect them.
code show as below:

jobs:
# Set an output variable from job A
- job: A
  pool:
    vmImage: 'windows-latest'
  steps:
  - powershell: echo "##vso[task.setvariable variable=myOutputVar;isOutput=true]job test"
    name: setvarStep
  - script: echo $(setvarStep.myOutputVar)
    name: echovar
    

# Map the variable into job B

- job: B
  dependsOn: A
  pool:
    vmImage: 'ubuntu-latest'
  variables:
    myVarFromJobA: $[ dependencies.A.outputs['setvarStep.myOutputVar'] ] # map in the variable # remember, expressions require single quotes
  condition: eq(variables.myVarFromJobA,'job test')
  steps:
    - script: echo $(myVarFromJobA)
      name: printfVar
    

    
  
- job: lisong
  dependsOn: A
  pool:
    vmImage: 'ubuntu-latest'
  variables:
    var : $[ dependencies.A.outputs['setvarStep.myOutputVar']]
  condition: ne(variables.var,'job test')
  steps:
    - script: echo $(var)
      name: PrintFVar
  

job variable definition

 steps:
  - powershell: echo "##vso[task.setvariable variable=myOutputVar;isOutput=true]job test"
    name: setvarStep

It is the same as the above except changing the soup but not the dressing.

Job variable value acquisition

 dependsOn: A
  pool:
    vmImage: 'ubuntu-latest'
  variables:
    var : $[ dependencies.A.outputs['setvarStep.myOutputVar']]
  condition: ne(variables.var,'job test')
  steps:
    - script: echo $(var)
      name: PrintFVar

1. We have also said before that dependsOn: job name is needed when obtaining the value.
We need to tell him the name of the job you depend on. The name of the job we define the variable is called ‘A’
Hence this place:
dependsOn:A
2. We can define a variable to receive the obtained value:
variable: (This is a fixed format, which means you need to define parameters)
Variable name: variable value
The format in which we get the value:

$[ dependencies.job name.outputs['task name.variable name']]

job condition

The method of using condition is the same, but to get the variable value we can use the variable value we received: variables.var

job code explanation

Job A sets a variable named myOutputVar with the value: job test’,
job B compares the output variable value equal to ‘job test’
job lisong compares the output variable value not equal to job test’
In the end, only job A and job B should be run.
Let’s look at the following results

Test job code


Let’s click on the job inside

No problem, as expected.

Code writing (stage)

Generally speaking, the principle of stage is the same as that of job, because they have no dependencies, and we need to establish them.

stage code display

# Starter pipeline
# Start with a minimal pipeline that you can customize to build and deploy your code.
# Add steps that build, run tests, deploy, and more:
# https://aka.ms/yaml

trigger:
- main

pool:
  vmImage: ubuntu-latest


stages: stages
- stage: ready
  jobs:
  - job: var
    steps:
    - bash: echo "##vso[task.setvariable variable=myOutputVar;isOutput=true]stagetest"
      name: setVar
  


- stage: afterA
  dependsOn:
  - ready
  variables:
    varls : $[ stageDependencies.ready.var.outputs['setVar.myOutputVar']]
  
  jobs:
  -job:ls
  condition: eq(variables.varls,'stage')
    steps:
    - script: |
        echo $(varls)
        echo aaaa
      name: printfafyerA

- stage: afterB
  dependsOn:
  - ready
  variables:
    varsl: $[ stageDependencies.ready.var.outputs['setVar.myOutputVar']]
  
  jobs:
  - job: sl
  condition: ne(variables.varsl,'stage')
    steps:
    - script: |
        echo $(varsl)
        echo bbb
      name: printfafyerB

Variable definition

stages:
- stage: ready
  jobs:
  - job: var
    steps:
    - bash: echo "##vso[task.setvariable variable=myOutputVar;isOutput=true]stagetest"
      name: setVar

The name of this stage is ready’
Then the parameter definition is the same as above.

Variable value acquisition

- stage: afterA
  dependsOn:
  - ready
  variables:
    varls : $[ stageDependencies.ready.var.outputs['setVar.myOutputVar']]
  
  jobs:
  -job:ls
  condition: eq(variables.varls,'stage')
    steps:
    - script: |
        echo $(varls)
        echo aaaa
      name: printfafyerA

In fact, they are all the same. We need to first
dependsOn: stage name
Or you can write:
dependsOn:

  • stage name
    Then you need to define a parameter to accept the obtained value
varls: $[ stageDependencies.stage name.job name.outputs['task name.variable name']]

Code explanation

The condition in stage afterB is ‘ne’ instead of ‘eq’. ne is not equal to, and eq is equal to.
Logically speaking, our pipeline should run stage ready and stage afterB.

Code testing


We click on the job and task in afterB

OK, perfectly handmade.
(Note: If the format reference is incorrect, or the parameters are incorrect, sometimes no error will be reported, but the variable value cannot be obtained!)