Jira Automation to copy certain labels from children
Asked by jeremyn:

Hey All,  

So I've been fighting with this for a little while and I'm pretty sure it isn't possible.  

Situation: We use labels in child issues to indicate some planning information. We need the parent to reflect the collection of these labels of all of its children. The labels are patterned and so any solution that requires me to know the exact label won't work.   

The labels follow a pattern similar to this regex: "\\d+\[4-9\]-Z\\d+"

Problem: I can not handle the situation where a status is removed from the "last" child.  

I have an automation running when a child label is updated to append that label (and any others matching the pattern) to the parent. I also have a scheduled automation that loops over all of the child issues and updates their parents (to catchup everything previously done).  

Now what I'm trying to figure out is how to tackle when a label is removed from the last child.  

Because I need to remove I'm pretty sure the only viable method is to work on the parents and somehow loop over the children "rebuilding" the label list.  

However, from what I can tell:  
1) You can't edit/concat a smart variable so I can build up a JSON to as I do a branch on children and then apply that post-branch  
2) You can't use a smart value created in a branch once the branch exits  
2) You can't call triggerissue in json (or any other way I can see) while in a branch.  

So lets say I have a situation like this:  

Parent: \[24-Z1, 24-Z2, 24-Z3\]  
Child 1: \[24-Z1, 24-Z2\]  
Child 2: \[24-Z2, 24-Z3\]  

When someone removes "24-Z3" from Child 2 I need to remove "24-Z3" from Parent. But, if someone removes "24-Z2" from Child 2 it can't remove it from the parent because it is still contained in Child 1.  

Any suggestions or am I screwed (I know I could create a CICD build job in our pipeline system and use REST API calls, but I really don't want to have to make my team do that....)


Answers:
author: Bill Sheboy
body: Hi [@jeremyn](/t5/user/viewprofilepage/user-id/4907373)

Are the parent issue's labels *always-and-only* a roll-up of the values from the child issues?

If so, I recommend using Lookup Issues to gather the child issues' label values and replace the parent value completely, for any triggering events, when needed.

The reason I suggest this is list and list-like fields have brittle changelog entries when accessed via automation rules. Some specific examples are Fix Versions and Sprint fields, which encounter broken changelogs as values are deleted / added. I do not know if that also applies to labels.

Kind regards,  
Bill

comments: author: jeremyn
body: Hi Bill,  

Excellent, I think I can make that work.  

Ideally, no, the parent labels would only contain the child labels that matched the pattern, while they could also contain their own labels.  

I already have a test automation where I remove all of the labels of the given pattern w/ JSON:  

1) Create Smart Value: varExistingLabels = {{issue.Labels}}  

2) Edit advanced: "labels": \[{"remove":""}{{#varExistingLabels.split(", ").toUpperCase().match("(\\d+\[4-9\]-Z\\d+)")}},{"remove":"{{.}}"}{{\^last}}{{/}}{{/}}\]  

<br />

So, if I could somehow create a smartValue list of all of the child issue's labels that match that same pattern I can rebuild, like you suggest, pretty easily.  

I think that with the {{#lookupIssues}} {{labels.split(", ").toUpperCase().match("(\\d+\[4-9\]-Z\\d+)")}} I can make it work...  

Thanks!


author: Darryl Lee
body: Man, I just *knew* Bill would beat me to the punch here. :-}

The one thing I have to add is that you might want to add a **.distinct**when you get those child labels into a list, to cover this possible case:
> Child 1: \[24-Z1, 24-Z2, **24-Z4**\]  
> Child 2: \[24-Z2, 24-Z3, **24-Z4**\]

Where if somebody removes 24-Z2 from Child 2 there's a *duplicate* label of 24-Z4.

Of course Bill has covered this in the past as well:

[How to get unique value from multi-select using smart value?](https://community.atlassian.com/t5/Jira-questions/How-to-get-unique-value-from-multi-select-using-smart-value/qaq-p/2253233)


author: jeremyn
body: Hi Darryl, thanks for the idea. In my case I still want the parent to retain 24-Z4 because at least one of its children is using that label.


author: jeremyn
body: Ok, so for posterity here is what I did to accomplish managing having labels that match a pattern properly add/delete from a parent dynamically as they are changed in the children.  

What happens with this is if any label is added to a child that matches the pattern it will add to the parent. If a Label is removed that matches the pattern it is removed ONLY IF there is no instances of that label on any of its siblings.  

To start, set Value Changed trigger for the child issue type:  

![add-labels-to-parents-1.png](https://community.atlassian.com/t5/image/serverpage/image-id/335736i2087A4DBC6B8C201/image-dimensions/320x481?v=v2 "add-labels-to-parents-1.png")  
varLabelsToRemove is the JSON (sans wrappers) list of labels we need to clean up from the parent before adding anything we want back in:  
**"labels": \[{"remove":""}{{#varParentLabels.replace(", ",",").split(",").toUpperCase().match("(\\d+\[4-9\]-Z\\d+)")}},{"remove":"{{.}}"}{{\^last}}{{/}}{{/}}\]** This ends up looking like so if you print it to the log:  
**"labels": \[{"remove":""},{"remove":"24-Z1"},{"remove":"25-Z2"},{"remove":"26-Z3"},{"remove":"24-Z45"}\]** NOTE: The first empty remove is to handle issues where the var is empty because there is no label.  

Next, we need to get and store all of the new labels we care about from ALL of the this issues siblings (including itself) so we do another Lookup Issues to get all the siblings:  
![add-labels-to-parents-2.png](https://community.atlassian.com/t5/image/serverpage/image-id/335737iE007E2164E823EF8/image-dimensions/318x376?v=v2 "add-labels-to-parents-2.png")  
varLabelsToAdd is similar to varLabelsToRemove except we swap out the remove for add:  
**"labels": \[{"add":""}{{#varLookupLabels.replace(", ",",").split(",").toUpperCase().match("(\\d+\[4-9\]-Z\\d+)").distinct}},{"add":"{{.}}"}{{\^last}}{{/}}{{/}}\]**   

Finally, we branch on the parent and use these two variables to first remove and then add back in the issues we care about:  

![add-labels-to-parents-3.png](https://community.atlassian.com/t5/image/serverpage/image-id/335741i8C393BB0AA6E2324/image-dimensions/330x442?v=v2 "add-labels-to-parents-3.png")  
Where the JSON for the remove is like so in the first edit block (the add is the same, but using the other variable):  

![add-labels-to-parents-4.png](https://community.atlassian.com/t5/image/serverpage/image-id/335742i2B4BB93D4BC136F0/image-dimensions/245x409?v=v2 "add-labels-to-parents-4.png")  

<br />

This took me a few days of messing around, but thanks to Bill for the push in the right direction!!!!


author: Darryl Lee
body: Hey [@jeremyn](/t5/user/viewprofilepage/user-id/4907373) glad you got it working!

Yeah, I was just saying that in my example, you would be adding the **24-Z4** label "twice", but in retrospect, because labels are unique, having that duplicate add shouldn't be a problem.


author: jeremyn
body: [@Darryl Lee](/t5/user/viewprofilepage/user-id/1365322) - You are right, I re-read that post you linked and realized what you were saying, and yes, add handles de-duping of labels...however, I tried your method and perhaps its a coincidence but the automation is now running about 1.5 seconds faster in my tests. perhaps the distinct is less processing intensive than the internal de-dup, or perhaps AWS is just running a bit faster than it was 30 mins ago...who knows.  

I updated my JSON to match the suggestions in that thread.


author: Darryl Lee
body: Cool!

I'd say that using **add**without removing potential duplicates doesn't "handle" de-duping so much as just ignores the issue entirely and (potentially) wastes extra cycles/calls adding labels that are already there.

Using the **.distinct** to filter out dupes prevents those extra cycles/calls from happening at all.


Tags: branch

jira