Dear community,
I would like to now the previous state of an issue within a Jira Automation.
I can get the change history of an issue via web request:
I then read the response into a variable by {{webhookResponse.body.changelog.histories.items}}.
There are all the changes, which have been done to an issue.
Question: how do I parse it down to the previous state of the issue?
I tried to follow this approach by @Erin Quick-Laughlin, but I am very much struggling with the {{smart values}}.
I have tried this, but get an empty audit log back:
{{#webhookResponse.body.changelog.histories.items}} {{#if(equals(field, "status"))}} {{fromString}} {{/}} {{/}}
Any help is very much appreciated.
Chris
Short answer: in my opinion, there is no simple / elegant way to do this using the REST API functions in a rule, and saving the prior status in a custom field may be easier to implement and maintain.
More information...
The changelog for an issue could be quite long, and so you may not find your status field in the first 100 records returned. And so paging to repeatedly call the REST API may be required, increasing the rule complexity...and reducing the chances of success.
Let's assume the rule trigger is issue transitioned, and so we can experiment and increase the chances of finding at least one match to the status field in the histories.
Next, rules have problems processing lists-within-lists inside of iterators. In this case, the histories are a list and so are histories.items. Inside the iterator, the fields will not resolve correctly when conditional filtering is used: they collapse to null. Noting the earlier post you linked-to for your question, that is why I suggested using inline-iteration and the match() function.
Thus one possible workaround for this is to flatten the structure into a known, delimited format; split to a list; and then use match...returning only the first record. That will be the one with the prior status id information in the "from" attribute.
Kind regards,
Bill
Here is a follow-up example with that workaround...assuming the answer is in the current response for the Send Web Request action.
{{#webhookResponse.body.changelog.histories}}field:{{items.field}}@@@{{items.from}}~~{{/}}
That would produce a delimited, text string like this:
field:status@@@3~~field:Fix Version@@@null~~field:status@@@10003~~and so on...
{{varHistory.split("~~").match("field:status@@@(.*)")}}
{{varHistory.split("~~").match("field:status@@@(.*)").first}}
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Dear @Bill Sheboy
Thank you very much for your input. Up until now, I did not unterstand the .split, .match and .first, but I am a big fan of regex. :-)
I very much value your inputs about the changelog. As it seems, the webresponse is ordered in a descending way -> newest entries come first. The webresponse from my current test ticket has 4000+ lines and I can still find all state-changes. I am confident, that the newest one should be available anyway, but I will try to implement a default behaviour, if no previous state could be found. (Trigger for my automation will be "comment created".)
My integration provider suggested a solution using .substringBetween to parse the webrequest response.
All your inputs got me going and I tried many different things.
To get a list of all state changes from the history, I found this:
{{response.match("((?=\{field=status)\{field=status, fieldtype=jira, fieldId=status, from=\d*, fromString=(([\w\s]*)|(\w)*), to=\d*, toString=(([\w\s]*)|(\w)*)\})")}}
This will result in something like this:
{field=status, fieldtype=jira, fieldId=status, from=3, fromString=In Progress, to=10006, toString=Warten auf Kunden}, {field=status, fieldtype=jira, fieldId=status, from=10006, fromString=Warten auf Kunden, to=3, toString=In Progress}, {field=status, fieldtype=jira, fieldId=status, from=10005, fromString=Pendent, to=10006, toString=Warten auf Kunden}, {field=status, fieldtype=jira, fieldId=status, from=10016, fromString=Selected for Development, to=10005, toString=Pendent}, {field=status, fieldtype=jira, fieldId=status, from=10004, fromString=in Vorbereitung, to=10016, toString=Selected for Development}, {field=status, fieldtype=jira, fieldId=status, from=10003, fromString=Backlog, to=10004, toString=in Vorbereitung}, {field=status, fieldtype=jira, fieldId=status, from=10016, fromString=Selected for Development, to=10003, toString=Backlog}, {field=status, fieldtype=jira, fieldId=status, from=10003, fromString=Backlog, to=10016, toString=Selected for Development}
by adding the .first, I can reduce it to the newest entry.
Then, I would have to use .split and .match to read the "from=" or "fromString".
Downsides are...
I then modified my approach a little bit.
This line directly provides the list of all from-status from all state-changes. (newest first)
{{response.match("((?<=\{field=status, fieldtype=jira, fieldId=status, from=)\d*)")}}
Again, by adding the .first, I get the ID I need directly into a variable.
{{response.match("((?<=\{field=status, fieldtype=jira, fieldId=status, from=)\d*)").first}}
The duration of the processing time is approx. 3-4 seconds.
Looking forward to your feedback on this solution.
Chris
EDIT: the original web response is a JSON. It would be so much easier, if the {{webhookResponse.body}} would be a JSON-object as well. Is there a way to read the response as JSON?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Thanks for your extra analysis, Christian!
Answering your last question, first...no, there is no way to read all possible responses as JSON. I recall there is an open suggestion to add a text function for rules to correctly interpret as JSON, allowing dereferencing by attributes at all levels / structures.
Next regarding use of more advanced, complicated regular expressions...the documentation states this, with emphasis added by me:
The underlying implementation is based on Java's Pattern class and uses Matcher.find() to find matches.
I have not found stated what is / is not supported in regular expressions for rules. Several community posts indicate expressions that work with other regular expression parsing tools do not work the same in automation rules. This can be caused by the parsing order, particularly when escaping characters is used. (One workaround for that is to store the expression in a created variable first, and then use it in the match() function.)
I recommend using the simplest regular expression that can possibly work, testing, and incrementally adding to handle edge cases. And if you have something that works, save that expression / rule, before modifying to enhance it.
Regarding the performance, I suspect at least 1 second of that time is for the Send Web Request call. And I have observed both complicated regular expressions and large text strings adding to rule run time. I cannot tell from your question if you are using Jira Cloud, Server, or Data Center. If Cloud, I have seen rule performance be inconsistent, even for trivially simple rules.
Perhaps try removing rule steps to isolate where the time is going, and then trying to improve those.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi,
I see two another solutions which may be helpful:
A) Create hidden custom fields and put there your status names: https://confluence.atlassian.com/jirakb/how-to-transition-to-the-previous-status-of-an-issue-using-automation-rules-in-jira-1236599919.html
B) Depending on complexity of your workflow you can rename all transitions to make the name uniques between statuses. You can create a combined Lookup Table inside automation rule with propper mappings as you will have transition names that defines "from" and "to" statuses.
This is more complex solution and it will not work if you want tyo globalise that rule across projects/workflows.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Thank you for your response. I have seen that approach as well, but I don't want to create another set of customfields, if I can get this done on the fly.
My automation should trigger, if a customer comments on an issue and then, the automation should transition the issue back to its previous state. As I have different workflows with different transitions in our Service Desk, I would like to solve this elegantly. :-)
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.