如何在 Azure DevOps 中获取进行中管道的构建 ID

How do I get Build ID of an In progress Pipeline in Azure DevOps

我通过 API 调用从发布管道触发构建管道作为 第一个任务,并且没有任何问题。

第二个任务 - 流水线需要等待直到第一个任务触发的流水线完成,然后转到第三个任务。我如何实现它?

我在下面的 powershell 任务中尝试从 运行 管道获取构建 ID 并尝试通过循环等待,但无法获取构建 ID

触发构建管道的第一个任务

curl -L -X POST 'https://dev.azure.com/Org/project/_apis/build/builds?definitionId-1549&api-version=6.1-preview.6' -H 'Authorization: $(ADO_BASIC_AUTH)' -H 'Content-Type: application/json' --data '{"definition": {"id": 1549}}'

您建议的第二个任务

   $B64Pat = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes(":$(ADO_BASIC_AUTH)"))

$header = @{ Authorization = "Basic $B64Pat" }


$continueCurrent = $true
$uriGetActiveBuilds1 = "https://dev.azure.com/org/project/_apis/build/builds?definitions=1549&statusFilter=inProgress,notStarted&api-version=5.1"
    
do
{
    $continueCurrent = $true

    $resultStatus = Invoke-RestMethod -Uri $uriGetActiveBuilds1 -Method Get -ContentType "application/json" -Headers $header
    

    if ($resultStatus.count -gt 0)
    {
        $continueCurrent = $false
        Write-Host " . "
        Start-Sleep -s 10
    }

}while($continueCurrent -eq $false)

Write-Host "Continue task"

即使从第一个任务触发的构建管道已完成,第二个仍在等待

我的流水线的输出

单向

调用 Write-Host $result.latestBuild.id 时会看到什么?

另一种方式

您可以添加状态过滤器 = inProgress

小例子:

第一个任务。 运行 构建:

$user = ""
$token = "<pat>"

$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $user,$token)))

$orgUrl = "https://dev.azure.com/<org>"
$teamProject = "<team_project>"
$buildDefId = <build_definition_id>

$body = '{"definition":{"id":<dev_id>}}' -replace "<dev_id>", $buildDefId

$continueCurrent = $true
$uriRunBuild = "$orgUrl/$teamProject/_apis/build/builds?api-version=5.1"

    
$resultQueue = Invoke-RestMethod -Uri $uriRunBuild -Method Post -ContentType "application/json" -Body $body -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)}

Write-Host "Build Id" $resultQueue.Id

第二个任务。等待构建一些构建定义

$user = ""
$token = "<pat>"

$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $user,$token)))

$orgUrl = "https://dev.azure.com/<org>"
$teamProject = "<project>"
$buildDefId = <build_definition_id>

$continueCurrent = $true
$uriGetActiveBuilds = "$orgUrl/$teamProject/_apis/build/builds?definitions=$buildDefId&statusFilter=inProgress,notStarted&api-version=5.1"

    
do
{
    $continueCurrent = $true

    $resultStatus = Invoke-RestMethod -Uri $uriGetActiveBuilds -Method Get -ContentType "application/json" -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)}

    #$resultStatus.value

    if ($resultStatus.count -gt 0)
    {
        $continueCurrent = $false
        Write-Host " . "
        Start-Sleep -s 2
    }

}while($continueCurrent -eq $false)

Write-Host "Continue task"

您可以使用其他方式。向您的版本添加一个新变量:

然后在脚本中使用它来定义构建 ID 并仅获取排队构建的状态。

运行 构建并传递构建 ID:

$user = ""
$token = "<pat>"

$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $user,$token)))

$orgUrl = "https://dev.azure.com/<org>"
$teamProject = "<team_project>"
$buildDefId = <build_definition_id>

$body = '{"definition":{"id":<dev_id>}}' -replace "<dev_id>", $buildDefId

$uriRunBuild = "$orgUrl/$teamProject/_apis/build/builds?api-version=5.1"

    
$resultQueue = Invoke-RestMethod -Uri $uriRunBuild -Method Post -ContentType "application/json" -Body $body -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)}

$buildId = $resultQueue.Id

Write-Host "Build Id: $buildId"
Write-Host "##vso[task.setvariable variable=Custom.BuildId]$buildId"

然后使用build id获取build状态:

$user = ""
$token = "<pat>"

$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $user,$token)))

$orgUrl = "https://dev.azure.com/<org>"
$teamProject = "<team_project>"

$uriGetBuild = "$orgUrl/$teamProject/_apis/build/builds/$(Custom.BuildId)?api-version=5.1"

$uriGetBuild

$buildStatus = ""
    
do
{
    $buildResult = Invoke-RestMethod -Uri $uriGetBuild -Method Get -ContentType "application/json" -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)}

    $buildStatus = $buildResult.status

    if ($buildStatus -ne "completed")
    {
        Write-Host " . "
        Start-Sleep -s 2
    }

}while($buildStatus -ne "completed")

Write-Host "Continue task"

How do I get Build ID of an In progress Pipeline in Azure DevOps

解决这个请求的思路可以是:

  1. 添加任务获取之前构建流水线的最新构建id 发布管道的第一个任务(触发构建管道)
  2. 然后在第二个任务中再次获取构建流水线的最新Id 执行第一个任务后。
  3. 如果和上一个一样,说明build 管道尚未 运行。等待 30 秒。
  4. 如果ID不同,说明新触发的build 管道已启动 运行。我们只需要判断是否 最新管道状态已完成

REST API 脚本在您的第一个任务之前获取最新的构建 ID:

$connectionToken="$(PAT)"
$base64AuthInfo= [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($connectionToken)"))

$BuildPipelineUrl = "https://dev.azure.com/<YourOrganization>/<YourProject>/_apis/build/builds?definitions=173&`$top=1&api-version=6.0" 

Write-Host "URL: $BuildPipelineUrl"

$BuildPipelineInfo = (Invoke-RestMethod -Uri $BuildPipelineUrl -Method Get -UseDefaultCredential -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)}) 


$LatestBuldId = $BuildPipelineInfo.value.id

Write-Host "LatestBuldId = $LatestBuldId"

Write-Host "##vso[task.setvariable variable=OldBuldPipelineId]$LatestBuldId"

REST API 脚本获取最新构建 ID 并在您的第二个任务后检查构建状态:

    $connectionToken = "$(PAT)"
    $base64AuthInfo= [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($connectionToken)"))
    $success = $false
    $count = 0
do{
    try{
    $Secondurl = "https://dev.azure.com/<YourOrganization>/<YourProject>/_apis/build/builds?definitions=173&`$top=1&api-version=6.0"
    $NewBuildPipelineInfo = Invoke-RestMethod -Method Get -ContentType application/json -Uri $Secondurl -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)}
  
    $NewBuildPipelineId = $NewBuildPipelineInfo.value.id

    $NewBuildPipelinestatus = $NewBuildPipelineInfo.value.status

    write-output $NewBuildPipelineId | ConvertTo-Json -Depth 100

    write-output $NewBuildPipelinestatus | ConvertTo-Json -Depth 100

    
 
       if($NewBuildPipelineId -eq '$(OldBuldPipelineId)') {           
            Write-output "Wait for new piepine trigger in 30 seconds"
            Start-sleep -Seconds 30         
      } else {           
            Write-Host "New Pipeline was triggered"
            if($NewBuildPipelinestatus -ne '"completed"') {
            Write-output "wait forpipeline complete,Next attempt in 30 seconds"
            Start-sleep -Seconds 30
            }
            else{
            write-output "Pipeline complete"
            $success = $true     
            }     
      }


    }
    catch{
        Write-output "catch - Next attempt in 30 seconds"
        write-output "1"
        Start-sleep -Seconds 30
    }
   
    $count++
   
}until($count -eq 2000 -or $success)
if(-not($success)){exit}

测试结果:

更新: