Friday, February 5, 2010

Release builds with TeamCity: Selecting the branch

We've long had TeamCity doing regular "CI style" checkin builds for our Java/Ant projects. We recently added nightly builds for extra reports, and for longer-running performance tests. This was straightforward.

We finally got TeamCity doing our release builds. There were a couple of tricky points, which I thought would be worth writing up:

  • Selecting the branch
  • Manipulating the repository
  • Ensuring correct (release) versions of dependencies

Selecting the branch

This was the trickiest thing. Checkin and nightly builds always run against trunk. Well, you could set up a checkin build for a long-running development branch too, but that's not difficult. The release build should be done from the release branch, and that can be different for each release. Or it can be the same, if you have to do a fix release on an existing one!

We found a pretty good way to do this with TeamCity, using Build Configuration Templates and Configuration Parameters.

The idea is that you set up a template that contains all of the settings for the release build, except for the branch name. The branch name is specified by a configuration parameter. Then, the template is instantiated for each branch as desired. Each time the template is instantiated, the branch name configuration parameter is given for that instance.

Here are some details, using Subversion VCS and a hypothetical project named "xxx":

Create the Release Build Template

  1. Edit project's existing checkin build config.
  2. Click "Extract Template" to create a new template.
  3. Enter "release-build-template" for Name.
  4. Back in the checkin build config, click "Detach from Template".
  5. Click OK.

We've created a template, with no configurations attached.

Set up the Release Build Template

Edit the template. Change settings as given in the following sections.

Version Control Settings

  1. Create a new VCS root named xxx-branches.
  2. Specify Subversion as the Type of VCS.
  3. Enter Svn repo URL + "/xxx/branches" as the URL.
  4. Test the Connection.
  5. Save the VCS root.
  6. Attach the template to the xxx-branches VCS root.
  7. Detach the template from the xxx-trunk VCS root.
  8. Add checkout rule for VCS root: "%release.branch%=>.". This tells TeamCity to checkout the specific release branch into the working directory.
  9. Save Version Control Settings.

Runner Settings

  1. Change Target to "release-build", or whatever you want to call your release build target.
  2. Save Runner Settings.

You must have a target in your build script called "release-build", or whatever you want to call your release build target. This target must build the release and publish it somewhere. For example, it could copy it to a staging area on a server. Or, it could publish it to your enterprise repository.

The Ant target might look something like this:

Build Triggering Settings

  1. Delete/disable all triggering (VCS and Dependencies).
  2. Save Build Triggering Settings.
We've modified the template so that it will checkout the source from a release branch, with the specific branch given by a configuration parameter ("release.branch"). It will then build and publish the release.

Create a Release Branch Build Config for Release xx.yy

This procedure creates a release build config for a particular branch.

  1. Edit the release-build template's build configuration.
  2. Click Create Build Configuration From Template.
  3. Enter "release-xx.yy" for Name, where "xx.yy" is the name of your release branch.
  4. Enter the name of the branch for the release.branch parameter. For example, "RB-01.05".
We've created a configuration for running a release build on the branch.

To create a release:

  1. Ensure all changes for the release are checked into trunk.
  2. Create the branch. For example:
    svn copy $SVN/xxx/trunk $SVN/xxx/branches/RB-xx.yy

  3. Click Run on the release build configuration in TeamCity.

You can keep the release build configuration around for a particular branch as long as you like. If you are finished with a branch, you can delete the build configuration. If you need it again, it's easy to recreate it from the template.

That's it. I hope to write up some notes on the other points (manipulating the repository and ensuring the correct release versions of dependencies) soon.


tumtumtum said...

Hey there john,

Interesting post. How do you plan on managing artifact dependencies between release and branch builds. Wouldn't you need to manually maintain different artifact sources for the release & branch projects?

Martin said...

Thanks for the info! We looking to have an environment variable that allows us to enter in the tag for a specific release - this does the trick. Some screen shots would be quite useful!

John Hurst said...

@tumtumtum: This is probably a very good point.

In our environment we haven't been making heavy use of feature branches: almost all development occurs on trunk, and only trunk and release branches are covered by CI. (When we do use feature branches, we haven't been covering them with TeamCity. Bad.)

@Martin: Thanks for the feedback. Next time I do such a tutorial, I will put some screen shots!