在 PowerShell 中使用 Azure DevOps REST API 更新构建定义
Update build definition using Azure DevOps REST API in PowerShell
我正在尝试通过 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":"Value cannot be null.\r\nParameter name:
definition.Repository","typeName":"System.ArgumentNullException, mscorlib","typeKey":"ArgumentNullException","errorCode":0,"eventId":0}
这是我想知道我是否在咆哮错误的树,因为这肯定更简单(我在 SO here 上找到了一个用于创建新构建定义的简单解决方案)。事实上,我只想更新触发器分支过滤器。
如何使用 PowerShell 和 REST 实现此目的 API?
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
这是适合我的幻灯片校正,
$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
}
似乎是从 list method cannot be used directly with the update method. This is quite clear in the list response type BuildDefinitionReference
which doesn't include properties such as triggers
. The definitions must be obtained from the get method using the definition IDs from the list method. This returns a BuildDefinition
which does indeed have the triggers
property. This can then be modified and passed to the 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 触发器是否存在。
我正在尝试通过 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":"Value cannot be null.\r\nParameter name: definition.Repository","typeName":"System.ArgumentNullException, mscorlib","typeKey":"ArgumentNullException","errorCode":0,"eventId":0}
这是我想知道我是否在咆哮错误的树,因为这肯定更简单(我在 SO here 上找到了一个用于创建新构建定义的简单解决方案)。事实上,我只想更新触发器分支过滤器。
如何使用 PowerShell 和 REST 实现此目的 API?
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
这是适合我的幻灯片校正,
$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
}
似乎是从 list method cannot be used directly with the update method. This is quite clear in the list response type BuildDefinitionReference
which doesn't include properties such as triggers
. The definitions must be obtained from the get method using the definition IDs from the list method. This returns a BuildDefinition
which does indeed have the triggers
property. This can then be modified and passed to the 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 触发器是否存在。