首页 > 解决方案 > 从 Azure DevOps Pipeline 祖父 Pipeline 下载工件

问题描述

给定 3 个 Azure DevOps Pipelines(可能存在更多),如下所示:

  1. 构建、单元测试、发布工件
  2. 部署登台、集成测试
  3. 部署生产,冒烟测试

如何确保 Pipeline 3 下载 Pipeline 1 中发布的特定工件?

我看到的挑战是,DownloadPipelineArtifact@2如果工件来自前一个管道,则任务仅提供了一种方法来执行此操作。通过使用以下管道任务:

- task: DownloadPipelineArtifact@2
  inputs:
    buildType: 'specific'
    project: '$(System.TeamProjectId)'
    definition: 1
    specificBuildWithTriggering: true
    buildVersionToDownload: 'latest'
    artifactName: 'example.zip'

这适用于父母“触发管道”,但不适用于祖父母。相反,它返回错误消息:

找不到构建 nnn 的工件 example.zip。

其中 nnn 是直接前任的运行 ID,就好像我已经指定了pipelineId: $(Build.TriggeredBy.BuildId). 实际上,Pipeline 3 尝试从 Pipeline 2 中检索 Pipeline 1 工件。如果该行做了一些事情会很好,但是,唉,当设置definition: 1时它似乎什么都不做。specificBuildWithTriggering: true

请注意,这buildType: 'latest'是不安全的;如果在管道 2 运行时从管道 1 发出,它似乎允许发布未经测试的工件。

可能无法使用DownloadPipelineArtifact@2. 很难确定,因为文档没有太多细节。也许还有另一种合理的方式来实现这一点......我想在每个中间管道上发布工件的另一个副本,即使是那些不使用它的管道,是一种方式,但不是很合理。我们可以通过发布一个记录了 BuildId 的工件来消除创建二进制文件副本的丑陋方面,但我们仍然必须从每个管道中检索并重新发布它。

如果有一种方法可以识别原始 CI 触发器,例如找到启动 GIT 提交的哈希,我可以使用它来命名和引用工件。在触发的构建之间是否Build.SourceVersion保持不变?任何其他“启动 ID”都可以正常工作。

欢迎您对示例管道场景发表评论,因为我实际上正在使用它,但这不是我的问题的重点。我认为这个问题是广泛适用的,因为它将适用于构建依赖包时,或者出于“触发器”有用的任何其他原因。

标签: azure-devopsazure-pipelinesazure-artifacts

解决方案


一位MS 代表建议为此使用 REST 。例如:

HTTP GET https://dev.azure.com/ORGNAME/PROJECTGUID/_apis/build/Builds/2536

-

{
    "id": 2536,
    "definition": {
        "id": 17
    },
    "triggeredByBuild": {
        "id": 2535,
        "definition": {
            "id": 10
        }
    }
}

通过走父母,可以找到具有所需定义ID(例如10)的祖先。然后它的运行 ID(例如 2535)可用于下载工件。

@merlin-liang-msft 针对与@sschmeck 不同的要求提出了类似的流程,他们的答案附有代码。


推荐阅读