Hello,
We are trying to copy attachments from one issue to another. The issues should be linked with the "Parent/Child" issue link, and we would probably keep 2 script listeners to always keep the issues in sync between 2 projects.
What we have:
import com.atlassian.jira.event.issue.IssueEvent
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.issue.attachment.Attachment
import com.atlassian.jira.issue.AttachmentManager
import com.atlassian.jira.ComponentAccessor
import com.atlassian.jira.issue.comments.Comment
import com.atlassian.jira.issue.comments.CommentManager
import com.atlassian.jira.issue.link.IssueLinkManager
import com.atlassian.jira.issue.link.IssueLink
import com.atlassian.jira.user.ApplicationUser
import org.ofbiz.core.entity.GenericValue
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.Issue;def linker = ComponentAccessor.getIssueLinkManager()
def commentMgr = ComponentAccessor.getCommentManager()
def issue = event.issue as MutableIssue
def project = issue.getProjectObject().getKey()
def attachmentManager = ComponentAccessor.getAttachmentManager()
def lastAttachment = attachmentManager.getAttachments(issue).last()def issueLinks = linker.getOutwardLinks(issue.getId())
def subElements = issueLinks.findAll { it.issueLinkType.name.contains('Parent/Child') && it.destinationObject.getProjectObject().getKey() == 'Test'}
def newComment = event.getComment()
def originalAuthor = newComment.getAuthorApplicationUser()
def commentBody = newComment.getBody()subElements.each {
if( commentBody != "")
{
commentMgr.create(it.getDestinationObject(), originalAuthor, commentBody , false)
}
}subElements.each {
if(lastAttachment)
{
attachmentManager.copyAttachment(lastAttachment, originalAuthor, it.getDestinationObject().key)
}
}
You can ignore the comments part, but since there isn't an issue attachment added event, I'm not sure how else to do this.
The script does not give any errors, but attachments are not copied at all.
Thank you in advance!
Hi @Mihai Mihai
As @fran garcia gomera mentioned use the Issue Commented event.
I tried trimmed version of your code and it works perfectly with slight change.
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.link.IssueLink
import com.atlassian.jira.issue.comments.Comment
import com.atlassian.jira.issue.comments.CommentManager
def issue = event.issue
def attachmentManager = ComponentAccessor.getAttachmentManager()
def lastAttachment = attachmentManager.getAttachments(issue).last()
def links = ComponentAccessor.getIssueLinkManager().getOutwardLinks(issue.getId())
def subElements = links.findAll { it.issueLinkType.name.contains('Parent/Child') }
def newComment = event.getComment()
def originalAuthor = newComment.getAuthorApplicationUser()
//return subElements*.destinationObject
subElements.each { it ->
if (lastAttachment) {
attachmentManager.copyAttachment(lastAttachment, originalAuthor, it.getDestinationObject().key )
}
}
I hope it helps.
Ravi
Hello,
Thank you for your reply!
I used the 'issue commented' event and the script that you added which is much cleaner.
It does not give any errors, but attachments do not get copied to the linked issue. I tried adding an image inside a comment or editing an issue and adding both a comment and a file attachment during that edit.
Do I have to attach the file in a specific way?
Thank you!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Is the name of your Issue Link exactly Parent/Child?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Also check whether the linked issues are outward links or inward links. The code is only checking for outward links.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Thank you for your replies. Yes, the issue link is "Parent/Child" and I am testing it on an outward link.
There aren't any errors, but nothing is added. Is there any other test that I can do?
Thank you!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I found one issue that somehow did not allow me to add attachments on the server:
2019-10-04 08:22:47,504 file-attachment-store:thread-41 WARN uidq5816 502x8986x1 1fi5fb7 10.208.247.63 /rest/internal/2/AttachTemporaryFile [c.a.j.issue.managers.DefaultAttachmentManager] Unable to copy attachment to issue with key TEST-10407. Exception: Unable to create target directory /opt/ea/atlassian/jira-home/data/attachments/TEST/20000/TEST-10407
and I corrected that. Now images added inside comments get copied.
However, by attachments, I also think of txt files and zip files added to an issue. Those do not get copied to the other issue. Is there any way to bring those items over as well?
Thank you very much!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Just to be sure you understand what I meant, we would need a listener for this type of attachments, not just the ones added through comments:
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Don't understand exactly the problem, if you choose custom listener there is an issue commented event that will launch your script.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi Ravi,
I am using your above formula bet still getting the error.
I am using the script in automation and want that when ever any comments has been added in the ticket it will check if that attachment has been already there or not. if not then only it will attach it in the linked issues ticket.
Please help me resolve this.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
@Mihai Mihai Check this out https://community.atlassian.com/t5/Marketplace-Apps-Integrations/Get-Attachment-of-a-Trigger-issue/qaq-p/703656#U704315
The comment from André Ramos.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hello,
Actually, it was never working.
The one that was adding the comments with the images was the previous one that I initially added in the description and it was not disabled.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hello @Ravi Sagar _Sparxsys_
Correction - it does work, but only with images, not with any other file type.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Not sure why it is not working for other files. I tried the same code with txt files. I will check.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I think I found something useful.
The problem might be coming from the "last" function, which does not seem to actually look for the last attachment.
For example, if an issue already has multiple attachments, it will only work with images for me.
If on an issue with 0 attachments I add any kind of file, then that one is copied to the linked issue.
Doing some more research I found on a thread that last does not work because attachments are sorted alphabetically.
Do you know any work-around for this?
Thank you!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Reproduction steps:
Issue a > parent of > Issue b
both issue a and issue b have 0 attachments.
add to issue b an attachment named: "abc" >>> it gets copied to issue a
add another attachment to issue b, named: "xyz" >>> it gets copied to issue a
add any other attachment to issue B, that has the name starting with any letter of the alphabet < x . ("lmn" >>> new attachment does not get copied anymore, xyz still does because it is last.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Please let me know if you know any possible solution for this situation.
Thank you!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Let me try to reproduce your last scenario.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi @Mihai Mihai
I was able to reproduce. The attachments are listed using their file names but we can sort them using their created date before fetching the last one.
Try this code.
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.link.IssueLink
import com.atlassian.jira.issue.comments.Comment
import com.atlassian.jira.issue.comments.CommentManager
def issue = event.issue
def attachmentManager = ComponentAccessor.getAttachmentManager()
def sortAttachment = attachmentManager.getAttachments(issue).sort { it.created }
def lastAttachment = sortAttachment.last()
def links = ComponentAccessor.getIssueLinkManager().getOutwardLinks(issue.getId())
def subElements = links.findAll { it.issueLinkType.name.contains('Parent/Child') }
def newComment = event.getComment()
def originalAuthor = newComment.getAuthorApplicationUser()
//return subElements*.destinationObject
subElements.each { it ->
if (lastAttachment) {
attachmentManager.copyAttachment(lastAttachment, originalAuthor, it.getDestinationObject().key )
}
}
Please note this code will copy attachment based on outward links which is in this case parent to child.
The main change is the following piece of code.
def sortAttachment = attachmentManager.getAttachments(issue).sort { it.created }
def lastAttachment = sortAttachment.last()
I hope it helps.
Let me know.
Ravi
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
This works indeed!
It copies the attachment, however, on each new comment, added to the linked issue, and it would be great if it could check if the attachment was either already copied or if it already exists on the other issue.
I think the filename should be a good enough indicator, probably together with the file type.
Please let me know if that is possible.
Thank you!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi @Mihai Mihai
Yes it can be done, before copying the attachment fetch the list of attachments of the linked issue, you will get a list. So before copying search for the file name in that list using list.contains("filename.txt"). If the attachment is found then don't copy.
Trying writing the code.
Ravi
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Thank you for your reply.
I am sure I am missing something here, because it still always adds the attachment on each comment:
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.link.IssueLink
import com.atlassian.jira.issue.comments.Comment
import com.atlassian.jira.issue.comments.CommentManager
def issue = event.issue
def attachmentManager = ComponentAccessor.getAttachmentManager()
def sortAttachment = attachmentManager.getAttachments(issue).sort { it.created }
def lastAttachment = sortAttachment.last()
def listOfCurrentIssueAttachments = attachmentManager.getAttachments(issue)
def links = ComponentAccessor.getIssueLinkManager().getOutwardLinks(issue.getId())
def subElements = links.findAll { it.issueLinkType.name.contains('Parent/Child') && it.destinationObject.getProjectObject().getKey() == 'TEST'}
def newComment = event.getComment()
def originalAuthor = newComment.getAuthorApplicationUser()
//return subElements*.destinationObject
subElements.each { it ->
if (!listOfCurrentIssueAttachments.contains(lastAttachment.filename)) {
attachmentManager.copyAttachment(lastAttachment, originalAuthor, it.getDestinationObject().key )
}
}
What I added is:
def listOfCurrentIssueAttachments = attachmentManager.getAttachments(issue)
and the change in the if statement.
Thank you.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Please help with the solution for copying attachments only if they don't already exist on the linked issue.
Thank you!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I also tried with:
def issue = event.issue
def attachmentManager = ComponentAccessor.getAttachmentManager()
def sortAttachment = attachmentManager.getAttachments(issue).sort { it.created }
def lastAttachment = sortAttachment.last()
def listOfCurrentIssueAttachments = attachmentManager.getAttachments(issue)
def links = ComponentAccessor.getIssueLinkManager().getOutwardLinks(issue.getId())
def subElements = links.findAll { it.issueLinkType.name.contains('Parent/Child') && it.destinationObject.getProjectObject().getKey() == 'TEST'}
def newComment = event.getComment()
def originalAuthor = newComment.getAuthorApplicationUser()
if (listOfCurrentIssueAttachments) {
listOfCurrentIssueAttachments.collect { it.filename }
subElements.each { it ->
if (!listOfCurrentIssueAttachments.contains(lastAttachment.filename)) {
attachmentManager.copyAttachment(lastAttachment, originalAuthor, it.getDestinationObject().key )
}
}
}
but it still copies the attachments. I assume I am not getting the list of attachment names in the right way, but I'm not sure how to do it in a different way.
Any help is appreciated, thank you!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
subElements.each { it ->
if (!listOfCurrentIssueAttachments.contains(lastAttachment.filename)
I was thinking that "lastAttachment.filename" in the above section refers to the attachments of the issues that are linked to the current one.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
No lastAttachment is the last attachment of the current issue not the linked issue. Use the same method you used for fetching the attachments but instead of the current issue pass the linked issue object.
Ravi
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I believe now I got the linked issue object, but it is still copying the attachment even if it exists:
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.link.IssueLink
import com.atlassian.jira.issue.comments.Comment
import com.atlassian.jira.issue.comments.CommentManager
def issue = event.issue
def attachmentManager = ComponentAccessor.getAttachmentManager()
def sortAttachment = attachmentManager.getAttachments(issue).sort { it.created }
def lastAttachment = sortAttachment.last()
def listOfCurrentIssueAttachments = attachmentManager.getAttachments(issue)
def emptyList = []
def links = ComponentAccessor.getIssueLinkManager().getOutwardLinks(issue.getId())
def subElements = links.findAll { it.issueLinkType.name.contains('Parent/Child') && it.destinationObject.getProjectObject().getKey() == 'TEST'}
def newComment = event.getComment()
def originalAuthor = newComment.getAuthorApplicationUser()
if (listOfCurrentIssueAttachments) {
listOfCurrentIssueAttachments.collect { it.filename }
subElements.each { it ->
def linkedIssue = it.destinationObject
def attachmentsOfLinkedIssues = attachmentManager.getAttachments(linkedIssue).sort { it.created }
def LastAttachmentOfLinkedIssues = attachmentsOfLinkedIssues.last()
if (!listOfCurrentIssueAttachments.contains(LastAttachmentOfLinkedIssues.filename)) {
attachmentManager.copyAttachment(lastAttachment, originalAuthor, it.getDestinationObject().key )
}
}
}
Thank you!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi @Mihai Mihai
Here is the complete code that will check whether the filename is already there in the child task (linked) for not.
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.link.IssueLink
import com.atlassian.jira.issue.comments.Comment
import com.atlassian.jira.issue.comments.CommentManager
import org.apache.log4j.Logger
import org.apache.log4j.Level
def log = Logger.getLogger("com.acme.listener")
log.setLevel(Level.DEBUG)
def issue = event.issue
def attachmentManager = ComponentAccessor.getAttachmentManager()
def sortAttachment = attachmentManager.getAttachments(issue).sort { it.created }
def lastAttachment = sortAttachment.last()
def links = ComponentAccessor.getIssueLinkManager().getOutwardLinks(issue.getId())
def subElements = links.findAll { it.issueLinkType.name.contains('Parent/Child') }
def newComment = event.getComment()
def originalAuthor = newComment.getAuthorApplicationUser()
//return subElements*.destinationObject
subElements.each { it ->
def subAttachmentManager = ComponentAccessor.getAttachmentManager()
def subAttachments = attachmentManager.getAttachments(it.getDestinationObject())
log.debug("Last Attachment from parent: " + lastAttachment.filename)
log.debug("Sub Attachments: " + subAttachments*.filename)
log.debug("Last Attachment already there before copy?: " + subAttachments*.filename.contains(lastAttachment.filename))
if (lastAttachment && !subAttachments*.filename.contains(lastAttachment.filename)) {
attachmentManager.copyAttachment(lastAttachment, originalAuthor, it.getDestinationObject().key )
}
}
You were quite close in your code but you were looking at the last attachment in your linked issue whereas you have to look into all the attachments. Also you have to search based on the file name using subAttachments*.filename.
I hope it is clear now.
Have a nice day.
Ravi
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.