Come for the products,
stay for the community

The Atlassian Community can help you and your team get more value out of Atlassian products and practices.

Atlassian Community about banner
4,293,343
Community Members
 
Community Events
165
Community Groups

Any option other than regex to perform workflow validation?

I'm a long time JIRA Server Admin and just recently switched to JIRA Cloud Admin.  We installed Scriptrunner to help with some workflow and reporting use cases.  I have found the Cloud version of Scriptrunner extremely disappointing.  Everything we wanted to use it for is not there OR isn't admin friendly to configure.  

My primary scenario is this:

We have Resolution + two custom drop downs, let's call them Defect Resolution & Defect Root Cause.  The requirement is to either show only those Defect Resolutions that apply to the Resolution selected or display an error to pick an appropriate one.  Then, Defect Root Cause should be appropriate to the Defect Resolution selected.  I know I can use a Cascading Select for Defect Resolution -> Defect Root Cause, but that only resolves half the issue.

In server, most, if not all, of this could be resolved using Behaviours and/or validations using groovy scripting.  Neither of these features/functionalities are available on Cloud.

I've looked through a lot of documentation for different plugins and they all seem to point to the use of Regular Expressions.  I have only ever written one or two simple regex before and believe this ask is much more complicated than regex may be able to handle, but with my limited knowledge, I'm not even sure.

So, I ask you a) is there an alternate solution or b) is regex capable of handling this complex requirement and, if so, 3) how do I even get started writing the regex I need?

Any and all suggestions would be much appreciated!

Sue

6 answers

6 accepted

2 votes
Answer accepted
Mike Rathwell Community Leader May 24, 2022

Hi, @swilson 

I feel your pain. I have been there and do miss the crispness of Groovy along with the features that don't exist in Cloud.

However...

I did see that ScriptRunner behaviors are coming to Cloud. Other than that it will exist, I do not know if it will bring the full panoply of features to Cloud.

I keep ScriptRunner because it has some good stuff in Cloud but I also really recommend adding Jira Misc Workflow Extensions to your environment as well. It is intensely powerful and let me solve a lot of the things you are facing.

Hi @Mike Rathwell the struggle is real.

Funny story....I was asked to review Scriptrunner because the users wanted it so bad.  I compared it to JMWE and actually leaned toward the latter myself, mostly because of the former's limitations.  I agree, having Scriptrunner in the arsenal isn't a bad thing, but the organization had me go through a complete JIRA audit to remove everything not in use and everyone not using.  So, keeping this one around when it failed their expectations  isn't an option.  Oh well, moving off my soap box.  I'm going to give JMWE a shot and see if I can't get this one solved.  Thanks so much for your input & suggestion!

Like # people like this
Mike Rathwell Community Leader May 24, 2022

The OTHER thing I use JMWE for, @swilson , is for a lot of the automations that Automation for Jira is ostensibly supposed to do.

I have found the selectivity, validation, and consistency to be a soothing balm, not to mention it can deal with attachments because attachments are a Thing. I took to doing the real automation at a system level in JMWE and let project admins do their snowflakey things in Automation for just their project.

Like # people like this

Ah, yes.  In the prior life, we had Scriptrunner & JMWE for server, among others.  So much functionality.  I used to automate in that way, too.  Came here and Automation is included, but nothing like what I was used to.  Seems a bit clunky and does not always provide the expected results.  Would be great to have an alternate way to automate.  We limit the Project Admin power to a select few.  I've seen it used & abused too many times.  I'd rather take the time to address their wish list than clean up after them.

Like Amir Katz _Outseer_ likes this
Mike Rathwell Community Leader May 24, 2022

That is precisely the reason I use JMWE in place of Automation. I have the control over that one and can make tools that benefit more than one flake. I do also limit the number of project admins and try to keep it at least of the "not dangerous with adult supervision" skill level

Like swilson likes this
Darryl Lee Community Leader May 24, 2022

IMHO, tools like JMWE (and as mentioned, anything that does Jira Expressions, which is almost every tool providing Workflow Validators and Conditions) serve a completely different purpose than Automation.

For old-school validation and conditions, Jira Expressions via JMWE, ScriptRunner, etc. absolutely makes sense. Using Automation to kick a ticket back to a previous status because it doesn't meet certain requirements is an awful user experience. (Yes, I have seen this. I may have even helped implement it. It is BAD BAD BAD.)

But when you've got to interact with other tickets (related, linked, whatever), or external systems (Slack, anything with a REST API), Automation is soooooo much better than post-functions (not to mention that every add-on implemented post-functions in a different way).

(Of course excepting Attachments, about which you are 100% correct about, @Mike Rathwell. Atlassian really needs to address this deficiency.)

Yes @swi, in the old world, ScriptRunner did it all. It was the Ginsu knife of add-ons, although you had to be careful to not cut yourself. Or well, be sure you knew how to handle knives. Ok, this analogy is quickly falling apart.

But full-disclosure: I did not have the patience or skills to learn Groovy, so way back when, I definitely preferred things like JMWE, JSU, etc.

There is something to be said for being able to look at a Workflow, and simply read what it is going to do, rather than having to open it up and examine code to figure that out.

Like # people like this

Agree on the caveats and benefits of the automations. As the name implies: all under the hood. Naming them properly is a must, to know what each one does.... and

I _heavily_ rely on automations. The project I lead is held together by them. But when validations are needed in between transitions... JMWE is my go to option. By far.

The issue with automations is that all automations triggered by same event, e.g. field X changed, will run in parallel... so there can be race conditions. I'm still adjusting to this having migrated from Zendesk where "triggers" were run top down, in order. And the best is the chained automations! one wrong move and ... ping pong ball on mouse traps....

Mike Rathwell Community Leader May 24, 2022

Using the "do these things in order" function in JMWE is your friend with the race conditions. I tend to use that were input of one step is dependent on the preceding step having completed, @Leonard Hussey 

Like Leonard Hussey likes this

@Darryl Lee I agree with the Ginsu analogy and learned quickly not to cut myself when working with this sharp tool.  I actually learned groovy, for the most part, while working with Scriptrunner & JMWE.  For me, it was a much easier learning task than regex is for me some 10 years later.  Maybe I'm getting old, maybe it just looks too much like code for my taste, but I need to give it a try if I want to provide value to our teams.  It is most definitely better to be able to read a workflow than examine code!

@Leonard Hussey like @Mike Rathwell said, JMWE is a good friend when it comes to race conditions.  Placing your steps in the right order in the workflow gives you the lead in the race every time.  

1 vote
Answer accepted

So I was thinking about this some more, and having created complex validators in the past, I have to say, you shouldn't do this.

@swilson you wrote:

I know I can use a Cascading Select for Defect Resolution -> Defect Root Cause, but that only resolves half the issue.

Why won't a Cascading Select work? It's exactly what you're trying to replicate with Validators, but if you use Validators, you violate a key user interface/experience principle: Don't Piss Off Your User.

Here's some thoughts:

  • To make this clear, you'll have to add a bunch of description text for the fields, saying "Hey remember if you choose Resolution X make sure that you only choose X Root Causes, not any of the other ones."
  • When somebody chooses the wrong option and then hits Submit they get an error message. They shouldn't have to hit Submit to figure out what the rules are.

Good UI makes it easy for people to do the right thing. Using Validators here makes it hard.

So I'm going to guess maybe that the reason a Cascading Select won't work is because you actually want users to set a Resolution.

I have a workaround: add a Done step (or insert a step before your last step) and automatically set the Resolution using Automation Rules to match the parent option from the Cascading Select field.

Here's how it would work:

The world's most boring workflow:

Screen Shot 2022-05-25 at 10.38.24 PM.png

And here's a cascading field Resolution/Root Cause

The primary values match the real Resolutions (this is important):

Screen Shot 2022-05-25 at 10.51.57 PM.png

So you need a Validator to make this field required in the Resolved transition screen:Screen Shot 2022-05-25 at 11.16.31 PM.png

You might want also want to create a Validator to make sure a Child value is selected. JMWE and ScriptRunner both let you do this with a scripted validator (known as "ScriptRunner Script Validator")

Automation time!

It's time to write an Automation Rule! (Don't worry. This is how you do things in Cloud. it's built-in, and it's incredibly powerful.)

The rule is below:

Screen Shot 2022-05-25 at 11.14.05 PM.png

So the cool thing is, Automation is smart enough to let you set the Resolution to the value of the parent option in the Resolution/Root Cause custom field, using the Smart Value {{issue.customfield_10106.value}}. This is why it's important your custom field's parent options match your Resolutions exactly. 

So NOW when you transition from In Progress to Resolved, there is a split second or two where it says "Resolved", but then it will flip to "Done" automatically, and set the Resolution to match with the parent option from the Resolution/Root Cause custom field, as shown below:

Screen Shot 2022-05-25 at 11.15.45 PM.png

I realize this is a lot to take in, but honestly it's WAAAAY more maintainable than hacking together a validator, and most importantly, it is WAY more user-friendly to the user.

Caveats

  • You probably should scope your rule to just the one project where it should work.
  • If you need this rule to work across multiple projects, you might need to upgrade your Cloud plan. Alternately if it's just a few projects, you could just copy it for each project.
  • There's like a split second where the "Resolved" step shows up and it's possible that somebody might be fast enough (or Automation might be slow enough) where they could manually click Done before the rule fires. So it might make sense to use the Hide From User condition for the Automatic Done transition to avoid that edge case.
Darryl Lee Community Leader May 26, 2022

If you really miss ScriptRunner, you could probably use a Post Function to set the Resolution from the parent option of the Cascading field (you might even need Groovy for this!) and use the "Fast-track Transition Issue" post function to move it to Done.

Like swilson likes this

@Darryl Lee I'm not quite sure I understand all of the above.  I was able to validate the correct Defect Resolution is selected based on Resolution selected.  Now that I have that worked out, the next step would be to validate the Defect Root Cause options based on the value of Defect Resolution.  I feel like, to make this work, I may need to repeat similar validators against these two fields and place them after the initial Resolution=>Defect Resolution validations?  Automations don't do validations, so I don't know if using it here would help other than forcing a specific selection, except there are multiple possible options.  Am I misreading the intent?

Hi - sorry, I was basically suggesting you not do what you're doing. :-}

As you mentioned in your original post, a Cascading Select would probably get you the data you need, letting you perfectly configure which Root Causes are valid for each Resolution, and most importantly, letting your USERS see which Root Causes are acceptable for each Resolution.

Using Validators makes this invisible.

Yes, you can add description text for the field laying out all the options. And yes, the error message for each validator can display what people did wrong.

But that is a lousy user experience.

So anyways, then I went on to show how you could implement a Cascading Select field that also sets Resolution.

I know Jira Server had Behaviours and Cloud does not, and there is a strong tendency to want to simply do things the way they worked. But Validators are a poor substitute for Behaviours. Cascading Select is a better option, from a USER's perspective.

Like swilson likes this

Ah, now I get it!  I completely agree that Cascading Selects are the better option!

But, the cascading select would work if we were just working with fields 2 & 3.  Since they wanted field 2 dependent on Resolution, it added an extra layer of complexity.  In the validators, I could list those that truly apply, but, after a meeting I had this morning, this whole exercise may end up being a private tutorial for me.  LOL

We may end up adding the Defect Resolution to the actual system Resolution field and only worrying about the Root Cause being selected correctly...maybe.

Alternately, I could add the system Resolutions to the Defect Resolution custom field as part of the cascading select idea, have Resolution hidden from the Close screen, and use a post function to set Resolution with the Defect Resolution value.  

Either way, not much I can do now until the business makes up their mind on which approach they want.

Darryl Lee Community Leader May 26, 2022

But, the cascading select would work if we were just working with fields 2 & 3.  Since they wanted field 2 dependent on Resolution, it added an extra layer of complexity.  In the validators, I could list those that truly apply, but, after a meeting I had this morning, this whole exercise may end up being a private tutorial for me.  LOL

Ahhhh.

Because your Defect Resolutions matched the default System Resolutions, that's what I thought you were doing.

OMG, so yeah if they wanted a Defect Resolution that can be different than System Resolution (which just sounds utterly confusing), then yeah, that's effectively a 3-level Cascading select. Ugh!

[There are (of course) add-ons for this, but unknown how the data would look to Automation/Scriptrunner:

It would be good feedback to let business know that making people fill out multiple Resolutions will be annoying, confusing, and a bad user experience. :-}

Like # people like this
Darryl Lee Community Leader May 26, 2022

Also, it is exciting that Behaviours are coming to Cloud, @Dirk Ronsmans , but various folks at the Team '22 conference that I spoke with, including some from Adaptavist, noted that Atlassian was only providing access to onInit events first, and that onChange events wouldn't be available for control until later this year.

The Developers Community Forum makes mention of an "Issue Adjustments API":

https://community.developer.atlassian.com/t/product-team-talk-time-w-jira-cloud-ecosystem/49846/6

Like swilson likes this

Yes, now you understand my struggle.  Whoever built/used the system before myself and several other fresh eyes came on scene really like the layered effect. 

The business already knows.  That's where I came in.  Since it was so convoluted, the users selected, maybe, the first positive (code change) or negative (No Change) and moved on.  Now those trying to report on these fields are having a virtual field day trying to review each & every one for true meaning.  I think they've realized the error of their ways.  Oi Vay!! 

I may look into the addons, but I really don't want to upsell multi-level cascading select fields.  That could just open up a whole new can of worms!

Instead, I am pushing toward adding all Resolutions to the system Resolution field to alleviate that confusion.  Then we can work on what their expectations are for Root Cause.  

Since Scriptrunner failed in other areas (reporting) that had other specific requirements, the business has decided to remove the plugin in its entirety, so I won't be around to see the Behaviours upgrade....good, bad, or indifferent.  But, sounds like a lot of other Cloud options that don't live up to the power of server for those who have experienced both.

But, hey, at least I got the JIRA expressions to work and can employ them once I install JMWE!!!  :-D

Quite a nice this discussion this turned out to be.

I 100% agree with @Darryl Lee on the validators part being an awful user experience. I myself have several 3+ layered fields issues... something our previous ticketing system was much better in.... and on top our workflow is already an awful spiderweb of states.

I really do not want to add more add-ons on top. We already have many already running... looong story, but in short: I feel we migrated into Jira one year too soon.

Luckily for me, my users are all internal and they are my team anyways... so they'll have to take the awful experience... Something I've noticed, though: The "argh!!!" effect of the validators has finally made them know what is the correct data to enter on first try instead of the dice game we were allowed to play earlier :)) as @swilson said: reports were fun to build: export, check, fix data, rinse and repeat :D

Like swilson likes this

@Leonard Hussey I agree.  This has been a nice discussion and a great learning experience.  I appreciate all who have taken the time to add feedback and forethought on how to handle this crazy experiment.  I do plan to look into the 3+ cascading selects, but I'm not sure I want to advertise that capability.  We only have one scenario and it already involves a system field, which means a little extra to make it all work, if it becomes an option.  

I also agree the validators aren't the greatest option, but once they learn to fill in fields correctly, the validation becomes less of a concern, so there is that.  ;-)

I am fortunate, too, that all my users are internal.  But, we are dealing with multiple teams from IT, Dev, and Product, so it gets a little sketchy from time to time.  LOL

I just did a plugin clean up of those not in use.  I have a little leadway to install new plugins, but everything has to go through a meeting for approval, especially if cost is involved, so there is a little red tape to cut through.  At least they know, if I'm recommending something, there's a good reason for it.

Like Leonard Hussey likes this
1 vote
Answer accepted
Mike Rathwell Community Leader May 25, 2022

I should have mentioned that there are some stellar regex testers available. When you don't live in regex, as many of us don't, one needs a bit of guidance with syntax to get it right and avoid unfortunate regex-induced faceplants.

The three I keep in my bookmark list (each has it's own flavor and abilities; I often bounce one off the other) are:

Sometimes you just can't avoid it... 

1 vote
Answer accepted

Hi @swilson 

For me regular expressions was also something I wanted to avoid. This was simply hard for me to understand. However, this is sometimes very useful in Jira Automation and in other plugins so I finally decided to learn it at any price.

The good news is that it turned out to be not that difficult (and I am not a developer).

I found this YouTube tutorial and the rest was 'plain sailing'. I highly recommend this to you as well; maybe not specifically for the use case you described but for other occasions.

https://youtu.be/rhzKDrUiJVk

1 vote
Answer accepted
Darryl Lee Community Leader May 24, 2022

Hey yeah, so yeah the thing with Cloud is, all validators and conditions use have to use something called Jira Expressions, and that's the case whether you're using ScriptRunner, JMWE, or any number of other options.

To your question, it's very possible to do validations like you need, with Jira Expressions. I don't think you necessarily need to use Regular Expressions, but you definitely will need to learn (or copy) Boolean logic. I wrote a bit about this, and have pointers to various "recipes' and examples:

Here's one that I did a while back, that's probably applicable to your case:

"Foo" or "Bar" Part (13461) can only be selected if Build Phase (13719) is Alpha or Beta.

(!['Alpha', 'Beta 1', 'Beta 2'].includes(issue.customfield_13719.value) && 
![Foo, Bar].includes(issue.customfield_13461.value)) ||
['Alpha', 'Beta 1', 'Beta 2'].includes(issue.customfield_13719.value)

If you run into trouble, post what you've tried here, and we can try to help you out. :-}

Oh boy, this brings back some memories (and headaches).

A few tips:

  1. Install Expression Tester. It's FREE, but I would pay money for it. No no, I take that back. But it is invaluable for debugging.

  2. Remember this tiny bit of the REST API:
    https://YOURHOST.atlassian.net/rest/api/3/issue/TESTISSUE-17

So then, you might see this in the REST API:

  "customfield_10049": {
"self": "https://YOURSITE.atlassian.net/rest/api/3/customFieldOption/10016",
"value": "Some Resolution",
"id": "10016",
"child": {
"self": "https://YOURSITE.atlassian.net/rest/api/3/customFieldOption/10018",
"value": "Some Root Cause",
"id": "10018"
}

This will show you the syntax for the fields you'll be referencing with Expressions. Then with Expression Tester you could start playing with Boolean Expressions like:

issue.customfield_10049.child.value == "Some Root Cause"

Where, if your test issue has a cascading child value of "Some Root Cause" then that would evaluate as true.

You can combine these with && and || (for me this is where the headaches come in) to create more elaborate tests. But with Expression Tester, you can try them against specific test issues and figure it out.

Like # people like this

As I'm lazy, for the REST API call mentioned by @Darryl Lee, I always append:

 ?expand=names 

... so I can search the name of the field, and from there get the desired customfield_xxxxx

And does not hurt to have a JSON parser add-on already installed for pretty printing the output.

Like # people like this
Darryl Lee Community Leader May 24, 2022

Oh man, great tips. I don't even think I knew the ?expand=names trick so I was just looking in the ticket for option names that matched. :-}

For Chrome I use:

  • JSON Viewer (Chrome extension for viewing JSON files)
    • You'll need to enable it to "Allow access to file URLs" to view downloaded rules. 

Firefox has a built in JSON viewer, which is nice.

Like # people like this

... the first line of the JSON output will show what you can expand. "names" is just one of of the options...

Another one that I check from time to time is "editmeta" that will show what operations are allowed for each field. Very useful when I'm doing some automation that sends "Advanced" actions (via JSON) or some REST API call for ad-hoc operations for which clicking is to slow or automation is too aggressive. 

Cloud REST API is really far far ahead of what the UI can do. Saved my neck several times...

Like # people like this

@Darryl Lee & @Leonard Hussey this is some GREAT information!!!  I did look at almost every single link you provided prior to posting my question.  Great article, by the way, Darryl!  My problem is, having no real background on regex or jira expressions, it's a bit overwhelming & I'm not even sure where to start.  I did write the following for what we are trying to achieve.  It works to error out when the combination is not met, but a) does not transition when a combination is correct and b) does not consider the 3rd field, "Defect Root Cause".  I'm thinking, if I use a Cascading Select for Defect Resolution, I don't need to concern myself with Defect Root Cause because the limitations have already been put in place.  BUT.....here I am, stuck on how to resolve what is written and what is left to do....

[issue?.resolutionObject?.name == 'Done' && issue?.customfield_10129?.value != "No Change - Deprecated" && issue?.customfield_10129?.value != "No Change - Duplicate" && issue?.customfield_10129?.value != "No Change - No Plans to Fix" && issue?.customfield_10129?.value != "No Change - No Plans to Fix" && issue?.customfield_10129?.value != "No Change - Not Reproducible (with the information provided)" && issue?.customfield_10129?.value != "No Change - Working as Designed"] || [issue?.resolutionObject?.name == 'Duplicate' && issue?.customfield_10129?.value == "No Change – Duplicate"] || [issue?.resolutionObject?.name == 'Declined' && issue?.customfield_10129?.value != "Code Change" && issue?.customfield_10129?.value != "Configuration Change" && issue?.customfield_10129?.value != "Data Change" && issue?.customfield_10129?.value != "Database Change" && issue?.customfield_10129?.value != "Deployment Change" && issue?.customfield_10129?.value != "Infrastructure Change" && issue?.customfield_10129?.value != "Third Party Change"] || [issue?.resolutionObject?.name == 'Cannot Reproduce' && issue?.customfield_10129?.value == "No Change - Not Reproducible (with the information provided)"] || [issue?.resolutionObject?.name == 'Won’t Do' && issue?.customfield_10129?.value != "Code Change" && issue?.customfield_10129?.value != "Configuration Change" && issue?.customfield_10129?.value != "Data Change" && issue?.customfield_10129?.value != "Database Change" && issue?.customfield_10129?.value != "Deployment Change" && issue?.customfield_10129?.value != "Infrastructure Change" && issue?.customfield_10129?.value != "Third Party Change" && issue?.customfield_10129?.value != "No Change - Duplicate" && issue?.customfield_10129?.value != "No Change – Not Reproducible (with the information provided)"] || [issue?.resolutionObject?.name == 'Backlog' && issue?.customfield_10129?.value != "No Change - Deprecated" && issue?.customfield_10129?.value != "No Change - Duplicate" && issue?.customfield_10129?.value != "No Change - No Plans to Fix" && issue?.customfield_10129?.value != "No Change - No Plans to Fix" && issue?.customfield_10129?.value != "No Change - Not Reproducible (with the information provided)" && issue?.customfield_10129?.value != "No Change - Working as Designed"]

Hi @swilson 

 

Regex has always been a limitation for me. Can't get my brain around it despite how much I tried over the years.

 

So, falling back to logical operators, I think you can make it easier if you split your big condition as follows:

- each of the OR parts (I see you have 6 parts) you can make as a separate validator via "Build-your-own (scripted)" JMWE options.

- for each, when failed, you can issue a failure message.

 

So, during transition, all validators have to hold true and if any of them fails they will pop up the  message (which can be any text you wish to guide the user).

 

For my case, for .e.g, From Open to Solved transition, I have over 10 validators, each being a "Build-your-own (scripted)" JMWE.

 

Similar to the following:

-----

Build-your-own (scripted)

The following Jira expression must return true:

your expression 1 to fulfill goes here

The following message will be displayed if validation fails: 'error message 1 to guide the user'

----
Build-your-own (scripted)
The following Jira expression must return true:
your expression 2 to fulfill goes here
The following message will be displayed if validation fails: error message 2 to guide the user'
----
... and so forth
For any of them that fails, the user will get the message. If more than one fails, then the user will get the message of the first one to fail. So, he/she can fix all of them.
I found this way to be much easier to guide the user with small chunks of info than one big validator. 
Hope it helps.
Like swilson likes this

@Leonard Hussey It is good to know I am not the only one AND I'm closer than what I thought.  Actually, that's exactly how I started.  Using Scriptrunner, I entered the first expression and it worked as expected.  Then, I added the 2nd expression only for it to continually fail.  If I entered the correct values for scenario 2, it always fails on scenario one AND lists all errors, not the specific one that applies.  So, I tried to 'or' (||) them together to see if it would pass over the first expression because it didn't apply and move on to the 2nd that did and so on.  Whether I split them into 6 expressions or || them together in one expression, it continually fails because it doesn't meet at least one expression in the lot, I think.  And that is where I am stuck now.

@swilson never tried Script Runner myself (though we have it). So I'm sorry I cannot help there.

I've made it work via JMWE. Works like a charm. I've used JMWE also as a Conditions, to disable a transition for certain complex use cases. But then enabling it for others.

But for your use case, you'd be better off popping up messages explaining the failure than silently not allowing the transition at all and having everyone asking "why?"

@Leonard Hussey understandable, although I think the concept of what I'm trying to achieve is the same. 

My concern is, if I go back to separating all 6 validators, they all must evaluate to true, so my validations will always fail, no? 

For example, in my 6 expressions, the first is Resolution = Done and custom field is not one of several values, 2nd is Resolution = Duplicate and custom field is a specific value, 3rd is Resolution = Declined and custom field is not one of several values, and so on.  So, if I enter Resolution = Cannot Reproduce and the expected custom field value, the first three validations fail, thus I cannot transition the ticket even if the 4th or 5th expression is true. 

If that is the case, further thinking is to 'or ||' them together to say if expression 1 doesn't pass, check 2, then 3, and so on until the correct combination is met.  But, that is not working either. 

I'm less concerned about 1 or many error messages (even though some would be incorrect messages and possibly lead to confusion) as I am with the inability to validate multiple possibilities to completion.

Hi @swilson 

You need to negate them.

Your condition right now is: "this is what I need the fields to be"

You negate them to "the fields must NOT be what I'm trying to avoid".

So, first part of your condition is currently as below. What you want to have.

[
issue?.resolutionObject?.name == 'Done'
&& issue?.customfield_10129?.value != "No Change - Deprecated"
&& issue?.customfield_10129?.value != "No Change - Duplicate"
&& issue?.customfield_10129?.value != "No Change - No Plans to Fix"
&& issue?.customfield_10129?.value != "No Change - No Plans to Fix"
&& issue?.customfield_10129?.value != "No Change - Not Reproducible (with the information provided)"
&& issue?.customfield_10129?.value != "No Change - Working as Designed"
]

 

You can negate it as shown below to NOT be what you don't want.

! issue?.resolutionObject?.name == 'Done' || issue?.resolutionObject?.name == 'Done' && 
! (
issue?.customfield_10129?.value = "No Change - Deprecated" ||
issue?.customfield_10129?.value = "No Change - Duplicate" ||
issue?.customfield_10129?.value = "No Change - No Plans to Fix" ||
issue?.customfield_10129?.value = "No Change - No Plans to Fix" ||
issue?.customfield_10129?.value = "No Change - Not Reproducible (with the information provided)" ||
issue?.customfield_10129?.value = "No Change - Working as Designed"
)

 

So your validator becomes, in words: " REsolution is NOT Done OR ( custom fields must NOT be: A, or B, or C, or D.") <- this implicitly means that if Resolution!=Done, then the check will pass and if it IS "Done", then the customfields must NOT be any of the listed values.

 

Same for all other parts: you pivot each validator on the Resolution value and then make it so that the customfield is NOT what you want to avoid for THAT Resolution value.

 

In this way, you will not have one validator conflicting with another. They'll work together allowing only what you want it to be.

 

I made them multi-line to easier reading.

 

Hope I did not make it worse

 

PS. corrected it. I think. My head hurts.

Like swilson likes this

@swilson 

 

I think the following, as single Validators, would work. If I did not mess up syntax.

Part 2:

From:

[issue?.resolutionObject?.name == 'Duplicate' && issue?.customfield_10129?.value == "No Change – Duplicate"]

To:

issue?.resolutionObject?.name != 'Duplicate' ||
( issue?.resolutionObject?.name == 'Duplicate' &&
issue?.customfield_10129?.value == "No Change – Duplicate"
)

 

Part 3:

From:

[
issue?.resolutionObject?.name == 'Declined' &&
issue?.customfield_10129?.value != "Code Change" &&
issue?.customfield_10129?.value != "Configuration Change" &&
issue?.customfield_10129?.value != "Data Change" &&
issue?.customfield_10129?.value != "Database Change" &&
issue?.customfield_10129?.value != "Deployment Change" &&
issue?.customfield_10129?.value != "Infrastructure Change" &&
issue?.customfield_10129?.value != "Third Party Change"
]

To:

issue?.resolutionObject?.name != 'Declined' || 
( issue?.resolutionObject?.name == 'Declined' &&
! ( issue?.customfield_10129?.value == "Code Change" ||
issue?.customfield_10129?.value == "Configuration Change" ||
issue?.customfield_10129?.value == "Data Change" ||
issue?.customfield_10129?.value == "Database Change" ||
issue?.customfield_10129?.value == "Deployment Change" ||
issue?.customfield_10129?.value == "Infrastructure Change" ||
issue?.customfield_10129?.value == "Third Party Change"
)
)

 

Part 4:

From:

[
issue?.resolutionObject?.name == 'Cannot Reproduce' &&
issue?.customfield_10129?.value == "No Change - Not Reproducible (with the information provided)"
]

To:

issue?.resolutionObject?.name != 'Cannot Reproduce' ||
( issue?.resolutionObject?.name == 'Cannot Reproduce' &&
issue?.customfield_10129?.value == "No Change - Not Reproducible (with the information provided)"
)

 

Part 5:

From:

[
issue?.resolutionObject?.name == 'Won’t Do' &&
issue?.customfield_10129?.value != "Code Change" &&
issue?.customfield_10129?.value != "Configuration Change" &&
issue?.customfield_10129?.value != "Data Change" &&
issue?.customfield_10129?.value != "Database Change" &&
issue?.customfield_10129?.value != "Deployment Change" &&
issue?.customfield_10129?.value != "Infrastructure Change" &&
issue?.customfield_10129?.value != "Third Party Change" &&
issue?.customfield_10129?.value != "No Change - Duplicate" &&
issue?.customfield_10129?.value != "No Change – Not Reproducible (with the information provided)"
]

To:

issue?.resolutionObject?.name != 'Won’t Do' || 
(
issue?.resolutionObject?.name == 'Won’t Do' &&
! ( issue?.customfield_10129?.value == "Code Change" ||
issue?.customfield_10129?.value == "Configuration Change" ||
issue?.customfield_10129?.value == "Data Change" ||
issue?.customfield_10129?.value == "Database Change" ||
issue?.customfield_10129?.value == "Deployment Change" ||
issue?.customfield_10129?.value == "Infrastructure Change" ||
issue?.customfield_10129?.value == "Third Party Change" ||
issue?.customfield_10129?.value == "No Change - Duplicate" ||
issue?.customfield_10129?.value == "No Change – Not Reproducible (with the information provided)"
)
)

 

 

Part 6:

From:

[
issue?.resolutionObject?.name == 'Backlog' &&
issue?.customfield_10129?.value != "No Change - Deprecated" &&
issue?.customfield_10129?.value != "No Change - Duplicate" &&
issue?.customfield_10129?.value != "No Change - No Plans to Fix" &&
issue?.customfield_10129?.value != "No Change - No Plans to Fix" &&
issue?.customfield_10129?.value != "No Change - Not Reproducible (with the information provided)" &&
issue?.customfield_10129?.value != "No Change - Working as Designed"
]

To:

issue?.resolutionObject?.name != 'Backlog' ||
( issue?.resolutionObject?.name == 'Backlog' &&
! ( issue?.customfield_10129?.value == "No Change - Deprecated" ||
issue?.customfield_10129?.value == "No Change - Duplicate" ||
issue?.customfield_10129?.value == "No Change - No Plans to Fix" ||
issue?.customfield_10129?.value == "No Change - No Plans to Fix" ||
issue?.customfield_10129?.value == "No Change - Not Reproducible (with the information provided)" ||
issue?.customfield_10129?.value == "No Change - Working as Designed"
)
)
Like swilson likes this

For any of the 6 Resolution values listed above:

- x5 validators will evaluate to True by the first condition

- x1 validator will evaluate to True by the 2nd condition (the long one) if the custom fields is OTHER than the ones you want to avoid.

And:

- if you have any Resolution value other than the 6 above, all validators will evaluate to TRUE with the first check of each part.

 

Means you don't need to go all-in to add all Resolutions right now. No future limitation on the Resolutions you want to add and you can grow these validators as needed in the future, too

Like swilson likes this

IT WORKS!!!!  I finally, after a few tweaks (not seeing you laid out each and every expression ... Thank You!!), added each validation separately using the negate methodology.  Every combination now fires the single expected error or transitions the task as expected based on the values entered.  Whew!!  Once I get confirmation from our team to allow me to install JMWE, I assume this same concept will work there, barring possible syntax differences?

I truly appreciate everyone's responses, suggestions, and support!  @Leonard Hussey YOU ROCK!!

0 votes
Answer accepted
Dirk Ronsmans Community Leader May 26, 2022

Just a side note since you mention Behaviours on Cloud, they are actually in Beta right now!

https://www.adaptavist.com/products/atlassian-apps/the-future-scriptrunner-for-jira-cloud

Suggest an answer

Log in or Sign up to answer
TAGS

Community Events

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

Find an event

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

Unfortunately there are no Community Events near you at the moment.

Host an event

You're one step closer to meeting fellow Atlassian users at your local event. Learn more about Community Events

Events near you