List all unresolved pull request comments
Asked Answered
A

3

6

We are using the @octokit/rest client to fetch all of the comments on a pull request:

client.pulls
  .listComments({
    owner,
    repo,
    pull_number: 34,
    per_page: 100,
  })
  .then((result) => {
    console.log(result.data.length);
    console.log(result.data[0]);
  });

How if at all can we list only the unresolved comments? There does not appear to be a property in the data that indicates whether someone has resolved the comment or not.

Appel answered 16/4, 2019 at 17:47 Comment(5)
Maybe you can get reviews in the PR using this and then for each pending review get comments using this. Haven't tested this yet.Blakely
To get pending reviews I think you can check for the state of the PR as CHANGES_REQUESTED. Again not implemented completely.Blakely
@DivyaMamgai the state that you have mentioned is of the PR. What the OP needs is the state of the comments on a PR's review.Coordinate
@MadhuBhat Yes, that is correct. Its just an assumption that if the particular review request is still on CHANGES_REQUESTED, then some comments on that particular review are still not resolved.Blakely
@DivyaMamgai but even if all comments of a review request are resolved, the state of the PR still stays as CHANGES_REQUESTED. It changes only of it is approved or dismissed. But anyhow, the OP requires to list the comments based on the status and not if they are present or not.Coordinate
C
9

Using GitHub's v4 GraphQL API, the GraphQL API Explorer (to explore/build my query), the GitHub CLI (to simplify calling the GraphQL API), and jq (to filter the results); I came up with the following solution (written as a bash script to ease calling, but the same principles would apply if calling the GraphQL API from code as well):

# Usage:
#   Retrieve unresolved review comments
#     ./pr-unresolved-review-comments myorganisation myrepo 1337
#
#   Count of unresolved review comment threads
#     ./pr-unresolved-review-comments myorganisation myrepo 1337 | jq length

gh api graphql -f owner="$1" -f repo="$2" -F pr="$3" -f query='
  query FetchReviewComments($owner: String!, $repo: String!, $pr: Int!) {
    repository(owner: $owner, name: $repo) {
      pullRequest(number: $pr) {
        url
        reviewDecision
        reviewThreads(first: 100) {
          edges {
            node {
              isResolved
              isOutdated
              isCollapsed
              comments(first: 100) {
                totalCount
                nodes {
                  author {
                    login
                  }
                  body
                  url
                }
              }
            }
          }
        }
      }
    }
  }
' | jq '.data.repository.pullRequest.reviewThreads.edges | map(select(.node.isResolved == false))'

The specific fields that you include as part of the GraphQL query are customisable, but this seemed to give me what I needed.

The output of running the above script will look something like the following:

[
  {
    "node": {
      "isResolved": false,
      "isOutdated": true,
      "isCollapsed": false,
      "comments": {
        "totalCount": 7,
        "nodes": [
          {
            "author": {
              "login": "0xdevalias"
            },
            "body": "This is an unresolved comment that is important!",
            "url": "https://github.com/myorganisation/myrepo/pull/1337#discussion_r559294516"
          },
          ..snip..
        ]
      }
    }
  },
  ..snip..
]

To list unresolved comments against all open PRs for a repo, this script can be used instead:

# Usage:
#   Retrieve all unresolved review comments for a repo
#     ./pr-unresolved-review-comments myorganisation myrepo

gh api graphql -f owner="$1" -f repo="$2" -f query='
  query FetchReviewComments($owner: String!, $repo: String!) {
    repository(owner: $owner, name: $repo) {
      pullRequests(first: 30, states: OPEN) {
        edges {
          node {
            url
            reviewDecision
            reviewThreads(first: 100) {
              edges {
                node {
                  isResolved
                  isOutdated
                  isCollapsed
                  comments(first: 100) {
                    totalCount
                    nodes {
                      author {
                        login
                      }
                      body
                      url
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
'  | jq '.data.repository.pullRequests.edges[].node.reviewThreads.edges | map(select(.node.isResolved == false))'

Contracted answered 6/2, 2021 at 0:1 Comment(1)
Very nice; I've turned this into a script that renders parts of the JSON into ASCII output.Abbatial
C
5

On GitHub.com, not all comments under a pull request have the resolved/unresolved status, but only the comments as part of a review. And GitHubs's v3 API, which octokit uses, doesn't provide any such status as part of the response of GET on comments of a review, and a sample response of the same is :

    [
      {
        "url": "https://api.github.com/repos/octocat/Hello-World/pulls/comments/1",
        "id": 10,
        "node_id": "MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDEw",
        "pull_request_review_id": 42,
        "diff_hunk": "@@ -16,33 +16,40 @@ public class Connection : IConnection...",
        "path": "file1.txt",
        "position": 1,
        "original_position": 4,
        "commit_id": "6dcb09b5b57875f334f61aebed695e2e4193db5e",
        "original_commit_id": "9c48853fa3dc5c1c3d6f1f1cd1f2743e72652840",
        "in_reply_to_id": 8,
        "user": {
          "login": "octocat",
          "id": 1,
          "node_id": "MDQ6VXNlcjE=",
          "avatar_url": "https://github.com/images/error/octocat_happy.gif",
          "gravatar_id": "",
          "url": "https://api.github.com/users/octocat",
          "html_url": "https://github.com/octocat",
          "followers_url": "https://api.github.com/users/octocat/followers",
          "following_url": "https://api.github.com/users/octocat/following{/other_user}",
          "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
          "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
          "subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
          "organizations_url": "https://api.github.com/users/octocat/orgs",
          "repos_url": "https://api.github.com/users/octocat/repos",
          "events_url": "https://api.github.com/users/octocat/events{/privacy}",
          "received_events_url": "https://api.github.com/users/octocat/received_events",
          "type": "User",
          "site_admin": false
        },
        "body": "Great stuff",
        "created_at": "2011-04-14T16:00:49Z",
        "updated_at": "2011-04-14T16:00:49Z",
        "html_url": "https://github.com/octocat/Hello-World/pull/1#discussion-diff-1",
        "pull_request_url": "https://api.github.com/repos/octocat/Hello-World/pulls/1",
        "_links": {
          "self": {
            "href": "https://api.github.com/repos/octocat/Hello-World/pulls/comments/1"
          },
          "html": {
            "href": "https://github.com/octocat/Hello-World/pull/1#discussion-diff-1"
          },
          "pull_request": {
            "href": "https://api.github.com/repos/octocat/Hello-World/pulls/1"
          }
        }
      }
    ]

So essentially, I don't think your requirement can currently be served by GitHub's v3 API or Octokit. You can see more about it on GitHub v3 API's documentation

Coordinate answered 16/4, 2019 at 18:17 Comment(1)
That's my sense too. I might have to do a fair amount of programmatic work to filter out the resolved comments.Appel
V
-4

I can get resolved/unresolved comments by list-review-comments-on-a-pull-request.

Try /repos/{owner}/{repo}/pulls/{pull_number}/comments 👍

Violetteviolin answered 28/1, 2021 at 3:9 Comment(1)
What field are you using to determine whether the comments have been resolved/unresolved with this method?Mckenney

© 2022 - 2024 — McMap. All rights reserved.