Как написать сценарий сборки с помощью Azure DevOps REST Api? - PullRequest
0 голосов
/ 25 октября 2019

Этот вопрос является продолжением другого моего вопроса - Как запланировать запуск сборки DevOps Azure на локальной машине каждые 5 минут?

Не могу понять, как составить сценарий для расписаниясборка. Какой API я должен использовать?

РЕДАКТИРОВАТЬ 1

Я хочу подчеркнуть - я не хочу ставить саму сборку в очередь каждые 5 минут. Я хочу написать скрипт сборки. Итак, я нахожусь в обновлении определения REST Api - https://docs.microsoft.com/en-us/rest/api/azure/devops/build/definitions/update?view=azure-devops-rest-5.1 и до сих пор не понимаю, как обновить расписание определения сборки. Совет открыть Fiddler и перепроектировать API заставляет меня думать, что это не задокументировано. Означает ли это, что все, что я реализую на основе анализа трафика, может быть повреждено в следующей версии?

РЕДАКТИРОВАТЬ 2

Использование предложенного решения работает. Вот мой код, основанный на предоставленном ответе. Мне пришлось изменить 2 вещи:

  1. Тело должно быть скалярным объектом, а не массивом. Поэтому я конвертирую $BuildDefinition вместо @($BuildDefinition) в json.
  2. Я использую аутентификацию Windows, потому что у нас есть локальный сервер Azure DevOps.

$BuildDefinition | Add-Member triggers $triggers -Force

$json = ConvertTo-Json $BuildDefinition -Depth 99 

$Url = $BuildDefinition.url -replace '(.+)\?.+',"`$1?api-version=5.0"
Invoke-RestMethod -Uri $url -Method Put -Body $json -ContentType "application/json" -UseDefaultCredentials

Однако объект определения сборки должен быть получен через GET API , а не LIST API . Последний возвращает сокращенную версию определения сборки, которую нельзя использовать для ее обновления.

РЕДАКТИРОВАТЬ 3

Очень важно указать ветку, используя полнуюобозначение, то есть refs/heads/master вместо просто master. Использование последнего, кажется, работает - графики созданы, фильтр ветвей выглядит корректно, но он не работает. Проблема в том, что графический интерфейс не дает никаких указаний, что-то не так.

1 Ответ

3 голосов
/ 25 октября 2019

Если вы имеете в виду настройку расписания сборки с помощью REST API, то вы можете использовать Определения - Обновление

Вы также можете нажать F12 в браузере, чтобы отслеживать API, когда задаете расписание изПользовательский интерфейс.

Вернемся к вашему требованию:

Как запланировать запуск сборки DevOps на локальном компьютере каждые 5 минут?

Так же, как выупоминается, что в настоящее время локальный сервер Azure DevOps не поддерживает расписания в YAML. И пользовательский интерфейс для определения основанных на времени триггеров сборки недостаточно гибок. Таким образом, мы не можем достичь этого, как встроенная функция.

Однако мы можем вызвать API REST для построения очереди , чтобы ставить в очередь сборку каждые 5 минут, у нас есть два способа сделать это:

  1. Записьсценарий для вызова очереди построения REST API, а затем периодически запускать его на клиентском компьютере, мы можем установить его с помощью планировщика заданий Windows. Ниже приведены ссылки на блоги:

  2. Жестко запрограммируйте в скрипте, откройте консоль для запуска скрипта в любом клиенте, который может получить доступсервер Azure DevOps (ниже работает скрипт PowerShell):

Пример:

Param(
       [string]$collectionurl = "https://server/DefaultCollection",
       [string]$projectName = "ProjectName",
       [string]$BuildDefinitionId = "11",
       [string]$user = "username",
       [string]$token = "password/PAT"
    )

    # Base64-encodes the Personal Access Token (PAT) appropriately
    $base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $user,$token)))

    function CreateJsonBody
    {

        $value = @"
      {
      "definition": {
        "id": $BuildDefinitionId
      }

    }
    "@

     return $value
    }

    $json = CreateJsonBody

    $uri = "$($collectionurl)/$($projectName)/_apis/build/builds?api-version=5.1"


    $EndTime = Get-Date
    while($true) {
        $EndTime = $EndTime.AddMinutes(5)

        ###Queue build###
        $result = Invoke-RestMethod -Uri $uri -Method Post -Body $json -ContentType "application/json" -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)}


        Start-Sleep -Seconds $( [int]( New-TimeSpan -End $EndTime ).TotalSeconds )
    }

ОБНОВЛЕНИЕ1:

Чтобы обновить определение сборки с включенным триггером расписания, нам нужно добавить атрибуты триггера в тело запроса.

ПОЛУЧИТЕ определение сборки , вызвав API REST, используйте ответ в качестве тела запроса.

Добавьте атрибуты триггеров в тело запроса ответа:

"triggers": [
    {
        "schedules": [
            {
                "branchFilters": [
                    "+refs/heads/master"
                ],
                "timeZoneId": "UTC",
                "startHours": 5,
                "startMinutes": 20,
                "daysToBuild": 31,
                "scheduleJobId": "5e8e3663-2d1c-482e-bb4d-91f804755010",
                "scheduleOnlyWithChanges": true
            }
        ],
        "triggerType": "schedule"
    }
]

UPDATE2:

Итак, вы можете использовать приведенный ниже скрипт PowerShell, чтобы включить / обновить триггер расписания сборки, обновив определение сборки:

Param(
   [string]$collectionurl = "https://server/DefaultCollection",
   [string]$project = "projectname",
   [string]$definitionid = "183",
   [string]$user = "username",
   [string]$token = "password/PAT"
)

# Base64-encodes the Personal Access Token (PAT) appropriately
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $user,$token)))

$ErrorActionPreference = 'SilentlyContinue' 

#Get resonse of the build definition
$defurl = "$collectionurl/$project/_apis/build/definitions/$($definitionid)?api-version=5.1"            
$definition = Invoke-RestMethod -Uri $defurl -Method Get -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)}

#Set trigger array


 $triggers =  ' 
        [{
            "schedules": [
                {
                    "branchFilters": [
                        "+refs/heads/master"
                    ],
                    "timeZoneId": "UTC",
                    "startHours": 9,
                    "startMinutes": 40,
                    "daysToBuild": 31,
                    "scheduleOnlyWithChanges": true
                }
            ],
            "triggerType": "schedule"
        }]'


 cls
#Add a trigger block to the response body

$definition | Add-Member -NotePropertyName "triggers" -NotePropertyValue (Convertfrom-Json $triggers) -Force

Remove-TypeData System.Array  # Remove the redundant ETS-supplied .Count and values property

#Convert the response body to Json
$json = @($definition) | ConvertTo-Json -Depth 99 

#Update build definition
$updatedef = Invoke-RestMethod  -Uri $defurl  -Method Put -Body $json -ContentType "application/json" -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)}

Write-Host ($updatedef.triggers | ConvertTo-Json -Depth 99)
...