在PowerShell中使用Azure DevOps REST API更新内部版本定义

时间:2019-07-02 15:28:06

标签: powershell azure-devops azure-devops-rest-api build-definition build-triggers

我正在尝试通过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 documentation尚不清楚,我应该如何使用此方法更新构建定义,但是以上内容导致出现以下错误:

  

Invoke-RestMethod:{“ $ id”:“ 1”,“ innerException”:null,“ message”:“值不能为空。\ r \ n参数名称:    definition.Repository ”,“ typeName”:“ System.ArgumentNullException,mscorlib”,“ typeKey”:“ ArgumentNullException”,“ errorCode”:0,“ eventId”:0}

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

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

3 个答案:

答案 0 :(得分:1)

triggers是数组,因此您不仅可以对其进行编辑,还需要编辑triggers[0],与branchFilters一样,还需要编辑{{1 }}。另外,您无需触摸branchFilters[0]

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

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

最后应该确定的是分支值,它应该是branchFilters[0]而不仅仅是分支名称。

因此,我有一个带有+refs/heads/branchName分支触发器的管道,并使用以下脚本成功将触发器编辑为testmaster

feature/*

答案 1 :(得分:1)

似乎从list method收到的定义不能直接与update method一起使用。这在列表响应类型BuildDefinitionReference中很明显,它不包含诸如triggers之类的属性。必须使用get method中的定义ID从list method中获得定义。这将返回确实具有triggers属性的BuildDefinition。然后可以对其进行修改并将其传递给update method

这是工作代码:

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

答案 2 :(得分:0)

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

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