Azure管道运行两个或多个独立管道

时间:2020-04-29 16:41:33

标签: azure-devops azure-pipelines

是否可以在Azure DevOps中创建一个管道,该管道仅运行两个或多个独立管道(并行或串行),而没有其他作用?

我有一个包含五个独立微服务的应用程序,每个微服务都可以通过其单独的构建管道(YAML)分别构建和部署。但是,对于我们来说,将它们一起构建和部署通常很方便;例如,在将生成的人工制品标记为新版本的一部分时。我已经搜索了官方文档,但没有发现如何执行此操作。 Pipeline triggers 不要帮我,因为我需要使这些管道分离,因为它们经常单独运行。我需要的是这样的东西(一厢情愿的伪代码):

trigger: none
pr: none

stages:
- stage: Pipeline 1
  jobs:
  - job: Pipeline 1
    displayName: 'Pipeline 1'
    pool:
      vmImage: 'ubuntu-16.04'
    steps:
    // custom script to run Pipeline 1
    - script: dotnet run pipeline1
      displayName: 'Run Pipeline 1 through a script'
    // or, alternatively, an in-built task to do it
    - task: RunPipeline@4
      displayName: 'Run Pipeline 1 through a task'
      inputs:
        PipelineName: 'Pipeline 1'
        etc.: ...

- stage: Pipeline 2
  jobs:
  - job: Pipeline 2
  ...

或者它可以是单个阶段中的单独作业,甚至可以是单个作业中的单独步骤-没关系。我只想要一个总体的“主管道”,它只需按一下按钮即可触发所有单独的管道并构建所有服务。

3 个答案:

答案 0 :(得分:1)

Azure管道可运行两个或多个独立管道

要实现这一点,我们可以使用REST API Builds - Queue在主管道中将其他构建管道排队:

POST https://dev.azure.com/{organization}/{project}/_apis/build/builds?api-version=5.0

就像我测试的YAML文件一样:

pool:

  name: MyPrivateAgent


steps:

- task: PowerShell@2

  displayName: QueueBuildForPipelineA

  inputs:
    targetType : inline
    Script: |
     $body = '
     { 
             "definition": {
                 "id": DefinitionIdHere
             } 
     }'

     $bodyJson=$body | ConvertFrom-Json
     Write-Output $bodyJson
     $bodyString=$bodyJson | ConvertTo-Json -Depth 100
     Write-Output $bodyString
     $user="test"
     $token="PAT"
     $base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $user,$token)))

     $Uri = "https://dev.azure.com/YourOrganization/YourProjectName/_apis/build/builds?api-version=5.0"
     $buildresponse = Invoke-RestMethod -Method Post -UseDefaultCredentials -ContentType application/json -Uri $Uri -Body $bodyString -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)}

  condition: and(always(), eq(variables['TriggerPipelineA'], 'True'))


- task: PowerShell@2

  displayName: QueueBuildForPipelineB
  ...

此外,我还为任务condition: and(always(), eq(variables['TriggerPipelineA'], 'True'))添加了条件,然后在变量中定义了变量TriggerPipelineA我们可以通过以下方式自由触发哪些管道在队列管线期间将该变量的值覆盖为False

enter image description here

希望这会有所帮助。

答案 1 :(得分:1)

我最终使用Azure Pipeline Templates获得了想要的结果。这并不是我想要的,因为我首先必须重写每个要从模板运行的管道,方法是将阶段定义移动到单独的模板文件中,然后在调用管道中定义变量(现在是几乎是空的)。之后,我能够编写我的主管道来依次调用各个模板,并且它可以无缝地工作。他们连续地跑着(一个接一个)。也许有一种方法可以并行运行,但是我不需要,因为我不介意花费多长时间。

最重要的提示:适合尝试此操作的任何人:您可以在顶层(即在调用管道中)定义变量,这些变量将在模板文件中可用。模板文件在运行之前就被简单地装进了管道中,就像服务器端包含文件(或#include对于像我一样大的任何人)一样。仅在您的各个管道共享一个变量名时需要使用模板参数,而每个变量名都需要进行不同的设置(例如,“服务名”)。请注意,模板参数(${{}})是在管道运行之前求值的(类似于C中的#define常量),而变量($())的求值是运行;因此,如果您的一个或多个管道无法按预期运行,则可能需要将变量转换为模板参数。

答案 2 :(得分:0)

假设您的管道都在同一个项目中,并假设您使用的基于Windows的生成代理的服务运行在Windows帐户下,该帐户有权访问Azure DevOps中的项目(与LOCAL SYSTEM等相对) ),您可以将以下脚本作为构建任务运行,以触发其他构建,然后触发版本。

param(
    [string[]] $namesOfBuildsToTrigger,
    [string] $azDoUrl,
    [string] $projectCollection,
    [string] $project
)

Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop";

$azDoUrl = "$azDoUrl/$projectCollection/$project"
$buildsUrl = $azDoUrl + '/_apis/build/builds?api-version=2.0'
$buildDefsUrl = $azDoUrl + '/_apis/build/definitions?api-version=2.0'

foreach ($build in $namesOfBuildsToTrigger) {
    try {
        $buildDefinitions = (Invoke-RestMethod -Uri ($buildDefsUrl) -Method GET -UseDefaultCredentials).Value
        $buildDefinitions | Where-Object { $_.name -eq $nameOfBuildToStart } | ForEach-Object {
            $body = '{ "definition": { "id": '+ $_.id + '}, reason: "Manual", priority: "Normal" }' 

            Write-Host "Queueing $($_.name)" 

            # Trigger new build 
            $result = Invoke-RestMethod -Method Post -Uri $buildsUrl -ContentType 'application/json' -Body $body -Verbose -UseDefaultCredentials
            $result
        }
    }
    catch {
        $_ | Out-File "$PSScriptRoot\ErrorLog_$(get-date -f yyyy-MM-dd-ss).log"
    }
}