Copy Comments from all Sub-Tasks into the Parent

Chase Brown April 22, 2019

First off, I work in a bureaucratic limited funding environment. I'm not able to get whatever add-on that might make this simpler (which seems to be the simple answer everyone seems to come up with). I have scriptrunner for Jira, and I have Power Custom Fields Premium, and it's a 6 month process to get addons approved here.

I need to be able to copy comments from sub-tasks to the parent task.  It doesn't have to be pretty, but only my techs touch the sub-tasks while my managers are monitoring the parents and can't seem to keep track of the dozen sub-tasks they are tracking amongst hundreds of requirements. 

4 answers

1 accepted

2 votes
Answer accepted
Peter-Dave Sheehan
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
April 22, 2019

I just had a quick play with this scenario.

This works in my environment:

import com.atlassian.jira.component.ComponentAccessor

def commentManager = ComponentAccessor.commentManager

if(event.issue.isSubTask() && event.comment){
def parent = event.issue.parentObject
def newCommnet = commentManager.create(
parent,
event.user,
"Comment from sub-task: $event.issue.key:\n{quote} $event.comment.body {quote}",
event.comment.groupLevel,
event.comment.roleLevelId,
true
)
}

 

I used true in the last parameter for the create() method because you probably want your managers to be notified of the comments... Also, I added some context around the original comment so that you can tell it's carried over from the child.

Chase Brown April 23, 2019

Thank you @Peter-Dave Sheehan! That worked perfect!

Iman July 22, 2019

Is it possible to keep the comment as internal if it is originally internal? as it currently posts as external. 

Peter-Dave Sheehan
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
July 22, 2019

I don't use Service Desk. So I can't verify.

But you should always consult the ScriptRunner documentation first: https://scriptrunner.adaptavist.com/latest/jira/recipes/misc/jira-service-desk.html#_creating_internal_comments

You'll usually find what you need.

Wojciech Woytynowski February 18, 2022

The script works great in Scipt Listener. How to reverse the comments from the parent to the sub-task

Brian Gulizia June 18, 2024

I just implemented this today and it works well!

 

Is there a way to modify the script so that it works for copying comments for a child story to a parent epic?

1 vote
Code to live blog October 1, 2022

You can achieve this functionality of copying the comment entered in the sub task to parent issue using the listener. I have briefly explained the steps in the below blog post to achieve the same for your reference,

https://codetolive.in/jira/How-to-I-use-a-JIRA-custom-listener-to-copy-comment-from-the-subtask-to-the-parent-issue/

0 votes
Wojciech Woytynowski February 18, 2022

The script works great in Scipt Listener. How to reverse the comments from the parent to the sub-task

Peter-Dave Sheehan
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
February 18, 2022

Here is a similar script for copying comments from the parent to each subtasks:

import com.atlassian.jira.component.ComponentAccessor

def commentManager = ComponentAccessor.commentManager
if(event.issue.subTaskObjects && event.comment){
event.issue.subTaskObjects.each { subtask ->
def newCommnet = commentManager.create(
subtask,
event.user,
"Comment from parent: $event.issue.key:\n{quote} $event.comment.body {quote}",
event.comment.groupLevel,
event.comment.roleLevelId,
true
)
}
}
Like wojciechwoytynowski likes this
wojciechwoytynowski February 19, 2022

When we enable both scripts:
1

import com.atlassian.jira.component.ComponentAccessor

def commentManager = ComponentAccessor.commentManager

if(event.issue.isSubTask() && event.comment){
def parent = event.issue.parentObject
def newCommnet = commentManager.create(
parent,
event.user,
"Comment from sub-task: $event.issue.key:\n{quote} $event.comment.body {quote}",
event.comment.groupLevel,
event.comment.roleLevelId,
true
)
}


2

import com.atlassian.jira.component.ComponentAccessor

def commentManager = ComponentAccessor.commentManager
if(event.issue.subTaskObjects && event.comment){
event.issue.subTaskObjects.each { subtask ->
def newCommnet = commentManager.create(
subtask,
event.user,
"Comment from parent: $event.issue.key:\n{quote} $event.comment.body {quote}",
event.comment.groupLevel,
event.comment.roleLevelId,
true
)
}
}


it does a loop and adds comment after comment

 

I didn't write before, sorry I need a Listener that moves comments both ways from Parent to subtask and from subtask to Parent

wojciechwoytynowski February 20, 2022

@Peter-Dave Sheehan Help me please :) 

Peter-Dave Sheehan
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
February 23, 2022

I haven't tested but perhaps combining the two into one using some simple logic gates to not create new comment if the triggering comment starts with text we recognize might work:

import com.atlassian.jira.component.ComponentAccessor


def commentManager = ComponentAccessor.commentManager

def PREFIX_SUBTASK = "Comment from parent: "
def PREFIX_PARENT = "Comment from sub-task: "

if(event.issue.subTaskObjects && event.comment && ! event.comment.body.startsWith({PREFIX_SUBTASK})){
event.issue.subTaskObjects.each { subtask ->
def newComment = commentManager.create(
subtask,
event.user,
"$PREFIX_SUBTASK$event.issue.key:\n{quote} $event.comment.body {quote}",
event.comment.groupLevel,
event.comment.roleLevelId,
true
)
}
}
if(event.issue.isSubTask() && event.comment && ! event.comment.body.startsWith(PREFIX_PARENT)){
def parent = event.issue.parentObject
def newComment = commentManager.create(
parent,
event.user,
"$PREFIX_SUBTASK$event.issue.key:\n{quote} $event.comment.body {quote}",
event.comment.groupLevel,
event.comment.roleLevelId,
true
)
}
Like # people like this
Wojciech Woytynowski February 23, 2022
 

 

wojciechwoytynowski February 24, 2022

I already have it and it works

 


import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.issue.comments.CommentManager
import com.atlassian.jira.issue.watchers.WatcherManager
import com.atlassian.jira.user.ApplicationUser

MutableIssue issue = event?.getIssue()
CommentManager cm = ComponentAccessor.getCommentManager();
WatcherManager wm = ComponentAccessor.getWatcherManager()
ApplicationUser currentUser = event.getUser()
ApplicationUser epmjraplugin = ComponentAccessor.getUserManager().getUserByName("epmjraplugin")

if (issue.issueType.name.toUpperCase() == "STORY" || issue.issueType.name.toUpperCase() == "BUG" || issue.isSubTask()) {

if (!currentUser.equals(epmjraplugin)) {
def comment = event.getComment()

if (issue.isSubTask()) {
issue.getParentObject().each { it ->
Issue sourceIssue = it
log.error(sourceIssue)
log.error(sourceIssue.getIssueTypeId())
log.error("status źródła " + sourceIssue.getStatusId())
cm.create(sourceIssue, epmjraplugin, "Comment copied from sub-task's comment: $event.issue.key" + "\nComment added by: " + event.getUser().getDisplayName() + " \nComment content: " + comment.getBody(), true)
}
} else {
issue.getSubTaskObjects().each {
Issue sourceIssue = it
log.error(sourceIssue)
log.error(sourceIssue.getIssueTypeId())
log.error("status źródła " + sourceIssue.getStatusId())
cm.create(sourceIssue, epmjraplugin, "comment copied from main task's comment: $event.issue.key" + "\nComment added by: " + event.getUser().getDisplayName() + " \nTreść komentarza: " + comment.getBody(), true)
}
}

}
}

 
0 votes
Chase Brown April 22, 2019

I'm trying to use this answer: 

https://community.atlassian.com/t5/Marketplace-Apps-questions/Scripting-with-outdated-API-on-version-7/qaq-p/431272#U1064195

 

But I'm getting failures due to the If statement using " && ", any suggestions?

Peter-Dave Sheehan
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
April 22, 2019

replace && " with two actual ampersands &&

The & encoding is an html encoding ... this was just a weird artifact of the post or some loss during migration from an older platform for community posts.

Chase Brown April 22, 2019

Now I'm getting an error with:

 

def commentToParent = commentManager.create(

Cannot find matching method. 

 

and 

comment.getAuthorApplicationUser(),

Cannot find matching method. 

Peter-Dave Sheehan
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
April 22, 2019

You'll need to go consult the Java API documentation for your version of JIRA.

Also, you can try to output the list of available methods to the logs.

For example

log.debug "get comment methods: ${comment.metaClass.methods.name.sort().unique()}

Also, don't worry too much about the errors reported in the scriptrunner code editor. Unless you very specifically type each variable, scriptrunner/groovy can't know which class to examine for the correct method. So try it (in a test environment ) and look at the logs.

Suggest an answer

Log in or Sign up to answer