Jira issue handling multiple attached images with same filename - ADO - Jira

When a comment is added with multiple inline attachments (images for example), these images are synced across with the same file name - i.e. image.png.

The comment on Jira side will only show a single image multiple times.

Example:

Azure DevOps:

Jira Cloud:

Both attachments are shown in the attachment list:

When looking at the incoming sync, Exalate does show both attachments with different IDs:

The incoming comment body differentiates between the two image.png files:

Question for everyone. Is it possible to update the incoming config on Jira side to rename the attachments in the format of:

attachment.id + attachment.filename

?

Hi @MikeFowler

Welcome to Exalate Community. :slight_smile:

In regards to the above mentioned scenario, would it be possible for you to share the Outgoing and Incoming script (ADO to Jira as per the situation), please?

Looking forward to it.

BR,
Jillani

Hi,

Apologies for delay in replying to this thread.

Please find below the outgoing ADO and incoming Jira scripts as requested:

ADO Outgoing

replica.key = workItem.key
replica.assignee = workItem.assignee
//replica.summary = workItem.summary
//replica.description = nodeHelper.stripHtml(workItem.description)
replica.description = workItem.description
replica.type = workItem.type
replica.status = workItem.status
//replica.labels = workItem.labels
replica.labels = workItem.labels.collect { it.label = it.label.trim().replace(" ", “_”); it }
replica.priority = workItem.priority
//replica.comments = nodeHelper.stripHtmlFromComments(workItem.comments)
replica.comments = workItem.comments
replica.attachments = workItem.attachments
replica.project = workItem.project
//replica.areaPath = workItem.areaPath
//replica.iterationPath = workItem.iterationPath
replica.customFields.CustomerName = workItem.customFields.“Customer Name”

/*
Custom Fields (CF)
How to send any field value from the source side to the destination side.
1/ Add the value to the replica object. Use the Field Name from the field or the API name:
How to Sync Work Item Fields Obtained through a REST API Call in Azure DevOps | Exalate Documentation
2/ Uncomment this next statement out and change accordingly:
replica.customFields.“CF Name” = issue.customFields.“CF Name”
*/

// Exalate API Reference Documentation: Exalate API Reference Documentation

Jira Incoming

if (firstSync) {
issue.projectKey = “XXXX”
// Set the same issue type as the source issue. If not found, set a default.
issue.typeName = nodeHelper.getIssueType(replica.type?.name, issue.projectKey)?.name ?: “XXXX”
}
//issue.summary = replica.summary
//issue.description = replica.description
//issue.comments = commentHelper.mergeComments(issue, replica)
issue.attachments = attachmentHelper.mergeAttachments(issue, replica)

//issue.labels = replica.labels
issue.labels = replica.labels.collect { it.label = it.label.replace(" ", “_”); it }
issue.description = nodeHelper.toMarkDownFromHtml(replica.description)
issue.comments = nodeHelper.toMarkDownComments(commentHelper.mergeComments(issue, replica))

if(replica.assignee != null){
def assignee = nodeHelper.getUserByEmail(replica.assignee?.email)
if(nodeHelper.isUserAssignable(issue.projectKey, assignee)){
issue.assignee = assignee
} else {
issue.assignee = null // Leave unassigned if not assignable
}
}

if (replica.status?.name == “Done” || replica.status?.name == “Rejected”){
String Detections_Status = “XXXX”
issue.comments = commentHelper.addComment(issue.comments) { comment →
comment.body = Detections_Status
comment.internal = true
}
issue.status = “To Do”
issue.assignee = null
}

/*
Custom Fields (CF)
To add incoming values to a Jira custom field, follow these steps:
1/ Find the Display Name of the CF. Note: If you have multiple custom fields with the same name,
then you can sync it using the custom field ID instead of its name. Know more about the steps here:
How To Sync Basic to Advanced Custom Fields in Jira -
2/ Check how the value is coming over from the source side, by checking the “Entity Sync Status”
of an issue in sync and then selecting the “Show Remote Replica”.
3/ Add it all together like this:
issue.customFields.“CF Name”.value = replica.customFields.“CF Name”.value

*/

/*
Status Synchronization
For Status sync, we map the source status, to the destination status with a hash map.
The syntax is as follows:
def statusMap = [
“remote status name”: “local status name”
]
Go to Entity Sync Status, put in the entity key, and it will show you where to find the remote replica
by clicking on Show remote replica.
def statusMap = [
“New” : “Open",
"Done” : ”Resolved”
]
def remoteStatusName = replica.status.name
issue.setStatus(statusMap[remoteStatusName] ?: remoteStatusName)
*/

/*
User Synchronization (Assignee/Reporter)
Set a Reporter/Assignee from the source side. If the user can’t be found, set a default user.
You can also use this approach for custom fields of the type User
def defaultUser = nodeHelper.getUserByEmail(“default@exalate.com”)
issue.reporter = nodeHelper.getUserByEmail(replica.reporter?.email) ?: defaultUser
issue.assignee = nodeHelper.getUserByEmail(replica.assignee?.email) ?: defaultUser
*/

/*
Comment Synchronization
Impersonate comments with the original author. The sync will work if the user already exists
in the local instance.
Note: Don’t forget to remove the original comments sync line if you are using this approach.
issue.comments = commentHelper.mergeComments(issue, replica) {
it.executor = nodeHelper.getUserByEmail(it.author?.email)
}
*/

// Exalate API Reference Documentation: Exalate API Reference Documentation