{"action":"created","comment":{"url":"https://api.github.com/repos/broadinstitute/cromwell/pulls/comments/46735996","id":46735996,"diff_hunk":"@@ -27,104 +51,93 @@ object SingleWorkflowRunnerActor {\n  */\n case class SingleWorkflowRunnerActor(source: WorkflowSourceFiles,\n                                      metadataOutputPath: Option[Path],\n-                                     workflowManager: ActorRef) extends Actor with CromwellActor {\n-  val log = Logging(context.system, classOf[SingleWorkflowRunnerActor])\n+                                     workflowManager: ActorRef) extends LoggingFSM[RunnerState, RunnerData] with CromwellActor {\n+\n   val tag = \"SingleWorkflowRunnerActor\"\n-  // Note that id isn't used until *after* the submitWorkflow Future is complete\n-  private var id: WorkflowId = _\n \n-  override def preStart(): Unit = {\n-    log.info(s\"$tag: launching workflow\")\n-    workflowManager ! SubmitWorkflow(source)\n+  startWith(NotStarted, RunnerData())\n+\n+  private def requestMetadata: State = {\n+    workflowManager ! WorkflowMetadata(stateData.id.get)\n+    goto (RequestingMetadata)\n   }\n \n-  def receive = {\n-    case workflowId: WorkflowId => subscribeToWorkflow(workflowId)\n-    case outputs: Map[FullyQualifiedName@unchecked, WdlValue@unchecked] => outputOutputs(outputs)\n-    case metadata: WorkflowMetadataResponse => outputMetadata(metadata) // pkg \"webservice\", but this is what WMA sends\n-    case currentState: CurrentState[_] => log.debug(s\"$tag: ignoring current state message: $currentState\")\n-    case Transition(_, _, state: WorkflowState) if state.isTerminal => handleTermination(state)\n-    case Transition(_, _, state: WorkflowState) => log.info(s\"$tag: transitioning to $state\")\n-    case Status.Failure(t) => handleFailure(t) // .pipeTo() transforms util.Failure() to Status.Failure()\n-    case m => log.warning(s\"$tag: received unexpected message: $m\")\n+  private def issueReply: State = {\n+    self ! IssueReply\n+    goto (Done)\n   }\n \n-  /**\n-   * Logs the workflow completion, then either a) if the workflow completed successfully: requests the outputs, and\n-   * later the metadata, or b) if not did not complete successfully, immediately requests the metadata.\n-   * @param state The workflow termination state.\n-   */\n-  private def handleTermination(state: WorkflowState): Unit = {\n-    log.info(s\"$tag: workflow finished with status '$state'.\")\n-\n-    // If this is a successful termination, retrieve & print out the outputs\n-    if (state == WorkflowSucceeded) {\n-      workflowManager ! WorkflowOutputs(id)\n-    } else {\n-      sendMetadataMessage()\n-    }\n+  when (NotStarted) {\n+    case Event(RunWorkflow, data) =>\n+      log.info(s\"$tag: launching workflow\")\n+      workflowManager ! SubmitWorkflow(source)\n+      goto (RunningWorkflow) using data.copy(replyTo = Option(sender()))\n   }\n \n-  /**\n-   * Logs the errors and shuts down.\n-   * @param t The error.\n-   */\n-  private def handleFailure(t: Throwable): Unit = {\n-    log.error(t, s\"$tag: ${t.getMessage}\")\n-    terminate()\n+  when (RunningWorkflow) {\n+    case Event(id: WorkflowId, data) =>\n+      log.info(s\"$tag: workflow ID UUID($id)\")\n+      workflowManager ! SubscribeToWorkflow(id)\n+      stay using data.copy(id = Option(id))\n+    case Event(Transition(_, _, WorkflowSucceeded), data) =>\n+      workflowManager ! WorkflowOutputs(data.id.get)\n+      goto(RequestingOutputs) using data.copy(terminalState = Option(WorkflowSucceeded))\n+    case Event(Transition(_, _, state: WorkflowState), data) if state.isTerminal =>\n+      // A terminal state that is not `WorkflowSucceeded` is a failure.\n+      val updatedData = data.copy(terminalState = Option(state)).addFailure(s\"Workflow ${data.id.get} transitioned to state $state\")\n+      // If there's an output path specified then request metadata, otherwise issue a reply to the original sender.\n+      val nextState = if (metadataOutputPath.isDefined) requestMetadata else issueReply\n+      nextState using updatedData\n+    case Event(Transition(_, _, state), _) =>\n+      log.info(s\"$tag: transitioning to $state\")\n+      stay()\n   }\n \n-  /**\n-   * Does a few things by side effect:\n-   *     - Sets 'id' to the submitted workflow id\n-   *     - Logs the workflow id\n-   *     - Subscribes to the new workflow's transition events\n-   */\n-  private def subscribeToWorkflow(workflowId: WorkflowId): Unit = {\n-    id = workflowId\n-    log.info(s\"SingleWorkflowRunnerActor: workflow ID UUID($id)\")\n-    workflowManager ! SubscribeToWorkflow(id)\n+  when (RequestingOutputs) {\n+    // Can't use the WorkflowOutputs type alias here since the @unchecked needs to be added to suppress\n+    // compile time warnings.\n+    case Event(outputs: Map[FullyQualifiedName@unchecked, WdlValue@unchecked], data) =>\n+      // Outputs go to stdout\n+      import cromwell.binding.values.WdlValueJsonFormatter._\n+      println(outputs.toJson.prettyPrint)\n+      if (metadataOutputPath.isDefined) requestMetadata else issueReply\n   }\n+  \n+  when (RequestingMetadata) {\n+    case Event(response: WorkflowMetadataResponse, data) =>\n+      val updatedData = outputMetadata(response) match {\n+        case Success(_) => data\n+        case Failure(e) => data.addFailure(e)\n+      }\n+      issueReply using updatedData\n+  }\n+\n+  when (Done) {\n+    case Event(IssueReply, data) =>\n+      data.terminalState foreach { state => log.info(s\"$tag workflow finished with status '$state'.\") }\n+      data.failures foreach { e => log.error(e, e.getMessage) }\n \n-  /**\n-   * Outputs the outputs to stdout, and then requests the metadata.\n-   */\n-  private def outputOutputs(outputs: binding.WorkflowOutputs): Unit = {\n-    import cromwell.binding.values.WdlValueJsonFormatter._\n-    println(outputs.toJson.prettyPrint)\n-    sendMetadataMessage()\n+      val message = data.terminalState collect { case WorkflowSucceeded => () } getOrElse Status.Failure(data.failures.head)","path":"src/main/scala/cromwell/engine/workflow/SingleWorkflowRunnerActor.scala","position":175,"original_position":175,"commit_id":"e8db1dcd266a651bb24061e6216a7bacef2deb1d","original_commit_id":"e8db1dcd266a651bb24061e6216a7bacef2deb1d","user":{"login":"Horneth","id":2978948,"avatar_url":"https://avatars.githubusercontent.com/u/2978948?v=3","gravatar_id":"","url":"https://api.github.com/users/Horneth","html_url":"https://github.com/Horneth","followers_url":"https://api.github.com/users/Horneth/followers","following_url":"https://api.github.com/users/Horneth/following{/other_user}","gists_url":"https://api.github.com/users/Horneth/gists{/gist_id}","starred_url":"https://api.github.com/users/Horneth/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Horneth/subscriptions","organizations_url":"https://api.github.com/users/Horneth/orgs","repos_url":"https://api.github.com/users/Horneth/repos","events_url":"https://api.github.com/users/Horneth/events{/privacy}","received_events_url":"https://api.github.com/users/Horneth/received_events","type":"User","site_admin":false},"body":"Is it possible to have more than one failure in `data.failures` ? If yes do we want to send them all back  somehow ?","created_at":"2015-12-04T21:43:44Z","updated_at":"2015-12-04T21:43:44Z","html_url":"https://github.com/broadinstitute/cromwell/pull/311#discussion_r46735996","pull_request_url":"https://api.github.com/repos/broadinstitute/cromwell/pulls/311","_links":{"self":{"href":"https://api.github.com/repos/broadinstitute/cromwell/pulls/comments/46735996"},"html":{"href":"https://github.com/broadinstitute/cromwell/pull/311#discussion_r46735996"},"pull_request":{"href":"https://api.github.com/repos/broadinstitute/cromwell/pulls/311"}}},"pull_request":{"url":"https://api.github.com/repos/broadinstitute/cromwell/pulls/311","id":52608802,"html_url":"https://github.com/broadinstitute/cromwell/pull/311","diff_url":"https://github.com/broadinstitute/cromwell/pull/311.diff","patch_url":"https://github.com/broadinstitute/cromwell/pull/311.patch","issue_url":"https://api.github.com/repos/broadinstitute/cromwell/issues/311","number":311,"state":"open","locked":false,"title":"Stabilize tests","user":{"login":"mcovarr","id":10790523,"avatar_url":"https://avatars.githubusercontent.com/u/10790523?v=3","gravatar_id":"","url":"https://api.github.com/users/mcovarr","html_url":"https://github.com/mcovarr","followers_url":"https://api.github.com/users/mcovarr/followers","following_url":"https://api.github.com/users/mcovarr/following{/other_user}","gists_url":"https://api.github.com/users/mcovarr/gists{/gist_id}","starred_url":"https://api.github.com/users/mcovarr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mcovarr/subscriptions","organizations_url":"https://api.github.com/users/mcovarr/orgs","repos_url":"https://api.github.com/users/mcovarr/repos","events_url":"https://api.github.com/users/mcovarr/events{/privacy}","received_events_url":"https://api.github.com/users/mcovarr/received_events","type":"User","site_admin":false},"body":"Lots of changes to `SingleWorkflowRunnerActor`:\r\n\r\n* Clients communicate with SWRA via an ask, giving callers like `Main` a `Future` whose success status can be used to generate an exit code.\r\n* SWRA no longer manages shutting down the actor system, that becomes the responsibility of the caller.  This allows tests that want to see certain error messages to shut down the system only after the error messages are seen by an event filter.  The previous structure allowed for a race condition where messages that filters wanted to see were produced, but the actor system was torn down before the messages were delivered to the filters.\r\n* SWRA is now an FSM.\r\n\r\nAlso increased the default patience in `CromwellTestkitSpec` for `InputLocalizationWorkflowSpec` and friends.\r\n\r\nDoes *not* include any changes to address MySQL connection issues sporadically seen in SlickDataAccessSpec; per discussion with Jeff I'll ticket that separately.","created_at":"2015-12-03T23:25:34Z","updated_at":"2015-12-04T21:43:44Z","closed_at":null,"merged_at":null,"merge_commit_sha":"708e006f81beb1d15f733f9c9f372c47fb8943c5","assignee":{"login":"Horneth","id":2978948,"avatar_url":"https://avatars.githubusercontent.com/u/2978948?v=3","gravatar_id":"","url":"https://api.github.com/users/Horneth","html_url":"https://github.com/Horneth","followers_url":"https://api.github.com/users/Horneth/followers","following_url":"https://api.github.com/users/Horneth/following{/other_user}","gists_url":"https://api.github.com/users/Horneth/gists{/gist_id}","starred_url":"https://api.github.com/users/Horneth/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Horneth/subscriptions","organizations_url":"https://api.github.com/users/Horneth/orgs","repos_url":"https://api.github.com/users/Horneth/repos","events_url":"https://api.github.com/users/Horneth/events{/privacy}","received_events_url":"https://api.github.com/users/Horneth/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/broadinstitute/cromwell/pulls/311/commits","review_comments_url":"https://api.github.com/repos/broadinstitute/cromwell/pulls/311/comments","review_comment_url":"https://api.github.com/repos/broadinstitute/cromwell/pulls/comments{/number}","comments_url":"https://api.github.com/repos/broadinstitute/cromwell/issues/311/comments","statuses_url":"https://api.github.com/repos/broadinstitute/cromwell/statuses/e8db1dcd266a651bb24061e6216a7bacef2deb1d","head":{"label":"broadinstitute:mlc_testy_tests","ref":"mlc_testy_tests","sha":"e8db1dcd266a651bb24061e6216a7bacef2deb1d","user":{"login":"broadinstitute","id":393552,"avatar_url":"https://avatars.githubusercontent.com/u/393552?v=3","gravatar_id":"","url":"https://api.github.com/users/broadinstitute","html_url":"https://github.com/broadinstitute","followers_url":"https://api.github.com/users/broadinstitute/followers","following_url":"https://api.github.com/users/broadinstitute/following{/other_user}","gists_url":"https://api.github.com/users/broadinstitute/gists{/gist_id}","starred_url":"https://api.github.com/users/broadinstitute/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/broadinstitute/subscriptions","organizations_url":"https://api.github.com/users/broadinstitute/orgs","repos_url":"https://api.github.com/users/broadinstitute/repos","events_url":"https://api.github.com/users/broadinstitute/events{/privacy}","received_events_url":"https://api.github.com/users/broadinstitute/received_events","type":"Organization","site_admin":false},"repo":{"id":34136406,"name":"cromwell","full_name":"broadinstitute/cromwell","owner":{"login":"broadinstitute","id":393552,"avatar_url":"https://avatars.githubusercontent.com/u/393552?v=3","gravatar_id":"","url":"https://api.github.com/users/broadinstitute","html_url":"https://github.com/broadinstitute","followers_url":"https://api.github.com/users/broadinstitute/followers","following_url":"https://api.github.com/users/broadinstitute/following{/other_user}","gists_url":"https://api.github.com/users/broadinstitute/gists{/gist_id}","starred_url":"https://api.github.com/users/broadinstitute/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/broadinstitute/subscriptions","organizations_url":"https://api.github.com/users/broadinstitute/orgs","repos_url":"https://api.github.com/users/broadinstitute/repos","events_url":"https://api.github.com/users/broadinstitute/events{/privacy}","received_events_url":"https://api.github.com/users/broadinstitute/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/broadinstitute/cromwell","description":"Workflow Execution Engine using WDL","fork":false,"url":"https://api.github.com/repos/broadinstitute/cromwell","forks_url":"https://api.github.com/repos/broadinstitute/cromwell/forks","keys_url":"https://api.github.com/repos/broadinstitute/cromwell/keys{/key_id}","collaborators_url":"https://api.github.com/repos/broadinstitute/cromwell/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/broadinstitute/cromwell/teams","hooks_url":"https://api.github.com/repos/broadinstitute/cromwell/hooks","issue_events_url":"https://api.github.com/repos/broadinstitute/cromwell/issues/events{/number}","events_url":"https://api.github.com/repos/broadinstitute/cromwell/events","assignees_url":"https://api.github.com/repos/broadinstitute/cromwell/assignees{/user}","branches_url":"https://api.github.com/repos/broadinstitute/cromwell/branches{/branch}","tags_url":"https://api.github.com/repos/broadinstitute/cromwell/tags","blobs_url":"https://api.github.com/repos/broadinstitute/cromwell/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/broadinstitute/cromwell/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/broadinstitute/cromwell/git/refs{/sha}","trees_url":"https://api.github.com/repos/broadinstitute/cromwell/git/trees{/sha}","statuses_url":"https://api.github.com/repos/broadinstitute/cromwell/statuses/{sha}","languages_url":"https://api.github.com/repos/broadinstitute/cromwell/languages","stargazers_url":"https://api.github.com/repos/broadinstitute/cromwell/stargazers","contributors_url":"https://api.github.com/repos/broadinstitute/cromwell/contributors","subscribers_url":"https://api.github.com/repos/broadinstitute/cromwell/subscribers","subscription_url":"https://api.github.com/repos/broadinstitute/cromwell/subscription","commits_url":"https://api.github.com/repos/broadinstitute/cromwell/commits{/sha}","git_commits_url":"https://api.github.com/repos/broadinstitute/cromwell/git/commits{/sha}","comments_url":"https://api.github.com/repos/broadinstitute/cromwell/comments{/number}","issue_comment_url":"https://api.github.com/repos/broadinstitute/cromwell/issues/comments{/number}","contents_url":"https://api.github.com/repos/broadinstitute/cromwell/contents/{+path}","compare_url":"https://api.github.com/repos/broadinstitute/cromwell/compare/{base}...{head}","merges_url":"https://api.github.com/repos/broadinstitute/cromwell/merges","archive_url":"https://api.github.com/repos/broadinstitute/cromwell/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/broadinstitute/cromwell/downloads","issues_url":"https://api.github.com/repos/broadinstitute/cromwell/issues{/number}","pulls_url":"https://api.github.com/repos/broadinstitute/cromwell/pulls{/number}","milestones_url":"https://api.github.com/repos/broadinstitute/cromwell/milestones{/number}","notifications_url":"https://api.github.com/repos/broadinstitute/cromwell/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/broadinstitute/cromwell/labels{/name}","releases_url":"https://api.github.com/repos/broadinstitute/cromwell/releases{/id}","created_at":"2015-04-17T19:39:36Z","updated_at":"2015-11-13T21:43:52Z","pushed_at":"2015-12-04T21:23:42Z","git_url":"git://github.com/broadinstitute/cromwell.git","ssh_url":"git@github.com:broadinstitute/cromwell.git","clone_url":"https://github.com/broadinstitute/cromwell.git","svn_url":"https://github.com/broadinstitute/cromwell","homepage":"","size":4174,"stargazers_count":10,"watchers_count":10,"language":"Scala","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":1,"mirror_url":null,"open_issues_count":7,"forks":1,"open_issues":7,"watchers":10,"default_branch":"develop"}},"base":{"label":"broadinstitute:develop","ref":"develop","sha":"01a6088236e8ea4b8894dc77ae743c004ec9595f","user":{"login":"broadinstitute","id":393552,"avatar_url":"https://avatars.githubusercontent.com/u/393552?v=3","gravatar_id":"","url":"https://api.github.com/users/broadinstitute","html_url":"https://github.com/broadinstitute","followers_url":"https://api.github.com/users/broadinstitute/followers","following_url":"https://api.github.com/users/broadinstitute/following{/other_user}","gists_url":"https://api.github.com/users/broadinstitute/gists{/gist_id}","starred_url":"https://api.github.com/users/broadinstitute/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/broadinstitute/subscriptions","organizations_url":"https://api.github.com/users/broadinstitute/orgs","repos_url":"https://api.github.com/users/broadinstitute/repos","events_url":"https://api.github.com/users/broadinstitute/events{/privacy}","received_events_url":"https://api.github.com/users/broadinstitute/received_events","type":"Organization","site_admin":false},"repo":{"id":34136406,"name":"cromwell","full_name":"broadinstitute/cromwell","owner":{"login":"broadinstitute","id":393552,"avatar_url":"https://avatars.githubusercontent.com/u/393552?v=3","gravatar_id":"","url":"https://api.github.com/users/broadinstitute","html_url":"https://github.com/broadinstitute","followers_url":"https://api.github.com/users/broadinstitute/followers","following_url":"https://api.github.com/users/broadinstitute/following{/other_user}","gists_url":"https://api.github.com/users/broadinstitute/gists{/gist_id}","starred_url":"https://api.github.com/users/broadinstitute/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/broadinstitute/subscriptions","organizations_url":"https://api.github.com/users/broadinstitute/orgs","repos_url":"https://api.github.com/users/broadinstitute/repos","events_url":"https://api.github.com/users/broadinstitute/events{/privacy}","received_events_url":"https://api.github.com/users/broadinstitute/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/broadinstitute/cromwell","description":"Workflow Execution Engine using WDL","fork":false,"url":"https://api.github.com/repos/broadinstitute/cromwell","forks_url":"https://api.github.com/repos/broadinstitute/cromwell/forks","keys_url":"https://api.github.com/repos/broadinstitute/cromwell/keys{/key_id}","collaborators_url":"https://api.github.com/repos/broadinstitute/cromwell/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/broadinstitute/cromwell/teams","hooks_url":"https://api.github.com/repos/broadinstitute/cromwell/hooks","issue_events_url":"https://api.github.com/repos/broadinstitute/cromwell/issues/events{/number}","events_url":"https://api.github.com/repos/broadinstitute/cromwell/events","assignees_url":"https://api.github.com/repos/broadinstitute/cromwell/assignees{/user}","branches_url":"https://api.github.com/repos/broadinstitute/cromwell/branches{/branch}","tags_url":"https://api.github.com/repos/broadinstitute/cromwell/tags","blobs_url":"https://api.github.com/repos/broadinstitute/cromwell/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/broadinstitute/cromwell/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/broadinstitute/cromwell/git/refs{/sha}","trees_url":"https://api.github.com/repos/broadinstitute/cromwell/git/trees{/sha}","statuses_url":"https://api.github.com/repos/broadinstitute/cromwell/statuses/{sha}","languages_url":"https://api.github.com/repos/broadinstitute/cromwell/languages","stargazers_url":"https://api.github.com/repos/broadinstitute/cromwell/stargazers","contributors_url":"https://api.github.com/repos/broadinstitute/cromwell/contributors","subscribers_url":"https://api.github.com/repos/broadinstitute/cromwell/subscribers","subscription_url":"https://api.github.com/repos/broadinstitute/cromwell/subscription","commits_url":"https://api.github.com/repos/broadinstitute/cromwell/commits{/sha}","git_commits_url":"https://api.github.com/repos/broadinstitute/cromwell/git/commits{/sha}","comments_url":"https://api.github.com/repos/broadinstitute/cromwell/comments{/number}","issue_comment_url":"https://api.github.com/repos/broadinstitute/cromwell/issues/comments{/number}","contents_url":"https://api.github.com/repos/broadinstitute/cromwell/contents/{+path}","compare_url":"https://api.github.com/repos/broadinstitute/cromwell/compare/{base}...{head}","merges_url":"https://api.github.com/repos/broadinstitute/cromwell/merges","archive_url":"https://api.github.com/repos/broadinstitute/cromwell/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/broadinstitute/cromwell/downloads","issues_url":"https://api.github.com/repos/broadinstitute/cromwell/issues{/number}","pulls_url":"https://api.github.com/repos/broadinstitute/cromwell/pulls{/number}","milestones_url":"https://api.github.com/repos/broadinstitute/cromwell/milestones{/number}","notifications_url":"https://api.github.com/repos/broadinstitute/cromwell/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/broadinstitute/cromwell/labels{/name}","releases_url":"https://api.github.com/repos/broadinstitute/cromwell/releases{/id}","created_at":"2015-04-17T19:39:36Z","updated_at":"2015-11-13T21:43:52Z","pushed_at":"2015-12-04T21:23:42Z","git_url":"git://github.com/broadinstitute/cromwell.git","ssh_url":"git@github.com:broadinstitute/cromwell.git","clone_url":"https://github.com/broadinstitute/cromwell.git","svn_url":"https://github.com/broadinstitute/cromwell","homepage":"","size":4174,"stargazers_count":10,"watchers_count":10,"language":"Scala","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":1,"mirror_url":null,"open_issues_count":7,"forks":1,"open_issues":7,"watchers":10,"default_branch":"develop"}},"_links":{"self":{"href":"https://api.github.com/repos/broadinstitute/cromwell/pulls/311"},"html":{"href":"https://github.com/broadinstitute/cromwell/pull/311"},"issue":{"href":"https://api.github.com/repos/broadinstitute/cromwell/issues/311"},"comments":{"href":"https://api.github.com/repos/broadinstitute/cromwell/issues/311/comments"},"review_comments":{"href":"https://api.github.com/repos/broadinstitute/cromwell/pulls/311/comments"},"review_comment":{"href":"https://api.github.com/repos/broadinstitute/cromwell/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/broadinstitute/cromwell/pulls/311/commits"},"statuses":{"href":"https://api.github.com/repos/broadinstitute/cromwell/statuses/e8db1dcd266a651bb24061e6216a7bacef2deb1d"}}}}