I’m currently working on setting up a one-way sync from Azure DevOps (ADO) to Jira using Exalate, and I’m trying to preserve the hierarchical relationships between work items.
In ADO we have the following structure:
Epic
Issue
Tasks
My goal is to:
Sync all these work items to Jira
Maintain the parent-child relationships so that:
Epics stay linked to their Issues
Issues stay linked to their Tasks
Ensure that in Jira I can clearly see which items belong together (similar hierarchy)
I’m struggling with defining the correct triggers and mapping logic to:
Sync all levels (Epic, Issue, Task)
Preserve and recreate the relationships in Jira
Any example scripts or patterns for this use case?
Does your Jira project use the standard Epic Link field?
This code is based upon the yes on that answer;
Please try this;
Outgoing ADO:
replica.parentId = workItem.parentId
Incoming Jira C:
if (replica.parentId) {
def localParent = nodeHelper.getLocalIssueFromRemoteId(replica.parentId.toLong())
if (replica.type?.name == "Task") {
if (localParent) {
issue.parentId = localParent.id
} else if (firstSync) {
throw new com.exalate.api.exception.IssueTrackerException(
"Parent work item ${replica.parentId} is not synchronized yet. Synchronize the parent Issue first, then the Task."
)
}
} else if (replica.type?.name == "Issue") {
if (localParent) {
issue.customFields."Epic Link".value = localParent
} else if (firstSync) {
throw new com.exalate.api.exception.IssueTrackerException(
"Parent work item ${replica.parentId} is not synchronized yet. Synchronize the parent Epic first, then the Issue."
)
}
}
}
You can use this trigger
[System.TeamProject] = 'YourProjectName'
AND [System.WorkItemType] IN ('Epic', 'Issue', 'Task')
The child will not be created before the parent or it will give an error so you can just retry the sync then.