TeamCity : Propagating parameters to snapshot dependencies

At $DAYWORK, we are using TeamCity to automate our release process. For each release, we have a set of independent builds. For the example, we will call them “Windows”, “Mac” and “Linux”. They are build from the same source code, and have the same version string for a given release.
On a release day, we want to press the “Run” button on a “Release” build in TeamCity, enter the version string (like v1.2), and that from them on, the following happens automatically:

  •   “Windows” is triggered with the version string as parameter
  •   “Mac” is triggered with the version string as parameter
  •   “Linux” is triggered with the version string as parameter
  •   All builds use the same source code, as selected
  •   If one of the build fails, “Release” fails too

Most of this is easy. “Release” has “Windows”, “Mac” and “Linux” as snapshot dependencies, and a “version_string” parameter of type “prompt”.

The problem is now: how to pass the version string entered by the user from “Release” to the dependencies ? TeamCity supports passing the parameters between dependencies via the dep.* parameters, but only in the other direction.

I contacted the support from JetBrains, and while TeamCity doesn’t support this use case directly, there is a workaround, documented here for the record.

The trick is to separate the preparation from the execution. There are 2 builds in addition to the 3 “real” ones:

  • Initialize
  • Execute

The role of “Initialize” is to capture:

  • the version string
  • the revisions to use from the VCS root

While “Execute”s role is to actually execute the 3 builds.

“Initialize” has a build parameter “version_string”, of kind “prompt”, that cannot be empty, and its VCS roots are the ones used by the 3 builds.

The 3 builds have a snapshot dependency to “Initialize”. That allows them to get the right revisions, and access to the version string through “dep.Initialize.version_string”.

“Execute” has snapshot dependencies to the 3 builds and “Initialize”.

With this configuration, you can start “Initialize” manually, enter the version_string. That will not trigger the 3 builds. You have to do this manually, by promoting the “Initalize” build to “Execute”. That will trigger the builds with the right revision and version_string.
But it’s easy to automate this: add a “Finish Build Trigger” to in “Execute”, watching “Initialize”.

Note that for this exact use case (release with a specific version string), you could also use an approach where the version string is not entered manually but retrieved automatically from a branch name, as described here.

This entry was posted in Uncategorized and tagged . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s