[Scriptrunner] Impossible to copy attachements from an issue to another with a listener

Antoine [Klee Group] May 22, 2024

Hello,

I am using a Scriptrunner Listener in order to create several issue when an issue from a certain type is created.

I also want to copy the attachments from that trigger issue.

The code works fine when testing it in the Script Console but once I switch to building a listener (or post-function), that does not work anymore.

 

Here's a MWE:

 

import com.atlassian.jira.issue.Issue
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.AttachmentManager

def myAttachmentManager = ComponentAccessor.getAttachmentManager()

// The trigger issue
Issue triggerIssue = event.getIssue()

List listOfIssuesToBeCreated= []

for (value in ['1', '2']) {
Issue createdIssue = Issues.create("Some project key", "Some issue type") {
        setSummary("${triggerIssue .getSummary()} - request $value")
        setCustomFieldValue(12011, value)
        setLinks("relates to", triggerIssue.getKey() )
       // setting other fields
    }
    listOfIssuesToBeCreated.add(createdIssue.getKey())
}
for (issueKey in listOfIssuesToBeCreated) {
    log.info("Copying Attachements from ${triggerIssue.getKey()} to ${issueKey}")
Map resultOfAttachementCopy = myAttachmentManager.copyAttachments(triggerIssue, null, issueKey)
log.info(resultOfAttachementCopy)
}
The `resultOfAttachementCopy` Map is always empty.
I used the following documentation (AttachmentManager (Atlassian JIRA 9.4.17 API))
As I said, when I execute this script in a Script Console, forcing the triggerIssue to be like triggerIssue  = Issues.getByKey("My issue key") that works fine.
What am I missing?

3 answers

1 accepted

1 vote
Answer accepted
Antoine [Klee Group] May 23, 2024

Well…

The code is actually working fine.

Instead of creating a new issue each time to test my post-functions, I cloned it. Seems like it's more the "clone" feature of Jira that does not work rather than the script.

 

Many thanks to you @Josh_Unito @Sean Chua _Adaptavist_ 

Josh_Unito
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.
May 23, 2024

Glad to hear it worked out! 

I think they have the right idea. Once we start cloning, when does it stop? First Dolly the Sheep, now Jira issues, then one day it'll be human beings! :D 

Like Antoine [Klee Group] likes this
Sean Chua _Adaptavist_
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.
May 23, 2024

Apologies I couldn't help more effectively as I'm based out of Malaysia (+8 UTC), so our hours didn't align, nevertheless, Good to hear you've got it working! 

Please don't hesitate to create a Support Ticket with us in the future. We are always happy to help where possible!

Have a great one ahead

Like Antoine [Klee Group] likes this
0 votes
Sean Chua _Adaptavist_
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.
May 23, 2024

Hey @Antoine [Klee Group] ,

Have you tried using this sample script Copy an Issue to a Separate Project from our Adaptavist Library?

Minimal changes to match my instance and requirements. Created an issue in Project 1, and an issue was copied/cloned into Project 2. The CF (eg: Target Start / End, wasn't copied because the other project didn't have that CF assigned).


Project 1 issue:

image.png

Project 2 issue:
image.png

Hope that helps.

Sean

Antoine [Klee Group] May 23, 2024

Thanks @Sean Chua _Adaptavist_, that could do the job infact.

How to edit the issue type, summary, description as well as a multi select list custom field of the cloned issue in this script though?

I would also like to use a specific link linking this cloned issue to the trigger one (the "relates to" link type)

 

I don't find that to be explicite in the code snipped you shared.

 

Best

Sean Chua _Adaptavist_
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.
May 23, 2024

Just for understanding, do you need issues to be created simultaneously into several projects? or perhaps you are looking for like a 1 - 1 kinda thing?

Cause if it is 1-1, then actually using this Built-in Script Listener should meet your needs to clone and link directly. You just need to go over to "Create Listener" , click into "Issues" tab and there is an easy to use UI for you to set it up.

image.png

 

Then if you need further script samples, you can find our Adaptavist Library samples directly from the </>Example Scripts button.

Pasted Graphic.png

 

But if you do really do need the script changes itself, you will need to add some code after:

// Execute the clone action with the specified inputs
def updatedExecutionContext = newClonedIssue.execute(inputs, executionContext)
//The issue has been successfully cloned
assert updatedExecutionContext.newIssue

Hope that helps.

Sean

Antoine [Klee Group] May 23, 2024

Thanks for your reply.

The use case is that I have the triggerIssue that holds a multiselect customfield.

For each of the selected values (what is described in the MWE as

for (value in ['1', '2']) {

), I want to create an issue of another issue type, linked to that trigger issue, that is basically a clone, with all fields copied from the trigger issue, within the same project. I just want to adjust the summary, description, and that multi-select list to only hold a single value in the clone and not all from the trigger issue.

I tried using a post-function in the workflow instead of the listener and the attachments aren't copied either btw...

 

My original script works fine for all fields except the attachements. Since it seems to be super close to the desired behaviour, I'm wondering if I'm missing something simple. Especially considering it does work in the script console.

0 votes
Josh_Unito
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.
May 22, 2024

Listeners run in the background, triggered by specific events. They execute under a system user or a specific user you configure. But if the user doesn't have the right permissions to view or copy attachments, you're going to have problems. 

Instead of relying on the
ComponentAccessor to get the AttachmentManager, you could explicitly specify the user whose permissions you want to use for the copy operation.

Replace "username_with_permissions" with the actual username of whoever has the necessary permissions.

Alternatively, if you prefer a faster, simpler solution to avoid this kind of troubleshooting, you could try syncing Jira instances with a no-code tool like Unito's two-way integration for Jira!

Antoine [Klee Group] May 23, 2024

Hi Thanks for hte reply @Josh_Unito

 

Replace "username_with_permissions" with the actual username of whoever has the necessary permissions.

 

What do you mean by that? I don't see this whether in my script or the doc I shared.

The trigger user is currently myself (I'm the reporter of the "cloned" issues) and I have the permissions to add attachements so I don't know if that's the matter.

Josh_Unito
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.
May 23, 2024

Oops! Sorry I forgot to paste the code I had in mind. That comment was in this context:

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.AttachmentManager
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.user.ApplicationUser

ApplicationUser copyUser = ComponentAccessor.getUserManager().getUserByKey("username_with_permissions")
def myAttachmentManager = ComponentAccessor.getComponent(AttachmentManager)

Issue triggerIssue = event.getIssue()

List<String> listOfIssuesToBeCreated = []

for (value in ['1', '2']) {
Issue createdIssue = Issues.create("Some project key", "Some issue type") {
setSummary("${triggerIssue.getSummary()} - request $value")
setCustomFieldValue(12011, value)
setLinks("relates to", triggerIssue.getKey())
// setting other fields
}
listOfIssuesToBeCreated.add(createdIssue.getKey().toString())

sleep(1000) // Add a delay for indexing
}

for (String issueKey in listOfIssuesToBeCreated) {
log.info("Copying Attachments from ${triggerIssue.getKey()} to ${issueKey}")
Map result = myAttachmentManager.copyAttachments(triggerIssue, copyUser, issueKey)
log.info(result)
}

But it sounds like you already have an answer above! Sorry about the mixup. 

Like Antoine [Klee Group] likes this
Antoine [Klee Group] May 23, 2024

Thanks @Josh_Unito, well I tried specifiying the user and sleep time and still have the same behaviour. Attachements aren't copied :(

 

Also tried running those codes in post-functions, and splitting them in two : one post-function on the "trigger Issue's workflow", the other on the "issues to be created" workflow, after the "indexing issues in the database" default post-function. And it still won't work...

Seems like the issue is with the copyAttachments but I can't figure out why.

Josh_Unito
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.
May 23, 2024

Hmmm.... That sounds really frustrating. Have you tried logging the exact content of the result map returned by copyAttachments() to see if it contains any error messages? That might give some clues as to why this isn't working for you.

log.info("Copy result details: " + result.toString()) 

You could try to log the list of attachments on the triggerIssue before attempting the copy to verify they exist and are accessible.

def attachments = triggerIssue.getAttachments()
log.info("Attachments on trigger issue: " + attachments)

 

Antoine [Klee Group] May 23, 2024

Well infact that "attachments" array is empty when it's ran from the listener or postfunction.(the Map is also empty btw)

But not from the console…

 

I gave the "browse project" permission of this project to any users, so that anyone can read issues, therefore their attachements. But I dont think that Scriptrunner is actually utilizing a user in Jira Datacenter. That's the case in Cloud though.

Weird behaviour.

Suggest an answer

Log in or Sign up to answer