0

我正在尝试通过 PowerShell 脚本使用 REST API 更新 Azure DevOps 中的构建定义...

$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参数名称:define.Repository " ,"typeName":"System.ArgumentNullException, mscorlib","typeKey":"ArgumentNullException","errorCode":0,"eventId":0}

这就是我想知道我是否在吠叫错误的树的地方,因为这肯定会更简单(我在 SO 上找到了一个简单的解决方案,用于创建新的构建定义)。事实上,我想做的只是更新触发器分支过滤器。

如何使用 PowerShell 和 REST API 实现此目的?

4

3 回答 3

3

是数组,triggers所以你不能只编辑它,你需要编辑triggers[0],同样的事情是branchFilters,你需要编辑branchFilters[0]. 此外,您无需在triggerType.

以上所有内容都假设构建中已经有一个触发器并且您想要编辑它,而不是添加新的触发器部分。

数组中还有一个棘手的问题branchFilters,如果您只有 1 个分支(master例如)并且想要添加另一个分支,则需要将其添加到数组中,而不仅仅是编辑branchFilters[0]值。

最后应该修复的是分支值,它应该+refs/heads/branchName不仅仅是分支名称。

因此,我有一个带有test分支触发器的管道,并且我成功地将触发器编辑到masterfeature/*使用此脚本:

# 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
于 2019-07-03T08:42:57.133 回答
2

看来从list 方法收到的定义不能直接与update 方法一起使用。这在BuildDefinitionReference不包含诸如triggers. 必须使用list 方法中的定义 ID 从get 方法中获取定义。这将返回 a确实具有该属性。然后可以对其进行修改并将其传递给更新方法BuildDefinitiontriggers

这是工作代码:

$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 触发器是否存在。

于 2019-07-04T11:41:45.607 回答
1

这是对我有用的幻灯片校正,

$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
}

于 2019-07-03T08:44:38.943 回答