Rate this page:
Available: | Bamboo 3.1 and later |
"Hello World" plugin example is not provided by Atlassian Plugin SDK default project anymore. But you can create a similar one by using this tutorial: Introduction to writing tasks
The Bamboo "Hello World" plugin is the example Bamboo plugin that ships with the Atlassian Plugin SDK default project. In this tutorial we break down the plugin and explain how to build a User Interface and add validation.
First download the copy of the latest Plugin SDK and install it on your machine.
Run atlas-create-bamboo-plugin from the command line.
When asked for the groupId, artifactId and package just enter "helloworld" and leave the other options as the defaults.
The "Hello World" plugin is the example plugin from the SDK that demonstrates how to build a Task plugin with a User Interface, validation and internationalisation. The plugin is very simple. It allows a user in Bamboo to configure the Task so that it prints a user configured value to the log and returns a successful TaskResult.
You have to have administrator's permissions to do that.
The first account you've registered on your server instance must have such permissions by default. Otherwise you could try to use login 'admin' with password 'admin'.
To try the default Hello World plugin out run the atlas-run command from the root of the project you generated when you started the tutorial. Once Bamboo is up, create a new Plan with a "None" repository type and configure the Job to contain the "Hello World" Task.
Try removing the default value in the "Say" field and saving. You should see a validation error like the one below:
Thats the validation we have defined in the Configurator. We will show you how to add your own validation in a moment. Change the "Say" field value to be "Hello, World!" then save the task then run your plan. Once the plan has completed running you should see the plugin executing and printing "Hello, World!" in the default Jobs logs
We will now break down the plugin into its components and explain how its put together.
We covered what a TaskType is and how it works in the Introduction to Tasks tutorial. This Task takes the a value out of the configuration map using the key "say" and adds a new entry with its value to the build log and returns a successful TaskResult.
From ExampleTask.java
1 2public class ExampleTask implements TaskType { @NotNull @java.lang.Override public TaskResult execute(@NotNull final TaskContext taskContext) throws TaskException { final BuildLogger buildLogger = taskContext.getBuildLogger(); final String say = taskContext.getConfigurationMap().get("say"); buildLogger.addBuildLogEntry(say); return TaskResultBuilder.create(taskContext).success().build(); } }
Lets have a look at the Hello World plugins templates. Bamboo uses the WebWork web framework and the Freemarker templating language to render its user interface. There are numerous tags available from WebWork that can be used from within freemarker to map values in the Configurator to elements in the user interface (we will talk more about the Configurator in a moment).
From editExampleTask.ftl
1 2[@ww.textfield labelKey="helloworld.say" name="say" required='true'/]
This template provides the configuration form for the Task. We use a textField
here to provide input. The labelKey
value helloworld.say
maps to a property defined in the english.properties
file that provides the translation and the name
specifies what the value of the textField
should be in the Configurator. In this case we always want the user to specify a value for the field so we mark it with the required
attribute with the value set to true
.
So whats a TaskConfigurator? A TaskConfigurator is a class that controls what objects and values are available when rendering the User Interface, how input is persisted and validated.
In our example we use the AbstractTaskConfigurator class instead of the TaskConfigurator interface as its possible you may not need to implement all of its interface members.
To save your configuration you need to override or implement the generateTaskConfigMap method on your TaskConfigurator.
From ExampleTaskConfigurator.java
1 2public Map<String, String> generateTaskConfigMap(@NotNull final ActionParametersMap params, @Nullable final TaskDefinition previousTaskDefinition) { final Map<String, String> config = super.generateTaskConfigMap(params, previousTaskDefinition); config.put("say", params.getString("say")); return config; }
When the user saves the Task the generateTaskConfigMap
method is called and a ActionParametersMap and TaskDefinition is provided.
The ActionParametersMap contains all the form parameter keys and values from the input fields of the editExampleTask.ftl
. The TaskDefinition is the saved state of the Task within Bamboo. It contains its user description and its map of configuration key/values. One thing to note is that if the Task is being created the TaskDefinition instance here is null but if it is being edited it contains the previous state of the Task before the user changes it.
Remember the field named "say" in the editExampleTask.ftl
? Well the value set by the user for this field is available in the ActionParametersMap. In order to persist the value in a new TaskDefinition we must return a new map that contains this value. For simplicity sake we use the same key for this value as was used as the name of the field.
From ExampleTaskConfigurator.java
1 2public void validate(@NotNull final ActionParametersMap params, @NotNull final ErrorCollection errorCollection) { super.validate(params, errorCollection); final String sayValue = params.getString("say"); if (StringUtils.isEmpty(sayValue)) { errorCollection.addError("say", textProvider.getText("helloworld.say.error")); } }
Before the generateTaskConfigMap
is called the ActionParametersMap
is validated to ensure it contains the correct values needed to create the new TaskDefinition
in generateTaskConfigMap
. Validation is simple. If the field does not pass your Tasks validation rules you simply call addError on the ErrorCollection with the name of the field that did not pass validation and a message about why it failed.
In this method you can set the default configuration of your Task when it is being created by populating the given context
map with the key of the field and the value you want it to contain.
From ExampleTaskConfigurator.java
1 2@Override public void populateContextForCreate(@NotNull final Map<String, Object> context) { super.populateContextForCreate(context); context.put("say", "Hello, World!"); }
Once your Task has been created the populateContextForEdit
can be used to show the configured values of the Task. Simply populate the given context
map with the values stored in the map on the TaskDefinition
(These are the values you set to a new map from the ActionParametersMap
in the generateTaskConfigMap
method). Like populateContextForCreate
, the keys of the context
map should match the field names in your templates.
From ExampleTaskConfigurator.java
1 2@Override public void populateContextForEdit(@NotNull final Map<String, Object> context, @NotNull final TaskDefinition taskDefinition) { super.populateContextForEdit(context, taskDefinition); context.put("say", taskDefinition.getConfiguration().get("say")); }
From atlassian-plugin.xml:
1 2<taskType name="helloworld" class="helloworld.ExampleTask" key="test"> <description>A simple Hello World Task</description> <!-- Categories available in 3.1: "builder", "test" and "deployment" <category name=""/> --> <configuration class="helloworld.ExampleTaskConfigurator"/> <resource type="freemarker" name="edit" location="editExampleTask.ftl"/> </taskType>
In our example we use the injected TextProvider in ExampleTaskConfiguratior.java
to load the helloworld.say.error
string from the english.properties
internationalisation file when validation fails.
To register the english.properties
with the plugin system add a line to the atlassian-plugin.xml
like so:
From atlassian-plugin.xml:
1 2<resource type="i18n" name="helloworld language" location="english"/>
Rate this page: