Estimated time to read: 10 minutes
TL;DR: Many issues and their fields are lists of things. Sometimes we need to find specific items within a list. Knowing ways to find them saves rule-writers effort, time, and frustration. There are built-in rule features to help search or filter lists, yet those have limitations. Learning how to workaround some of the limitations can help.
Disclaimer: yes, many of us wish for better searching / filtering, JSON handling, branch management, etc. in Jira Automation rules. The automation product continues to evolve and improve, and that improvement takes time. We need to be patient and creative until such features arrive. Thus some may find this article borders on "hackery" to solve challenges, so feel free to read no further.
With that out of the way, why would you need dynamic searching of a list? Let's start with some basics of iterating and searching...
There are built in rule features to iterate over lists, such as branching when one needs to process something one item at a time. Examples include using a Related Issues branch on JQL to span issues or an Advanced Branch over smart values to select the items wanted, with additional filtering possible by adding rule Conditions. For example:
Rules also support iterating over a batch of things, using the various list functions with the long-format of iterator. Iterators like this also help when the rule has a branch, because branches cannot be nested at this time. You may try this method for needs such as listing the results of a Lookup Issues, Lookup Objects, or Lookup Table to create an email, and to summarize measures / counts.
Here are the issues:
{{#lookupIssues}}
* {{key}} -- {{summary}}
{{/}}
Total story points: {{lookupIssues.Story points.sum|0}}
With that format of iterator, we may filter the list using conditional logic. Specifically, using smart value, list filtering. Note the filtering still allows us to access the individual fields.
Here are the bug issues only:
{{#lookupIssues}}
{{#if(equals(issuetype.name, "Bug"))}}
* {{key}} -- {{summary}}
{{/}}
{{/}}
There is another format of iterator, inline iteration, which you may have used many times and not even realized it. It may be used to show, or search, the items in a list. Searching is done with the match() function. Note the difference from the long-format iterator, as with inline the entire record is returned, and there are no individual fields.
{{issue.sprint.name}}
-- Returns a comma-separated list of sprint names:
Feature sprint A, Release sprint 12, Bug Bash Sprint
{{issue.labels.match("(Event.*)")}}
-- Extract a list of the labels starting with "Event":
Event_A, Event_issue_created
Yet what if the filter criteria is unknown until the rule ran? Perhaps the selection for "Bug" issue type or "Event" label prefix filtering is stored in an issue field, or comes from a Manually Triggered rule input parameter. For actions like Lookup Issues, the JQL could be adjusted to account for this.
But there are other lists where JQL cannot help. Examples include the Sprint or Comments fields of an issue, the results of a Send Web Request action, etc. How could those be filtered when the criteria might not be known until the rule runs? This is where the dynamic searching can help.
From a recent question, I saw this scenario:
GIVEN there is an issue with multiple comments
AND the issue has an assignee
WHEN the issue has not been updated in the last 5 days
THEN find the last comment posted by the assignee
AND send them a follow-up communication regarding the comment
One would think smart value, list filtering would work for this scenario:
!! THIS DOES NOT WORK !!
{{#issue.comments}}{{#if(equals(author.displayName,issue.assignee.displayName))}}{{body}}{{/}}{{/}}
The reason it does not work is other issue fields are not visible once inside of the iterator over the comments. That is, the assignee cannot be used for filtering. This is a known, scoping limitation of iterators.
A possible workaround is to use the inline iterator we noted earlier:
Remember the earlier disclaimer I noted about "hackery"? Yes, this is repackaging the list just to search it. And it can help for some searches...but not all. If using this method just feels wrong to you, feel free not to use it. Instead, you may wait until other search / filter features are added to rules.
Let's create an example rule to solve the scenario with comments and the assignee:
({{issue.assignee.displayName}}:.*)
{{#issue.comments}}{{author.displayName}}:{{body}}{{^last}}~~{{/}}{{/}}
{{varCommentList.split("~~").match(varRegularExpression).last.substringAfter(":")}}
I have used (or helped others use) this technique for several scenarios, such as:
If you have read all the way to here, congratulations! You are investing in yourself to learn about automation and working around some of the limitations. I look forward to seeing your feedback and how you might use automation to help your teams. Thank you!
Bill Sheboy
agile coach, idling
None
Atlassian Community
2,553 accepted answers
2 comments