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

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

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.

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.

Sorry, I forgot the import. Not at machine now, will post tomorrow.

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.

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.

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

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
Community showcase
Published Oct 31, 2018 in Marketplace Apps

Marketplace Spotlight: Zephyr

Hello Atlassian Community! Each month, we run a series of Spotlights to highlight Marketplace vendors and apps that our team thinks this Community would find valuable. In last month's Spotlig...

339 views 0 1
Read article

Atlassian User Groups

Connect with like-minded Atlassian users at free events near you!

Find a group

Connect with like-minded Atlassian users at free events near you!

Find my local user group

Unfortunately there are no AUG chapters near you at the moment.

Start an AUG

You're one step closer to meeting fellow Atlassian users at your local meet up. Learn more about AUGs

Groups near you