Jira (Story>Epic) to Azure DevOps (User Story>Feature) parent-child link

Originally asked by Nicolas Brown on 17 March 2023 (original question)


Hi there,

I want to retain a parent-child link between items, however in Jira (cloud) we use Story>Epic and in ADO we use User Story>Feature. How would I need to modify my code to cater for this?

Here is what I have so far (on the ADO side):

if(firstSync){
   // Set type name from source entity, if not found set a default
   workItem.projectKey  =  "WebPlatform"
   def typeMap = [
       "Story" : "User Story",
       "Epic" : "Feature",
       "Bug" : "Bug",
       "Sub-task" : "Task",
       ]
   workItem.typeName = nodeHelper.getIssueType(typeMap[replica.type?.name],workItem.projectKey)?.name  
}

workItem.summary      = replica.summary
workItem.description  = replica.description
workItem.attachments  = attachmentHelper.mergeAttachments(workItem, replica)
workItem.comments     = commentHelper.mergeComments(workItem, replica)
workItem.labels       = replica.labels
workItem.priority     = replica.priority

def statusMap = [

       // "remote status name": "local status name"
         "To Do" : "New",
         "Refining" : "New",
         "Discovery" : "New",
         "Refined" : "New",
         "3 Amigo" : "Approved",
         "Ready for Dev" : "Approved",
         "In Progress" : "Active",
         "Done" : "Closed"
   ]
def remoteStatusName = replica.status.name
issue.setStatus(statusMap[remoteStatusName] ?: remoteStatusName)

/*
Area Path Sync
This also works for iterationPath field

Set Area Path Manually
workItem.areaPath = "Name of the project\\name of the area"

Set Area Path based on remote side drop-down list
Change "area-path-select-list" to actual custom field name
workItem.areaPath = replica.customFields."area-path-select-list"?.value?.value

Set Area Path based on remote side text field
Change "area-path" to actual custom field name
workItem.areaPath = replica.customFields."area-path".value
*/

/*
Status Synchronization

Sync status according to the mapping [remote workItem status: local workItem status]
If statuses are the same on both sides don"t include them in the mapping
def statusMapping = ["Open":"New", "To Do":"Open"]
def remoteStatusName = replica.status.name
workItem.setStatus(statusMapping[remoteStatusName] ?: remoteStatusName)
*/