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属性。 如果省

我有一个带有多个代理的Azure DevOps多级管道。一般来说,我的阶段包括:

  • 构建和发布工件
  • 部署到环境1
  • UI测试环境1
  • 部署到环境2
  • UI测试环境2
等等,适用于多种环境。如何允许同时运行管道(例如,为Build#2构建和发布工件,同时为Build#1构建和发布UI测试环境2),同时确保没有两个代理会同时为给定环境执行UI测试


似乎接近我想要的,但我认为这不允许在管道级别而不是阶段级别进行并发。

将任务放入不同的
作业中,并为需要等待特定作业完成的作业指定
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测试阶段的第一个任务,并另外确保没有其他构建在同一阶段运行,从而使此解决方案处于阶段级别。如果您使用自托管代理,您可以根据需要尝试它。我相信添加脚本来检查以前的版本是最好的解决方法。如果这个答案有帮助,你会接受它作为答案吗?因此,它可以帮助其他社区成员谁得到同样的问题,我们可以存档此线程。谢谢祝你今天愉快。:)伙计,我不知道独占锁,那正是我需要的,谢谢!