Script Runner-Behaviour-Fix Versions/s invalid value sticks?

Mark Schnee August 25, 2014

Problem

Using ScriptRunner-Behaviour-Fix Version/s validator during resolve transaction, an invalid selection is still showing up when 'resolve' button pushed after a invalid version is selected then cleared, and a valid version is then selected and resolve is pushed again.

I'm thinking this could be a problem with what seems to be special handling of the Fix Version/s field by Jira and attempting to use the Behaviour plugin capability on it, but it could well be user error since I'm no expert in Jira or Groovy.

Setup

Trying to make sure 'Fix Version/s' is one or more fields containing two dot separated numbers. We make a distinction between release versions (#.#) and Build versions (#.#.#.#) which are only used in a custom 'Implemented In Build #' single select version field.

Jira: 6.3 6328
Jira Agile: 6.5.0
Script Runner: 3.0.5

Using a test copy of 'classic default workflow' with only modification being to use the new field behaviours.

Behaviour Config:

  • On 'Fix Version/s' field
  • Resolve and Close transitions only
  • Groovy Script:
FormField fixfield = getFieldById(getFieldChanged())
String raw_value = ''
raw_value = fixfield.getValue()

// Raw string is '[#.#,#.#]' - Parse into list.
// First remove square brackets
value = raw_value.replaceAll("\\[|\\]", "");

// Split list on comma's and trim white space
List raw_versions = value.split(',')
List versions = raw_versions*.trim()

// Make sure all versions consist of 2 '.' separated numeric fields.
valid = true
bad_versions = []
for (version in versions) {
    if (version && !(version.matches(/^\d+\.\d+$/))) {
        valid = false
        bad_versions += version
    }
}
if (! valid) {
    fixfield.setValid(false)
    fixfield.setError("'Fix Version/s' must consist of 1 or more versions with 2 '.' separated numeric fields (ex: 14.1) "+bad_versions+"{"+raw_value+"}")
    return
}

Steps to Reproduce

  • Make sure an issue exists
  • Make sure 'Versions' for project contain '#.#' and '#.#.#.#' selections where '#'s are integers.
  • Press 'Resolve' button for a specific issue
  • Fill required fields except Fix Versions/s (In my case Fix Versions/s is NOT required)
  • Select a '#.#.#.#' Fix Version/s. Should see red text indicating it's not a valid selection - expected.
  • Click 'x' on selection to clear it and select a '#.#' option. Red text should go away and make it look like it's OK to press the 'Resolve' button - expected.
  • Click 'Resolve' button. Red text re-appears with previously selected 4 field selection as 'bad_version' and the same for 'raw_version' even though '14.2' is the only thing showing in the form???
  • No matter what I do from this point on it always fails. I can get it to work by cancelling the transaction and restarting it and only selecting 2 field versions, but obviously that isn't going to fly with most users.

Note: I'm using a similar behaviour on the 'Implemented In Build #' custom version single pick field and it works as expected.

Discussion

  • I'm trying to do this in a way that is likely to survive Jira updates
  • The 4 field 'Version's are auto-generated by our Jenkins CI system and added to Jira via the Jira CLI.
  • Ideally I'd prefer to filter what the user could select rather than validating on the fly, but I couldn't find a method to do that would be likely to survive Jira updates.
  • Finally I'm amenable to any alternatives anyone might suggest for tackling this problem that might better use Jira's stock built-in/plugin functionality.

2 answers

1 accepted

0 votes
Answer accepted
JamieA
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
August 27, 2014

I think your problems are:

* errors that you set are persistent, they don't automatically get removed just because the server-side validator is called again.

This is where clearError() comes in

* second, you are casting fixfield.getValue() to a String, which means you need to do that parsing code, whereas it is already giving you an array of Version objects.

In testing it wasn't a bug I had to rewrite your code, my version is here: https://gist.github.com/jechlin/3197c7a9d6542ac3cf53

> Finally I'm amenable to any alternatives anyone might suggest for tackling this problem that might better use Jira's stock built-in/plugin functionality.

Unless you really need the dynamic behaviour that err, behaviours plugin gives, it's usually simpler, safer and easier to write a standard validator script on your workflow. You can convert your code very quickly to a simple scripted validator.

Mark Schnee August 27, 2014

I'm getting:

Compilation failure: startup failed: Script1.groovy: 4: unable to resolve class Version @ line 4, column 44. = fixfield.getValue() as List<Version> ^ 1 error

when I try to save your script. Apparently 'Version' class isn't in my classPath? I have no idea how to fix this (as I said, I'm no Jira or Groovy expert... yet). Guess I can go back to parsing the string.

I'm getting the feeling I need to learn more about the 'internals' of Jira in order to do this effectively. For instance I actually tried doing the 'getValue' as List but had no idea what it returned so wasn't able to do anything with it. Adding <Version> apparently takes care of that, but I had no way to know what was suppose to go between the <>'s until I saw your code. Where do I find this stuff? In the source code? Is there documentation? Through an IDE (which I don't have at the moment)? I've read a lot of the Jira Docs, maybe I haven't found the right one yet.

JamieA
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
August 27, 2014
Sorry, I forgot the import. Not at machine now, will post tomorrow.
JamieA
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
August 27, 2014

At the top of the script add:

import com.atlassian.jira.project.version.Version

> Where do I find this stuff? In the source code? Is there documentation? Through an IDE (which I don't have at the moment)?

I've written stuff on this before, not that I expect you to search for it but equally I can't be bothered to type it again ;-)

Basically yes, set up an IDE, do tutorials, read javadoc, just put in the graft. If I get some time I will try to blog with some more useful advice.

Mark Schnee August 27, 2014

That got it working.

I'll take a look at your past blogs to see if that helps. Any help getting through the learning curve quicker is appreciated.

Thanks for your help and all your advice here and elsewhere. It really helped me get as far as I did before having to submit this question.

JamieA
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
August 31, 2014

No problem, and thanks for a well-written question.

0 votes
Peter Berner September 10, 2014

For me this Simple Scripted Validator worked fine:

import com.atlassian.jira.project.version.Version;
def versions = issue.getFixVersions() as List&lt;Version&gt;
issue.getResolutionObject().getName() != "Fixed" || versions.any {it.getName().matches(/(^V\d+\.\d+$)|(^0.\d+.0.\d+$)/)}

Suggest an answer

Log in or Sign up to answer
TAGS
AUG Leaders

Atlassian Community Events