TeamCity best practices

We are trying to use TC but we have some  difficulties to transfer our workflow from our in-house build system to TC.  Please consider following scenario. We have three builds to run to complete the  cycle, Win32, Win64 and Linux 64. They are pretty same, so I will focus on  Win32.
Win32 build consists of following  operations:
-Checkout files (git)
-Build VS main solution (using  incredibuild)
-Build VS testers solution (using  incredibuild)
-Run all testers
-Create installation package  (installshield)
-Instal above package
-Run all tests again on installed  product
-Copy to network location

These are main steps, we have more than 100  steps in our build. My difficulty created by lack of knowledge of TC procedures  and best practices. We want to be able to do following:
1) Create a configuration (?) for all testers,  adding testers as build steps. AFAIK, this will prevent me from re-running  failed tester. Correct? So, what I have to do? Add each tester as new  configuration?
2) I want to run some testers concurrently on  local machine, but some tests depend on results of previous testers so they have  to run sequentially. How do I arrange that?
3) First step in build gets input from user,  which branch to checkout, if build fails and I re-run it, since this  configuration depends on check-out config it will ask for branches once again.  Can I prevent it?
4) And the last but not least, I want to run all  above builds (Win32/64/Lin64) in parallel on three different machines, but each  build step should be executed locally on build dedicated machine. How do I  achieve that?

Thanks in advance!

Comment actions Permalink


Anyone? Anything?

Comment actions Permalink

First of all, you need to figure out a way for your build to run non-interactively. I use a system of configuration files to set up various build parameters. You can also use teamcity's parameter feature which will pass in values eitehr in the java environment or as environment variables. I don't endorse that mechanism too much because  configuration files are already naturally under version control, whereas the auditing of changes to the build configs  is harder and different....

Questions such as "which branch?" should be answered at the time you create the VCS root for your build.

Next is to examine your build dependencies. If build dependencies can be constructed or satisfied locally on the same buidl host, your build scripts should do them. This usually includes running unit tests and such. If your build dependencies rely on the results of other builds, then you need to examine the artifact dependency feature and build conmpletion triggers available to you.

Multi-Platform builds are usually accomplished  by defining a "master" task that has snapshot dependencies to the platform specific tasks. The master task will wait until the platform specific tasks complete. You can put aggregation tasks into the master task and retrieve the build results from the platform specific tasks via artifact dependencies.

Comment actions Permalink


Sorry for not replying in time. How is your TeamCity adoption goes? Any feedback or suggestions for TeamCity functionality?

TeamCity provides several features like snapshot dependencies that allow to address some parts of you case, but specific configuration is up to you as the specific implementation depends on the specifuc requirements that you have.

Generally, Christian's answer is in line to what we usually recommend. I will try to detail a bit.

We generally recommend to use TeamCity-provided VCS integration as this way you get and details lists of changes and revisions in TeamCity UI.

> First step in build gets input from user,  which branch to checkout, if  build fails and I re-run it, since this  configuration depends on  check-out config it will ask for branches once again.
This assumes you used to specify the branch manually on the build run. I'd suggest to reconsider the beahvior to make the build require no user input. Like making TeamCity to watch a specific branch and advance the branch to the desired commit. Or the same for tags instead of branches. If you do need to provide the branch name before the build, you can do this by using "Run custom build" (ellipsis on the RUn button) and specifying name of a branch in the dialog, then using the branch name as a reference in the VCS root. However, changes reported in TeamCity might be not consistent for this type of use.

> -Build VS main solution (using  incredibuild)
> -Build VS testers solution (using  incredibuild)
> -Run all testers
> -Create installation package  (installshield)
> -Instal above package
> -Run all tests again on installed  product
> -Copy to network location

There generally are two approaches to defining the procedure:
1. define them in a single build configuration as build steps (or as single step inside a custom build script)
2. define them in several build configurations and use TeamCity artifacts/snapshot dependencies between them (see also )

A build configuration has own settings for sources checkout, triggering, parameters, cleanup, notifications. Also, a build configuration defines a piece of work (build) that runs on a single agent.

Approach #1 is trivial to understand and implement, but provides minimum customization abilities.
The most you can do is to affect build behavior by passing properties (e.g. environment variables) into the build from TeamCity and making the build script to change the logic according to the paameters passed. With this approach you can probably setup selective test run.

Approach #2 allows more, but will need some effort to configure in the right way but it will provide more convenience as the expense of addign a level of complexity.
Currently, approach #2 is not compatible with ability to specify the branch name in the custom run build dialog as snapshot dependencies does not support references in VCS roots.

Let me describe a sample setup for approach 2 for you case (certain approach might not work, but I will try to convey the idea):

Create the following build configurations:
- Compile Main
- Compile Tests
- Unit Tests Win 32
- Unit Tests Win 64
- Unit Tests Linux
- Installer
- Functional Tests Win 32
- Functional Tests Win 64
- Functional Tests Linux
- Publish

Add the following dependencies:
- snapshot dependency in Unit Tests * from Compile Main and Compile Tests
- artifact dependency in Unit Tests * from Compile Main and Compile Tests to retrieve all the necesary binaries
- snapshot and artifact dependency in Installer from Compile Main (might also have a snapshot dependency on Unit Tests * if you do not need installer if any test fails)
- snapshot and artifact dependencies in Functional Tests * from Installer and may be on Compile Tests
- snapshot and artifact dependency in Publish from Installer and Functional Tests *

If you have several types of tests (testers), you can extract them in separate build configurations. This way you will be able to re-run them. Also, you can extract dependent tests grooups in different build configurations and expose that dependency into TeamCity via snapshot dependencies.

Please let us know if you jave more specific questions on setting up the build process like this.
Comment actions Permalink

Well, sorry, but its been too late, we have abandoned the idea to use team city :( We have already invested time in inhouse build system to allow parallel building. I will show your answer to our team leader, but doubt we will switch at this moment. Thank you anyway.

Comment actions Permalink

Thank you for the letting us know the current state of affiars.

Actually, unless you have very specific requirements that could not be changed, developing own build system does not seem to pay off with all the products present on the market. But of course it's your company decision.

If you have more questions on TeamCity for this or other projects, please do not hesitate to contact us.


Please sign in to leave a comment.