How do I compare against fixVersions field in ScriptRunner

Terry Beavers April 22, 2016

Greetings,

I am trying to create a validator in my JIRA workflow to check against a range of versions in Fix Version field, but can't seem to duplicate what I can execute with JQL.

For example, I can successfully execute fixVersion >= 2.7.0 AND fixVersion <= 2.10.0 in JQL and it will return all tickets that have a Fix Version that is equal to or falls in between those two versions, such as 2.7.1, 2.8.0, 2.9.0, etc.

I try using the same logic in the ScriptRunner validator in my JIRA workflow, but get errors in script:

(issue.fixVersions >= '2.7.0' && issue.fixVersions <= '2.10.0')

I would think if it is possible in JQL, then it is possible in ScriptRunner, and I am probably just missing something simple with my syntax in ScriptRunner.

Any thoughts, ideas, or suggestions would be gratefully appreciated.

Thanks for your support,

Terry

2 answers

1 vote
Jeremy Gaudet
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.
April 22, 2016

I'm guessing JQL is actually comparing those using the project level ordering of the versions; so, for example, if you placed a '3.1.0' in between those in the Version manager for the project, it would show up.

With that thought as my base assumption, for that to work in ScriptRunner, at a minimum you'd probably have to fetch the exact Version object for this project's "2.7.0", and compare against that.  Something like:

VersionManager versionManager = ComponentManager.getInstance().getVersionManager();
Version twoSevenZero = versionManager.getVersion(issue.getProject().getId(),"2.7.0");
Version twoTenZero = versionManager.getVersion(issue.getProject().getId(),"2.10.0");

You'd then have to iterate through the list of versions returned by issue.getFixVersions() and compare each one individually.  Even then, you may have to compare Version.getSequence(), not the direct versions; I'm guessing they don't have a built-in comparitor, as such a thing would only really be feasible for a group of Version objects belonging to the same project.

Thanos Batagiannis _Adaptavist_
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.
April 22, 2016

Hi Terry,

Exactly what @Jeremy Gaudet said, and wrapping it in a validator

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.project.version.Version
import com.opensymphony.workflow.InvalidInputException

Issue issue = issue
def versionManager = ComponentAccessor.getVersionManager()
def issueVersions = issue.getFixVersions()
def projectId = issue.getProjectId()

Version maxVersion = versionManager.getVersion(projectId, "2.0")
Version minVersion = versionManager.getVersion(projectId, "1.0")

for (version in issueVersions) {
    def comparisonResult = version.sequence &gt;= minVersion.getSequence() &amp;&amp; version.sequence &lt;= maxVersion.getSequence()
// with the first issue's fixVersion that fails the comparison throw exception without waiting to compare the rest
    if (!comparisonResult) {
        invalidInputException = new InvalidInputException("Version " + version.name + " is less than " + minVersion.name + " OR greater than " + maxVersion.name)
    }
}

A note here. If let's say that you create a new version 1.1.1 after the 2.0 then your validator will fail (the same happens with your JQL) because it actually compares the sequences (which depends on which version created earlier)

0 votes
Jamie Echlin _ScriptRunner - The Adaptavist Group_
Marketplace Partner
Marketplace Partners provide apps and integrations available on the Atlassian Marketplace that extend the power of Atlassian products.
April 24, 2016

It's true IIRC that in JQL it will use the version sequences, which is counter-intuitive, but I guess will work even when people use things like codenames for versions.

If you want semantic versioning comparison, you can use a utility class which happens to be available in ScriptRunner:

import org.apache.maven.artifact.versioning.DefaultArtifactVersion

    /**
     * Compares two version strings
     *
     * @param v1 a version string
     * @param v2 a version string
     * @return Returns negative if v1 is less than v2, and positive if v1 is greater than v2, else zero
     */
    public static Integer compareVersions (String v1, String v2) {
        new DefaultArtifactVersion(v1).compareTo(new DefaultArtifactVersion(v2))
    }

but you might need to check that the strings can be parsed as versions...

Terry Beavers April 26, 2016

So I am trying to simplify my solution using the Simple Scripted Validator, but it doesn't seem to work due to the way it exits the evaluation if the first clause is met.

For example, I only want to transition the ticket if the Fix Version is NOT set to version A, version B, version C or empty (None)?

I tried using (issue.fixVersions[0].toString() != '2.10.0' && issue.fixVersions[0].toString() != '2.11.0' && issue.fixVersions[0].toString() != 'Future' && issue.fixVersions), but the Simple Scripted Validator doesn't continue to evaluate the second clause if the first is TRUE, so if the Fix Version is set to '2.11.0' it will still transition and not throw the error message since the first clause is met.

I am probably overthinking what should be a simple solution, so any help would be gratefully appreciated.

Thanks for your support,

Terry

Jamie Echlin _ScriptRunner - The Adaptavist Group_
Marketplace Partner
Marketplace Partners provide apps and integrations available on the Atlassian Marketplace that extend the power of Atlassian products.
April 28, 2016

that's called short-circuit evaluation. Try something like

! issue.fixVersions*.name.intersect(["2.0.0", "2.1.0", "etc"])
Terry Beavers April 28, 2016

Thanks Jamie!  That looks like it will work for the validator.

I also played around with the Script Condition (Allows the transition if this query matches a JQL query) and was able to get the following to work as well.

fixVersion &gt;= 2.5.3 AND fixVersion &lt;= 2.9.0 OR fixVersion = FB

Thanks again for all of your help!

Just need to figure out which one Product Management wants to use now and go from there.

Suresh November 2, 2017

we have two version names are 1.Future release, 2. Future.
based on one issuetype,on create screen user should not select above both values.

I am trying following line in my workflow validator on create action.
How can restrict user not select above two versions from the version field on create action.

["Future Release","Feature"] in issue.fixVersions*.name

Suresh November 2, 2017

@Jamie Echlin _ScriptRunner - The Adaptavist Group_I have tried following code on create action, but i am unable to validate.Can you help me to figured it out, 

!('Future Release' in issue.fixVersions*.name || 'Feature' in issue.fixVersions*.name)

Thanos Batagiannis _Adaptavist_
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.
November 2, 2017

Hi Suresh,

If it is for a Simple Scripted Validator then try something like 

! (issue.fixVersions*.name.contains("Version1") || issue.fixVersions*.name.contains("Version2"))

Regards, Thanos 

Suresh November 2, 2017

Thank you Thanos,
we are using custom field ,that loads all the fixversion values.
The customfield(multi select version type) name is: Target Version


do we need to replace with the 'fixVersions' by 'Target Version'?

!(issue.Target Version*.name.contains("Feature") || issue.Target Version*.name.contains("Future Release"))

Suggest an answer

Log in or Sign up to answer
TAGS
AUG Leaders

Atlassian Community Events