Create
cancel
Showing results for 
Search instead for 
Did you mean: 
Sign up Log in

Automation concepts -- Dynamic searches within a list

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:

  • trigger: sprint started
  • branch: on issues in Sprint
    • condition: issue type equals Bug
    • action: add a comment

 

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 IssuesLookup Objects, or Lookup Table to create an email, and to summarize measures / counts.

  • action: lookup issues with JQL
  • action: send email
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:

  • build a regular expression to perform the searching / filtering
  • create a list we can search with the above expression
  • use inline iteration to perform the search with the match() function
  • finally, parse out the results.

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:

  • Name: find the last comment added by the assignee
  • trigger: scheduled trigger over assigned issues not updated for a while
  • action: create variable, for the regular expression. To learn more about creating regular expressions, please review the documentation linked to the match() function.
    • name: varRegularExpression
    • smart value: 
({{issue.assignee.displayName}}:.*)
  • action: create variable, expanding all comments into a delimited list with their author using an long-format iterator. There is a colon between the author name and comment body, and a double-tilde ~~ to separate the records.
    • name: varCommentList
    • smart value:
{{#issue.comments}}{{author.displayName}}:{{body}}{{^last}}~~{{/}}{{/}}
  • action: some action to notify the assignee
{{varCommentList.split("~~").match(varRegularExpression).last.substringAfter(":")}}
  • This works by...
    • split the comments variable into a list of records
    • match with the regular expression to find any comments by the assignee
    • grab the last record returned from the results
    • extract the comment body as the substringAfter the colon delimiter

 

 

I have used (or helped others use) this technique for several scenarios, such as:

  • build a search expression which contains reserved characters
  • get the last attachment added by a specific user
  • find the latest release date for versions in issues, and return the version id, name, etc.

 

 

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!

 

2 comments

Darryl Lee
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
October 8, 2024

Amazing @Bill Sheboy - honestly if you keep writing articles like this, people will want to send YOU to Barcelona. Heck, I do. ;-}

Like # people like this
Jason M_
Contributor
November 26, 2024

Your contributions to the community are legion, thank you for continuing to provide these valuable insights!

Like Bill Sheboy likes this

Comment

Log in or Sign up to comment
TAGS
AUG Leaders

Atlassian Community Events