How to combine build chains?
Completed
I'm scheduling multiple builds at the same time from a single build in order to enable our team to build multiple configurations of our product. The way I achieve this is via a build command via the REST API and setting the dependency build manually. But how do I get these two builds to appear in the same build chain to make seeing status easier? This post request creates two new build chains when I'd really like to have one build chain with two builds in it.
<build>
<buildType id=\"BuildConfiguration_2\"/>
<triggeringOptions />
<comment>
<text>triggered from promote build: %system.teamcity.buildConfName%</text>
</comment>
<revisions>
<revision version=\"%build.vcs.number%\" vcsBranchName=\"%vcsroot.branch%\" />
</revisions>
<properties>
<property name=\"AgentBuildRole\" value=\"$buildRole\"/>
<property name=\"BuildConfiguration\" value=\"$configId\"/>
<property name=\"teamcity.build.branch\" value=\"%teamcity.build.branch%\"/>
</properties>
<snapshot-dependencies>
<build id=\"%teamcity.build.id%\" />
</snapshot-dependencies>
</build>
Please sign in to leave a comment.
First of all, I would like to confirm I have understood the end goal correctly - do you want to create 2 or more build configurations which would have the same dependancy on a existing build configuration? (i.e. builds B1 and B2, dependant on static build A). If this is correct, maybe composite build would be of use for you? (https://www.jetbrains.com/help/teamcity/composite-build-configuration.html)The setup could look like this: you have "static" (i.e. set up once) configuration(s) which act as a base dependancies; you create dynamic build configurations via REST API and specify "static" build configurations as their dependancies; finally, you add/update composite configuration which has all of the dynamic configurations as its dependancies. Please do note that this approach could amend your workflow to a degree, specifically, it would be shown in queue as a single build, you could tie all of the artifacts to it, so that the artifact publish is governed at one place, and it would also aggregate the log output.If this approach does not work for you, or if my assumption about the goal you aim for is incorrect, please elaborate on your setup and I will see what else could be done. You could find more details on build chains here: https://www.jetbrains.com/help/teamcity/build-chain.html
Hi Fedor,
I think the composite build type would work potentially if I always build the same platform and configuration each time, but my goal is to allow the user to pick the configurations that are built during the build phase. Could the composite build take all these parameters and kick off and collect the BuildConfiguration jobs? That way users can select what they want to build and have it build and collect the results automatically?
To be clear, each configuration selected schedules a TeamCity BuildConfigration job to run. That job targets a set of agents based on what platform it's targeting. (We have to do this to keep Unity build times low. Switching platforms increases the duration of by build by 100%)
Is that still possible with a composite build?
OR, is there a parameter that I can add on the <build> XML that would consider one of the several BuildConfiguration jobs to be considered as part of the same build chain? That would be my ideal solution if possible.
One other thing to note, I cannot use the Composite build because of the issue that I cannot select what platforms are built. I currently have 12 platforms that can be built and building all of them for a single check-in is unacceptable. I need to be able to define what platforms are built for a given build. Is there a way to do that using Composite Builds? This feature seems like a conditional dependency.
By design, there is no option currently to trigger a build conditionally. I have created a feature request to allow running build dependencies conditionally: https://youtrack.jetbrains.com/issue/TW-65341
May I suggest an alternate approach here:
1) you would have to ensure there is a separate build configuration for each platform;
2) a composite build configuration is created (with no dependencies set up);
3) finally, another build configuration ("preparer") is created which includes just a single step - running a REST API script. This script would take a list of dependencies you want to build as an input, run a REST API call to update composite configuration (so that it depends only on the configurations you want it to) and finally starts the composite.
As a result, each time you run the "preparer" build, it updates the composite so only the required configurations are triggered, and you can check the composite build to see all the artifacts.
Hi Fedor,
Thank you, the documentation on how to use the REST API to change the build configuration dependencies isn't very clear. I've attempted to use this URL using a POST request, but it's rejecting the input.
I've taken the output generated on a GET from the URL below and fed it into a POST request, but it rejects it with this error. Is there documentation or an XSD that I could reference to generate a valid request for this? The only way i've been able to interact with this is via asking in the forums.
/app/rest/buildTypes/id:CONFIGID/snapshot-dependencies
Actually, I'm mistaken. It looks like PUT is the required verb. I'm able to change it now.
I can confirm this worked well for me, thank you.
That`s great to hear, thank you for coming back on this thread!
Yes, as a rule of thumb PUT would be used to update an existing entity while POST is for creating an entity from scratch (https://www.jetbrains.com/help/teamcity/rest-api.html#RESTAPI-SupportedHTTPMethods). For additional reference on the API methods, you could also use /app/rest/swagger.json endpoint which will yield the list of supported methods; methods are grouped by tag which is referring to a specific entity (say, BuildType), and do list:
-short operationId (ex. getSnapshotDeps)
-supported parameters(name, type, is required)
-specific responses to look for
Fedor, it looks like I spoke too soon. I'm having issues where if I select a branch other than the default branch, the dependent builds do not select the correct branch.
StartBuild updates the dependencies of BuildComplete to setup a snapshot dependency and then starts the BuildComplete build. In the example below, lobby_arm build branch is selected, however BuildOculusQuestDebug is reverting back to dev.
When I manually run BuildComplete in the TeamCity webpage, BuildOculusQuestDebug does pick lobby_arm branch correctly, however when starting it via the web request, it fails.
Below is how i'm starting BuileComplete. Am I starting the build incorrectly?
Hello Gabe,
If this approach works for you, I suppose the build chain configuration could be simplified.

How exactly have you configured the "StartBuild"/"BuildComplete" configurations interface? Per my suggestion, REST API script would update the dependencies on "BuildComplete" and then run "BuildComplete" (so TeamCity will trigger its dependencies on its own). With this setup, "StartBuild" does not appear on the chain as there is no dependency on it either from platform-specific builds nor from composite build. A quick example I did now is based on a project with the following setup:
1) "Starter" build which executes a script to launch a REST API request which sets the dependencies for "Composite" and launches it;
2) "Platform1"/"Platform2" - represent the actual platform-specific configurations;
3) "Composite" - an aggregator of build results.
With the launch of "Starter", "Composite" was triggered here; however, "Starter" does not appear on the chain because there is no direct dependency on it.
Speaking of passing the branch - "teamcity.build.branch" raises a few questions. Essentially, we are trying to launch "BuildComplete" with the parameter set to reference %teamcity.build.branch% - however, is there a valid source of data for this parameter in your configuration? It appears that there is none, so the teamcity.build.branch parameter is resetting to a default branch - dev in our case. You could try to set the actual branch name instead of %teamcity.build.branch% in the script - so that the parts of configuration which refer to teamcity.build.branch will use this parameter properly.
There is another option: in above example, default branch is refs/heads/master; if I amend the script to make sure "Starter" will launch "Composite" with a specific branch (namely, by amending <build> tag to include branchName="branch_name"), corresponding branch is correctly passed into "Composite" and its dependencies:
Maybe this approach will work for you? You could pass the branch into the script (so to populate the branchName parameter).
Please feel free to reach out if there is anything else I could look into.
Hi Fedor,
That last tip was what I needed to fix the issue. By <build> tag was missing branchName="branch_name" to signal the branch.
In terms of the build that starts the build process, I was able to make the composite build have a snapshot-dependency on the build that's currently running, so it shows up in the entire build chain correctly.
Hello Gabe,
Good to know! I suppose that, usability-wise, seeing the whole chain (with the "StartBuild" included) is more informative approach - thank you for mentioning that amendment.