Overview
This article describes how to capture a snippet of command output from a pulse™ build and include that output in an email notification message.
Note that there are alternative ways to approach this problem, each with their own pros and cons. The approach described in this article uses post-processing to extract the output and a custom subscription template to include it in an email. This approach leverages as much as possible of what is already built-in to pulse™, so requires less total code. A valid alternative would be to use a post-build hook with a run executable task to launch a custom script. This script could query for build details via the remote API, giving greater control of available information at the cost of greater work to write the script.
Extracting the Output
To extract interesting "features" like error and warning messages from command output, pulse™ uses post-processors. Apart from errors and warnings, a third feature category is reserved for informative features. As this category is not used by any built-in processors, it is suitable to use for extraction of an arbitrary chunk of output.
The easiest way to extract the desired output is by defining a regular expression post-processor. To do so, you need to define a regular expression which matches part of a line of the output you want to capture. You can capture the surrounding lines by specifying a leading and trailing context. To use such a custom processor, you must either:
- Define the new processor in the "post-processors" section of your project configuration; or
- Write your pulse file by hand.
We will use the latter method below.
As an example, you can create a simple custom project that runs an ant build. For this I will assume you have a basic ant build file handy with a sensible default target. The custom pulse file will look like:
<?xml version="1.0"?>
<project default-recipe="ant build">
<recipe name="ant build">
<ant name="build"/>
</recipe>
</project>
A successful ant build using this produces output like:
Buildfile: build.xml
default:
BUILD SUCCESSFUL
Total time: 1 second
To capture the BUILD SUCCESSFUL message and the two lines before and one line after it, we can define and apply a regular expression post-processor by modifying your custom pulse file as follows:
<?xml version="1.0"?>
<project default-recipe="ant build">
<regex.pp name="extract.output" leading-context="2" trailing-context="1">
<pattern category="info" expression="BUILD SUCCESSFUL"/>
</regex.pp>
<recipe name="ant build">
<ant name="build">
<process processor="$(extract.output)"/>
</ant>
</recipe>
</project>
The processor may be verified by running a build and drilling down to the build command on the "detailed view" tab. This should show an info feature which contains:
default:
BUILD SUCCESSFUL
Total time: 1 second
Including the Feature in an Email
By default, pulse™ notification emails do not include info features. However, it is possible to include them by using your own custom subscription template. These templates are stored in $PULSE_DATA/config/templates/notifications/project-builds. You should find an example template in that directory already. The templates consist of a couple of parts:
- A properties file that defines the name of the template in the pulse™ UI and the email MIME type.
- A FreeMarker
template which is evaluated to form the body of the email.
- An optional subject template which is evaluated to form the subject of the email. If not present a default subject is used.
To begin, create the file extracted-output-email.properties with contents:
display=extracted output email
type=text/plain
This means that the template will be named "extracted output email" in the web UI, and the email will be plain text. Next, create the file extracted-output-email.ftl with contents:
[#ftl]
Project: ${result.project.name}
Number : ${result.number?c}
Status : ${result.state.prettyString}
Link : ${buildLink(result)}
Output:
[#list result.root.children as stage]
[#list stage.result.commandResults as commandResult]
[#list commandResult.artifacts as artifact]
[#list artifact.children as fileArtifact]
[#list artifact.getFeatures(infoLevel) as feature]
${feature.summary}
[/#list]
[/#list]
[/#list]
[/#list]
[/#list]
The important part of this template is the nested set of loops that drills down to the info feature which is captured by our post-processor. Notice it needs to drill down through the whole build structure as the feature is associated with the output artifact where it was captured.
Subscribing
Finally, to receive an email notification using your new template, you need to subscribe to project build results for your project. To do so, go to your preferences and (if you have not already) create a contact point for the desired destination email address. Then, add a new subscription to project builds for your custom project, and select the "extracted output email" template from the drop-down list. To test your subscription, trigger a build of the project. When it completes you should received an email that looks something like:
Project: my-project
Number : 3
Status : success
Link : http:
Output:
default:
BUILD SUCCESSFUL
Total time: 1 second
That's it!