Is there any way we can get task name in the release pipeline to execute specific task based on an condition - azure-devops

I'm working on a release pipeline there are around 3 task in the 1 Agent. taskA,taskB,taskC
I want to run specific task based on specific task failed. I tried custom condition but it didn't satisfied my case.
I want task C to be execute when only task B is failed for that I'm using output variable as well. In this case its working only for taskB. When TaskA failed Task B will skip and output variable become null in that case my task C is execute which is not correct.
I'm trying to make a condition which fulfill both TaskA and TaskB condition.
if TaskA failed --> TaskC should not run
if TaskB failed --> TaskC should run.
Here is my condition:-> and(eq(Agent.JobStatus, 'failed'), in(variables['oneboxout.oneboxvar'],'False'))
Is there any way we can get task name only so my work would be easier.
Below are my task screenshot for your reference.

Is there any way we can get task name only so my work would be easier.
The answer is yes.
We could use the REST API Releases - Get Release to get the task name or status;
https://learn.microsoft.com/en-us/rest/api/azure/devops/release/releases/get%20release?view=azure-devops-rest-6.0
As the above REST API, we need provide the current release Id to that REST API. To resolve this, we could use the REST API Releases - List with Parameter definitionId={definitionId} and powershell parameter Select-Object -first 1 to get the current release Id.
To resolve this request, I would like use following method:
Summary:
Add powershell a task (Let's call it Get JobB task result)between JobB and JobC to invoke REST API
to get the result of the JobB with condition Even if a previous task has failed, unless the build was canceled.
Set a variable RunJobC with different value based on the result of the task JobB in above powershell task.
Set condition and(always(), eq(variables['RunJobC'], 'True')) for the JobC.
My test scripts (Check Allow scripts to access the OAuth token option in the Phase):
$url = "https://vsrm.dev.azure.com/M<YourOrganization>/<YourProject>/_apis/release/releases?definitionId=24&api-version=6.0"
$RealeasePipeline= Invoke-RestMethod -Uri $url -Headers #{
Authorization = "Bearer $env:SYSTEM_ACCESSTOKEN"
} -Method Get
$ReleaseId= $RealeasePipeline.value.id | Select-Object -first 1
Write-Host The current Release Id: $ReleaseId
$url2 = "https://vsrm.dev.azure.com/<YourOrganization>/<YourProject>/_apis/release/releases/$($ReleaseId)?api-version=6.0"
$ReleaseInfo= Invoke-RestMethod -Uri $url2 -Headers #{
Authorization = "Bearer $env:SYSTEM_ACCESSTOKEN"
} -Method Get
$TargetTask=$ReleaseInfo.environments.deploySteps.releaseDeployPhases.deploymentJobs.tasks| where { $_.Name -eq "JobB"}
Write-Host JobB task Result is: $TargetTask.status
if ($TargetTask.status -eq "succeeded"){
Write-Host ("##vso[task.setvariable variable=RunJobC]False")
}elseif($TargetTask.status -eq "Failed"){
Write-Host ("##vso[task.setvariable variable=RunJobC]True")
}
My test result:

Related

is there a way to prevent a scheduled pipeline to execute again when a first execution hasnt ended?

I have a pipeline that executes every hour and sometimes the execution takes more than an hour and the other execution starts, is there a way to prevent this? and for example the new execution to get queued?
thank you for all the help
It seems you have multiple build agents. Assuming you are using self-hosted build agents, you could specify certain demands of the agent to use only one agent. In this way, if the agent is not free, the build will keep waiting. To use a particular agent, add a demand of Agent.Name equals agentname, check the screenshot below. Agent name can be found in capabilities of the agent.
pool:
name: MyPool
demands:
- myCustomCapability # check for existence of capability
- agent.name -equals agentname # check for specific string in capability
Another way is triggering the pipeline via REST api and through the PowerShell task. You could use the REST API Builds - List to get the detailed build info and check the latest build status:
https://dev.azure.com/{organization}/{project}/_apis/build/builds?definitions={definitions}&api-version=6.0
In the YAML, we could add a powershell task to get the build status, like:
- task: PowerShell#2
inputs:
targetType : inline
script: |
$url = "https://dev.azure.com/{organization}/{project}/_apis/build/builds?definitions={definitionID}&api-version=6.0"
$connectionToken="Your PAT Here"
$base64AuthInfo= [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($connectionToken)"))
$buildPipeline= Invoke-RestMethod -Uri $url -Headers #{authorization = "Basic $base64AuthInfo"} -Method Get
$BuildStatus= $buildPipeline.value.status | Select-Object -first 1
Write-Host This is Build Status: $BuildStatus
This list all the build status for the specify definitions, then use Select-Object -first 1 to get the latest build status. If the status is completed, then queue the build. If the status is not completed, do not queue the build.

Skip a stage if the previous one has errors in Azure Pipeline Release

I've got a very simple Azure Pipeline Release, I just want to skip a stage if there are any errors in the previous one. I've already checked https://learn.microsoft.com/en-us/azure/devops/pipelines/process/conditions?view=azure-devops&tabs=classic
Setting the Test job to run "Only when all previous jobs have succeeded" doesn't help
My main goal is to skip the test stage whenever there's a particular condition in the previous one, and passing variables between stages doesn't seem to be possible, nor using the gates, so I've got to idea to deliberately raise an error in the stage. The stages run some PS scripts, and I can't make the whole stage fail from that either
Screen shot
The stages run some PS scripts, and I can't make the whole stage fail
from that either
Are you using PowerShell task or similar tasks? Try editing the task and enabling the Fail on Standard Error option:
After that task will fail if there's any error is written to the error pipeline. Also in pre-deployment conditions of your Test stage, make sure the trigger when ... checkbox is unchecked:
From what I understood you need sth like this feature. So as you see this is not supported out of the box.
You can use REST API to get state of running release and analyze response to verify it there is any issue with issueType = Error. Then in this script you need to call exit 1. This is not ideal, but it works.
$uri = "https://vsrm.dev.azure.com/thecodemanual/Devops manual/_apis/release/releases/$(Release.ReleaseId)?api-version=5.1"
Write-Host $(Release.ReleaseId)
Write-Host $uri
# Invoke the REST call
$result = Invoke-RestMethod -Uri $uri -Method Get -Headers #{Authorization = "Bearer $env:SYSTEM_ACCESSTOKEN"}
$errors = #()
$result.environments |
ForEach-Object { $_.deploySteps |
ForEach-Object { $_.releaseDeployPhases |
ForEach-Object { $_.deploymentJobs |
ForEach-Object { $_.tasks |
ForEach-Object { $errors += $_.issues | Where-Object { $_.issueType -eq "Error" } }}}}}
Write-Host $errors.Count
if($errors.Count -gt 0) {
Write-Host Error
exit 1
}
Without step above I got this:
And with this step this:

How to get notification in Azure in case total runtime is more for a new build

I have pipeline in Azure DevOps, in which Gatling loading test scenario executes every night. How can I get notification in Azure (and on e-mail also) in case total runtime in last time is more than in previous time (e.g. 31.03.2020 total runtime was 10 min, 01.04.2020 total runtime was 12 min - in this case i want to get notification)?
You can create a new build pipeline which only is triggered by the Build Completion of your test pipeline.
And add a script task to call Build rest api to this new pipeline to calculate the total runtime of the builds. And add a Send email task to send you email on the condition of duration time is greater than the previous build. The detailed steps is listed as below.
1, Setup a new pipeline and configure the Build Completion trigger
Go to Get sources --> Check Don't sync sources to skip checkout sources
Click Agent job--> Check Allow scripts to access the OAuth token to allow scripts to call rest api
Go to Triggers tab--> Build completion--> Click Add to select your test pipeline as Trigggering build
By setting up the Build completion Triggering build, this new pipeline will be triggered when your test pipeline is complete.
2, Add a script task to call Build rest api and calculate the duration time. And store the result to a variable. Check below powershell script:
$url = "$(System.TeamFoundationCollectionUri)$(System.TeamProject)/_apis/build/builds/$(Build.TriggeredBy.BuildId)?api-version=5.1"
echo $url
$result = Invoke-RestMethod -Uri $url -Headers #{authorization = "Bearer $env:SYSTEM_ACCESSTOKEN"} -ContentType "application/json" -Method get
# calculate the totaltime of the newest build
$time = [datetime]$result.finishTime - [datetime]$result.startTime
$thisBuild= $time.TotalMinutes
# get the last build
$lasturl = "$(System.TeamFoundationCollectionUri)$(System.TeamProject)/_apis/build/builds?definitions=$(Build.TriggeredBy.DefinitionId)&resultFilter=succeeded&`$top=2&api-version=5.1"
$lastResult =Invoke-RestMethod -Uri $lasturl -Headers #{authorization = "Bearer $env:SYSTEM_ACCESSTOKEN"} -ContentType "application/json" -Method get
#Caculate the totaltime of the last build
$lasttime = [datetime]$lastResult.value[1].finishTime - [datetime]$lastResult.value[1].startTime
$lastBuild = $lasttime.TotalMinutes
#Store the result to varialbe isLonger
if($thisBuild -ge $lastBuild ){ echo "##vso[task.setvariable variable=isLonger]True" }
3, Add Send email task to send out the email. And set a custom condtion to eq(variables.isLonger, 'True'). So that this task will only be executed when the total time is greater.
Hope above helps!

How to see Gatling html report in Azure DevOps and compare results

I have a simple pipeline, in which gatling load script executes:
My pipeline
After the script is completed, we see the script execution time:
Execution time
My first question is: how can I extract value of execution time and compare it with previous execution (my script executes every night), and if execution time in last time is more than in previous time, I want to get notification.
Also, after execution generates report: Report
And my next question is: how can I open the generated report directly in Azure (or at least send it by mail as an attachment to a standard notification from Azure)?
You can use Build timeline API to get the execution time of a specific task.
I add a few more lines of scripts to my previous answer. Please check below scripts.
I added script $result.records | where {$_.name -eq "MyTaskName"} to filter the task records by its name. Note: You need to define a unique Display name for your powershell task.
$url = "$(System.TeamFoundationCollectionUri)$(System.TeamProject)/_apis/build/builds/$(Build.TriggeredBy.BuildId)/timeline?api-version=5.1"
echo $url
$result = Invoke-RestMethod -Uri $url -Headers #{authorization = "Bearer $env:SYSTEM_ACCESSTOKEN"} -ContentType "application/json" -Method get
# filter the task's records by name
$taskResult = $result.records | where {$_.name -eq "MyTaskName"}
# calculate the totaltime of the newest build
$time = [datetime]$taskResult.finishTime - [datetime]$taskResult.startTime
$thisTaskTime= $time.TotalMinutes
# get the last build's Id
$lasturl = "$(System.TeamFoundationCollectionUri)$(System.TeamProject)/_apis/build/builds?definitions=$(Build.TriggeredBy.DefinitionId)&resultFilter=succeeded&`$top=2&api-version=5.1"
$buildResult =Invoke-RestMethod -Uri $lasturl -Headers #{authorization = "Bearer $env:SYSTEM_ACCESSTOKEN"} -ContentType "application/json" -Method get
#extract last buildId
$lastBuildId = $buildResult.value[1].id
#get the timeline of the last build
$timeUrl = "$(System.TeamFoundationCollectionUri)$(System.TeamProject)/_apis/build/builds/$($lastBuildId)/timeline?api-version=5.1"
$lastResult =Invoke-RestMethod -Uri $timeUrl -Headers #{authorization = "Bearer $env:SYSTEM_ACCESSTOKEN"} -ContentType "application/json" -Method get
#Caculate the totaltime of the last build task
# filter the task's records by name
$lastTaskResult = $lastResult.records | where {$_.name -eq "TaskName"}
$LastTime = [datetime]$lastTaskResult.finishTime - [datetime]$lastTaskResult.startTime
$lastTaskTime= $LastTime.TotalMinutes
#Store the result to varialbe isLonger
if($thisTaskTime -ge $lastTaskTime){ echo "##vso[task.setvariable variable=isLonger]True" }
If you want to use the azure default notification when the task execution time is greater then previous time. You can add another script task to the end of your pipeline to purposely fail your pipeline, if the time is greater. And then set up a build fails notification for your project.
if($(isLonger) -eq "True")
{
exit 1
}
For your second question, I am afraid you cannot view the report directly in azure devops.
You can use copy files task to copy out the generated report and use publish build artifacts task to upload the report to azure devops server, where you can download directly from your build history.
Copy Files task
Publish build artifact task
Then you can download the report file from the build UI.
Go to Builds under Pipelines--> Select your pipeline--> Click lastest build from the History
There are other ways to upload the report file to the build besides Publish build artifact task by using statement ##vso[task.addattachment]value, ##vso[task.uploadfile]local file path. For example run below statement in a script task to add the report file to the build.
##vso[task.addattachment type=myattachmenttype;name=myattachmentname;]$(System.DefaultWorkingDirectory)\reportTempFolder\index.html
Please check here for more information.

Get Build Status from Azure Pipeline using azure-pipeline.yaml file

How to configure azure-pipeline.yaml file in post build to get the build status? I have to get the current build status of the pipeline by using azure-devops-rest-api or azure-devops-node-api within the azure-pipeline.yaml file.
Please help!
How to configure azure-pipeline.yaml file in post build to get the build status?
We could use the REST API Builds - List to get the detailed build info:
https://dev.azure.com/{organization}/{project}/_apis/build/builds?definitions={definitions}&api-version=5.1
In the YAML, we could add a powershell task to get the build result, like:
- task: PowerShell#2
inputs:
targetType : inline
script: |
$url = "https://dev.azure.com/{organization}/{project}/_apis/build/builds?definitions={definitionID}&api-version=5.1"
$connectionToken="Your PAT Here"
$base64AuthInfo= [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($connectionToken)"))
$buildPipeline= Invoke-RestMethod -Uri $url -Headers #{authorization = "Basic $base64AuthInfo"} -Method Get
$BuildResult= $buildPipeline.value.result | Select-Object -first 1
Write-Host This is Build Result: $BuildResult
We list all the build result for the specify definitions, then use Select-Object -first 1 to get the latest build result.
As test, use the REST API, we could get the result of latest build for the current pipeline, but we could not get the results of the build we are performing this time.
Besides, there is a Predefined variables, which we could check the get the current build status of the pipeline by the Predefined variables Agent.JobStatus, so I add a command line task to output this value in YAML:
- script: |
echo $(Agent.JobStatus)
This variable could get the current build status.
Hope this helps.