It's not the same without you

Join the community to find out what other Atlassian users are discussing, debating and creating.

Atlassian Community Hero Image Collage

Subtask-to-Parent Commenting

JIRA Version: 4.4 (soon upgrading to 5)

Thank you for reading / considering this...

We have the desire to do either of the following (preferring the first - copy - method):

  • Automatically, each time, copy a user created subtask comment into a parent comment

... OR ...

  • Block / forbid users from entering subtask comments (forcing comments only at the parent level)

I have some experience with Groovy -- based on Jamie Echlin's years of guidance and mastery of JIRA, although writing / editing classes is something I am currently unable to grasp.

Thanks again for your consideration.

8 answers

1 accepted

Comments for this post are closed

Community moderators have prevented the ability to post new answers.

Post a new question

Save this code to ...atlassian-jira/WEB-INF/classes/SubtaskCommentListener.groovy:

import com.atlassian.jira.ComponentManager
import com.atlassian.jira.event.issue.AbstractIssueEventListener
import com.atlassian.jira.event.issue.IssueEvent
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.comments.Comment
import com.atlassian.jira.issue.comments.CommentManager
import org.apache.log4j.Category

class SubtaskCommentListener extends AbstractIssueEventListener {
    Category log = Category.getInstance(SubtaskCommentListener.class)
    CommentManager commentManager = ComponentManager.instance.commentManager

    @Override
    void workflowEvent(IssueEvent event) {
        // only one central way...
        this.customEvent(event)
    }

    @Override
    void customEvent(IssueEvent event) {
        // set explicit to debug
        log.setLevel(org.apache.log4j.Level.DEBUG)
        log.debug "Event: \"${ComponentManager.instance.eventTypeManager.eventTypesMap[event.getEventTypeId()].name}\" fired for ${event.issue}"

        // Here you should put any subtask based restrictions for this task like
        // only for special subtask issue types or similar

        Comment comment = event?.getComment()
        if (comment && event.issue.isSubTask()) {
            log.debug "New commment for subtask found."
            Issue parent = event.issue.getParentObject()
            // Here you should put any parent task based restrictions like
            // only for special issue types or similar
            commentManager.create(parent, comment.author, comment.updateAuthor, comment.body, comment.groupLevel, comment.roleLevelId, comment.created, comment.updated, true, true)
            log.debug ("Created comment on ${parent.key}")
        }
    }
}

  

Create a Script Runner Listener (Custom listener) with "SubtaskCommentListener" as name of groovy class, listening on all events and the projects you want. Test and take a look into you catalina.out logfile. Done. :-)

With this script, edited comments are created as new comments on the parent issue (marked as edited). If you don't want that take a look into https://developer.atlassian.com/static/javadoc/jira/5.1.6/reference/com/atlassian/jira/issue/comments/CommentManager.html and adapt the commentManager.create() params.

Henning

You're welcome. :-)

Dear Henning,

Thank you so much for holding my hand through this and for writing this code for us...

IT WORKS PERFECTLY! THANK YOU!

I promise to leverage your guidance and will work to learn more.

Thank you, again, have a great weekend.

Sincerely, cristiano

Hi, I get a red error warning on this line of code:  

if (comment && event.issue.isSubTask()) {

I corrected the error, I think the're a result of the conversion from Answers to the new community site.

Davin Studer Community Leader Aug 29, 2018

Updated for Jira 7.12

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.event.issue.AbstractIssueEventListener
import com.atlassian.jira.event.issue.IssueEvent
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.comments.Comment
import com.atlassian.jira.issue.comments.CommentManager
import org.apache.log4j.Category

class SubtaskCommentListener extends AbstractIssueEventListener {
    Category log = Category.getInstance(SubtaskCommentListener.class)
    CommentManager commentManager = ComponentAccessor.getCommentManager()

    @Override
    void workflowEvent(IssueEvent event) {
        // only one central way...
        this.customEvent(event)
    }

    @Override
    void customEvent(IssueEvent event) {
        // set explicit to debug
        log.setLevel(org.apache.log4j.Level.DEBUG)
        log.debug "Event: \"${ComponentManager.instance.eventTypeManager.eventTypesMap[event.getEventTypeId()].name}\" fired for ${event.issue}"

        // Here you should put any subtask based restrictions for this task like
        // only for special subtask issue types or similar

        Comment comment = event?.getComment()
        if (comment && event.issue.isSubTask()) {
            log.debug "New commment for subtask found."
            Issue parent = event.issue.getParentObject()
            // Here you should put any parent task based restrictions like
            // only for special issue types or similar
            commentManager.create(parent, comment.getAuthorApplicationUser(), comment.getUpdateAuthorApplicationUser(), comment.body, comment.groupLevel, comment.roleLevelId, comment.created, comment.updated, true, true)
            log.debug ("Created comment on ${parent.key}")
        }
    }
}

Hi Davin,

I need some help, how can i change the listener to delete the comment in the parent when the comment is deleted in the subtask?

 

Regards

Joerg

Davin Studer Community Leader Mar 20, 2019

That is more difficult as there is no real link between the two. You could try and scan the comments of the parent ticket to look for a comment match the sub-task comments. However, if the parent comment has been edited in any way that process would fail.

Like Joerg_Strehl likes this

Thanks for your answer. Then we won't delete anything, think it makes more problems than it has a added value

I would suggest, you create a Groovy listener, using Script Runner plugin. Within the listener you should catch not only the Issue Commented event, because if the issue is edited and commented you want get this event. You can catch all events within the listener and configure the events to listen on later from the groovy plugin.

I'm not sure if there is a quick way to know if with the event a new comment was added. Maybe you have to check the date of the latest comment against the current date, but this may lead to double comments within the parent issue...

Good point about adding comments while editing and such. You can find from the event if a comment was added. It has a getComment method.

Jobin and Henning, thanks for your help. I'm stuck on how to approach this and will look into how to start. If you believe there's an relatively easy example, please let me know. I do know how to create a "Script Listener" via the UI, but really don't understand how to execute groovy code based on an event trigger. Thanks again for your understanding.

There's now a very easy to configure way to copy field values from parent to sub-tasks or sub-tasks to parent  (including comments) using Automation for JIRA!

You can easily modify related issues (such as parents, stories, sub-tasks, epics, linked issues and even JQL) using our related issues action and condition:

related-branch.png

(this example transitions sub-tasks, but you could just as easily change this to edit fields for both sub-tasks and/or parent, or add comments)

Andreas,

I'm able to view the 2nd image but not the first. My goal is to use Automation for JIRA to display sub-task comments on parent issue. Any time a comment is left on a sub-task it will update the parent issue to also show the comment. Would you have example of how to achieve this?

 

Thank you,

Davina Tsosie

andreas Community Leader Aug 15, 2017

Hi Davina,

There was only one image - I've edited the comment so it shows up properly now.

 

Now regarding your comment sync question, you could setup a rule like this:

  • Trigger: Issue commented
  • JQL Condition: type = "Sub-task"
  • Related issue action: With parent selected
    • Add Comment action with:
      {{comment.body}}

This would simply add the same comment to the parent issue whenever one is added to a sub-task.

The comment author on the parent issue would be the the rule actor though.

You could also use this in your add comment action:

{{comment.author.displayName}}: {{comment.body}}

Cheers,

  Andreas

Thank you very much. This works beautifully. I do have one question. It's not updating if said comments are edited. What addition would I add to the rule to make this possible?

 

Thanks for all your help,

Davina

Disregard below.

I located setting to Check if this rule should only add this comment once to a particular issue.

                                                                                                                      

Also, I tried to add an additional comment and got the following message in the audit log: No new comment was added since this issue has been commented on before: DIGITAL-112(parent issue)

 

Is there something I should include so that all sub-task comments are added to parent?

Thank you,

Davina

one more thing. How do I include the Subtask key instead of the parent key in the comments?  I entered it in as {{issue.key}}
{{comment.author.displayName}}: {{comment.body}}

Digital-112 is the parent issue not the subtask issue.

it shows as follows:

parent issue key displayed.jpg

Hello,

Any insight on this portion of my question?

How do I include the Subtask key instead of the parent key in the comments?  I entered it in as {{issue.key}}
{{comment.author.displayName}}: {{comment.body}}

Digital-112 is the parent issue not the subtask issue.

as shown in screenshot above.

 

Thank you,

Davina

Scott Harwood Community Leader Aug 29, 2017

Hi Davina,

You need to use {{triggerIssue.key}} instead.

Cheers,

Scott

You can do this pretty easily in a listerner. Capture the "Issue Commented" event, check if it is on a subtask and if so copy the comments to the parent task.

Dear Jobin,

Thanks so much for your guidance. May I ask a few follow-up questions (forgive me for asking these simple questions that I should know)?

  1. Should I use a 'Listener' or a 'Script Listener' (via Jame's Script Runner plugin)?
  2. I see the "Issue Commented" event, which type of Listener (or class should I use)?
  3. If I should trigger a specific "Event to Fire" from the Event list when the "Issue Commented" event runs, is there a specific event type that would allow me to refer to a groovy script (.groovy file)?

Thanks again Jobin, cristiano

Unfortunately, most of this specific to groovy, which I can't answer. I usually write a Java listener and you can find a tutorial here:

https://developer.atlassian.com/display/JIRADEV/Writing+JIRA+event+listeners+with+the+atlassian-event+library

Hello Jobin, can you take a look at this case? Thank you! https://answers.atlassian.com/questions/5702342/answers/5702487

Just a thought. Maybe you can allow people to comment on sub-tasks but when a sub-task is closed, copy all its comments to the parent task. You can also append a statement to the comment saying "This comment was copied from subtask <issue-id>". Will this work? In this case, you can write a post-function that is fired when a subtask is closed.

@Henning Tietgens Thanks for resolution! May be you help me to copy assignee value from subtasks to parent multy picker user field? 

You have to modify the script to get a MutableIssue of the parent issue and than you can add the assignee of the subtask to a customfield of the parent task (in this case to the field "Contributors"). [...] import com.atlassian.jira.issue.MutableIssue import com.atlassian.jira.user.ApplicationUsers import static com.atlassian.jira.event.type.EventDispatchOption.DO_NOT_DISPATCH [...] CustomFieldManager customFieldManager = ComponentAccessor.customFieldManager IssueManager issueManager = ComponentAccessor.issueManager [...] if (comment && event.issue.isSubTask()) { log.debug "New commment for subtask found." MutableIssue parent = issueManager.getIssueObject(event.issue.getParentObject().id) // Here you should put any parent task based restrictions like // only for special issue types or similar commentManager.create(parent, comment.authorApplicationUser, comment.updateAuthorApplicationUser, comment.body, comment.groupLevel, comment.roleLevelId, comment.created, comment.updated, true, true) log.debug ("Created comment on ${parent.key}") def assignee = event.issue.getAssignee() def cfContributors = customFieldManager.getCustomFieldObjectByName('Contributors') if (cfContributors) { def contributors = cfContributors.getValue(parent) ?: [] contributors << ApplicationUsers.from(assignee) contributors -= null parent.setCustomFieldValue(cfContributors, contributors) issueManager.updateIssue(event.user, parent, DO_NOT_DISPATCH, false) } }

Hello @Henning Tietgens 

I have a similar requirement where the subticket should get updated when ever there is any comment made, edited or deleted on parent ticket. Is this possible in Jira? If its possible.. would be you kind enough to help me with the code or the process to follow so I could achieve the same pls? 

p.s... we already have Script runner installed at our instance.

Thank You!!

Hi @Sravan_Kumar, you could replace the part after the getComment() to work on all subtasks instead of the parent issue:

Comment comment = event?.getComment()
def subtasks = event.issue.getSubTaskObjects()
if (comment && subtasks?.size() > 0) {
log.debug "New commment for issue with subtasks found."
subtasks.each { subtask ->
// Here you should put any sub-task based restrictions like
// only for special issue types or similar
commentManager.create(subtask, comment.getAuthorApplicationUser(), comment.getUpdateAuthorApplicationUser(), comment.body, comment.groupLevel, comment.roleLevelId, comment.created, comment.updated, true, true)
log.debug("Created comment on ${subtask.key}")
}
}

Here's what's working for us (on Jira 8.0.0) from another thread:

 

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.comments.Comment

Issue subtask = event.issue
Comment comment = event.comment
def commentManager = ComponentAccessor.getCommentManager()

if (subtask.isSubTask() && comment) {
def parentIssue = subtask.getParentObject()
def commentToParent = commentManager.create(
parentIssue, //the parent issue to copy the comment
comment.getAuthorApplicationUser(), //the author of the subtask's comment
comment.getBody(), //the actual comment body
//comment.getGroupLevel(), // is the group name to limit comment visibility to, this must be a valid group name.
//comment.getRoleLevelId(), // is the id of the the ProjectRole to limit comment visibility to, this must reference a valid project role.
true) //if true then an event of type EventType.ISSUE_COMMENTED_ID will be dispatched and any notifications listening for that event will be triggered. If false no event will be dispatched.
log.info "Comment copied to parent issue ${parentIssue.getKey()}"
}

 I commented out some user/group restrictions that aren't useful for us.

Comments for this post are closed

Community moderators have prevented the ability to post new answers.

Post a new question

Community showcase
Posted in United States

Welcome new members!

Wow, we've grown by 20%+ in the past month to 45+ members in one year! Please welcome @jonkocen , @João Mano , @Sramanth_pandeti , and @Kythera_Contreras  plus Atlassian staff members @A...

18 views 0 1
View post

Community Events

Connect with like-minded Atlassian users at free events near you!

Find an event

Connect with like-minded Atlassian users at free events near you!

Unfortunately there are no Community Events near you at the moment.

Host an event

You're one step closer to meeting fellow Atlassian users at your local event. Learn more about Community Events

Events near you