Azure трубопровод для запуска двух или более независимых трубопроводов - PullRequest
0 голосов
/ 29 апреля 2020

Можно ли создать конвейер в Azure DevOps, который просто запускает два или более независимых конвейера (параллельно или последовательно) и больше ничего не делает?

У меня есть приложение, состоящее из пяти независимых микросервисов, каждое из которых может быть построено и развернуто отдельно через отдельный конвейер сборки (YAML). Однако нам часто удобно создавать и развертывать их все вместе; например, при маркировке результирующих артефактов как части новой версии. Я просмотрел официальные документы, но ничего не нашел о том, как это сделать. Триггеры конвейера мне не помогают , потому что мне нужно держать эти конвейеры разъединенными, так как они часто запускаются индивидуально. Мне нужно что-то вроде этого ( желаемый псевдокод ):

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 ]

1 голос
/ 30 апреля 2020

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 голос
/ 01 мая 2020

Я добился желаемого результата, используя Azure Конвейерные шаблоны . Это не точно , что я хотел, так как сначала мне пришлось переписать каждый отдельный конвейер для запуска из шаблона, переместив определения этапов в отдельный файл шаблона и определив переменные в вызывающем конвейере (который сейчас почти пустой). После этого я смог написать свой основной конвейер для вызова отдельных шаблонов один за другим, и это работало без проблем. Они бежали в серии (один за другим); мог бы быть способ заставить затем работать параллельно, но мне это не нужно, поскольку я не против того, сколько времени это займет.

Главный совет для тех, кто пытается это: вы Можно определить переменные на верхнем уровне (т. е. в вызывающем конвейере), и они будут доступны в файлах шаблонов. Файлы шаблонов просто сшиваются в конвейер непосредственно перед его запуском, во многом как на стороне сервера (или #include для любого, кто старше меня). Вам нужно использовать параметры шаблона только в том случае, если ваши отдельные конвейеры имеют общее имя переменной, которое должно быть установлено по-разному для каждого (например, «service-name»). Имейте в виду, что параметры шаблона (${{}}) оцениваются до конвейера (очень похоже на #define константы в C), тогда как переменные ($()) оцениваются во время выполнения; поэтому, если один или несколько ваших конвейеров не работают должным образом, вам может потребоваться превратить переменную в параметр шаблона.

0 голосов
/ 29 апреля 2020

Предполагая, что все ваши конвейеры находятся в одном проекте, и если вы используете агенты сборки на основе 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"
    }
}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...