JIRA-Groovy Plugin

This plugin moved to http://confluence.atlassian.com/display/JIRAEXT/Groovy+Runner. There is some background info here though.

I discovered the JIRA Groovy Runner recently, whilst looking for a starting point to integrate Jython in to JIRA. I succeeded in adding a Python runner, but then realised it wasn’t particularly useful, me not being a strong Python programmer.

However, it did make me look harder at the Groovy Runner, and manage to extend it somewhat to cover Conditions, Post-Functions, Validators and services… In theory you can cover all the areas where JIRA provides something to hook in to, eg Portlets, Reports, Listeners, Services etc.

The main advantage for me in using Groovy here, is that using a Groovy script (as opposed to a Groovy class), you can quickly test and debug your post-function (or whatever), and make changes without having to restart JIRA. Another big advantage, is that Jetbrains IDEA has full support for Groovy (debugging, intellisense, interefactoring) etc. And finally the language itself tends to make you more productive when doing RAD-type work. Having completed the Groovy script to your satisfaction, you can either write it properly as a java plugin, or just leave as is.

Take an example… I was using a Condition that checks all sub-tasks are in a certain state. I then added another state to the sub-task workflow. Rather than adding the additional state as a parameter, I just wanted it to allow the transition if all sub-tasks had a resolution, regardless of their status.

Using a

loading http://blogs.onresolve.com/jechlin/55/SimpleAllResolved…

The fact that you can debug this, make changes, and rerun it without restarting JIRA is a huge advantage…

img22.jpg

It will also be useful where you have complex business logic for something like a validator, that you don’t have time to parameterise properly… e.g. Date A must me after Date B, unless Option C is checked.

If you write Groovy from a java perspective you can pretty much paste it in to your java file. A lot of the time spent when writing a plugin is all the plumbing, e.g. the factory class, the templates, and messing around with atlassian-plugin.xml. This lets you avoid some of that whilst you scope out your plugin.

Usage

  1. Download Groovy-runner.jar or source. Copy jar in to WEB-INF/lib.
  2. Download Groovy. Copy Groovy-all-n.n.n.jar to WEB-INF/lib.
  3. Turn up debugging:
  4. Restart JIRA.
  5. Add a new condition, post-function, validator or service. Give the path to the Groovy script relative to the working directory of your JIRA instance, which is $CATALINA_BASE in the standalone version.
  6. Note that the template implies you can paste in Groovy text – I removed that capability because I didn’t think it was useful.
  7. It may be handy to create a directory called groovy_scripts at the root of your installation, to store the scripts.
  8. Start small:
  9. In the file path, enter the name of the script, eg groovy_scripts/myvalidator.Groovy.

Debugging

You can put breakpoints in your Groovy script, your IDE should stop execution when they are hit.

I’ve had good success with Intellij IDEA, but Eclipse has a Groovy plugin as well.

Examples

None of these have had much, if any, testing.

Validators

One field or the other is required, not both. Jira Suite Utilities can require that a field is present, but not more complex stuff like one field or another is required, but not both, and not neither. Horribly contrived example to require a Sponsor OR a description.

loading http://blogs.onresolve.com/jechlin/55/OneOrOther.groovy…

To disallow the transition you set invalidInputException to an instance of a new InvalidInputException. This is a hack, but I couldn’t work out how to throw an InvalidInputException in a script and have it caught by the class invoking the script.

NB – this has a dependency on Jira Suite Utilities for simplicity of code.

Conditions

All sub-tasks must be resolved:

loading http://blogs.onresolve.com/jechlin/55/AllSubTasksResolved.groovy…

Current user is equal to the value of a field, eg Sponsor:

loading http://blogs.onresolve.com/jechlin/55/OnlySponsor.groovy…

Sub-tasks all assigned to me

loading http://blogs.onresolve.com/jechlin/55/SubTasksAssignedToMe.groovy…

“Depends on” links all need to be resolved:

loading http://blogs.onresolve.com/jechlin/55/LinksBlocking.groovy…

Only allow changes in the afternoon (!):

loading http://blogs.onresolve.com/jechlin/55/ChangesInMorningOnly.groovy…

The problem I have with conditions, is that when a condition is failed, the transition is not displayed. This can lead to confusion for users – “I’m sure I saw that action the last issue I looked at, and I think I’m supposed to resolve this, but the link isn’t there”… followed by a support call. Ideally if a condition is failed the link should be present but disabled… when you mouse over it it could you give you some explanatory text, eg “Cannot resolve because this issue depends on issues that are not resolved”. You could provide that message as a parameter in the condition.

The other odd thing is that conditions seem to be invoked three times for every page view, not once as I would expect.

If not obvious from the examples, set passesCondition to true/false depending on whether you want the condition to be allowed or not.

Post-functions

Auto close all child issues.

loading http://blogs.onresolve.com/jechlin/55/AutoCloseChildIssues.groovy…

Automatically append some generated comment on a transition:

loading http://blogs.onresolve.com/jechlin/55/AddComment.groovy…

Use a regular expression to copy a string from one field, to another (NB this relies on the JIRA Suite Utilities jar):

loading http://blogs.onresolve.com/jechlin/55/CopyRegEx.groovy…

Create another issue, possibly in another project, that is dependent on this one:

loading http://blogs.onresolve.com/jechlin/55/CreateDependentIssue.groovy…

Services

A Groovy service is included. I have not included an output file location – you can configure log4j to have it log to a separate file if you like.

Performance

Note that all these are Groovy scripts as opposed to a Groovy class, and as such, that there is a performance penalty to pay when the script is “compiled” and run. As far as I know you could use a Groovy class anywhere you can use a java class in JIRA, and it’s compiled to bytecode there will be little performance impact.

Mostly I am not fussed about performance, the penalty to pay on something like a post-function which runs relatively infrequently is not anything to get worried about. However, that is different for conditions, especially if you have large list of sub-tasks, or you use the plugin that shows available workflow actions on the issue navigator.

I did experiment with using Groovy classes, but could not get them to reload without restarting JIRA (which is my main goal here). I had an experiment using JCI but couldn’t get it to work.

Problems

The exception handling is not very good.

Also there is no way to pass parameters to your function. Because they’re easy to modify, I would just copy the script and hard-code params in there. Going forward it would be nice to have a text area, where you can pass arguments to the script in java properties format.

27 comments to JIRA-Groovy Plugin

Leave a Reply