3

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 Answer 1

5

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 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.