Chapter 12. Use cases

Table of Contents

Basic use cases
Working with your first build
Working with Maven
Working with project dependencies
Trigger other builds after build of a particular project
Working with multiple branches
Working with configuration inheritance and overriding
Sharing working directories
Sharing build versions
Using date and iteration as part of build version
Managing major, minor, and iteration part of the version string
Specifying label to build against
Updating information for many projects
Working with build queues
Working with public configurations
Working with RSS
Real-time continuous integration use cases
Set up real-time continuous integration for CVS
Set up real-time continuous integration for Subversion
Remote and parallel use cases
Building multi-platform products
Working with parallel builds
Performing automation/smoke tests on a machine other than the build machine
LDAP authentication use cases
Authenticate using Microsoft Active Directory and retrieve user group information
Authenticate using Microsoft Active Directory, but manage user group relationship in QuickBuild
Authenticate uing Fedora Directory Server and retrieve user role information
Build promotion use cases
Promote build from one configuration into another
Promote build from one configuration into another and re-label the source code with new version
Run additional steps to further process an existing build (for example, deploy an existing build)
Promote build from one configuration into another by constructing the new build from the source code of source build.
Build notification use cases
Subscribe to configurations and get notified of new builds
Get notified of manually triggered build
Send build notification to dynamic list of users
Get build notification through RSS
Repository specific use cases
Monitor particular StarTeam promotion state, and trigger new build if new label detected for that state
Promote the build label at StarTeam side automatically when build is promoted from one configuration into another at QuickBuild side
Monitor ClearCase UCM latest baselines, and trigger new build if latest baselines has been changed

This chapter shows how to use QuickBuild by going through a couple of typical use cases. Most of these use cases have corresponding online demos running at http://livedemo.pmease.com:8081, and most of these online demos uses CVS as sample repository which can be accessed through :pserver:anonymous@cvsdemo.pmease.com:/home/cvsroot with an empty password. You can checkout CVS module for these online demos, to examine detail information such as contents of build files, etc.

Basic use cases

Working with your first build

Check out code from CVS, build it with Ant, and tag the source if build is successful. If build fails, notification should be sent to users who have checked in code recently.

[Note]Note

Although this use case checks out code from CVS, and builds with Ant, QuickBuild is not limited for using with CVS, Ant, or building Java projects. For all supported version control systems and builders, please refer to QuickBuild's feature list.

  1. Make sure the following softwares are installed in the computer running QuickBuild:

    • JDK 1.5 or higher

    • Apache Ant 1.6 or higher. The JUNIT library junit.jar should be placed into ${ANT_HOME}/lib directory. The clover.jar and the license file should be put into this directory as well if you want to integrate QuickBuild with Clover (a Java code coverage tool).

    • CVS command line tool.

  2. Install QuickBuild following instructions in the readme file. Open a browser and connect to your QuickBuild installation, login as admin, and edit the basic settings tab of the root configuration and change value of variable "cvs" and "ant" based on your CVS and Ant installaion.

  3. From the dashboard, trigger the configuration root.myfirstbuild, the Editing manual trigger settings page will be displayed. For property Build necessary condition,choose menu item Force build from the drop down menu. This will force a build even if there are no changes in CVS repository since the last build. Click on OK, and the build should start running. Wait a while and then refresh the dashboard page; you'll see that the build has finished. If all things go well, this should be a successful build. Click on status icon of the newly generated build, the build log will be displayed. In case the build cannot be generated, you can click on status icon of the configuration, and examine what went wrong in the configuration log.

  4. You now have successfully ran your first build. Let's examine some important aspects of this configuration.

    • Basic settings

      This page shows some basic settings of the configuration. You can set working directory and publish directory for this configuration. Working directory is used to store files and directories specific to the current configuration, for example, configuration logs. In this working directory, a directory named checkouts will be created to hold files and directories checked out from the configured repositories. In the configuration's publish directory, a directory named builds will be created to hold the generated builds, including build logs, published artifacts, etc. If these two directories are set as empty value, they will inherit settings from the parent configuration. If you specify a relative path, it is assumed that the path is relative to the parent's working or publish directory.

    • Repositories

      Create the CVS repository on this page. Pay particular attention to the CVS executable path property which we assign the value ${var["cvs"]}. The expression embedded in ${...} is OGNL expression. Almost all text properties in QuickBuild can embed OGNL expressions as long as they are surrounded by ${...}. Root of the OGNL expression is always the current configuration object. We are referring to the variable of the name "cvs" in the configuration object. For all properties that can be used in your OGNL expression, please refer to OGNL reference section.

      Variables can be defined in higher level configuration, and inherited and overrided by descendent configurations. With this nature, it can be used to simplify configuration definitions when there are many configurations to maintain ( for example, by defining CVS executable path as a variable in root configuration, you don't need to change configurations one by one when upgrade to a new version of CVS. Instead, you only need to change the variable definition in root configuration).

      Multiple repositories can be defined. Particularly, for the newly created repository, if you choose a name that is the same as another repository defined in ancestor configuration, the newly created repository will override the previously defined one. This is also true for builders and steps. So you can define common objects in ancestor configurations, and define particular objects specific to particular child configurations in descendant configurations. This makes configuring new builds quite simple.

    • Builders

      Create the Ant builder on this page. Here again we use OGNL expressions in Path to Ant executable and Build properties. Take a look at Build properties, we are passing several properties to Ant. Among them, buildVersion is used to pass the current build version; artifactsDir is used to pass the directory path to which your build results should be copied. This directory is a sub directory of the current build publish directory, and it is called artifacts. The current build publish directory is a sub directory named by the build version under the current configuration's publish directory. junitHtmlReportDir is used to pass directory, where you should store your JUNIT html reports. cloverHtmlReportDir is used to pass directory, where you should store your Clover html reports. Of course you can choose property names other than artifactsDir or buildVersion, as long as you refer to these property names in your Ant build script file.

      [Note]Note

      Besides copying build results into the directory indicated by OGNL expression ${build.artifactsDir}, you can also use the publish artifacts step to publish build results.

      Multiple builders can be defined. Particularly, for the newly created builder, if you choose a name that is the same as the name of another builder defined in the ancestor configuration, newly created builder will override the previously defined one.

      Let's take a look at what should be done in your Ant build script file. After you have successfully run the build, change to directory <QuickBuild installation directory>\working\root\basic-samples\sample1\checkouts, and you'll find checked out files and directories from the configured CVS repository. Change to directory sample1\build, and open file build.xml; pay attention to the target distribute. This target creates distribution file under the directory defined by property artifactsDir. Also in target test, we generate JUNIT html report into the directory defined by property junitHtmlReportDir; in target cloverreport, we generate Clover coverage report into the directory defined by property cloverHtmlReportDir. This way, we can access build results, JUNIT html report, and Clover html report from QuickBuild's web interface.

      [Note]Note

      There are two methods to make build results accessible from QuickBuild's user interface:

      1. Save build results under directory defined by artifactsDir property. This is what we do in this use case.

      2. Put build results in any directory you want, and use the publish step to create soft links under directory defined by artifactsDir property. These soft links will point to your build results. This is what we will do in the next use case.

      [Note]Note

      Clover html report will only be generated if you have installed Clover.

    • Notifiers

      Create desired notifiers on this page. We've defined an Email notifier. This notifier will be used when we define the notification step, which is used to send failed build notification to users who has checked in since the last successful build. Message title and body for this notifier can be customized by using Velocity template. Notification sent out using this notifier will contain links to appropriate configuration, build, build log, revision log, and also several lines surrounding the error line in the build log.

      [Note]Note

      You can define your notifiers in a high level configuration, so that they can be used by every descendant configuration without need to re-define them.

    • Steps

      Create desired steps on this page. We've defined four steps, check out from cvs, build with ant, create label for successful builds, send notification for failed builds and default, respectively. Pay particular attention to the default step. Actually, when the configuration runs, QuickBuild will only locate and execute the default step (will look for this step in ancestor configurations if not found in thecurrent configuration; the same is true about the other steps). As you may have noticed, that the default step is a serial composite step that will trigger other three steps one by one.

    • Login mappings

      This page is used to map repository logins to QuickBuild users. As you see in steps definition, after a failed build, the send notification for failed builds step will collect CVS logins of users who has checked code into CVS repository since the last successful build, and it will send notifications to those users. Before this notification is send, these logins should be mapped to the corresponding QuickBuild users in order to get contact information for those users such as Emails, MSN messenger accounts, etc. When you define repositories, you can refer to these login mappings, so that logins in those repositories can be resolved to the correct users in QuickBuild system.

      [Note]Note

      You can define your login mapping objects in a high level configuration, so that they can be used by every descendant configuration without need to re-define them.

    • Child configurations

      Create child configurations under the current configuration. Currently it is the only place to create, delete or move configurations.

Working with Maven

Check out the code from CVS, and build it with Maven. Instruct Maven to use version managed by QuickBuild, and publish artifacts to Maven repository also accessible from QuickBuild's web interface.

  1. Access http://livedemo.pmease.com:8081, trigger the configuration root.basic-samples.maven-sample with force build option. QuickBuild should check out the code from CVS repository and trigger the maven builder. During the build, Maven publishes generated artifacts to /maven-repository (configured in file <current configuration's checkouts dir>/maven-sample/project.properties). Of course, you can change the local repository to any other directory if you like.

  2. You now have successfully ran the build with Maven integration. On build detail page, you should see several files are listed there as published artifacts. Please note that these files are actually located in Maven repository. They appear here because symbol links to them are created under the artifacts directory of the current build. This was done by setting "Is create symbol links" option to "yes" when define the step of type publish artifacts (see steps tab of this configuration). In this step, we specify /maven-repository/maven-sample/jars as source directory for publishing, and specify maven-sample-${build.version}.* as the file name pattern. Before this publish step runs, OGNL expression in this pattern will be replaced with the current build version, for example, 1.0.3, and the publishing file name pattern will actually be maven-sample-1.0.3.*, which means all files under the source directory with the file name starting with maven-sample-1.0.3 will be published in the artifacts directory of the current build, that is, symbol links to these files have been created under the artifacts directory.

    [Note]Note

    If your build version contains spaces, you should surround the pattern maven-sample-${build.version}.* with double quotes; otherwise, it will be treated as multiple patterns separated by spaces.

  3. Maven is using version number managed by QuickBuild as the current version. This is done in two steps:

    • When you define Maven builder, pass in a property named buildVersion (You can choose other name of course), and set its value to be "${build.version}". Here quotes are used just in case that the evaluated OGNL expression contains white spaces.

    • In the project definition file (<checkouts dir>/maven-sample/project.xml here), instruct Maven to use the value passed in the buildVersion property as the current version:

      <currentVersion>${buildVersion}</currentVersion>
  4. For Maven2, please refer to configuration root.basic-samples.maven2-sample.

Working with project dependencies

Some of my products depend on common components. For flexibility, create separate build for these components. Before you build the products that depend on common component(s), common components should be checked first to see if they need to be re-built.

  1. Let's assume that we have two Java projects: productA and componentA. productA uses build result (componentA-xxx.jar) of componentA, and thus depends on componentA.

  2. Create the configuration for the componentA, say root.componentA. This configuration checks out the code for the componentA from CVS repository, builds with Ant and generates componentA-xxx.jar in the current build artifacts directory. This Jar file is needed by productA.

  3. Create the configuration for projectA, say root.productA. Set up the following in this configuration:

    • Create repositories:

      repository1

      This repository is a CVS repository which is used to check out the source code of the productA from CVS.

      repository2

      This repository is a QuickBuild repository which is used to check out componentA-xxx.jar from the latest build of the configuration root.componentA. Modules information are set up so that componentA-xxx.jar will be placed into the directory <configuration root.productA's checkouts directory>/productA/componentA.

    • Create an Ant builder to build productA. In the build script file, it uses Jar file generated by componentA.

    • Create steps:

      check out productA from CVS

      This step uses the repository1 to check out the source code of the productA from CVS.

      check out build results of componentA

      This step uses the repository2 to check out the componentA-xxx.jar from CVS.

      create label

      This step does the following:

      • Creates a label of the source code of the productA in CVS.

      • Creates a label of the root.componentA to mark the build number of the componentA whose artifacts are used by this version of the productA.

      default

      This step is a serial composition step that runs the above five steps serially.

  4. Now the productA is dependent on the componentA. When the root.productA is triggered, the root.componentA will also be triggered to see if it is necessary to built it, and the build results of the componentA will be checked out to the work space of the productA to accomplish the productA's build.

    [Warning]Warning

    When you set up a configuration to be dependent on another configuration, you should never let the configuration to share the same working directory. Otherwise, deadlock will happen. See here for the reason.

  5. A live demo is available at http://livedemo.pmease.com:8081. In this live demo:

    • root.basic-samples.sample4.productA represents the root.productA.

    • root.basic-samples.sample4.componentA represents the root.componentA.

Trigger other builds after build of a particular project

productA depends on componentA. After componentA finishes build, productA should be built to make use of the most up-to-date artifacts of componentA.

[Note]Note

This scenario can not be addressed through project dependency use case, because the dependency mechanism only guarantees that build of projectA can trigger the build of the componentA, but not vice versa.

  1. Let's assume productA corresponds to configuration root.productA, and componentA corresponds to root.componentA.

  2. Edit configuration root.componentA to add a step of type "trigger build in another configuration" with the following properties:

    Remote QuickBuild URL

    Specify QuickBuild servlet URL if configuration root.productA runs in a different machine than root.componentA. Otherwise, leave it empty.

    Configuration

    root.productA

    All other properties

    Specify proper value for all other properties

    Configure this step into the execution series of the default step, and set it as the last step. With this step, build in other configurations can be triggered after current build finishes. Of course, you can configure multiple steps of this type to trigger build for more than one configuration.

  3. A live demo is available at http://livedemo.pmease.com:8081. In this demo:

    • root.basic-samples.sample7.productA represents root.productA.

    • root.basic-samples.sample7.componentA represents root.componentA.

Working with multiple branches

I want to set up build for multiple branches of my product. I do not want to enter the repositories or the builders information multiple times for each branch, how can I do that?

  1. Let's assume that you want to set up the build for two branches of your product: bugfix and main. First set up a configuration for your product, say root.product1. In this configuration, set up the information such as repositories, builders, and steps. Particularly, for branch property of your repository, set it to: ${var["branch"]}. This means that the value of the branch variable defined in your configuration will be used as actual branch to check out.

  2. Create configuration bugfix under the root.product1. In this configuration, you only need to set up the next build version and define the following variable:

    branch=bugfix

    This way, the configuration root.product1.bugfix is set up to build against the bugfix branch of your repository.

  3. Create the configuration main under root.product1. For this configuration, you only need to set up the next build version and define the following variable:

    branch=

    This way, the configuration root.product1.main is set up to build against main branch of your repository.

    [Note]Note

    An empty value for the branch field means main branch.

  4. A live demo is available at http://livedemo.pmease.com:8081. In this live demo:

    • root.basic-samples.sample6.bugfix branch represents root.product1.bugfix.

    • root.basic-samples.sample6.main branch represents root.product1.main.

Working with configuration inheritance and overriding

I want to set up nightly, test, and release build for a project. The nighty build should not label the source code at any time, while test and release build should label the source code for each successful build. The repository and builder information of these three configurations is the same. Is there any way to only input the repository and builder information just once and reuse them in all of the three configurations?

  1. The configuration root.basic-samples.sample3 running at http://livedemo.pmease.com:8081 is demonstrate this use case. It holds all repository, builder and step definitions. And its child configurations (nightly, test and release) inherits these objects, but have independent working directory and next build version value.

  2. The nightly configuration defines an extra step "label CVS" to override the step with the same name in parent configuration, and the step necessary condition is set to false. In this way, builds in nightly configuration will never create label on source code even when the build is successful.

Sharing working directories

In the above use case, every child configuration of "root.basic-samples.sample3" has its own working directory and holds its own copy of checked out code from CVS. For a large project, this may consume a lot of disk space. Is there any way to check out only one copy of code for these three child configurations?

  1. By default, a newly created configuration will use ${name} as the value of the working directory property. This means that the new configuration will create a sub directory under working directory of its parent configuration, and name of the sub directory will be the same as the name of the newly created configuration. So there will be three different working directories for the nightly, test and release configurations. In order to use the same working directory for these three child configurations, the simplest way is to leave their working directory property empty. Then they will all use the parent configuration's working directory. Of course, you can point them to any arbitrary directory, as long as they all refer to the same directory.

  2. Now the nightly, test and release configurations have the same working directory, and there will be only one copy of the code checked out for the build, which resides in the <working directory>/checkouts.

    [Note]Note

    For configurations sharing the same working directory, only one configuaration can be executed at the same time. If you trigger other configurations while one configuration is already running, the newly triggered configuration(s) will be put in the queue, until the current one has finished its execution.

    [Note]Note

    If multiple configurations share the same working directory, and some of them are configured to incremental build, it is highly recommended that all these configurations check out the same set of the source code, build with the same set of builders. Otherwise, increment builds may be incorrect if the code is incrementally updated based on a different code base.

Sharing build versions

In use case working with configuration inheritance and overriding, I want all child configurations share the same stream of build version. That is, if the most recent build (among all child configurations) has version "myproduct-1.0.1 build 4", then the next build should have version "myproject-1.0.1 build5" without regard of its configuration.

  1. In the basic settings tab of the configuration root.basic-samples.sample3, set the value for the property next build version, for example: myproduct-1.0.1 build 1.

  2. For all child configurations under the root.basic-samples.sample3, set an empty value for the property next build version. Then all the child configurations will inherit the next build version from the parent configuration, that is, share the same stream of the build version. If the next build version of the parent configuration is also empty, it will inherit the value from its parent, until non-empty value is found or until the root configuration is reached.

Using date and iteration as part of build version

In use case working with configuration inheritance and overriding, I want the current date and iterations of the current date can be embedded into build version of the child configurations.

  1. Let's take the test child configuration as example. From the drop down menu of the property next build version, choose date and iteration, a complicated value that contains quite a lot of OGNL expressions will be used for next build version. It will generate versions like 2005-Sep-25.4 as default, where 2005-sep-25 is the date of the build, and 4 means iterations for this date.

  2. If you are not satisfied with this default format, you can modify the value of the next build version. Before doing this, make sure you know the grammar of OGNL expressions as well as date and time properties in QuickBuild. For example, you can add the string myproduct-QA- at the very start of the next build version. Then the version generated will be myproduct-QA-2005-Sep-25.4, myproduct-QA-2005-Sep-25.5, etc.

    [Note]Note

    When you choose date and iteration as the next build version, and then you run the configuration, QuickBuild will automatically put two variables in the current configuration, day and dayIterator. For the variables that have not been defined (either in the current configuration or in the ancestor configurations), QuickBuild will assume that it has an empty value when referenced as string, or 0 when referenced as number. QuickBuild will automatically create these variables in the current configuration if they have assigned values.

Managing major, minor, and iteration part of the version string

In use case working with configuration inheritance and overriding, I want to define a version schema with major release part, minor release part and iteration part. Major release part will be set manually. The "Release" configuration increases minor release part of the version, while "QA" configuration increases QA iteration part of the version. When minor release part of the version changes, QA iteration part should be reset to 1.

  1. Access http://livedemo.pmease.com:8081, we'll take the configuration root.basic-samples.sample3 for example. The following variables are defined in this configuration:

    major_release=myproduct-1.0
    next_minor_release=1
    next_qa_iteration=1
  2. next build version of configuration root.basic-samples.sample3.QA is defined as:

    ${var["major_release"]}.${var["next_minor_release"]} QA#${var["next_qa_iteration"].increaseAsInt()}
  3. next build version of configuration root.basic-samples.sample3.Release is defined as:

    ${var["major_release"]}.${var["next_qa_iteration"].setValue(1), var["next_minor_release"].increaseAsInt()}
  4. In this way, generated builds in configuration root.basic-samples.sample3.QA (make sure to leave the build as version property as empty when your trigger the configuration) will use versions like: myproduct-1.0.1 QA#1, myproduct-1.0.1 QA#2, myproduct-1.0.1 QA#3, ...., myproduct-1.0.2 QA#1, myproduct-1.0.2 QA#2, ..., and generated builds in configuration root.basic-samples.sample3.Release will use versions like: myproduct-1.0.1, myproduct-1.0.2, myproduct-1.0.3, ...

Specifying label to build against

I have set up a configuration to build against latest code of my project. But, when I build this project manually, I want to be able to specify the label to build against. Is there anyway to do this?

  1. Open the configuration root.basic-samples.sample5 and check modules definition of its CVS repository setting. You'll find that the label value of the source path sample1 has the value of ${var["label"]}. And in the basic settings tab of this configuration, a variable label was defined with an empty value like this:

    label=

    It means that this configuration will build against the latest code unless you specify a non-empty value for the variable label.

  2. Now forcibly trigger this configuration, and in the Editing manual trigger settings page provide a different value for the label variable like this:

    label=myproduct-1_0_0 

    This way, the configuration root.basic-samples.sample5 is triggered to be build against the label myproduct-1_0_0.

    [Tip]Tip

    By using variables, you can override almost any part of repositories, builders, or steps definitions when you manually trigger the build. It is also possible to override these variables in the child configurations, which gives you the flexibility to modify part of objects defined in the ancestor configurations.

Updating information for many projects

I have a CVS server with many projects, and I have set up dozens of configurations for these projects in QuickBuild. After sometime, server name (or ip address) of our CVS server has changed. Now I need to go through all the defined repositories and change the server name (or ip address) accordingly. Is there any simple way to do this? How can I handle such kind of batch processing?

  1. Define a variable for example cvsServerName in a high level configuration (a proper candidate for this high level configuration can be your department's or team's root configuration), and set its value to server name or ip address of your CVS server.

  2. Refer to the above variable when you define CVS root of your repositories, for example:

    :pserver:build@${var["cvsServerName"]}:/cvsroot

    Now if you want to point all your CVS repositories to the new CVS server, simply modify the value of the variable cvsServerName.

    [Tip]Tip

    It is a good idea to extract dynamic parts (that maybe changed frequently) of repositories, builders and steps, and then create the variables in higher level configurations. Then you can easily change the property of all affected objects.

Working with build queues

I have set up a number of configurations for projects of deparment1, and all of them are under the configuration "root.department1". Now I want to make sure that at the same time, only two builds can be performed for this department in order to save CPU resources for other departments.

  1. Create a queue, say queue_department1, with two working threads.

  2. Edit the root configuration, and set the build queue to queue_department1 (This step is necessary in order to use queue_department1 even if administrator of the root.department1 sets the build queue to inherit from parent).

  3. Assign the users of department1 to groups with only queue_department1 authorized.

  4. Then the configuration subtree under the root.department1 is limited to only use queue_department1.

Working with public configurations

I want to make artifacts of some projects to be publicly accessible, but I do not want these projects to be modified or built publicly.

  1. Set up publicly accessible projects under a particular configuration, for example, root.public.

  2. Add a group named anonymous, and configure this group to have View permission on the configuration subtree rooted at root.public.

  3. Then anonymous users can only access the configurations under the root.public, without the permission to build or edit these configurations.

Working with RSS

I want to be notified of failed build of configuration root.project1 through RSS.

  1. From QuickBuild web interface, switch to "FIND BUILDS" tab, and provide below properties as search criterions:

    Status

    failed

    Configuration

    root.project1

    All other search criterion properties should be left empty.

  2. Click the search button, and the matching builds will be presented with an XML button at right side of the search results header.

  3. Paste link of the XML button into your RSS reader. Note that you need to make configuration root.project1 publicly accessible; otherwise your RSS reader should be able to authenticate as proper user against QuickBuild.

  4. Your RSS reader should now be able to pull contents from QuickBuild. Channel name of the RSS is explained here.