问题
I'm trying to update a build definition through REST API with PowerShell.
The script used is:
$url = "http://tfs:8080/tfs/collection/project/_apis/build/definitions/$($buildId)?api-version=2.0"
$obj = Invoke-RestMethod -Uri $url2 -Method Get -ContentType "application/json" -UseDefaultCredentials
$json = ConvertTo-Json $obj
Invoke-RestMethod -Uri $url -Method Put -Body $json -ContentType "application/json" -UseDefaultCredentials
First I've tried with a new empty definition and I've got the below error:
The collection must contain at least one element.Parameter name: definition.Options.Inputs
So I added an extra code to remove the "options" part from the returned json:
if($obj.options -ne $null){
$obj.options = $null }
and the update worked. But when I'm using the code on an "real" existing build definition that is in production then I get another error:
The collection must contain at least one element. Parameter name: definition.RetentionRules.Rule.Branches.Filter
I'm using TFS2015 Update 3.
Why is not working a simple update (without any modification) of a build definition via REST API?
回答1:
The line $json = ConvertTo-Json $obj
needs changed to include the -Depth
argument with a minimum value of 3
. The default is 2 and because of the nesting the values are lost when converted from an object to Json. More specifically what happens is the values get converted from an array to a simple string.
How to tell this is happening in the Json
Without the depth parameter
"retentionRules": [
{
"branches": "+refs/heads/*",
"artifacts": "build.SourceLabel",
"daysToKeep": 10,
"minimumToKeep": 1,
"deleteBuildRecord": true,
"deleteTestResults": true
}
]
With the depth parameter
"retentionRules": [
{
"branches": [
"+refs/heads/*"
],
"artifacts": [
"build.SourceLabel"
],
"daysToKeep": 10,
"minimumToKeep": 1,
"deleteBuildRecord": true,
"deleteTestResults": true
}
]
You will see that the the branches
and artifacts
values change from a string to an array with the proper depth value.
What your example code should be
$url = "http://tfs:8080/tfs/collection/project/_apis/build/definitions/$($buildId)?api-version=2.0"
$obj = Invoke-RestMethod -Uri $url2 -Method Get -ContentType "application/json" -UseDefaultCredentials
$json = ConvertTo-Json $obj -Depth 3
Invoke-RestMethod -Uri $url -Method Put -Body $json -ContentType "application/json" -UseDefaultCredentials
来源:https://stackoverflow.com/questions/38378702/tfs2015-rest-api-build-definition-update