{"action":"created","comment":{"url":"https://api.github.com/repos/SonarSource/sonarqube/pulls/comments/172551536","pull_request_review_id":101586656,"id":172551536,"diff_hunk":"@@ -0,0 +1,142 @@\n+/*\n+ * SonarQube\n+ * Copyright (C) 2009-2018 SonarSource SA\n+ * mailto:info AT sonarsource DOT com\n+ *\n+ * This program is free software; you can redistribute it and/or\n+ * modify it under the terms of the GNU Lesser General Public\n+ * License as published by the Free Software Foundation; either\n+ * version 3 of the License, or (at your option) any later version.\n+ *\n+ * This program is distributed in the hope that it will be useful,\n+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\n+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n+ * Lesser General Public License for more details.\n+ *\n+ * You should have received a copy of the GNU Lesser General Public License\n+ * along with this program; if not, write to the Free Software Foundation,\n+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.\n+ */\n+package org.sonar.server.branch.pr.ws;\n+\n+import java.util.List;\n+import java.util.Map;\n+import java.util.Objects;\n+import java.util.Optional;\n+import java.util.function.Function;\n+import javax.annotation.Nullable;\n+import org.sonar.api.server.ws.Request;\n+import org.sonar.api.server.ws.Response;\n+import org.sonar.api.server.ws.WebService;\n+import org.sonar.api.web.UserRole;\n+import org.sonar.db.DbClient;\n+import org.sonar.db.DbSession;\n+import org.sonar.db.component.BranchDto;\n+import org.sonar.db.component.ComponentDto;\n+import org.sonar.db.component.SnapshotDto;\n+import org.sonar.db.protobuf.DbProjectBranches;\n+import org.sonar.server.component.ComponentFinder;\n+import org.sonar.server.issue.index.BranchStatistics;\n+import org.sonar.server.issue.index.IssueIndex;\n+import org.sonar.server.user.UserSession;\n+import org.sonarqube.ws.ProjectPullRequests;\n+\n+import static com.google.common.base.Preconditions.checkArgument;\n+import static org.sonar.api.resources.Qualifiers.PROJECT;\n+import static org.sonar.api.utils.DateUtils.formatDateTime;\n+import static org.sonar.core.util.Protobuf.setNullable;\n+import static org.sonar.core.util.stream.MoreCollectors.toList;\n+import static org.sonar.core.util.stream.MoreCollectors.uniqueIndex;\n+import static org.sonar.db.component.BranchType.PULL_REQUEST;\n+import static org.sonar.server.branch.pr.ws.PullRequestsWs.addProjectParam;\n+import static org.sonar.server.branch.pr.ws.PullRequestsWsParameters.PARAM_PROJECT;\n+import static org.sonar.server.ws.WsUtils.writeProtobuf;\n+\n+public class ListAction implements PullRequestWsAction {\n+\n+  private final DbClient dbClient;\n+  private final UserSession userSession;\n+  private final ComponentFinder componentFinder;\n+  private final IssueIndex issueIndex;\n+\n+  public ListAction(DbClient dbClient, UserSession userSession, ComponentFinder componentFinder, IssueIndex issueIndex) {\n+    this.dbClient = dbClient;\n+    this.userSession = userSession;\n+    this.componentFinder = componentFinder;\n+    this.issueIndex = issueIndex;\n+  }\n+\n+  @Override\n+  public void define(WebService.NewController context) {\n+    WebService.NewAction action = context.createAction(\"list\")\n+      .setSince(\"7.1\")\n+      .setDescription(\"List the pull requests of a project.<br/>\" +\n+        \"Requires 'Administer' rights on the specified project.\")\n+      .setResponseExample(getClass().getResource(\"list-example.json\"))\n+      .setHandler(this);\n+\n+    addProjectParam(action);\n+  }\n+\n+  @Override\n+  public void handle(Request request, Response response) throws Exception {\n+    String projectKey = request.mandatoryParam(PARAM_PROJECT);\n+\n+    try (DbSession dbSession = dbClient.openSession(false)) {\n+      ComponentDto project = componentFinder.getByKey(dbSession, projectKey);\n+      userSession.checkComponentPermission(UserRole.USER, project);\n+      checkArgument(project.isEnabled() && PROJECT.equals(project.qualifier()), \"Invalid project key\");\n+\n+      List<BranchDto> pullRequests = dbClient.branchDao().selectByComponent(dbSession, project).stream()\n+        .filter(b -> b.getBranchType() == PULL_REQUEST)\n+        .collect(toList());\n+      List<String> pullRequestUuids = pullRequests.stream().map(BranchDto::getUuid).collect(toList());\n+\n+      Map<String, BranchDto> mergeBranchesByUuid = dbClient.branchDao()\n+        .selectByUuids(dbSession, pullRequests.stream().map(BranchDto::getMergeBranchUuid).filter(Objects::nonNull).collect(toList()))\n+        .stream().collect(uniqueIndex(BranchDto::getUuid));\n+      Map<String, BranchStatistics> branchStatisticsByBranchUuid = issueIndex.searchBranchStatistics(project.uuid(), pullRequestUuids).stream()\n+        .collect(uniqueIndex(BranchStatistics::getBranchUuid, Function.identity()));\n+      Map<String, String> analysisDateByBranchUuid = dbClient.snapshotDao().selectLastAnalysesByRootComponentUuids(dbSession, pullRequestUuids).stream()\n+        .collect(uniqueIndex(SnapshotDto::getComponentUuid, s -> formatDateTime(s.getCreatedAt())));\n+\n+      ProjectPullRequests.ListWsResponse.Builder protobufResponse = ProjectPullRequests.ListWsResponse.newBuilder();\n+      pullRequests\n+        .forEach(b -> addPullRequest(protobufResponse, b, mergeBranchesByUuid, branchStatisticsByBranchUuid.get(b.getUuid()),\n+          analysisDateByBranchUuid.get(b.getUuid())));\n+      writeProtobuf(protobufResponse.build(), request, response);\n+    }\n+  }\n+\n+  private static void addPullRequest(ProjectPullRequests.ListWsResponse.Builder response, BranchDto branch, Map<String, BranchDto> mergeBranchesByUuid,\n+    BranchStatistics branchStatistics, @Nullable String analysisDate) {\n+    Optional<BranchDto> mergeBranch = Optional.ofNullable(mergeBranchesByUuid.get(branch.getMergeBranchUuid()));\n+\n+    ProjectPullRequests.PullRequest.Builder builder = ProjectPullRequests.PullRequest.newBuilder();\n+    builder.setId(branch.getKey());\n+\n+    // known to be non-null; all pull requests have non-null value, and caller filters accordingly\n+    DbProjectBranches.PullRequestData pullRequestData = branch.getPullRequestData();\n+    builder.setBranch(pullRequestData.getBranch());","path":"server/sonar-server/src/main/java/org/sonar/server/branch/pr/ws/ListAction.java","position":120,"original_position":120,"commit_id":"ca0b3c6672b5c353e675e53dc9cab66d047a0545","original_commit_id":"ca0b3c6672b5c353e675e53dc9cab66d047a0545","user":{"login":"SonarTech","id":1842438,"avatar_url":"https://avatars2.githubusercontent.com/u/1842438?v=4","gravatar_id":"","url":"https://api.github.com/users/SonarTech","html_url":"https://github.com/SonarTech","followers_url":"https://api.github.com/users/SonarTech/followers","following_url":"https://api.github.com/users/SonarTech/following{/other_user}","gists_url":"https://api.github.com/users/SonarTech/gists{/gist_id}","starred_url":"https://api.github.com/users/SonarTech/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/SonarTech/subscriptions","organizations_url":"https://api.github.com/users/SonarTech/orgs","repos_url":"https://api.github.com/users/SonarTech/repos","events_url":"https://api.github.com/users/SonarTech/events{/privacy}","received_events_url":"https://api.github.com/users/SonarTech/received_events","type":"User","site_admin":false},"body":"![Bug](https://sonarsource.github.io/sonar-github/bug.png 'Bug') Bug: A \"NullPointerException\" could be thrown; \"pullRequestData\" is nullable here. ([squid:S2259](https://next.sonarqube.com/sonarqube/coding_rules#rule_key=squid%3AS2259))\n\n[See it in SonarQube](https://next.sonarqube.com/sonarqube/project/issues?id=org.sonarsource.sonarqube%3Asonarqube&branch=feature%2Fbranch%2Ffirst-class-pull-request&issues=AWG-CCgHJBf1BWcDXKCn&open=AWG-CCgHJBf1BWcDXKCn)\n\n[ISSUE_KEY]: AWG-CCgHJBf1BWcDXKCn","created_at":"2018-03-06T15:23:41Z","updated_at":"2018-03-06T15:23:42Z","html_url":"https://github.com/SonarSource/sonarqube/pull/3010#discussion_r172551536","pull_request_url":"https://api.github.com/repos/SonarSource/sonarqube/pulls/3010","author_association":"NONE","_links":{"self":{"href":"https://api.github.com/repos/SonarSource/sonarqube/pulls/comments/172551536"},"html":{"href":"https://github.com/SonarSource/sonarqube/pull/3010#discussion_r172551536"},"pull_request":{"href":"https://api.github.com/repos/SonarSource/sonarqube/pulls/3010"}}},"pull_request":{"url":"https://api.github.com/repos/SonarSource/sonarqube/pulls/3010","id":166557586,"html_url":"https://github.com/SonarSource/sonarqube/pull/3010","diff_url":"https://github.com/SonarSource/sonarqube/pull/3010.diff","patch_url":"https://github.com/SonarSource/sonarqube/pull/3010.patch","issue_url":"https://api.github.com/repos/SonarSource/sonarqube/issues/3010","number":3010,"state":"open","locked":false,"title":"MMF-1134 Pull Request as 1st class citizen","user":{"login":"teryk","id":1247713,"avatar_url":"https://avatars0.githubusercontent.com/u/1247713?v=4","gravatar_id":"","url":"https://api.github.com/users/teryk","html_url":"https://github.com/teryk","followers_url":"https://api.github.com/users/teryk/followers","following_url":"https://api.github.com/users/teryk/following{/other_user}","gists_url":"https://api.github.com/users/teryk/gists{/gist_id}","starred_url":"https://api.github.com/users/teryk/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/teryk/subscriptions","organizations_url":"https://api.github.com/users/teryk/orgs","repos_url":"https://api.github.com/users/teryk/repos","events_url":"https://api.github.com/users/teryk/events{/privacy}","received_events_url":"https://api.github.com/users/teryk/received_events","type":"User","site_admin":false},"body":"👨‍🏭 WIP 👷 ","created_at":"2018-02-01T14:49:22Z","updated_at":"2018-03-06T15:23:42Z","closed_at":null,"merged_at":null,"merge_commit_sha":"a7a96adc5518fc0f884a9ef1e1260c27faf1aeb9","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/SonarSource/sonarqube/pulls/3010/commits","review_comments_url":"https://api.github.com/repos/SonarSource/sonarqube/pulls/3010/comments","review_comment_url":"https://api.github.com/repos/SonarSource/sonarqube/pulls/comments{/number}","comments_url":"https://api.github.com/repos/SonarSource/sonarqube/issues/3010/comments","statuses_url":"https://api.github.com/repos/SonarSource/sonarqube/statuses/ca0b3c6672b5c353e675e53dc9cab66d047a0545","head":{"label":"SonarSource:feature/branch/first-class-pull-request","ref":"feature/branch/first-class-pull-request","sha":"ca0b3c6672b5c353e675e53dc9cab66d047a0545","user":{"login":"SonarSource","id":545988,"avatar_url":"https://avatars0.githubusercontent.com/u/545988?v=4","gravatar_id":"","url":"https://api.github.com/users/SonarSource","html_url":"https://github.com/SonarSource","followers_url":"https://api.github.com/users/SonarSource/followers","following_url":"https://api.github.com/users/SonarSource/following{/other_user}","gists_url":"https://api.github.com/users/SonarSource/gists{/gist_id}","starred_url":"https://api.github.com/users/SonarSource/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/SonarSource/subscriptions","organizations_url":"https://api.github.com/users/SonarSource/orgs","repos_url":"https://api.github.com/users/SonarSource/repos","events_url":"https://api.github.com/users/SonarSource/events{/privacy}","received_events_url":"https://api.github.com/users/SonarSource/received_events","type":"Organization","site_admin":false},"repo":{"id":1222504,"name":"sonarqube","full_name":"SonarSource/sonarqube","owner":{"login":"SonarSource","id":545988,"avatar_url":"https://avatars0.githubusercontent.com/u/545988?v=4","gravatar_id":"","url":"https://api.github.com/users/SonarSource","html_url":"https://github.com/SonarSource","followers_url":"https://api.github.com/users/SonarSource/followers","following_url":"https://api.github.com/users/SonarSource/following{/other_user}","gists_url":"https://api.github.com/users/SonarSource/gists{/gist_id}","starred_url":"https://api.github.com/users/SonarSource/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/SonarSource/subscriptions","organizations_url":"https://api.github.com/users/SonarSource/orgs","repos_url":"https://api.github.com/users/SonarSource/repos","events_url":"https://api.github.com/users/SonarSource/events{/privacy}","received_events_url":"https://api.github.com/users/SonarSource/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/SonarSource/sonarqube","description":"Continuous Code Quality","fork":false,"url":"https://api.github.com/repos/SonarSource/sonarqube","forks_url":"https://api.github.com/repos/SonarSource/sonarqube/forks","keys_url":"https://api.github.com/repos/SonarSource/sonarqube/keys{/key_id}","collaborators_url":"https://api.github.com/repos/SonarSource/sonarqube/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/SonarSource/sonarqube/teams","hooks_url":"https://api.github.com/repos/SonarSource/sonarqube/hooks","issue_events_url":"https://api.github.com/repos/SonarSource/sonarqube/issues/events{/number}","events_url":"https://api.github.com/repos/SonarSource/sonarqube/events","assignees_url":"https://api.github.com/repos/SonarSource/sonarqube/assignees{/user}","branches_url":"https://api.github.com/repos/SonarSource/sonarqube/branches{/branch}","tags_url":"https://api.github.com/repos/SonarSource/sonarqube/tags","blobs_url":"https://api.github.com/repos/SonarSource/sonarqube/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/SonarSource/sonarqube/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/SonarSource/sonarqube/git/refs{/sha}","trees_url":"https://api.github.com/repos/SonarSource/sonarqube/git/trees{/sha}","statuses_url":"https://api.github.com/repos/SonarSource/sonarqube/statuses/{sha}","languages_url":"https://api.github.com/repos/SonarSource/sonarqube/languages","stargazers_url":"https://api.github.com/repos/SonarSource/sonarqube/stargazers","contributors_url":"https://api.github.com/repos/SonarSource/sonarqube/contributors","subscribers_url":"https://api.github.com/repos/SonarSource/sonarqube/subscribers","subscription_url":"https://api.github.com/repos/SonarSource/sonarqube/subscription","commits_url":"https://api.github.com/repos/SonarSource/sonarqube/commits{/sha}","git_commits_url":"https://api.github.com/repos/SonarSource/sonarqube/git/commits{/sha}","comments_url":"https://api.github.com/repos/SonarSource/sonarqube/comments{/number}","issue_comment_url":"https://api.github.com/repos/SonarSource/sonarqube/issues/comments{/number}","contents_url":"https://api.github.com/repos/SonarSource/sonarqube/contents/{+path}","compare_url":"https://api.github.com/repos/SonarSource/sonarqube/compare/{base}...{head}","merges_url":"https://api.github.com/repos/SonarSource/sonarqube/merges","archive_url":"https://api.github.com/repos/SonarSource/sonarqube/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/SonarSource/sonarqube/downloads","issues_url":"https://api.github.com/repos/SonarSource/sonarqube/issues{/number}","pulls_url":"https://api.github.com/repos/SonarSource/sonarqube/pulls{/number}","milestones_url":"https://api.github.com/repos/SonarSource/sonarqube/milestones{/number}","notifications_url":"https://api.github.com/repos/SonarSource/sonarqube/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/SonarSource/sonarqube/labels{/name}","releases_url":"https://api.github.com/repos/SonarSource/sonarqube/releases{/id}","deployments_url":"https://api.github.com/repos/SonarSource/sonarqube/deployments","created_at":"2011-01-05T11:05:17Z","updated_at":"2018-03-06T14:45:12Z","pushed_at":"2018-03-06T15:00:32Z","git_url":"git://github.com/SonarSource/sonarqube.git","ssh_url":"git@github.com:SonarSource/sonarqube.git","clone_url":"https://github.com/SonarSource/sonarqube.git","svn_url":"https://github.com/SonarSource/sonarqube","homepage":"http://www.sonarqube.org","size":274839,"stargazers_count":2461,"watchers_count":2461,"language":"Java","has_issues":false,"has_projects":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":805,"mirror_url":null,"archived":false,"open_issues_count":22,"license":{"key":"other","name":"Other","spdx_id":null,"url":null},"forks":805,"open_issues":22,"watchers":2461,"default_branch":"master"}},"base":{"label":"SonarSource:master","ref":"master","sha":"321d6082dc978b1f50bf50d0638110d83e07e545","user":{"login":"SonarSource","id":545988,"avatar_url":"https://avatars0.githubusercontent.com/u/545988?v=4","gravatar_id":"","url":"https://api.github.com/users/SonarSource","html_url":"https://github.com/SonarSource","followers_url":"https://api.github.com/users/SonarSource/followers","following_url":"https://api.github.com/users/SonarSource/following{/other_user}","gists_url":"https://api.github.com/users/SonarSource/gists{/gist_id}","starred_url":"https://api.github.com/users/SonarSource/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/SonarSource/subscriptions","organizations_url":"https://api.github.com/users/SonarSource/orgs","repos_url":"https://api.github.com/users/SonarSource/repos","events_url":"https://api.github.com/users/SonarSource/events{/privacy}","received_events_url":"https://api.github.com/users/SonarSource/received_events","type":"Organization","site_admin":false},"repo":{"id":1222504,"name":"sonarqube","full_name":"SonarSource/sonarqube","owner":{"login":"SonarSource","id":545988,"avatar_url":"https://avatars0.githubusercontent.com/u/545988?v=4","gravatar_id":"","url":"https://api.github.com/users/SonarSource","html_url":"https://github.com/SonarSource","followers_url":"https://api.github.com/users/SonarSource/followers","following_url":"https://api.github.com/users/SonarSource/following{/other_user}","gists_url":"https://api.github.com/users/SonarSource/gists{/gist_id}","starred_url":"https://api.github.com/users/SonarSource/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/SonarSource/subscriptions","organizations_url":"https://api.github.com/users/SonarSource/orgs","repos_url":"https://api.github.com/users/SonarSource/repos","events_url":"https://api.github.com/users/SonarSource/events{/privacy}","received_events_url":"https://api.github.com/users/SonarSource/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/SonarSource/sonarqube","description":"Continuous Code Quality","fork":false,"url":"https://api.github.com/repos/SonarSource/sonarqube","forks_url":"https://api.github.com/repos/SonarSource/sonarqube/forks","keys_url":"https://api.github.com/repos/SonarSource/sonarqube/keys{/key_id}","collaborators_url":"https://api.github.com/repos/SonarSource/sonarqube/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/SonarSource/sonarqube/teams","hooks_url":"https://api.github.com/repos/SonarSource/sonarqube/hooks","issue_events_url":"https://api.github.com/repos/SonarSource/sonarqube/issues/events{/number}","events_url":"https://api.github.com/repos/SonarSource/sonarqube/events","assignees_url":"https://api.github.com/repos/SonarSource/sonarqube/assignees{/user}","branches_url":"https://api.github.com/repos/SonarSource/sonarqube/branches{/branch}","tags_url":"https://api.github.com/repos/SonarSource/sonarqube/tags","blobs_url":"https://api.github.com/repos/SonarSource/sonarqube/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/SonarSource/sonarqube/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/SonarSource/sonarqube/git/refs{/sha}","trees_url":"https://api.github.com/repos/SonarSource/sonarqube/git/trees{/sha}","statuses_url":"https://api.github.com/repos/SonarSource/sonarqube/statuses/{sha}","languages_url":"https://api.github.com/repos/SonarSource/sonarqube/languages","stargazers_url":"https://api.github.com/repos/SonarSource/sonarqube/stargazers","contributors_url":"https://api.github.com/repos/SonarSource/sonarqube/contributors","subscribers_url":"https://api.github.com/repos/SonarSource/sonarqube/subscribers","subscription_url":"https://api.github.com/repos/SonarSource/sonarqube/subscription","commits_url":"https://api.github.com/repos/SonarSource/sonarqube/commits{/sha}","git_commits_url":"https://api.github.com/repos/SonarSource/sonarqube/git/commits{/sha}","comments_url":"https://api.github.com/repos/SonarSource/sonarqube/comments{/number}","issue_comment_url":"https://api.github.com/repos/SonarSource/sonarqube/issues/comments{/number}","contents_url":"https://api.github.com/repos/SonarSource/sonarqube/contents/{+path}","compare_url":"https://api.github.com/repos/SonarSource/sonarqube/compare/{base}...{head}","merges_url":"https://api.github.com/repos/SonarSource/sonarqube/merges","archive_url":"https://api.github.com/repos/SonarSource/sonarqube/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/SonarSource/sonarqube/downloads","issues_url":"https://api.github.com/repos/SonarSource/sonarqube/issues{/number}","pulls_url":"https://api.github.com/repos/SonarSource/sonarqube/pulls{/number}","milestones_url":"https://api.github.com/repos/SonarSource/sonarqube/milestones{/number}","notifications_url":"https://api.github.com/repos/SonarSource/sonarqube/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/SonarSource/sonarqube/labels{/name}","releases_url":"https://api.github.com/repos/SonarSource/sonarqube/releases{/id}","deployments_url":"https://api.github.com/repos/SonarSource/sonarqube/deployments","created_at":"2011-01-05T11:05:17Z","updated_at":"2018-03-06T14:45:12Z","pushed_at":"2018-03-06T15:00:32Z","git_url":"git://github.com/SonarSource/sonarqube.git","ssh_url":"git@github.com:SonarSource/sonarqube.git","clone_url":"https://github.com/SonarSource/sonarqube.git","svn_url":"https://github.com/SonarSource/sonarqube","homepage":"http://www.sonarqube.org","size":274839,"stargazers_count":2461,"watchers_count":2461,"language":"Java","has_issues":false,"has_projects":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":805,"mirror_url":null,"archived":false,"open_issues_count":22,"license":{"key":"other","name":"Other","spdx_id":null,"url":null},"forks":805,"open_issues":22,"watchers":2461,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/SonarSource/sonarqube/pulls/3010"},"html":{"href":"https://github.com/SonarSource/sonarqube/pull/3010"},"issue":{"href":"https://api.github.com/repos/SonarSource/sonarqube/issues/3010"},"comments":{"href":"https://api.github.com/repos/SonarSource/sonarqube/issues/3010/comments"},"review_comments":{"href":"https://api.github.com/repos/SonarSource/sonarqube/pulls/3010/comments"},"review_comment":{"href":"https://api.github.com/repos/SonarSource/sonarqube/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/SonarSource/sonarqube/pulls/3010/commits"},"statuses":{"href":"https://api.github.com/repos/SonarSource/sonarqube/statuses/ca0b3c6672b5c353e675e53dc9cab66d047a0545"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"SonarTech"}}