Обновите определение сборки с помощью API-интерфейса REST Azure DevOps в PowerShell - PullRequest
0 голосов
/ 02 июля 2019

Я пытаюсь обновить свои определения сборки в DevOps Azure, используя REST API через скрипт PowerShell ...

$header = @{Authorization = 'Basic ' + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$($personalAccessToken)"))}
$definitions = Invoke-RestMethod -Uri "https://devops.domain.com/Collection/Project/_apis/build/definitions" -Method GET -Header $header
$branchNames = 'master', 'feature'

ForEach ($definition in $definitions.value) {
    $definition | Add-Member -NotePropertyName triggers -NotePropertyValue (@{ triggerType = 'continuousIntegration'; branchFilters = $branchNames | % {"+refs/heads/$_/*"} }) -Force

    $body = $definition | ConvertTo-Json
    Write-Host $body

    Invoke-RestMethod -Uri "https://devops.domain.com/Collection/Project/_apis/build/definitions/$($definition.id)?api-version=5.0" -Method PUT -ContentType application/json -Body $body -Header $header
}

Из документации Azure DevOps не совсем понятно, как мне обновить определение сборки, используя этот метод, но приведенное выше сообщение приводит к следующей ошибке:

Invoke-RestMethod: {"$ id": "1", "innerException": null, "message": "Значение не может быть нулевым. \ R \ nИмя параметра: definition.Repository"," typeName ":" System.ArgumentNullException, mscorlib "," typeKey ":" ArgumentNullException "," errorCode ": 0," eventId ": 0}

Здесь я задаюсь вопросом, не лаю ли я неправильное дерево, поскольку это, безусловно, должно быть проще (я нашел простое решение для SO здесь для создания нового определения сборки). Фактически, все, что я хочу сделать, это обновить фильтры ветви триггера.

Как мне добиться этого с помощью PowerShell и REST API?

Ответы [ 3 ]

1 голос
/ 04 июля 2019

Похоже, что определения, полученные из метода списка , нельзя использовать напрямую с методом обновления .Это довольно ясно в типе ответа списка BuildDefinitionReference, который не включает такие свойства, как triggers.Определения должны быть получены из метода get с использованием идентификаторов определений из метода list .Это возвращает BuildDefinition, который действительно обладает свойством triggers.Затем его можно изменить и передать в метод обновления .

Это рабочий код:

$header = @{Authorization = 'Basic ' + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$($personalAccessToken)"))}
$definitions = Invoke-RestMethod -Uri "https://devops.domain.com/Collection/Project/_apis/build/definitions" -Method GET -Header $header
$branchNames = 'master', 'feature'

ForEach ($definition in $definitions.value) {
    $definitionToUpdate = Invoke-RestMethod -Uri "$($collection)$($project.name)/_apis/build/definitions/$($definition.id)" -Method GET -Header $header
    $trigger = $definitionToUpdate.triggers | Where {$_.triggerType -eq 'continuousIntegration'}

    if ($trigger) {
        $trigger.branchFilters = $branchNames | % {"+refs/heads/$_/*"}
        Invoke-RestMethod -Uri "https://devops.domain.com/Collection/Project/_apis/build/definitions/$($definition.id)?api-version=5.0" -Method PUT -ContentType application/json -Body ($definitionToUpdate | ConvertTo-Json -Depth 10) -Header $header
    }
}

Код проверяет наличие триггера CI перед обновлением егоотраслевые фильтры.

1 голос
/ 03 июля 2019

triggers - это массив, поэтому вы не можете просто отредактировать его, вам нужно отредактировать triggers[0], то же самое, что и branchFilters, вам нужно отредактировать branchFilters[0]. Кроме того, вам не нужно прикасаться к triggerType.

Все вышеизложенное предполагает, что в сборке уже есть триггер, и вы хотите отредактировать его, а не добавлять новый раздел триггера.

В массиве branchFilters есть хитрость: если у вас есть только одна ветвь (например, master), и вы хотите добавить другую ветку, вам нужно добавить ее в массив, а не просто редактировать branchFilters[0] значение.

Последнее, что должно быть исправлено, это значение ветви, оно должно быть +refs/heads/branchName, а не только имя ветви.

Итак, у меня есть конвейер с триггером ветки test, и мне удалось отредактировать триггер на master и feature/* с помощью этого сценария:

# I get only one definition and update him, not iterate all my definitions
$definition = Invoke-RestMethod -Uri $url -Method Get

# Change the branch trigger from "test" to "master"
$definition.triggers[0].branchFilters[0] = "+refs/heads/master"

# Add another branch trigger - "feature/*"
$definition.triggers[0].branchFilters[0] += "+refs/heads/feature/*"

$body = $definition | ConvertTo-Json -Depth 10
Write-Host $body

Invoke-RestMethod -Uri $url -Method Put -ContentType application/json -Body $body
0 голосов
/ 03 июля 2019

Вот корректировка слайдов, которая работает для меня,

$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$token = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$($personalAccessToken)"))
$headers.Add("Authorization", "Basic $token")
$headers.Add("Content-Type", "application/json")
$definitions = Invoke-RestMethod -Uri "https://devops.domain.com/Collection/Project/_apis/build/definitions" -Method GET -Headers $headers

ForEach ($definition in $definitions.value) {
    $definition.triggers = (@{ triggerType = 'continuousIntegration'; branchFilters = 'master', 'feature/*' })
    $definition.revision++

    $body = $definition | ConvertTo-Json
    Write-Host $body

    Invoke-RestMethod -Uri "https://devops.domain.com/Collection/Project/_apis/build/definitions/$($definition.id)?api-version=5.0" -Method PUT -ContentType application/json -Body $body -Headers $headers
}

...