To understand how pulse™ works, you need to understand builds. The purpose of the build is to ensure the integrity of the code line being built: ensuring it compiles and passes all relevant tests. Additionally, the build may produce output artifacts to be downloaded from the pulse™ server (e.g. nightly build packages).
A build in pulse™ is made up of one or more build stages which are executed independently (and possibly in parallel). The purpose of stages is to allow parallel testing and testing in multiple environments. Each stage involves the execution of a recipe on a build agent. A recipe is a sequence of commands executed to build and test a project. Commands will typically perform some or all of the following actions:
- preparing the working copy to be built
- compiling the project source code
- running project tests
- executing various static analysis tools over the source code
- packaging project artifacts into archives
The commands executed are not restricted to the list above, and are completely up to you.
To describe to pulse™ how to build your software, you need to provide some information via the web interface. Firstly, you need to add a project for each code line that you want to build. Projects are configured in a template inheritance hierarchy to allow similar build scenarios to be configured efficiently. For example one project may be used for continuous integration builds and another for nightly builds, but both can share many details in a common template.
Within a project you configure the build stages to execute, and indicate which agent they should be executed on. It is also possible to dispatch a stage to any capable agent by configuring the resources required for the stage. All stages in a project are executed when that project is triggered, and the result of the build is a combination of the results for all stages. This allows a single project to cover testing across multiple agents: the build will only pass if it executes successfully in all tested environments.
To configure the commands run as part of a stage, you need to configure recipes. For simple projects, a default recipe is defined for you when you create the project. For example, for a single-step Ant project you provide the location of the build.xml file and the targets to execute, and a simple recipe with a single Ant command is created for you. For more complicated projects you can define one or more recipes yourself using a multi-step project or a pulse file project.
To illustrate the concepts introduced above, consider a typical Java project built with Apache Ant. The project is built and tested from the command line by executing:
To set this project up in pulse™, you would go to the "administration" section to add a new single-step project. In the wizard, you configure the project name, the location of the project's source code (i.e. the SCM server details), and the Ant build file and targets (test.all) used to execute the build. With just that configuration, your project will be configured with a default build stage that can be used to execute the build. This build stage will execute the default project recipe on any capable agent.
Multi Platform Testing
Now imagine the project is designed to run on Linux, Solaris and Windows, and needs to be tested on each platform. To facilitate this you can use multiple build stages, one for each platform, all as part of one project. The stages will all execute the same recipe, but will be configured to execute on different agents. One agent will be running Linux, the second Solaris and the third Windows. Now every time the project is built the stages will run in parallel on the three agents. The build will only succeed if the all of the stages succeed.
Taking It Further
This example is just the beginning. There are many other things you can do as part of a build, including:
- taking complete control over recipes by writing a pulse file by hand
- capturing build artifacts (such as Jar files, packages and HTML reports) and making them available via the pulse™ web interface
- applying post-processors to command output and artifacts to detect errors and warnings (e.g. by regular expressions)
- integrating test results into the build result information
- running build hooks to tag project source code
You can also subscribe to build notifications in a very flexible manner.
To further illustrate how builds work, the build lifecycle is outlined below:
- A trigger fires, queuing a build for a given project to the build queue.
- When the project is free to build (i.e. no other builds are in progress for the project), a request to build the appropriate recipe for each stage in the project is added to the recipe queue.
- Each recipe request remains queued until a capable agent is available to execute the recipe.
- The recipes are dispatched to the recipe processor on an available agent:
- The recipe processor checks out a working copy of the project source code.
- The recipe processor executes each command in the recipe in order, until a command fails or the recipe is complete.
- The results of the stage and captured artifacts are collected to a permanent storage location on the master.
- When all stages are complete, the build itself is complete.
- Build notifications are sent to subscribed users.
Note that the stages in a build all run independently, and in parallel where possible.