This documentation relates to an earlier version of Bamboo.
View

Unknown macro: {spacejump}

or visit the current documentation home.

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

Step 1 - Adding configuration views

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.

Edit Configuration View

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.

Display Configuration View

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.

Registering the views in the Plugin Descriptor

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:

Step 2 - Adding validation

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.

Step 3 - Applying the configuration

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).

  • ラベルなし