Azure devops 限制同步进程阶段
我有一个带有多个代理的Azure DevOps多级管道。一般来说,我的阶段包括:Azure devops 限制同步进程阶段,azure-devops,azure-pipelines,Azure Devops,Azure Pipelines,我有一个带有多个代理的Azure DevOps多级管道。一般来说,我的阶段包括: 构建和发布工件 部署到环境1 UI测试环境1 部署到环境2 UI测试环境2 等等,适用于多种环境。如何允许同时运行管道(例如,为Build#2构建和发布工件,同时为Build#1构建和发布UI测试环境2),同时确保没有两个代理会同时为给定环境执行UI测试 似乎接近我想要的,但我认为这不允许在管道级别而不是阶段级别进行并发。将任务放入不同的作业中,并为需要等待特定作业完成的作业指定dependsOn属性。 如果省
- 构建和发布工件
- 部署到环境1
- UI测试环境1
- 部署到环境2
- UI测试环境2
似乎接近我想要的,但我认为这不允许在管道级别而不是阶段级别进行并发。将任务放入不同的
作业中,并为需要等待特定作业完成的作业指定dependsOn
属性。
如果省略依赖项
,它将同步运行
在仔细阅读您的提示之后,我认为您只需要一个build
阶段来构建和发布您的工件
然后为每个环境部署一个测试阶段。阶段默认按顺序运行(与作业不同)如果有人运行发布管道两次,您需要它逐个运行,而不是并行运行,对吗
作为解决办法:
每个版本将从第1阶段开始。因此,我们可以添加一个PowerShell任务作为阶段1的第一个任务,以检查以前是否有正在进行的部署
在这个PowerShell任务中,我们可以调用它来检查发布阶段的状态
powershell脚本:
# Base64-encodes the Personal Access Token (PAT) appropriately
$token = "$(pat)"
$base64AuthInfo= [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($connectionToken)"))
$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 -Method Get -ContentType application/json -Uri $stageurl2 -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)}
$inprogressdeployments = $stageinfo2.value | where {($_.deploymentStatus -eq "inProgress") -and ($_.release.name -ne $ENV:RELEASE_RELEASENAME) -and ($_.releaseEnvironment.name -ne 'stop services')} | Sort-Object -Property completedOn -Descending
#write-output $inprogressdeployments
$stageurl3 = "https://vsrm.dev.azure.com/{org name}/{project name}/_apis/release/deployments?definitionId={release definition ID}&operationStatus=QueuedForAgent&api-version=6.0"
$stageinfo3 = Invoke-RestMethod -Method Get -ContentType application/json -Uri $stageurl3 -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)}
$queueddeployments = $stageinfo3.value
#write-output $queueddeployments
if($inprogressdeployments) {
Write-output "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($queueddeployments) {
write-output "Current Queued deployments"
Write-output "if 2 - 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}
结果:
阶段1将继续检查,直到所有以前的版本完成
我们也可以尝试,我们可以指定相同的要求。使用需求确保管道所需的功能存在于运行它的代理上。除非代理满足一个或多个要求,否则它不会运行。您的
UI测试环境1阶段(特别是运行测试的部署作业)应以
最环保的环境。
UI测试环境2阶段(特别是运行测试的部署作业)应以
env2uitest环境。
然后在这两个环境上设置独占锁()策略。
它应该满足您的需要:
“确保不会有两个代理同时对给定环境执行UI测试”
对不起,我可能问得不好,或者我不理解这个答案。它已经连续运行了一次,这正是我想要的。问题是当同时有多个运行时,例如,如果两个人在同一时间合并代码,从而触发两个运行,并且每个运行都由不同的代理处理,这样运行会并行进行。在这种情况下,触发器批处理是您的最佳选择。我认为这受到与触发器相同的限制:批处理,也就是说,它不允许在管道级别(而不是阶段级别)进行并发。但是,我认为我可以将与此代码非常相似的内容作为每个UI测试阶段的第一个任务,并另外确保没有其他构建在同一阶段运行,从而使此解决方案处于阶段级别。如果您使用自托管代理,您可以根据需要尝试它。我相信添加脚本来检查以前的版本是最好的解决方法。如果这个答案有帮助,你会接受它作为答案吗?因此,它可以帮助其他社区成员谁得到同样的问题,我们可以存档此线程。谢谢祝你今天愉快。:)伙计,我不知道独占锁,那正是我需要的,谢谢!