{"action":"created","comment":{"url":"https://api.github.com/repos/VertebrateResequencing/wr/pulls/comments/232419481","pull_request_review_id":173623807,"id":232419481,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIzMjQxOTQ4MQ==","diff_hunk":"@@ -307,20 +460,258 @@ func TestJobqueueSignal(t *testing.T) {\n \t\t\t\t// all signals handled the same way, so no need for further\n \t\t\t\t// tests\n \t\t\t})\n+\t\t})\n+\n+\t\tConvey(\"Running jobs are recovered after a hard server crash\", func() {\n+\t\t\tcmd := \"sleep 10\"\n+\t\t\tcmd2 := \"perl -e 'for (1..10) { sleep(1) }'\" // we want to kill this part way, but `sleep` processes don't seem to die straight away when killed\n+\t\t\tvar jobs []*Job\n+\t\t\tjobs = append(jobs, &Job{Cmd: cmd, Cwd: \"/tmp\", ReqGroup: \"fake_group\", Requirements: &jqs.Requirements{RAM: 1, Time: 10 * time.Second, Cores: 0}, Retries: uint8(0), RepGroup: \"recover\"})\n+\t\t\tjobs = append(jobs, &Job{Cmd: cmd2, Cwd: \"/tmp\", ReqGroup: \"fake_group\", Requirements: &jqs.Requirements{RAM: 1, Time: 10 * time.Second, Cores: 0}, Retries: uint8(0), RepGroup: \"buried\"})\n+\t\t\tinserts, already, err := jq.Add(jobs, envVars, true)\n+\t\t\tSo(err, ShouldBeNil)\n+\t\t\tSo(inserts, ShouldEqual, 2)\n+\t\t\tSo(already, ShouldEqual, 0)\n+\n+\t\t\tjob, err := jq.Reserve(50 * time.Millisecond)\n+\t\t\tSo(err, ShouldBeNil)\n+\t\t\tSo(job.Cmd, ShouldEqual, cmd)\n+\t\t\tSo(job.State, ShouldEqual, JobStateReserved)\n \n-\t\t\tRecSecRound = 1800 // revert back to normal\n+\t\t\tjob2, err := jq.Reserve(50 * time.Millisecond)\n+\t\t\tSo(err, ShouldBeNil)\n+\t\t\tSo(job2.Cmd, ShouldEqual, cmd2)\n+\t\t\tSo(job2.State, ShouldEqual, JobStateReserved)\n+\n+\t\t\tserverCmdCh := make(chan *exec.Cmd)\n+\t\t\tgo func() {\n+\t\t\t\t<-time.After(2 * time.Second)\n+\t\t\t\tgotJob, errg := jq.GetByEssence(&JobEssence{Cmd: cmd2}, false, false)\n+\t\t\t\tsyscall.Kill(serverPid, syscall.SIGKILL)\n+\t\t\t\tif errg == nil && gotJob != nil {\n+\t\t\t\t\t<-time.After(2 * time.Second)\n+\t\t\t\t\tsyscall.Kill(gotJob.Pid, syscall.SIGKILL)\n+\t\t\t\t} else {\n+\t\t\t\t\tlog.Printf(\"failed to get job: %s\\n\", errg)\n+\t\t\t\t}\n+\t\t\t\t<-time.After(4 * time.Second)\n+\t\t\t\tnewJQ, _, newServerCmd, errf := startServer(serverExe, true, false, config, addr)\n+\t\t\t\tif errf != nil {\n+\t\t\t\t\tlog.Printf(\"failed to start new server: %s\\n\", errf)\n+\t\t\t\t} else if newJQ != nil {\n+\t\t\t\t\tnewJQ.Disconnect()\n+\t\t\t\t}\n+\t\t\t\tserverCmdCh <- newServerCmd\n+\t\t\t}()\n+\n+\t\t\tj1worked := make(chan bool)\n+\t\t\tgiveUp1 := time.After(16 * time.Second)\n+\t\t\tgo func() {\n+\t\t\t\terrch := make(chan error)\n+\t\t\t\tgo func() {\n+\t\t\t\t\terrch <- jq.Execute(job, config.RunnerExecShell)\n+\t\t\t\t}()\n+\t\t\t\tselect {\n+\t\t\t\tcase erre := <-errch:\n+\t\t\t\t\tif erre != nil {\n+\t\t\t\t\t\t// we expect that we lost the connection when we killed\n+\t\t\t\t\t\t// the server, then reconnected to the new server and\n+\t\t\t\t\t\t// therefore got ErrStopReserving, but otherwise\n+\t\t\t\t\t\t// everything was fine\n+\t\t\t\t\t\tjqerr, ok := erre.(Error)\n+\t\t\t\t\t\tif !ok || jqerr.Err != ErrStopReserving {\n+\t\t\t\t\t\t\tj1worked <- false\n+\t\t\t\t\t\t\treturn\n+\t\t\t\t\t\t}\n+\t\t\t\t\t} // though sometimes we manage to not lose the connection\n+\t\t\t\t\tj1worked <- true\n+\t\t\t\t\treturn\n+\t\t\t\tcase <-giveUp1:\n+\t\t\t\t\tj1worked <- false\n+\t\t\t\t}\n+\t\t\t}()\n+\n+\t\t\tj2worked := make(chan bool)\n+\t\t\tgiveUp2 := time.After(16 * time.Second)\n+\t\t\tgo func() {\n+\t\t\t\terrch := make(chan error)\n+\t\t\t\tgo func() {\n+\t\t\t\t\terrch <- jq.Execute(job2, config.RunnerExecShell)\n+\t\t\t\t}()\n+\t\t\t\tselect {\n+\t\t\t\tcase erre := <-errch:\n+\t\t\t\t\tif erre != nil && strings.Contains(erre.Error(), \"exited with code -1\") {\n+\t\t\t\t\t\tj2worked <- true\n+\t\t\t\t\t\treturn\n+\t\t\t\t\t}\n+\t\t\t\t\tj2worked <- false\n+\t\t\t\t\treturn\n+\t\t\t\tcase <-giveUp2:\n+\t\t\t\t\tj2worked <- false\n+\t\t\t\t}\n+\t\t\t}()\n+\n+\t\t\tserverCmd = <-serverCmdCh\n+\t\t\tserverPid = serverCmd.Process.Pid\n+\t\t\tSo(<-j1worked, ShouldBeTrue)\n+\t\t\tSo(<-j2worked, ShouldBeTrue)\n+\n+\t\t\tjq2, err := Connect(addr, config.ManagerCAFile, config.ManagerCertDomain, token, clientConnectTime)\n+\t\t\tSo(err, ShouldBeNil)\n+\t\t\tdefer jq2.Disconnect()\n+\t\t\tjob, err = jq2.GetByEssence(&JobEssence{Cmd: cmd}, false, false)\n+\t\t\tSo(err, ShouldBeNil)\n+\t\t\tSo(job, ShouldNotBeNil)\n+\t\t\tSo(job.Cmd, ShouldEqual, cmd)\n+\t\t\tSo(job.State, ShouldEqual, JobStateComplete)\n+\n+\t\t\tjob2, err = jq2.GetByEssence(&JobEssence{Cmd: cmd2}, false, false)\n+\t\t\tSo(err, ShouldBeNil)\n+\t\t\tSo(job2, ShouldNotBeNil)\n+\t\t\tSo(job2.Cmd, ShouldEqual, cmd2)\n+\t\t\tSo(job2.State, ShouldEqual, JobStateBuried)\n \t\t})\n \n \t\tReset(func() {\n-\t\t\tsyscall.Kill(child.Pid, syscall.SIGTERM)\n+\t\t\tsyscall.Kill(serverPid, syscall.SIGTERM)\n \t\t})\n \t})\n \n-\t<-time.After(5 * time.Second) // wait for the \"fork\" to really not be listening on the ports any more\n+\t// the next tests will have runners enabled so that we can see what happens\n+\t// when we force kill both the server and a runner\n+\tConvey(\"Once a jobqueue server using local scheduler is up as a daemon\", t, func() {\n+\t\tjq, token, serverCmd, errf := startServer(serverExe, false, true, config, addr)\n+\t\tserverPid := serverCmd.Process.Pid\n+\t\tSo(errf, ShouldBeNil)\n+\t\tdefer func() {\n+\t\t\tsyscall.Kill(serverPid, syscall.SIGTERM)\n+\t\t\tserverCmd.Wait()\n+\t\t}()\n+\t\tdefer jq.Disconnect()\n+\n+\t\tSo(jq.ServerInfo.PID, ShouldEqual, serverPid)\n+\n+\t\tConvey(\"Killed runners after a hard server crash come up lost, and new runners don't overcommit resources due to existing runners\", func() {\n+\t\t\tcmd := \"sleep 10\"\n+\t\t\tcmd2 := \"perl -e 'for (1..10) { sleep(1) }'\"\n+\t\t\tvar jobs []*Job\n+\t\t\tjobs = append(jobs, &Job{Cmd: cmd, Cwd: \"/tmp\", ReqGroup: \"fake_group\", Requirements: &jqs.Requirements{RAM: 1, Time: 10 * time.Second, Cores: float64(runtime.NumCPU())}, Retries: uint8(0), RepGroup: \"recover\"})\n+\t\t\tjobs = append(jobs, &Job{Cmd: cmd2, Cwd: \"/tmp\", ReqGroup: \"fake_group\", Requirements: &jqs.Requirements{RAM: 1, Time: 10 * time.Second, Cores: 0}, Retries: uint8(0), RepGroup: \"lost\"})\n+\t\t\tinserts, already, erra := jq.Add(jobs, envVars, true)\n+\t\t\tSo(erra, ShouldBeNil)\n+\t\t\tSo(inserts, ShouldEqual, 2)\n+\t\t\tSo(already, ShouldEqual, 0)\n+\n+\t\t\t// get pids of the runners the server spawned\n+\t\t\t<-time.After(2 * time.Second)\n+\t\t\tprocesses, err := process.Processes()\n+\t\t\tSo(err, ShouldBeNil)\n+\t\t\trunnerPids := make(map[int]bool)\n+\t\t\tvar runnerPidToKill int\n+\t\t\tfor _, p := range processes {\n+\t\t\t\tthisCmd, errc := p.Cmdline()\n+\t\t\t\tif errc != nil {\n+\t\t\t\t\tcontinue\n+\t\t\t\t}\n+\t\t\t\tif strings.Contains(thisCmd, \"sleep\") {\n+\t\t\t\t\tparent, err := p.Parent()\n+\t\t\t\t\tif err != nil {\n+\t\t\t\t\t\tcontinue\n+\t\t\t\t\t}\n+\t\t\t\t\tparentCmd, err := parent.Cmdline()\n+\t\t\t\t\tif err != nil {\n+\t\t\t\t\t\tcontinue\n+\t\t\t\t\t}\n+\t\t\t\t\tif strings.Contains(parentCmd, serverExe) {\n+\t\t\t\t\t\tpid := int(parent.Pid)\n+\n+\t\t\t\t\t\tif strings.Contains(thisCmd, \"perl\") {\n+\t\t\t\t\t\t\trunnerPidToKill = pid\n+\t\t\t\t\t\t}\n+\n+\t\t\t\t\t\trunnerPids[pid] = true\n+\t\t\t\t\t\tif len(runnerPids) == 2 {\n+\t\t\t\t\t\t\tbreak\n+\t\t\t\t\t\t}\n+\t\t\t\t\t}\n+\t\t\t\t}\n+\t\t\t}\n+\t\t\tSo(len(runnerPids), ShouldEqual, 2)\n+\t\t\tSo(runnerPidToKill, ShouldNotEqual, 0)\n+\n+\t\t\t// kill server and then second runner, then wait before starting new\n+\t\t\t// server\n+\t\t\tsyscall.Kill(serverPid, syscall.SIGKILL)\n+\t\t\t<-time.After(2 * time.Second)\n+\t\t\tsyscall.Kill(runnerPidToKill, syscall.SIGKILL)\n+\t\t\t<-time.After(4 * time.Second)\n+\t\t\tvar errf error\n+\t\t\tjq, _, serverCmd, errf = startServer(serverExe, true, true, config, addr)\n+\t\t\tserverPid = serverCmd.Process.Pid\n+\t\t\tSo(errf, ShouldBeNil)\n+\t\t\tSo(jq, ShouldNotBeNil)\n+\t\t\tnewServerStartedAt := time.Now()\n+\n+\t\t\t// add a new job which should wait until job 1 completes, since it\n+\t\t\t// uses all CPUs\n+\t\t\tcmd3 := \"echo 1\"\n+\t\t\tjobs = []*Job{{Cmd: cmd3, Cwd: \"/tmp\", ReqGroup: \"fake_group\", Requirements: &jqs.Requirements{RAM: 1, Time: 10 * time.Second, Cores: 1}, Retries: uint8(0), RepGroup: \"wait\"}}\n+\t\t\tinserts, already, err = jq.Add(jobs, envVars, true)\n+\t\t\tjq.Disconnect()\n+\t\t\tSo(err, ShouldBeNil)\n+\t\t\tSo(inserts, ShouldEqual, 1)\n+\t\t\tSo(already, ShouldEqual, 0)\n+\n+\t\t\t// wait for runner pids to no longer exist\n+\t\t\twaitUntilPidsAreGone(runnerPids, 16)\n+\t\t\tSo(len(runnerPids), ShouldEqual, 0)\n+\n+\t\t\tjq2, err := Connect(addr, config.ManagerCAFile, config.ManagerCertDomain, token, clientConnectTime)\n+\t\t\tSo(err, ShouldBeNil)\n+\t\t\tdefer jq2.Disconnect()\n+\t\t\tjob, err := jq2.GetByEssence(&JobEssence{Cmd: cmd}, false, false)\n+\t\t\tSo(err, ShouldBeNil)\n+\t\t\tSo(job, ShouldNotBeNil)\n+\t\t\tSo(job.Cmd, ShouldEqual, cmd)\n+\t\t\tSo(job.State, ShouldEqual, JobStateComplete)\n+\t\t\tSo(job.EndTime, ShouldHappenAfter, newServerStartedAt)\n+\n+\t\t\tjob2, err := jq2.GetByEssence(&JobEssence{Cmd: cmd2}, false, false)\n+\t\t\tSo(err, ShouldBeNil)\n+\t\t\tSo(job2, ShouldNotBeNil)\n+\t\t\tSo(job2.Cmd, ShouldEqual, cmd2)\n+\t\t\tSo(job2.State, ShouldEqual, JobStateLost)\n+\n+\t\t\t// now allow 2 secs for job3 to start and complete\n+\t\t\tvar job3 *Job\n+\t\t\tfor i := 0; i < 8; i++ {\n+\t\t\t\tjob3, err = jq2.GetByEssence(&JobEssence{Cmd: cmd3}, false, false)\n+\t\t\t\tif job3 != nil && job3.State == JobStateComplete {\n+\t\t\t\t\tbreak\n+\t\t\t\t}\n+\t\t\t\t<-time.After(250 * time.Millisecond)\n+\t\t\t}\n+\t\t\tSo(err, ShouldBeNil)\n+\t\t\tSo(job3, ShouldNotBeNil)\n+\t\t\tSo(job3.Cmd, ShouldEqual, cmd3)\n+\t\t\tSo(job3.State, ShouldEqual, JobStateComplete)\n+\t\t\tSo(job3.StartTime, ShouldHappenAfter, job.EndTime)\n+\n+\t\t\t// for subsequent tests to work, we need to wait for the server to\n+\t\t\t// really be gone\n+\t\t\tsyscall.Kill(serverPid, syscall.SIGTERM)\n+\t\t\tserverCmd.Wait()","path":"jobqueue/jobqueue_test.go","position":599,"original_position":599,"commit_id":"46ff3e5096de6c0968b2868f0fbc2a2d01073268","original_commit_id":"46ff3e5096de6c0968b2868f0fbc2a2d01073268","user":{"login":"golangcibot","id":42910462,"node_id":"MDQ6VXNlcjQyOTEwNDYy","avatar_url":"https://avatars1.githubusercontent.com/u/42910462?v=4","gravatar_id":"","url":"https://api.github.com/users/golangcibot","html_url":"https://github.com/golangcibot","followers_url":"https://api.github.com/users/golangcibot/followers","following_url":"https://api.github.com/users/golangcibot/following{/other_user}","gists_url":"https://api.github.com/users/golangcibot/gists{/gist_id}","starred_url":"https://api.github.com/users/golangcibot/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/golangcibot/subscriptions","organizations_url":"https://api.github.com/users/golangcibot/orgs","repos_url":"https://api.github.com/users/golangcibot/repos","events_url":"https://api.github.com/users/golangcibot/events{/privacy}","received_events_url":"https://api.github.com/users/golangcibot/received_events","type":"User","site_admin":false},"body":"Error return value of `serverCmd.Wait` is not checked","created_at":"2018-11-09T23:08:33Z","updated_at":"2018-11-09T23:08:34Z","html_url":"https://github.com/VertebrateResequencing/wr/pull/165#discussion_r232419481","pull_request_url":"https://api.github.com/repos/VertebrateResequencing/wr/pulls/165","author_association":"NONE","_links":{"self":{"href":"https://api.github.com/repos/VertebrateResequencing/wr/pulls/comments/232419481"},"html":{"href":"https://github.com/VertebrateResequencing/wr/pull/165#discussion_r232419481"},"pull_request":{"href":"https://api.github.com/repos/VertebrateResequencing/wr/pulls/165"}}},"pull_request":{"url":"https://api.github.com/repos/VertebrateResequencing/wr/pulls/165","id":229737940,"node_id":"MDExOlB1bGxSZXF1ZXN0MjI5NzM3OTQw","html_url":"https://github.com/VertebrateResequencing/wr/pull/165","diff_url":"https://github.com/VertebrateResequencing/wr/pull/165.diff","patch_url":"https://github.com/VertebrateResequencing/wr/pull/165.patch","issue_url":"https://api.github.com/repos/VertebrateResequencing/wr/issues/165","number":165,"state":"open","locked":false,"title":"Resolve #107: existing runners reconnect to new manager.","user":{"login":"sb10","id":507951,"node_id":"MDQ6VXNlcjUwNzk1MQ==","avatar_url":"https://avatars2.githubusercontent.com/u/507951?v=4","gravatar_id":"","url":"https://api.github.com/users/sb10","html_url":"https://github.com/sb10","followers_url":"https://api.github.com/users/sb10/followers","following_url":"https://api.github.com/users/sb10/following{/other_user}","gists_url":"https://api.github.com/users/sb10/gists{/gist_id}","starred_url":"https://api.github.com/users/sb10/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sb10/subscriptions","organizations_url":"https://api.github.com/users/sb10/orgs","repos_url":"https://api.github.com/users/sb10/repos","events_url":"https://api.github.com/users/sb10/events{/privacy}","received_events_url":"https://api.github.com/users/sb10/received_events","type":"User","site_admin":false},"body":"","created_at":"2018-11-09T15:56:55Z","updated_at":"2018-11-09T23:08:33Z","closed_at":null,"merged_at":null,"merge_commit_sha":"cb4201bf650b91cc9b94cada1243fe6b1783b2ea","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[{"name":"wr reviewers","id":2833638,"node_id":"MDQ6VGVhbTI4MzM2Mzg=","slug":"wr-reviewers","description":"Review wr pull requests","privacy":"closed","url":"https://api.github.com/teams/2833638","members_url":"https://api.github.com/teams/2833638/members{/member}","repositories_url":"https://api.github.com/teams/2833638/repos","permission":"pull"}],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/VertebrateResequencing/wr/pulls/165/commits","review_comments_url":"https://api.github.com/repos/VertebrateResequencing/wr/pulls/165/comments","review_comment_url":"https://api.github.com/repos/VertebrateResequencing/wr/pulls/comments{/number}","comments_url":"https://api.github.com/repos/VertebrateResequencing/wr/issues/165/comments","statuses_url":"https://api.github.com/repos/VertebrateResequencing/wr/statuses/46ff3e5096de6c0968b2868f0fbc2a2d01073268","head":{"label":"sb10:feature/107","ref":"feature/107","sha":"46ff3e5096de6c0968b2868f0fbc2a2d01073268","user":{"login":"sb10","id":507951,"node_id":"MDQ6VXNlcjUwNzk1MQ==","avatar_url":"https://avatars2.githubusercontent.com/u/507951?v=4","gravatar_id":"","url":"https://api.github.com/users/sb10","html_url":"https://github.com/sb10","followers_url":"https://api.github.com/users/sb10/followers","following_url":"https://api.github.com/users/sb10/following{/other_user}","gists_url":"https://api.github.com/users/sb10/gists{/gist_id}","starred_url":"https://api.github.com/users/sb10/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sb10/subscriptions","organizations_url":"https://api.github.com/users/sb10/orgs","repos_url":"https://api.github.com/users/sb10/repos","events_url":"https://api.github.com/users/sb10/events{/privacy}","received_events_url":"https://api.github.com/users/sb10/received_events","type":"User","site_admin":false},"repo":{"id":144967210,"node_id":"MDEwOlJlcG9zaXRvcnkxNDQ5NjcyMTA=","name":"wr","full_name":"sb10/wr","private":false,"owner":{"login":"sb10","id":507951,"node_id":"MDQ6VXNlcjUwNzk1MQ==","avatar_url":"https://avatars2.githubusercontent.com/u/507951?v=4","gravatar_id":"","url":"https://api.github.com/users/sb10","html_url":"https://github.com/sb10","followers_url":"https://api.github.com/users/sb10/followers","following_url":"https://api.github.com/users/sb10/following{/other_user}","gists_url":"https://api.github.com/users/sb10/gists{/gist_id}","starred_url":"https://api.github.com/users/sb10/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sb10/subscriptions","organizations_url":"https://api.github.com/users/sb10/orgs","repos_url":"https://api.github.com/users/sb10/repos","events_url":"https://api.github.com/users/sb10/events{/privacy}","received_events_url":"https://api.github.com/users/sb10/received_events","type":"User","site_admin":false},"html_url":"https://github.com/sb10/wr","description":"High performance Workflow Runner","fork":true,"url":"https://api.github.com/repos/sb10/wr","forks_url":"https://api.github.com/repos/sb10/wr/forks","keys_url":"https://api.github.com/repos/sb10/wr/keys{/key_id}","collaborators_url":"https://api.github.com/repos/sb10/wr/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/sb10/wr/teams","hooks_url":"https://api.github.com/repos/sb10/wr/hooks","issue_events_url":"https://api.github.com/repos/sb10/wr/issues/events{/number}","events_url":"https://api.github.com/repos/sb10/wr/events","assignees_url":"https://api.github.com/repos/sb10/wr/assignees{/user}","branches_url":"https://api.github.com/repos/sb10/wr/branches{/branch}","tags_url":"https://api.github.com/repos/sb10/wr/tags","blobs_url":"https://api.github.com/repos/sb10/wr/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/sb10/wr/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/sb10/wr/git/refs{/sha}","trees_url":"https://api.github.com/repos/sb10/wr/git/trees{/sha}","statuses_url":"https://api.github.com/repos/sb10/wr/statuses/{sha}","languages_url":"https://api.github.com/repos/sb10/wr/languages","stargazers_url":"https://api.github.com/repos/sb10/wr/stargazers","contributors_url":"https://api.github.com/repos/sb10/wr/contributors","subscribers_url":"https://api.github.com/repos/sb10/wr/subscribers","subscription_url":"https://api.github.com/repos/sb10/wr/subscription","commits_url":"https://api.github.com/repos/sb10/wr/commits{/sha}","git_commits_url":"https://api.github.com/repos/sb10/wr/git/commits{/sha}","comments_url":"https://api.github.com/repos/sb10/wr/comments{/number}","issue_comment_url":"https://api.github.com/repos/sb10/wr/issues/comments{/number}","contents_url":"https://api.github.com/repos/sb10/wr/contents/{+path}","compare_url":"https://api.github.com/repos/sb10/wr/compare/{base}...{head}","merges_url":"https://api.github.com/repos/sb10/wr/merges","archive_url":"https://api.github.com/repos/sb10/wr/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/sb10/wr/downloads","issues_url":"https://api.github.com/repos/sb10/wr/issues{/number}","pulls_url":"https://api.github.com/repos/sb10/wr/pulls{/number}","milestones_url":"https://api.github.com/repos/sb10/wr/milestones{/number}","notifications_url":"https://api.github.com/repos/sb10/wr/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/sb10/wr/labels{/name}","releases_url":"https://api.github.com/repos/sb10/wr/releases{/id}","deployments_url":"https://api.github.com/repos/sb10/wr/deployments","created_at":"2018-08-16T09:33:48Z","updated_at":"2018-09-03T14:05:03Z","pushed_at":"2018-11-09T18:18:49Z","git_url":"git://github.com/sb10/wr.git","ssh_url":"git@github.com:sb10/wr.git","clone_url":"https://github.com/sb10/wr.git","svn_url":"https://github.com/sb10/wr","homepage":"","size":3767,"stargazers_count":0,"watchers_count":0,"language":"Go","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":{"key":"gpl-3.0","name":"GNU General Public License v3.0","spdx_id":"GPL-3.0","url":"https://api.github.com/licenses/gpl-3.0","node_id":"MDc6TGljZW5zZTk="},"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"VertebrateResequencing:develop","ref":"develop","sha":"e7c8852d37e63bbfc306010449de86e5ad8d8cb2","user":{"login":"VertebrateResequencing","id":506811,"node_id":"MDEyOk9yZ2FuaXphdGlvbjUwNjgxMQ==","avatar_url":"https://avatars2.githubusercontent.com/u/506811?v=4","gravatar_id":"","url":"https://api.github.com/users/VertebrateResequencing","html_url":"https://github.com/VertebrateResequencing","followers_url":"https://api.github.com/users/VertebrateResequencing/followers","following_url":"https://api.github.com/users/VertebrateResequencing/following{/other_user}","gists_url":"https://api.github.com/users/VertebrateResequencing/gists{/gist_id}","starred_url":"https://api.github.com/users/VertebrateResequencing/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/VertebrateResequencing/subscriptions","organizations_url":"https://api.github.com/users/VertebrateResequencing/orgs","repos_url":"https://api.github.com/users/VertebrateResequencing/repos","events_url":"https://api.github.com/users/VertebrateResequencing/events{/privacy}","received_events_url":"https://api.github.com/users/VertebrateResequencing/received_events","type":"Organization","site_admin":false},"repo":{"id":10549212,"node_id":"MDEwOlJlcG9zaXRvcnkxMDU0OTIxMg==","name":"wr","full_name":"VertebrateResequencing/wr","private":false,"owner":{"login":"VertebrateResequencing","id":506811,"node_id":"MDEyOk9yZ2FuaXphdGlvbjUwNjgxMQ==","avatar_url":"https://avatars2.githubusercontent.com/u/506811?v=4","gravatar_id":"","url":"https://api.github.com/users/VertebrateResequencing","html_url":"https://github.com/VertebrateResequencing","followers_url":"https://api.github.com/users/VertebrateResequencing/followers","following_url":"https://api.github.com/users/VertebrateResequencing/following{/other_user}","gists_url":"https://api.github.com/users/VertebrateResequencing/gists{/gist_id}","starred_url":"https://api.github.com/users/VertebrateResequencing/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/VertebrateResequencing/subscriptions","organizations_url":"https://api.github.com/users/VertebrateResequencing/orgs","repos_url":"https://api.github.com/users/VertebrateResequencing/repos","events_url":"https://api.github.com/users/VertebrateResequencing/events{/privacy}","received_events_url":"https://api.github.com/users/VertebrateResequencing/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/VertebrateResequencing/wr","description":"High performance Workflow Runner","fork":false,"url":"https://api.github.com/repos/VertebrateResequencing/wr","forks_url":"https://api.github.com/repos/VertebrateResequencing/wr/forks","keys_url":"https://api.github.com/repos/VertebrateResequencing/wr/keys{/key_id}","collaborators_url":"https://api.github.com/repos/VertebrateResequencing/wr/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/VertebrateResequencing/wr/teams","hooks_url":"https://api.github.com/repos/VertebrateResequencing/wr/hooks","issue_events_url":"https://api.github.com/repos/VertebrateResequencing/wr/issues/events{/number}","events_url":"https://api.github.com/repos/VertebrateResequencing/wr/events","assignees_url":"https://api.github.com/repos/VertebrateResequencing/wr/assignees{/user}","branches_url":"https://api.github.com/repos/VertebrateResequencing/wr/branches{/branch}","tags_url":"https://api.github.com/repos/VertebrateResequencing/wr/tags","blobs_url":"https://api.github.com/repos/VertebrateResequencing/wr/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/VertebrateResequencing/wr/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/VertebrateResequencing/wr/git/refs{/sha}","trees_url":"https://api.github.com/repos/VertebrateResequencing/wr/git/trees{/sha}","statuses_url":"https://api.github.com/repos/VertebrateResequencing/wr/statuses/{sha}","languages_url":"https://api.github.com/repos/VertebrateResequencing/wr/languages","stargazers_url":"https://api.github.com/repos/VertebrateResequencing/wr/stargazers","contributors_url":"https://api.github.com/repos/VertebrateResequencing/wr/contributors","subscribers_url":"https://api.github.com/repos/VertebrateResequencing/wr/subscribers","subscription_url":"https://api.github.com/repos/VertebrateResequencing/wr/subscription","commits_url":"https://api.github.com/repos/VertebrateResequencing/wr/commits{/sha}","git_commits_url":"https://api.github.com/repos/VertebrateResequencing/wr/git/commits{/sha}","comments_url":"https://api.github.com/repos/VertebrateResequencing/wr/comments{/number}","issue_comment_url":"https://api.github.com/repos/VertebrateResequencing/wr/issues/comments{/number}","contents_url":"https://api.github.com/repos/VertebrateResequencing/wr/contents/{+path}","compare_url":"https://api.github.com/repos/VertebrateResequencing/wr/compare/{base}...{head}","merges_url":"https://api.github.com/repos/VertebrateResequencing/wr/merges","archive_url":"https://api.github.com/repos/VertebrateResequencing/wr/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/VertebrateResequencing/wr/downloads","issues_url":"https://api.github.com/repos/VertebrateResequencing/wr/issues{/number}","pulls_url":"https://api.github.com/repos/VertebrateResequencing/wr/pulls{/number}","milestones_url":"https://api.github.com/repos/VertebrateResequencing/wr/milestones{/number}","notifications_url":"https://api.github.com/repos/VertebrateResequencing/wr/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/VertebrateResequencing/wr/labels{/name}","releases_url":"https://api.github.com/repos/VertebrateResequencing/wr/releases{/id}","deployments_url":"https://api.github.com/repos/VertebrateResequencing/wr/deployments","created_at":"2013-06-07T12:16:02Z","updated_at":"2018-10-28T19:31:47Z","pushed_at":"2018-11-09T18:44:46Z","git_url":"git://github.com/VertebrateResequencing/wr.git","ssh_url":"git@github.com:VertebrateResequencing/wr.git","clone_url":"https://github.com/VertebrateResequencing/wr.git","svn_url":"https://github.com/VertebrateResequencing/wr","homepage":"","size":3610,"stargazers_count":13,"watchers_count":13,"language":"Go","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":12,"mirror_url":null,"archived":false,"open_issues_count":32,"license":{"key":"gpl-3.0","name":"GNU General Public License v3.0","spdx_id":"GPL-3.0","url":"https://api.github.com/licenses/gpl-3.0","node_id":"MDc6TGljZW5zZTk="},"forks":12,"open_issues":32,"watchers":13,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/VertebrateResequencing/wr/pulls/165"},"html":{"href":"https://github.com/VertebrateResequencing/wr/pull/165"},"issue":{"href":"https://api.github.com/repos/VertebrateResequencing/wr/issues/165"},"comments":{"href":"https://api.github.com/repos/VertebrateResequencing/wr/issues/165/comments"},"review_comments":{"href":"https://api.github.com/repos/VertebrateResequencing/wr/pulls/165/comments"},"review_comment":{"href":"https://api.github.com/repos/VertebrateResequencing/wr/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/VertebrateResequencing/wr/pulls/165/commits"},"statuses":{"href":"https://api.github.com/repos/VertebrateResequencing/wr/statuses/46ff3e5096de6c0968b2868f0fbc2a2d01073268"}},"author_association":"MEMBER"}}
{"actor":{"display_login":"golangcibot"}}