Start and Cancel Builds
In this article, we explore common use cases concerning starting and canceling builds via TeamCity REST API:
Starting a TeamCity build from an external software.
Implementing a complex build logic by invoking REST API from the Command Line build runner.
tip
See more information about triggering requests.
To be able to start a build, you need to access the build queue via this endpoint:
POST/app/rest/buildQueue
Queueing a new build requires two steps:
Prepare the request payload (that is, the
Build
entity) which will represent the target build.Send a
POST
request with the payload.
Step 1:
The payload of this Build
entity must include a reference to a build configuration (or, in REST API terms, BuildType
). We will include it as a sub-entity of Build
.
<build>
<buildType id="buildConfID"/>
</build>
{
"buildType": {
"id": "buildConfID"
}
}
tip
By default, TeamCity expects a payload in XML. To switch to JSON, set
Content-Type
andAccept
headers toapplication/json
.
Step 2:
To add a build to the queue, send a POST
request with the body specified in Step 1:
POST/app/rest/buildQueue
The request headers should include an authorization header (unless the guest authorization scheme is used) and, optionally, Content-Type
/Accept
headers.
The endpoint will respond with a short description of the launched build. It will also include the TCSESSIONID
cookie: you can reuse it to skip authorization in the following runs.
A more complex example is when you need to run a build with settings that differ from those specified in its build configuration. In this case, you need to send extra data about the build in your request.
From the fields available for the Build
entity, we will pass the following:
personal
: to define that the build is personalbranchName
: to launch a build in a non-default branchagent
: to select a specific agent for this build by sending anAgent
sub-entitycomment
: to supply a build with a descriptionproperties
: to set custom properties by sending a complexProperties
entity
Most of the data should be available locally. However, in this example we request a specific agent which requires knowing its ID. If you know an agent by name, you can find its ID by sending the following request:
GET/app/rest/agents?locator=name:myAgentName
Here, the ?locator=...
part specifies an AgentLocator
entity which is used to find the agent by name. The request will return the respective Agent
entity from which you can parse out an ID.
The eventual payload for our POST
request will look as follows:
<build personal="true" branchName="myBranch">
<agent id="3"/>
<buildType id="buildConfID"/>
<comment><text>Build for testing REST API</text></comment>
<properties>
<property name="env.myProperty" value="myValue"/>
</properties>
</build>
{
"branchName": "myBranch",
"buildType": {
"id": "buildConfID"
},
"comment": {
"text": "Build for testing REST API"
},
"agent": {
"id": 3
},
"properties": {
"property": [{
"name": "env.myProperty",
"value": "myValue"
}
]
},
"personal": true
}
Send it via a POST
request as in the basic case. As a result, a personal build will be run in the myBranch
branch on the specified agent and with the redefined myProperty
property.
In this example, we will show how to compose a payload to rerun a build, clean its sources, and select a specific revision.
Inside the Build
entity, we will supply:
triggeringOptions
: to specify extra parameters by sending theBuildTriggeringOptions
sub-entity.lastChanges
: to select a specific revision for the build by sending theChange
entity. The element also supports a locator field which expectsChangeLocator
to identify a specific revision.
In triggeringOptions
, we want to enable clean checkout, rebuild all dependencies before the current build, and put the build at the top of the queue.
In lastChanges
, we will use the locator as follows:
version
: SHA of the specific revision already detected by TeamCitybuildType
:BuildTypeLocator
which will point to the sameBuiltType
as the one we run the build on.
The expected payload:
<build>
<triggeringOptions cleanSources="true" rebuildAllDependencies="true" queueAtTop="true"/>
<buildType id="buildConfID"/>
<lastChanges>
<change locator="version:a286767fc1154b0c2b93d5728dd5bbcdefdfaca,buildType:(id:buildConfID)"/>
</lastChanges>
</build>
{
"buildType": {
"id": "Playground_BuildConfigurationLevelLogic_BuildsInDefaultBranchAreDisabledBuild"
},
"lastChanges": {
"change": [{
"locator": "buildType:(id:(Playground_BuildConfigurationLevelLogic_UpdatePromptViaRESTAPI)),version:(SHA)",
}
]
},
"triggeringOptions": {
"cleanSources": true,
"rebuildAllDependencies": true,
"queueAtTop": true
}
}
After queueing a build, you can check its status:
GET/app/rest/buildQueue?locator=<BuildQueueLocator>
where BuildQueueLocator
represents a queued build — you can supply the build ID you received on sending the POST
request.
This request returns a Build
entity. By default, TeamCity will return basic fields of the entity. For polling purposes, you might want to receive only the build status. You can limit the scope of fields available in the response by using the ?fields
parameter in the request path (read more):
GET/app/rest/buildQueue?locator=id:<myBuildID>&fields=build(id,state)
As a result of the call, TeamCity will return the Build
entity with only two fields populated: id
and state
.
To cancel a just queued build, send:
POST/app/rest/buildQueue/<queuedBuildLocator>
where a BuildCancelRequest
entity is used as a payload.
This entity comprises two fields:
comment
: to provide an optional comment on why the build was canceledreaddIntoQueue
: a boolean property which declares if this is a request to restore a previously canceled build; as we are aiming to cancel the build, not to restore it, we will set it tofalse
The resulting payload:
<buildCancelRequest comment='Canceling a queued build' readdIntoQueue='false'/>
{
"comment": "Canceling a queued build",
"readdIntoQueue": false
}
To cancel a build by its ID, send:
POST/app/rest/buildQueue/id:<build ID>
Alternatively, you may choose to simply delete a queued build (if you don't need its metadata). To do so, run a DELETE
request on the same endpoint:
DELETE/app/rest/buildQueue/id:<build ID>
To cancel a build that has already started, send:
POST/app/rest/builds/<buildLocator>
with the same BuildCancelRequest
entity as in the above example:
<buildCancelRequest comment='Canceling a running build' readdIntoQueue='false'/>
{
"comment": "Canceling a running build",
"readdIntoQueue": false
}
To cancel a build by its ID, send:
POST<TeamCity URL>:[<port>]/app/rest/builds/id:<build ID>
Thanks for your feedback!