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!)