通过 REST 从 Azure Devops 构建中获取使用的管道工件 API

Get consumed pipeline artifacts from Azure Devops build via REST API

对于发布管道,我想通过 REST API(或任务)从构建工件中获取 consumed 管道工件。

背景: 我在 azure devops 中有一个发布管道,它使用一个主要工件,即设置。该安装程序在特定版本中打包了多个二进制文件。在发布管道中,我想找到适合安装程序中打包的二进制文件的系统测试。这些系统测试与二进制文件一起作为工件发布。

我有以下管道,一个接一个被触发:

  1. BinaryPipeline -> 发布工件:“二进制文件”“系统测试”
  2. SetupPipeline -> 使用来自 BinaryPipeline 的工件 "binaries",发布工件:"setup",
  3. 发布管道 -> 从设置管道消耗工件“设置”,消耗“系统测试” 来自 BinaryPipeline

问题: 发布管道应该使用来自用于构建设置的相同构建(BinaryPipeline)的工件“系统测试”。

我试图用 REST API 解决问题,但是

https://dev.azure.com/<company>/<project>/_apis/build/builds/<buildid>/artifacts

returns只有生产的工件,没有消耗的工件。

我看到了以下解决方法,但我仍然不喜欢它们:

  1. 发布包含版本信息的文本文件 -> 最佳解决方法。我不喜欢我必须依赖工件中的特殊文件。
  2. 设置构建属性(虽然我没有找到如何在构建过程中设置属性) -> 没搞清楚
  3. 在我的安装版本中重新发布系统测试 -> 复制工件的错误做法
  4. 解析日志 -> 不好,因为我必须依赖任务的标题名称

如何在 Azure Devops 中通过 REST API 从构建中获取 consumed 管道工件?

当您使用 DownloadBuildArtifacts 任务下载工件时,您可以指定要下载的构建版本:

根据我的请求从 Visual Studio 社区获得(私人)帮助后 Trigger release with defined artifacts 事实证明,没有内置且舒适的方式来获取消耗的工件。解决方案 4)(见上文)是 VSCommunity 的一项提议。

我现在正在生产的解决方案: 在发布版本 (SetupPipeline) 上:

  1. 创建 BuildInfo.XML 文件,其中包含有关已使用构建的信息

    [xml]$Doc = New-Object System.Xml.XmlDocument
    $dec = $Doc.CreateXmlDeclaration("1.0","UTF-8",$null)
    $doc.AppendChild($dec)
    $root = $doc.CreateNode("element","ConsumedBuilds",$null)
    $build = $doc.CreateNode("element", "Build", $null)
    $build.SetAttribute("BuildVersion", "$(RESOURCES.PIPELINE.build.RUNNAME)")
    $build.SetAttribute("BuildId", "$(RESOURCES.PIPELINE.build.RUNID)")
    $root.AppendChild($build)
    $Doc.AppendChild($root)
    $doc.Save("$BuildInfoXml")
    
  2. 将 BuildInfo.XML 发布为单独的工件(以便您可以单独下载)

关于发布管道:

  • 用BuildInfo.xml

    下载神器
  • 在 powershell 中解析 XML

    $ovf = New-Object System.XML.XMLDocument
    $ovf.Load("$($BuildInfoXmlPath.FullName)")
    $build= $ovf.ConsumedBuilds.Build | Where { ... }
    
  • 通过 REST 和 powershell 下载工件版本(因为下载管道工件任务无法参数化)

    $artifactUri = ("https://dev.azure.com/{organization}/{0}/_apis/build/builds/{1}/artifacts?artifactName={2}&api-version=4.1" -f $azureProjectName, $buildId, $artifactName)
    $artifact = Invoke-RestMethod -Uri "$artifactUri"  -Method get -Headers $AzureDevOpsAuthenicationHeader -ContentType 'application/zip' 
    $downloadUrl = "$($artifact.resource.downloadUrl)"
    $wc = New-Object System.Net.WebClient
    $wc.Headers.Add('Authorization','Basic ' + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$($accessToken)")) )
    $file = $wc.DownloadFile("$downloadUrl", $outputFile)
    

由于后者不是很透明,因为下载的工件没有显示为在发布管道中使用(它是由 powershell 脚本下载的):

  • 创建一个由 SetupPipeline 触发的触发器管道,稍等片刻,然后使用来自 XML 的工件在 ReleasePipeline 中对新版本进行排队。注意:您不能从未成功和(完全)完成的构建中触发发布管道。

这里是一些用于触发发布管道的 powershell 代码:

  $AzureDevOpsAuthenicationHeader = @{Authorization = 'Basic ' + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$($accessToken)")) }
  $createReleaseBody = 
  @"
  {
      "definitionId": $(ReleasePipelineDefinitionId),
      "description": "...",
      "artifacts": [
      {
            "alias": "buildName",
            "instanceReference": {
            "id": "$($build.BuildId)",
            "name": "$($build.BuildVersion)"
            }
        },
      {
         ...
      }
      ],
     "isDraft": false,
     "reason": "none",
     "manualEnvironments": null
  }
  "@
  Invoke-RestMethod -Uri "https://vsrm.dev.azure.com/{org}/{project}/_apis/release/releases?api-version=5.0" -Method post -Headers $AzureDevOpsAuthenicationHeader -Body $createReleaseBody -ContentType 'application/json'