Hi all,
Jira processes data using Jira Wiki, while Azure DevOps utilizes HTML for data processing.
One limitation we face out-of-the-box is the inability to synchronize images between these systems.
However, with Exalate this will be possible. By utilizing the script mode, we can modify the language used by these systems to interpret and handle data.
To learn more about this solution, I added a video tutorial.
The code:
import com.atlassian.jira.component.ComponentAccessor class WikiToHtml { static String transform(String wikiFormat) { if (!wikiFormat) { return null } // access the correct services def jcl = ComponentAccessor.classLoader def app = ComponentAccessor.getApplicationProperties() def epubClass = jcl.loadClass("com.atlassian.event.api.EventPublisher") def epub = ComponentAccessor.getOSGiComponentInstanceOfType(epubClass) def fmanClass = jcl.loadClass("com.atlassian.jira.config.FeatureManager") def fman = ComponentAccessor.getOSGiComponentInstanceOfType(fmanClass) def vreqClass = jcl.loadClass("com.atlassian.jira.util.velocity.VelocityRequestContextFactory") def vreq = ComponentAccessor.getOSGiComponentInstanceOfType(vreqClass) def wrenderClass = jcl.loadClass("com.atlassian.jira.issue.fields.renderer.wiki.AtlassianWikiRenderer") def wrender = wrenderClass.newInstance(epub, app, vreq, fman) def fixImage = wikiFormat?.replaceAll(/\!(\S+)\|\S+\!/, '<!-- inline image filename=#$1# -->') fixImage = fixImage.replaceAll(/\!\^(\S+)\|\S+\!/, '<!-- inline image filename=#$1# -->') fixImage = fixImage.replaceAll(/\!\^(\S+)\!/, '<!-- inline image filename=#$1# -->') fixImage = fixImage.replaceAll(/\!(\S+)\!/, '<!-- inline image filename=#$1# -->') // wiki text can also contain files fixImage = fixImage.replaceAll(/\[(\S+)\|\^(\S+)\]/, '<!-- inline file filename=#$2# -->') fixImage = fixImage.replaceAll(/\[\^(\S+)\]/, '<!-- inline file filename=#$1# -->') return wrender.render(fixImage, null) } } replica.description = WikiToHtml.transform(issue.description) replica.labels = issue.labels replica.comments = issue.comments.collect { comment -> comment.body = WikiToHtml.transform (comment.body) comment } |
//change the projectKey! if(firstSync){ // Set type name from source entity, if not found set a default workItem.projectKey = "Mathieu" workItem.typeName = nodeHelper.getIssueType(replica.type?.name)?.name ?: "Task"; } workItem.summary = replica.summary workItem.attachments = attachmentHelper.mergeAttachments(workItem, replica) workItem.labels = replica.labels workItem.priority = replica.priority def setInlineImage(def comment){ // List of possible regex paterns def patternList = [ /<p><!-- inline image filename=#(.*?)#<\/a> --><\/p>/, /(?s)<!-- inline image filename=(.*?)-->/ , /<p><!-- inline image filename=#(.*?)#<\/a> --><\/p>/, /filename=#(.+?)# -->/ ] def pattern = null def matcher = null patternList.each{ p -> matcher = comment =~ p if(matcher.find()){ matcher = comment =~ p } } def inlineImage = "" if (matcher.find()) { def match = matcher[0] def attId = replica.attachments.find { it.filename?.equals(match[1]) }?.remoteId inlineImage = comment.replace(match[0], """<img src="/secure/attachment/${attId}/${attId}_${match[1]}" />""".toString()) }else{ return comment } inlineImage = inlineImage.replaceAll("<!-- inline image", "").replaceAll("<!-- inline image", "") return inlineImage } workItem.comments = commentHelper.mergeComments(workItem, replica, { comment -> comment.body = setInlineImage(comment.body) }) |
Thank you.
Kind regards,
Mathieu Lepoutre