Azure Devops Pipeline Build Parameters - azure

The code below is an API call that will run an azure pipeline but the only problem I am having is I am unable to run it on custom branches and I have tried az commands but with az commands, you can't pass though parameters. My goal is basically I have a pipeline A and I want to run Pipeline B which isn't mind so I can't edit it but Pipeline B takes in a parameter called Tag and I want to pass that though from Pineline A but struggling to do so.
$token = -join("$Username", ":", "$PAT")
$headers = #{
Authorization = "Basic "+ [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($token))
'Content-Type' = "application/json"
}
$uri = "https://dev.azure.com/{$Company}/{$Team}/_apis/pipelines/{$ProjectID}/runs/?api-version=6.0-preview.1"
$pipelineBody=#{
resources=#{
repositories=#{
self=#{
ref="$Branch"
}
}
}
templateParameters=#{
Tag="$Tag"
}
} | ConvertTo-Json
$result = Invoke-WebRequest -Uri $uri `
-Headers $headers `
-Body "$pipelineBody" `
-Method Post `
#-SkipCertificateCheck `
#-SkipHttpErrorCheck `
#-ErrorAction Stop
if($result.StatusCode -ne "200")
{
throw $result
}
return ($result.Content | ConvertFrom-Json).url

You can closely (not directly what you want) achieve this by following below steps:
Create single pipeline for Pipeline A (Stage 1) and Pipeline B(Stage 2).
Add a dependency of Pipeline A(Stage 1) on Pipeline B(Stage 2) that it runs only when Pipeline A succeeds.
Use Powershell script in Stage 1 to set a pipeline variable to a value you trying to set for Stage 2 - using out variable in Powershell script task of ADO.
Consume the pipeline variable set above in the desired step (of Pipeline B).

Related

Failing Azure DevOps build pipeline if the build has any warning

Hi There I have been asked to modify all current CI yml pipelines to fail if the C# API or WEB app has any warning, also it needs to be in its own stage in the process.
I have been looking on the net and can't find any code please can someone help with the code needed
thanks
There are two options for your reference.
1.You could add a PowerShell task in the stage, and then run the Rest API: Timeline - Get to traverse the warning messages in the previous task. And use logging commands to control the results.
PowerShell script:
$token = "PAT"
$url="https://dev.azure.com/{OrgName}/{ProjName}/_apis/build/builds/$(build.buildid)/timeline?api-version=5.0"
$token = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($token)"))
$count = 0
$response = Invoke-RestMethod -Uri $url -Headers #{Authorization = "Basic $token"} -Method Get -ContentType application/json
ForEach( $issues in $response.records.issues )
{
if($issues.type -eq "warning")
{
echo $issues.Message
$count ++
}
}
echo $count
if($count -ne 0 )
{
Write-Host "##vso[task.complete result=Failed;]"
}
Pipeline Output:
2.Using Extension task: Build Quality Checks is another option.
Add this task to your target stage to check the warnings.

How can I query for the yaml filepath for all pipelines in our dev azure project?

I want to list all the yaml files in use in any devops pipeline. I can do:
az pipelines show --project ProjectName --query '{pipeline:name,repo:repository.name,yml:process.yamlFilename}' --output table --name PipelineName
and get the right result:
Pipeline Repo Yml
------------- ------------- ---------------------------------------
PipelineName RepoName path/to/azure-pipeline.yaml
but if I list instead of show -- I want all of them, not one at a time -- list doesn't return the same level of detail. It doesn't give me repository and process data, so I can't list the repo name or the yaml path.
How can I get repo name and yaml path for all my pipelines?
To get repo name and yaml path for all your pipeline, you could use REST API to list all your pipeline, and get each pipeline details, then, according to result to get repository. Finally, generate a file with pipeline name, repository name and path. Here is the PowerShell script for the whole process. Please replace with your own PAT, organization name, project name and the path you want to store the file. Here set the path=null for classic pipeline.
$PAT ="<PAT>"
$base64AuthInfo= [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($PAT)"))
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Authorization", "Basic $base64AuthInfo")
$response = Invoke-RestMethod "https://dev.azure.com/<orgName>/<ProjectName>/_apis/pipelines?api-version=6.0-preview.1" -Method 'GET' -Headers $headers
$response | ConvertTo-Json
foreach ($value in $response.value)
{
$mid=$value.id
$url = "https://dev.azure.com/<orgName>/<ProjectName>/_apis/pipelines/"+$mid+"?api-version=7.1-preview.1"
$pipeline = Invoke-RestMethod $url -Method 'GET' -Headers $headers
$pipeline | ConvertTo-Json
$pipelinename = $pipeline.name
if ($pipeline.configuration.path)
{
$path=$pipeline.configuration.path
$repositoryid=$pipeline.configuration.repository.id
$url = "https://dev.azure.com/<orgName>/<ProjectName>/_apis/git/repositories/"+$repositoryid+"?api-version=6.0"
$repositorydetails = Invoke-RestMethod $url -Method 'GET' -Headers $headers
$repositorydetails | ConvertTo-Json
$repositoryName=$repositorydetails.name
}
else
{
$path="null"
$repositoryname=$pipeline.configuration.designerJson.repository.name
}
Write-Output "$pipelinename, $repositoryName, $path" >> C:\workspace1\new1\test.txt
}

Output variables in Azure DevOps release pipeline gates

How do I use output variables in Azure DevOps release pipeline gates?
I would like to output a variable equal to the value of something in the response of the HTTP request.
e.g. The http request will return { success: true, userId: 12345 }. I would like to set a variable for userId which I can use in the next HTTP request gate.
As of this time, however, outputting variables in Invoke REST API in gates is not supported.
The output variables section cannot output the custom defined variables, but only the variables defined by the task.
Unfortunately, this task does not define an output variable. You can see it in the screenshot:
There are no output variables associated with this task.
Maybe this isn't what you are looking for, but you can use Azure Powershell to invoke HTTP Request and output the value of response that way to a pipeline variable for use in subsequent steps.
Refer to this Stack Overflow Post: How to access the response of the InvokeRestAPI task from another job in an Azure DevOps pipeline?
$url = "https://vsrm.dev.azure.com/thecodemanual/$env:SYSTEM_TEAMPROJECTID/_apis/Release/definitions/$($env:RELEASE_DEFINITIONID)?api-version=5.0"
$pipeline = Invoke-RestMethod -Uri $url -Headers #{Authorization = "Bearer
$env:SYSTEM_ACCESSTOKEN"}
Write-Host "Pipeline = $($pipeline | ConvertTo-Json -Depth 100)"
$buildNumber = $env:BUILD_BUILDNUMBER
$pipeline.variables.ReleaseVersion.value = $buildNumber
####****************** update the modified object **************************
$json = #($pipeline) | ConvertTo-Json -Depth 99
$updatedef = Invoke-RestMethod -Uri $url -Method Put -Body $json -ContentType "application/json" -Headers #{Authorization = "Bearer $env:SYSTEM_ACCESSTOKEN"}

How to trigger a build from another build pipeline in azure devops

I have two build pipeline for two different projects.One is for building the actual project and another build pipeline for test automation. I want to automatically trigger the build pipeline of test automation once the actual project build succeed.
does there any possible way can i add one more task down to the actual build to trigger the test automation build, or suggest a possible way for the same.
Answers are much appreciable!!
You can use the "Build Completion" trigger in your second pipeline:
Additionally, you can add PowerShell script to queue another build from the parent build. Example:
$user = ""
$token = $env:SYSTEM_ACCESSTOKEN
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $user,$token)))
$orgUrl = "$env:SYSTEM_COLLECTIONURI"
$teamProject = "$env:SYSTEM_TEAMPROJECT"
$buildBodyTemplate = "{`"definition`": {`"id`": <build_id>}}"
$restApiQueueBuild = "$orgUrl/$teamProject/_apis/build/builds?api-version=6.0"
function InvokePostRequest ($PostUrl, $body)
{
return Invoke-RestMethod -Uri $PostUrl -Method Post -ContentType "application/json" -Headers #{Authorization=("Basic {0}" -f $base64AuthInfo)} -Body $body
}
function RunBuild($buildId)
{
$buildBody = $buildBodyTemplate.Replace("<build_id>", $buildId)
Write-Host $buildBody
$buildresponse = InvokePostRequest $restApiQueueBuild $buildBody
Write-Host $buildresponse
}
RunBuild SECOND_BUILD_ID
Update SECOND_BUILD_ID to ID of your build definition with tests. Additionally, add access to the security token in the parent build:

Trigger Azure DevOps pipeline from another pipeline

I was looking at the azure triggers documentation and still not able to find an appropriate solution.
How during the execution of pipeline 1 can you trigger pipeline 2, wait for it to successfully finish or fail, and based on pipeline 2 results either continue execution of pipeline 1 or fail?
How during the execution of pipeline 1 can you trigger pipeline 2, wait for it to successfully finish or fail, and based on pipeline 2 results either continue execution of pipeline 1 or fail?
Trigger one pipeline after another, it will run your pipeline upon the successful completion of the triggering pipeline. We cannot use it to trigger pipeline 1 in the execution of pipeline 1.
As a workaround:
a. We can add task power shell and add script to call the REST API to queue the build.
$connectionToken="PAT"
$base64AuthInfo= [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($connectionToken)"))
$PipelineUrl = "https://dev.azure.com/{Org name}/{project name}/_apis/pipelines/{Pipeline ID}/runs?api-version=6.0-preview.1"
$body ="{
`"resources`":{
`"repositories`":{
`"self`":{`"refName`":`"refs/heads/master`"
}
}
}
}"
$Pipelines = Invoke-RestMethod -Uri $PipelineUrl -ContentType "application/json" -Body $body -Headers #{Authorization=("Basic {0}" -f $base64AuthInfo)} -Method POST
b. Add task power shell and enter the code Start-Sleep -Seconds 1000 to sleep the pipeline 1
c. Add the task power shell in the pipeline 1 to get the pipeline 2 build result via the REST API, and set the result as env variable.
d. Configure the condition in the next task to check the env variable value. If the value is succeeded, continue run the pipeline 1
You are probably looking for something like this.
# this is being defined in app-ci pipeline
resources:
pipelines:
- pipeline: securitylib # Name of the pipeline resource
source: security-lib-ci # Name of the pipeline referenced by the pipeline resource
trigger:
branches:
- releases/*
- master
its right there in the link, you have linked, but in the sibling section of the docs. I am surprised you missed it.
https://learn.microsoft.com/en-us/azure/devops/pipelines/process/pipeline-triggers?view=azure-devops&tabs=yaml
So here is my solution based on the suggestion above:
- task: PowerShell#2
displayName: Running second pipeline
inputs:
targetType: 'inline'
script: |
Write-Host "Triggering pipeline..."
$connectionToken= "$(PAT)"
$base64AuthInfo= [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($connectionToken)"))
$PipelineUrl = "https://dev.azure.com/YourOrganization/yourProject/_apis/pipelines/${{ parameters.pipelineId }}/runs?api-version=6.0-preview.1"
Write-Host "Pipeline url: $PipelineUrl"
$body ="{
`"resources`":{
`"repositories`":{
`"self`":{`"refName`":`"refs/heads/${{ parameters.branch }}`"
}
}
}
}"
$response = Invoke-RestMethod -Uri $PipelineUrl -ContentType "application/json" -Body $body -Headers #{Authorization=("Basic {0}" -f $base64AuthInfo)} -Method POST
Write-Host "Response: $response"
$BuildUrl = "https://dev.azure.com/YourOrganization/yourProject/_apis/build/builds/$($response.Id)?api-version=6.1-preview.6"
Write-Host $BuildUrl
$TimeoutAfter = New-TimeSpan -Minutes 15
$WaitBetweenPolling = New-TimeSpan -Seconds 10
$Timeout = (Get-Date).Add($TimeoutAfter)
do
{
$Response = Invoke-RestMethod -Uri $BuildUrl -ContentType "application/json" -Headers #{Authorization=("Basic {0}" -f $base64AuthInfo)}
Write-Host $Response.status
Start-Sleep -Seconds $WaitBetweenPolling.Seconds
}
while ((($Response.status -eq "notStarted") -or ($Response.status -eq "inProgress")) -and ((Get-Date) -lt $Timeout))
if ($Response.result -ne "succeeded")
{
Write-Host $Response.result
exit 1
}
parameter for pipeline id: pipelineId: $(resources.pipeline.resource.pipelineId)
If you're ok with using extensions, the Trigger Build Task you can get in the marketplace should support all of your requirements.
It lets you trigger another pipeline, with an option to wait for it, and options about how to treat failures of that pipeline if you do wait. So you can use that to trigger a build, wait for it, and succeed / fail based on if the build succeeds / fails.

Resources