【问题标题】:How do I get Build ID of an In progress Pipeline in Azure DevOps如何在 Azure DevOps 中获取正在进行的管道的构建 ID
【发布时间】:2021-04-12 11:42:20
【问题描述】:

我通过 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"

即使第一个任务触发的构建管道完成,第二个也会继续等待

我的管道输出

【问题讨论】:

    标签: azure-devops azure-pipelines azure-devops-rest-api


    【解决方案1】:

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

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

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

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

    $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"
    

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

        $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}
    

    测试结果:

    更新:

    【讨论】:

    • 嗨@Leo Liu-MSFT,我试过两种情况都遇到同样的问题,我没有得到构建ID
    • 嗨@Leo Liu-MSFT,我已经尝试过这两种情况都有相同的问题,我没有得到构建ID,这是一个空行-用我的输出更新了我的问题。
    • 嗨@Leo Liu-MSFT 值 $LatestBuldId = $BuildPipelineInfo.value.id 什么也没打印,我的主要问题是这个我尝试了很多方法来获取构建 ID,但没有运气
    • 嗨 @Leo Lou-MSFT 还想检查是否 100% 确定没有获得构建 ID - 您示例的 url 中的定义 = 173 是否代表构建定义 ID?如果是这样,我只是得到一个空行而不是构建 ID
    • @saikumarreddy,在 url &`$top 中有一个`。请将我的脚本复制到内联 powershell,并替换组织名称、项目名称和构建定义 ID。 173 是定义 ID。并用您的 PAT 值定义变量 PAT。如果您仍然无法使用方法,请在您的问题中分享您的脚本并获取个人信息。
    【解决方案2】:

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

    然后在脚本中使用它来定义构建 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"
    

    然后使用构建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>"
    
    $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"
    

    【讨论】:

    • 嗨 @Shamrai Aleksander,仍然无法获取构建 ID
    • @saikumarreddy 只需使用 PowerShell(第一个任务)排队一个新的构建,而你ll get the build ID: $buildId = $resultQueue.Id`
    • 嗨@Shamrai Aleksander - 我能够调试问题并发现如果我引用存储在变量组中的身份验证令牌构建不会被触发,所以我没有得到构建ID。我创建了一个新令牌并尝试了仍然相同。但是,如果我在内联脚本中添加令牌,它可以工作,我可以看到构建 ID 并且管道正在等待完成
    【解决方案3】:

    一种方式

    当你打电话给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"
    

    【讨论】:

    • 我在日志中看不到任何内容,这是一个空行。让我试试这个
    • 嗨@shamrai Aleksander 我已经尝试过你的解决方案,即使触发的管道完成,任务也会一直等待
    • @saikumarreddy 它适用于我的组织。此外,您应该添加notStarted 状态以检查未启动的构建。您可以取消注释 $resultStatus.value 以查看您在请求结果中看到的构建。
    • 第一个任务触发的流水线完成后这个脚本是否退出?然后转到第三个任务?
    • @saikumarreddy 你可以在一个或单独的任务中使用它。我已经更新了我的示例,以便在一个版本中用于两个单独的任务。
    猜你喜欢
    • 1970-01-01
    • 2021-01-21
    • 1970-01-01
    • 1970-01-01
    • 2020-08-29
    • 2022-11-02
    • 1970-01-01
    • 2022-11-24
    • 1970-01-01
    相关资源
    最近更新 更多