すべてのバージョン
Bamboo 5.13Bamboo 5.7.x
Bamboo 5.6.x
More...
In the previous tutorial, we have made our plugin label the build whenever the logs had the words "OutOfMemoryError". This, however, is not very useful for the other builds which don't have this memory problem. Also, it is not very useful to only be able to tag with "out_of_memory". In this tutorial, we will extend on the plugin module so that we can configure when to label, and what to label a build with.
The source code to the plugin used in this tutorial is available on the Atlassian public source repository. You can check out the source code here
To do this, we must first add the views for configuring the labeller. The BuildCompleteAction
module type comes with the capability to accept Freemarker templates which allows you to edit and view custom configuration in the Build Plan Configuration page, under the Post Action tab.
The Freemarker template to edit our Labeller configuration is below (regexLabellerEdit.ftl
):
[@ui.bambooSection title='Pattern matching labellling.' ] [@ww.textfield name='custom.bamboo.labeller.regex' label='Regex Pattern' description='The regular expression for which to match the log files on.' /] [@ww.textfield name='custom.bamboo.labeller.label' label='Label(s)' description='The label(s) for the build if it matches the specified regex pattern.' /] [/@ui.bambooSection ]
Here, we define a section with a title 'Pattern matching labelling.' Inside our configuration section are two text fields, one for the regex expression for matching against the logs, and one for the label(s) that we want to tag a build with if the regex expression matches.
We have named our two text fields custom.bamboo.labeller.regex
and custom.bamboo.labeller.label
. These are the keys to your custom configuration property stored in Bamboo.
Please note that these keys must start with "custom." for Bamboo to recognize and store within the plan's configuration. You may also notice that the keys are "namespaced". This is a good idea to prevent a clash of custom configuration properties.
We also define a Freemarker view for viewing the configuration (read-only). The display configuration view is below (regexLabellerView.ftl
):
[#if build.buildDefinition.customConfiguration.get('custom.bamboo.labeller.regex')?has_content ] [@ui.bambooInfoDisplay titleKey='Pattern Matching Labelling' float=false height='80px'] [@ww.label label='Regex Pattern' ] [@ww.param name='value']${build.buildDefinition.customConfiguration.get('custom.bamboo.labeller.regex')?if_exists}[/@ww.param] [/@ww.label] [@ww.label label='Labels' ] [@ww.param name='value']${build.buildDefinition.customConfiguration.get('custom.bamboo.labeller.label')?if_exists}[/@ww.param] [/@ww.label] [/@ui.bambooInfoDisplay] [/#if]
Here we simply build display the configuration by retrieving your custom properties via the same keys we used in the edit view.
We need to register these two Freemarker templates as part of our BuildCompleteAction
module. We do this by adding <resource>
tags with the file path of the templates within the module descriptor definition.
<buildCompleteAction key="labeller" name="Build Labeller class="com.atlassian.bamboo.plugins.labeller.BuildLabeller"> <description>An automatic labelling plugin.</description> <resource type="freemarker" name="edit" location="templates/buildCompleteAction/regexLabellerEdit.ftl"/> <resource type="freemarker" name="view" location="templates/buildCompleteAction/regexLabellerView.ftl"/> </buildCompleteAction>
Once that's done, we can see the templates in action.
Under the edit configuration page:
And under the view configuration page:
Inserting the templates has allowed us to view and edit custom plan configuration properties. However, we should validate the input we provide for the BuildLabeller
, to catch invalid labels or regex patterns.
This is where we use the validate
method within our BuildLabeller
class, which we have previously left to return null
in the first tutorial. Bamboo will run this validate method before trying to save custom configuration properties.
/** * This method is used to validate a build configuration for a build plan * * This is used if the CustomBuildCompleteAction needs to have configuration stored * against the build plan. * * @param buildConfiguration * @return */ public ErrorCollection validate(BuildConfiguration buildConfiguration) { // Check the label values to see if they have any invalid characters ErrorCollection errors = new SimpleErrorCollection(); String labelInput = buildConfiguration.getString("custom.bamboo.labeller.label"); List labels = LabelParser.split(labelInput); for (Iterator iterator = labels.iterator(); iterator.hasNext();) { String label = (String) iterator.next(); boolean validLabel = LabelParser.isValidLabelName(label); if (!validLabel) { errors.addError("custom.bamboo.labeller.label", label + " contains invalid characters " + LabelParser.getInvalidCharactersAsString()); } } // See if the regex is a valid one by trying to compile it String regex = buildConfiguration.getString("custom.bamboo.labeller.regex"); try { Pattern.compile(regex); } catch(PatternSyntaxException e) { errors.addError("custom.bamboo.labeller.regex", regex + " is not a valid regex pattern."); } return errors; }
The BuildConfiguration
object passed to the validation method is the in-memory version of the build plan configuration. You can get your custom property by simply calling getString
on the object, providing the custom property key that you used in the Freemarker templates.
At this stage, we can edit, validate, and view our custom configuration for this plugin module. We now need to modify our original run
method within the BuildLabeller
to read the custom configuration properties.
/*** * This action will run after a build has completed. * * The build will be tagged with a specified set of labels if the logs matches the specified regex pattern. * * @param build * @param buildResults */ public void run(Build build, BuildResults buildResults) { // grab the custom configuration object Map customConfiguration = build.getBuildDefinition().getCustomConfiguration(); if (customConfiguration != null) { if (customConfiguration.containsKey("custom.bamboo.labeller.label")) { List logs = buildResults.getBuildLog(); String pattern = (String) customConfiguration.get("custom.bamboo.labeller.regex"); Pattern regexPattern = Pattern.compile(pattern); // Go through the logs for (Iterator iterator = logs.iterator(); iterator.hasNext();) { SimpleLogEntry log = (SimpleLogEntry) iterator.next(); Matcher matcher = regexPattern.matcher(log.getLog()); // Use a matcher to see if the logs contained the specified regex if (matcher.find()) { String labelsInput = (String) customConfiguration.get("custom.bamboo.labeller.label"); // Our configuration also allows for multiple labels. List labels = LabelParser.split(labelsInput); for (Iterator iterator2 = labels.iterator(); iterator2.hasNext();) { String label = (String) iterator2.next(); getLabelManager().addLabel(label, buildResults, null); } break; } } } } }
So that's it! We have now completed a Bamboo plugin containing one BuildCompleteAction
module which will match the output logs against a regular expression, and tag it with a set of label(s).