是否有可能在不知道总共有多少个阶段的情况下,在Azure管道中运行最后阶段? [英] Is it possible to run a "final stage" in Azure Pipelines without knowing how many stages there are in total?
问题描述
是否有办法让阶段作为最后一个阶段运行(不包括作业后/报告生成状态)?
问题是:我有一个元素数量未知的each-循环,每个元素都有自己的阶段。
因此,我们不能只在最后一个阶段使用";DependOn;,因为以前的每个阶段在运行时都有一个唯一的名称。
各阶段的顺序如下:
- 准备
2-n)使用特定的停靠容器构建/编译/测试
最后)移除所有容器
目前运行正常,但有一个小问题,即最后一个阶段将在n个阶段中的最后一个阶段结束后运行(在Suceededor Failed条件下完成) 问题是,当n个阶段中的最后一个阶段比所有其他阶段都快时。删除容器阶段是分开的,因为我们遇到了问题,当所有n个阶段同时尝试删除其容器时,停靠程序无法处理。
管道在YAML文件上运行
推荐答案
是否可以在不知道总共有多少个阶段的情况下在Azure管道中运行"最后阶段"?
答案是肯定的。
该解决方案的主要思想是:
在最后一个阶段(移除所有容器),在Remove all containers
之前添加一个Inline powershell
任务。此任务将调用REST APIDefinitions - Get来监视当前发布管道中的所有阶段是否都具有inprocess
和queue
状态。如果是,请等待30
秒,然后再次循环,直到当前发布流水线中的所有其他阶段没有inprocess
和queue
状态。然后将执行下一步删除所有容器任务。
脚本:
例如,我在Dev
阶段添加了Inline powershell
任务,脚本如下:
$connectionToken="$(Your PAT here)"
$base64AuthInfo= [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($connectionToken)"))
Start-sleep -Seconds 20 # In case this stage run as first stage.
$success = $false
$count = 0
do{
try{
$stageurl2 = "https://vsrm.dev.azure.com/{org name}/{project name}/_apis/release/deployments?definitionId={release definition ID}&deploymentStatus=inProgress&api-version=6.0"
$stageinfo2 = (Invoke-RestMethod -Uri $stageurl2 -Method Get -UseDefaultCredential -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)})
$stageInProgressNum= $stageinfo2.count
$stageurl3 = "https://vsrm.dev.azure.com/{org name}/{project name}/_apis/release/deployments?definitionId={release definition ID}&deploymentStatus=notDeployed&api-version=6.0"
$stageinfo3 = Invoke-RestMethod -Method Get -ContentType application/json -Uri $stageurl3 -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)}
$stageInQueuedNum = $stageinfo3.count
Write-Host "stage In Progress Num is = $stageInProgressNum"
Write-Host "stage In Queued Num is = $stageInQueuedNum"
if($stageInProgressNum -ne 1) { #The value set to 1 is because the ststus of curret stage is in inProgress when this powershell scripts is executed.
Write-output "There is/are $stageInProgressNum Deployment In Progress, Waiting for it to finish!"
Write-output "Next attempt in 30 seconds"
Start-sleep -Seconds 30
} else {
Write-Host "No Current Deployment in Progress"
if($stageInQueuedNum -ne 0) {
write-output "There is/are $stageInQueuedNum Queued deployments"
Write-output "Next attempt in 30 seconds"
Start-sleep -Seconds 30
}
else{
write-output "No Queued deployments, starting release"
$success = $true
}
}
}
catch{
Write-output "catch - Next attempt in 30 seconds"
write-output "1"
Start-sleep -Seconds 30
# Put the start-sleep in the catch statemtnt so we
# don't sleep if the condition is true and waste time
}
$count++
}until($count -eq 2000 -or $success)
if(-not($success)){exit}
测试结果:
Dev
将继续检查,直到所有其他阶段完成:
注意:您需要在最新阶段添加内联PowerShell任务,我将其添加在阶段中间是为了清楚地表明内联PowerShell任务将在其他阶段完成之前监视整个版本。
更新:
我尝试将其转换为构建管道,而不是发布 管道。但是,我找不到任何对状态的API引用 建造阶段。分期单据为空 Docs.microsoft.com/en-us/rest/api/azure/devops/build/…和邮递员 不想筛选生成区域中的定义
如果您想要将其用于构建管道,目前还没有文档记录的REST API来获取阶段状态。但我们可以在浏览器中按F12
,然后选择Network
来捕获请求以获取阶段结果。您可以从响应正文中捕获结果。但不同的阶段结果用不同的数字表示,即0-未开始、1-正在进行、2-已完成等:
https://dev.azure.com/<YourOrgName>/LeoTest/_build/results?buildId=6522&__rt=fps&__ver=2
现在,我们可以使用相同的思想来确定状态的值,以满足您的需求。我不会在这里重复分享代码,如果您有任何进一步的问题,请让我知道。
这篇关于是否有可能在不知道总共有多少个阶段的情况下,在Azure管道中运行最后阶段?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!