Sync issues from Jira Cloud to Github Cloud

Originally asked by Mark Lynch on 16 June 2020 (original question)


On the Github side of the connection I have the following :

issue.summary = replica.key + " " + replica.summary 
issue.description = replica.description 
//issue.reporter = nodeHelper.getUserByEmail(replica.reporter?.email) 
issue.labels = replica.labels 
issue.comments = commentHelper.mergeComments(issue, replica) 
if(replica.fixVersions) { 
  issue.labels += nodeHelper.getLabel(replica.fixVersions.name) 
} 
if(replica.status.name == "Done"){ 
  issue.status = nodeHelper.getStatus("closed")
}else{ 
  issue.status = nodeHelper.getStatus("open") 
} 
issue.labels += nodeHelper.getLabel(replica.status.name)
issue.fixVersions = replica.fixVersions.collect { v -> nodeHelper.createVersion(issue, v.name, v.description) } 
issue.milestone = issue.fixVersions.name

I have a couple of problems I’d like to solve. 1. How can I make the status of the github issue be correct. They are always imported as open. 2. I’d like the reporter to match the github user - not the exalate bot. If I uncomment the reporter line it crashes. Otherwise it looks great. Thanks

Source: Github Cloud


Comments:

Juan Grases commented on 16 June 2020

1. How can I make the status of the github issue be correct. They are always imported as open.

Are you sure the JIra issue status name is Done?

2. I’d like the reporter to match the github user - not the exalate bot. If I uncomment the reporter line it crashes

Do the email of the users match between the two systems?

Mark Lynch commented on 16 June 2020

Thanks for the quick reply Juan.

Yeah, the status is definitely Done. I apply it as a label as well and I could probably just select all the issues with this label in Github and then close them but there’s a lot so I’d really prefer if I could automate it. What are the correct status names for github? I assume “open” and “closed” or is there a boolean closed=true or something else?

The users should match on email. My only doubt here was if it had enough priveleges (I used a Personal Access Token) - I allowed all the repo permissions and read:user and user:email. I didn’t see any permission errors anyway.

Here’s what I see if I uncomment the getUserByEmail

  • Error Detail Message: Unexpected error occurred. Generate an exalate support.zip file and contact support.
  • Error Stack Trace: com.exalate.api.exception.bug.BugException: Unexpected error occurred. Generate an exalate support.zip file and contact support. at com.exalate.error.services.BugExceptionCategoryService.generateBugException(BugExceptionCategoryService.scala:20) at com.exalate.replication.services.replication.in.RequestProcessorService$$anonfun$processSyncRequest$3$$anonfun$1.applyOrElse(RequestProcessorService.scala:174) at com.exalate.replication.services.replication.in.RequestProcessorService$$anonfun$processSyncRequest$3$$anonfun$1.applyOrElse(RequestProcessorService.scala:167) at scala.concurrent.Future$$anonfun$recoverWith$1.apply(Future.scala:346) at scala.concurrent.Future$$anonfun$recoverWith$1.apply(Future.scala:345) at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:32) at scala.concurrent.impl.ExecutionContextImpl$AdaptedForkJoinTask.exec(ExecutionContextImpl.scala:121) at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260) at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339) at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979) at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107) Caused by: java.util.concurrent.ExecutionException: Boxed Error at scala.concurrent.impl.Promise$.resolver(Promise.scala:55) at scala.concurrent.impl.Promise$.scala$concurrent$impl$Promise$$resolveTry(Promise.scala:47) at scala.concurrent.impl.Promise$KeptPromise.(Promise.scala:324) at scala.concurrent.Promise$.fromTry(Promise.scala:142) at scala.concurrent.Future$.fromTry(Future.scala:483) at com.exalate.replication.services.processor.CreateIssueProcessor.executeScriptRules(CreateIssueProcessor.scala:96) at com.exalate.replication.services.processor.CreateIssueProcessor.createIssue(CreateIssueProcessor.scala:77) at com.exalate.replication.services.replication.request.CreateIssueSyncRequestState.transition(CreateIssueSyncRequestState.scala:37) at com.exalate.replication.services.replication.request.CreateIssueSyncRequestState.transition(CreateIssueSyncRequestState.scala:21) at com.exalate.replication.services.replication.in.RequestProcessorService$$anonfun$processSyncRequest$3.apply(RequestProcessorService.scala:165) at com.exalate.replication.services.replication.in.RequestProcessorService$$anonfun$processSyncRequest$3.apply(RequestProcessorService.scala:149) at scala.util.Try$.apply(Try.scala:192) at com.exalate.replication.services.replication.in.RequestProcessorService.processSyncRequest(RequestProcessorService.scala:149) at com.exalate.replication.services.replication.in.RequestProcessorService$$anonfun$processSyncRequestsForIssue$1.apply(RequestProcessorService.scala:101) at com.exalate.replication.services.replication.in.RequestProcessorService$$anonfun$processSyncRequestsForIssue$1.apply(RequestProcessorService.scala:101) at scala.collection.immutable.List.foreach(List.scala:381) at com.exalate.replication.services.replication.in.RequestProcessorService.processSyncRequestsForIssue(RequestProcessorService.scala:101) at com.exalate.replication.services.replication.in.RequestProcessorService$$anonfun$processSyncRequests$1$$anonfun$apply$4.apply(RequestProcessorService.scala:67) at com.exalate.replication.services.replication.in.RequestProcessorService$$anonfun$processSyncRequests$1$$anonfun$apply$4.apply(RequestProcessorService.scala:67) at scala.collection.immutable.List.foreach(List.scala:381) at com.exalate.replication.services.replication.in.RequestProcessorService$$anonfun$processSyncRequests$1.apply(RequestProcessorService.scala:67) at com.exalate.replication.services.replication.in.RequestProcessorService$$anonfun$processSyncRequests$1.apply(RequestProcessorService.scala:49) at scala.collection.Iterator$class.foreach(Iterator.scala:893) at scala.collection.AbstractIterator.foreach(Iterator.scala:1336) at scala.collection.IterableLike$class.foreach(IterableLike.scala:72) at scala.collection.AbstractIterable.foreach(Iterable.scala:54) at com.exalate.replication.services.replication.in.RequestProcessorService.processSyncRequests(RequestProcessorService.scala:49) at com.exalate.replication.services.replication.worker.RequestWorkerActor$$anonfun$com$exalate$replication$services$replication$worker$RequestWorkerActor$$waitingForAfterTheLastMessage$1.applyOrElse(RequestWorkerActor.scala:119) at akka.actor.Actor$class.aroundReceive(Actor.scala:484) at com.exalate.replication.services.replication.worker.RequestWorkerActor.aroundReceive(RequestWorkerActor.scala:98) at akka.actor.ActorCell.receiveMessage(ActorCell.scala:526) at akka.actor.ActorCell.invoke(ActorCell.scala:495) at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:257) at akka.dispatch.Mailbox.run(Mailbox.scala:224) at akka.dispatch.Mailbox.exec(Mailbox.scala:234) … 4 more Caused by: scala.NotImplementedError: an implementation is missing at scala.Predef$.$qmark$qmark$qmark(Predef.scala:230) at services.node.hubobjects.NodeHelper.getUserByEmail(NodeHelper.scala:86) at com.exalate.api.hubobject.jira.INodeHelper$getUserByEmail$2.call(Unknown Source) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116) at Script206.run(Script206.groovy:3) at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:345) at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:145) at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:264) at com.exalate.processor.ExalateProcessor.execute(ExalateProcessor.java:73) at com.exalate.processor.ExalateProcessor.executeProcessor(ExalateProcessor.java:46) at com.exalate.replication.services.processor.CreateIssueProcessor$$anonfun$4.apply(CreateIssueProcessor.scala:99) at scala.util.Try$.apply(Try.scala:192) at com.exalate.replication.services.processor.CreateIssueProcessor.executeScriptRules(CreateIssueProcessor.scala:97) … 33 more

Answer by Mark Lynch on 18 June 2020

The answer it seems is to not use Exalate as it’s quite limited for importing from jira→github. I guess this isn’t its most common use case, and we just wanted one-way, not sync. We took this repo, made a few modifications and had something quite good going quickly.


Comments:

Francis Martens (Exalate) commented on 18 June 2020

Good suggestion, will keep it in mind