TFS 2015 Queue new build using REST Api - Set Dema

2019-08-19 08:52发布

Im trying to queue a new build using the TFS 2015.3 REST API, i have followed many articles but cannot get it to work.

I am executing this in PowerShell, a standard queue new build call works when passing only the Definition ID, but passing anything else in addition to the id doesn't seem to work.

my code:

$buildDef = Invoke-RestMethod -Method Get -UseDefaultCredentials -Uri "$($tfsRoot)/_apis/build/definitions?api-version=2.0&name=$buildDefintionName"        

        $detailedResults = Invoke-RestMethod -Uri $buildDef.Value[0].Url -Method Get -ContentType "application/json" -UseDefaultCredentials

        if ($buildDef.Value[0].Id)
        {
            $agentDemandString = "Agent.Name -equals $agent"
            $demands = $detailedResults.Demands

            $json = "definition: { id:$($buildDef.Value[0].Id) }, demands: $demands" 
            $bodyjson = $json | ConvertTo-Json
            Write-Host "Queuing build $buildDefintionName on agent $agent with parameters $json"
            $build = Invoke-RestMethod -Method Post -UseDefaultCredentials -ContentType application/json -Uri "$($tfsRoot)/_apis/build/builds?api-version=2.0" -Body $bodyjson
        }

I have tried many different variations of passing the demands, but it looks like it is not even getting to that point as its complaining about the "build" parameter.

Invoke-RestMethod : {"$id":"1","innerException":null,"message":"Value cannot be null.\r\nParameter name: build","typeName":"System.ArgumentNullException, mscorlib, Version=4.0.0.0, Culture=neutral

If im right the build parameter contains the build steps to execute. Which makes me think that the queued build is dropping all existing configuration and tries to rely only on what has been passed in the JsonBody, this is ofcourse not what i want.

What and how should i pass in order to queue a new build but with updated/additional demands.

标签: tfs
4条回答
姐就是有狂的资本
2楼-- · 2019-08-19 09:11

Based on my test, we cannot Set Demands directly with the Queue build REST Api.

The build will still use the agent which was set in definition even though we specified other agents with the "Demands" set when queue the build. You can check this with the REST API, below screenshot for your reference.

And with the REST API to get a build eg:

GET http://SERVER:8080/tfs/CollectionLC/6debd6ea-fa97-4ea2-b0c0-3cbbc4afa802/_apis/build/Builds/1071/

You can see that, the "Demands" is not included in the response. It only appears in build definition response.

Actually, the "Demands" is set in build definition,it's against the build definition only. When queue a build with REST API, it just trigger the build definition. So, if you want to trigger build with the specific agent using REST API, you need to update the definition (set demands )first, then trigger the build definition.

To update the definition use the REST API : See Update a build definition

PUT https://{instance}/DefaultCollection/{project}/_apis/build/definitions/{definitionId}?api-version={version}

So, you can write the script to update build definition fist, then trigger the build with build definition ID.

enter image description here

查看更多
\"骚年 ilove
3楼-- · 2019-08-19 09:13

I finaly got it working with some help. The Demands property is accepted. Looks like it was not working because of the powerShell code with Json conversion. If i use below and dont convert it to Json, it works !

Function queuebuild{ 

      $uri="$($tfsRoot)/_apis/build/builds?api-version=2.0"

      $body='{
                 "definition": {
                 "id": 1061
                 },
                    "sourceBranch": "$/Project/Branch",
                    "demands":["Demand1", "Agent.Name -equals Computer2-E-A2"]
                 }';

        $result=Invoke-RestMethod -Uri $uri -Method Post -ContentType "application/json" -UseDefaultCredentials -Body $body

}

查看更多
爱情/是我丢掉的垃圾
4楼-- · 2019-08-19 09:21

$json = "definition: { id:$($buildDef.Value[0].Id) }, demands: $demands" is not going to be valid JSON -- it wouldn't be wrapped in curly braces, for example.

I recommend creating an associative array that will properly convert to valid JSON. The example JSON provided in the documentation is:

{
  "definition": {
    "id": 25
  },
  "sourceBranch": "refs/heads/master",
  "parameters": "{\"system.debug\":\"true\",\"BuildConfiguration\":\"debug\",\"BuildPlatform\":\"x64\"}"
}

So this would generate an appropriate JSON object:

$body = @{
    definition = @{ id=25 }
    sourceBranch = 'refs/heads/master'
    parameters = '{\"system.debug\":\"true\",\"BuildConfiguration\":\"debug\",\"BuildPlatform\":\"x64\"}'
} 

$body | convertto-json

Or if you wanted to be extra fancy and eliminate the inner JSON-as-a-string bit:

$body = @{
    definition = @{ id=25 }
    sourceBranch = 'refs/heads/master'
    parameters = (@{'system.debug' = $true; BuildConfiguration='debug'; BuildPlatform='x64'}) | convertto-json -Compress
} 

$body | convertto-json
查看更多
闹够了就滚
5楼-- · 2019-08-19 09:24

Try to set the depth:

$bodyjson = $json | ConvertTo-Json -Depth 3

查看更多
登录 后发表回答