As in my previous Atlassian related article, I will stress from the very beginning that we are not going to develop anything revolutionary or something that does not exist as plugin on the Atlassian Market. On the other side, the article will demonstrate how easy is to develop and implement JIRA plugin that will support definition of Workflow Post Functions based on Dynamic Groovy Script specified in the JIRA user interface.
JIRA Workflows can be customized in various ways by defining new Steps and Transitions. For each Transition we can specify Screen, Conditions, Validators and Post Functions. In this article we are particularly interested for the Post Functions that allow us to add additional logic during the transition from one state into another. For example:
- On Issue creation automatically add comment that will mention all users associated with the JIRA project’s role Approvers (this way they will receive mail notification)
- Create automatically Sub-Tasks once the Task has been approved.
We are going to develop JIRA plugin that will allow us to specify JIRA Workflow Post Functions that will execute custom and dynamic Groovy script specified by the JIRA administrator.
Groovy is a powerful dynamic language for the Java Virtual Machine (remember Grails?).
Someone can very easily embed externalized, scripted logic based on Groovy into their Maven based Java application by including the following dependency:
Let’s assume that we have the following Groovy toy script:
script.groovy
The code that will execute the above script is as simple as:
RunGroovyScript.java
Note that the binding contains variable l, but not the variable result. The binding rule is very simple: the variables in the Groovy script specified with the def keyword are NOT available in the binding objects after the script execution.
Pretty simple, isn’t it?
So, let’s implement the same technique in the context of JIRA plugin. The idea is to bind the current issue and make it available into dynamic Groovy script executed as JIRA Workflow Post Function.
Execute the command atlas-create-jira-plugin and answer the wizard questions. Navigate into the created plugin’s folder and run the module creation command:
We are going to create Post Function, so choose the option 33 in the wizard. I’ve chosen the name GroovyScriptFunction that generates the following definition in the file atlassian-plugin.xml:
The best in the whole scenario is that the generated skeleton code provides almost all that we need for the plugin. In order to define and run Groovy scripts, we need only one HTML Text Area in the user interface that will accept the script definition. The velocity templates that define the UI part of the plugin are:
groovy-script-function-input.vm
groovy-script-function.vm
The Java code is also very, very simple and self-explanatory. The post function factory that deals with UI parameters collection is:
GroovyScriptFunctionFactory.java
The factory code contains parameters mapping only.
Finally, the post function itself is defined into several lines:
GroovyScriptFunction.java
There is nothing special in the method execute(). We are getting the current Issue and the Groovy Script text. The issue is exposed in the Groovy binding under the name issue, i.e. the Groovy script will have access to the issue variable.
One thing that I’ve found tricky is class loading and the available Java packages in the plugin code. The JIRA plugin system is OSGI based (Apache Felix) and the plugin’s OSGI dependencies must be specified into the plugin’s JAR manifest. For Java only compiled code based plugin there is no need for any configuration, because the maven-jira-plugin will scan the plugin classes and automatically add any dependencies in the manifest file. However, our plugin will execute Groovy scripts that will reference classes not known at the compile time. I’ve assumed that our Groovy code will execute code related to JIRA Issues, Comments etc. For that purposes, in the Maven’s pom.xml I’ve defined the OSGI packages to be imported as:
Probably you will have to add additional packages here depending on what you are trying to script.
At this stage we are ready to try the plugin. Start JIRA with the command:
In order to test the auto-comment scenario specified above, you should create:
- Project (TEST) of type Project Management
- System wide role Approvers
- Users: alice, bob and trudy
- Add users alice and bob to the Approvers role in the TEST project
Finally, we shall modify the TEST project’s associated workflow and define Post Function on the Create transition (click on that transition in the Diagram view). Once the transition has been selected, click the Post Functions link on the right of the screen and Add post function link after that. Choose the “Groovy Script Function” option and enter the following script into the provided text area:
In essence, this script:
- Gets issue’s project
- Gets the project’s approvers, i.e. collection of users assigned to the project’s role Approvers
- Iterates through the approvers and builds comment string
- Adds the comment to the issue.
In our case the comment string will be:
The syntax [~username] is known as JIRA mention. It will trigger notification to the referenced user.
Note: Move the Post Function created at the bottom of the list of existing Post Functions.
Publish the modified JIRA workflow and create new Issue in the TEST project. Notice the comment created automatically!
How about automatic creation of Sub-tasks after some transition? Here is a sample Groovy script that will do that if specified as a transition Post Function:
Let’s summarize what we have done:
- We have built a Groovy script based JIRA plugin with very little effort
- We have provided 2 simple and short Groovy scripts that accomplish very common scenarios if you need customized JIRA Workflows (who doesn’t :-)?)
Till next time!