Skip to content

Instantly share code, notes, and snippets.

@MichaelCurrin
Last active April 14, 2024 16:26
Show Gist options
  • Star 31 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save MichaelCurrin/f8a7a11451ce4ec055d41000c915b595 to your computer and use it in GitHub Desktop.
Save MichaelCurrin/f8a7a11451ce4ec055d41000c915b595 to your computer and use it in GitHub Desktop.
GitHub GraphQL - Get Pull Requests using GH's GraphQL API

Get Pull Requests using GH's GraphQL API

How to get Pull Requests data using Github in the browser, or using the API to allow for automating reporting or building in values into a website.

Resources

Queries

There some approaches followed in this gist.

Get Pull Requests for the user

Use the pullRequests object on the viewer (current user). And showing the repo associated. This is not so clean.

Or get PRs withing repos of the view.

Search Pull Requests against other repos

The approaches above are not so flexible.

This approach uses a search that one can do in the browser on Github and use that query in a search function in the GQL API.

  1. Click Pull Requests on Github or go to https://github.com/pulls .
  2. Change the search parameters or enter your own search.
  3. Use that search for the search GQL file in this gist.
    • Note that type should be ISSUE to get Pull Requests. Alternatively, get USER or REPOSITORY objects for other searches.
    • The default order is newest first. You can use oldest first with sort:created-asc.

Here are sample searches:

  • Default:
    • Get all own PRs for my user, whether for my own repos or not. Includes private repos by default and excludes archived repos.
    • is:open is:pr author:MichaelCurrin archived:false
  • Get all my contributions to public repos not owned by me:
  • PRs in atom/atom and atom/github after a given data:
    • is:pr created:>2019-04-01 repo:atom/atom repo:atom/github

Running queries

Explorer

Use the explorer linked in Resources, copy and paste a query and run.

Command-line

Request

How to run a query using curl and an auth token.

curl -H "Authorization: bearer token" -X POST -d " \
 { \
   \"query\": \"query { viewer { login }}\" \
 } \
" https://api.github.com/graphql

See Forming calls in the docs for details.

Results

See below for simplified sample data for search query described earlier.

{
  "issueCount": 1,
  "edges": [
    {
      "node": {
        "number": 105,
        "title": "fix: Allow config flag to take a parameter",
        "repository": {
          "nameWithOwner": "docsifyjs/docsify-cli"
        },
        "createdAt": "2020-05-17T18:59:33Z",
        "mergedAt": "2020-05-18T08:39:27Z",
        "url": "https://github.com/docsifyjs/docsify-cli/pull/105",
        "changedFiles": 1,
        "additions": 1,
        "deletions": 1
      }
    }
  ]
}

Future development

I like the search approach so want to use that more.

  • The query can be parametized - send JSON data as the search query. Unfortunately the query has to be prepated in JSON - you can't send just username as an argument (unless GQL has a way to concatenate strings).
  • Adding paging for higher volume searches.
  • Extend to search for other types not just PRs.
  • Add a parser to turn the data in a CSV, or embed on a website.
{
viewer {
pullRequests(first: 100, states: CLOSED, orderBy: {field: UPDATED_AT, direction: DESC}) {
nodes {
repository {
name
isPrivate
}
}
}
}
}
{
viewer {
repositories(first: 5) {
nodes {
name
pullRequests(last: 5) {
nodes {
number
url
state
reviews(last: 100) {
nodes {
author {
login
}
state
}
}
}
}
}
}
}
}
{
search(query: "is:merged is:pr is:public archived:false author:MichaelCurrin -user:MichaelCurrin", type: ISSUE, first: 100) {
issueCount
edges {
node {
... on PullRequest {
number
title
repository {
nameWithOwner
}
createdAt
mergedAt
url
changedFiles
additions
deletions
}
}
}
}
}
@noraj
Copy link

noraj commented May 8, 2022

I that possible to get the list of Github projects a user XYZ contributed to, sorted by number of PR, with the number of PR by projects, in order to create graphs?

also only counting open + merged and not closed would be nice but since merged is a sub-set of close it sounds difficult to do since the search query doesn't allow is:open + is:merged in the same query.

@MichaelCurrin
Copy link
Author

MichaelCurrin commented May 9, 2022

You could use search_my_merged_prs_on_public_repos.gql to simply fetch the PRs by a user and then use your application logic to group and sort those PRs.


You might have to query open and merged PRs separately then combine them.

I tried doing a negative search as is:pr -is:closed but couldn't get it to work. Why not just get all the PRs and then on the application side you can exclude any items which are closed without merging.

{
  search(query: "is:pr is:public author:MichaelCurrin , type: ISSUE, first: 100) {
    issueCount
    edges {
      node {
        ... on PullRequest {
          number
          title
          repository {
            nameWithOwner
          }
          state  # will be one of "MERGED" or "OPEN" or "CLOSED"
        }
      }
    }
  }
}

@dadamsGS
Copy link

I am trying to get all the PRs from two repos in my org. One repo, the repo where the Action runs works the other does not.

This is an example of the job that runs/fails:

jobs:
  publish_pull_requests_to_slack:
    strategy:
      matrix:
        repo: ["application", "otherrepo-aws"]
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
    - uses: octokit/graphql-action@v2.2.23
      id: get_latest_release
      with:
        query: |
          query pullRequest($owner:String!,$repo:String!) {
            repository(owner: $owner, name: $repo) {
              pullRequests(states: OPEN, first: 100) {
                nodes {
                  title
                  isDraft
                  url
                }
              }
            }
          }
        owner: ${{ github.event.repository.owner.name }}
        repo: ${{ matrix.repo }}
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

The error I get is:

Could not resolve to a Repository with the name 'MyOrg/otherepo-aws'.

Should running a matrix work?

@MichaelCurrin
Copy link
Author

MichaelCurrin commented Dec 22, 2022

ah interesting use with an action.

Matrix does make sense but for two repos you can try without using matrix and just do a single run but hardcode the values. At least to get the query to run without an error.

  query pullRequest($owner:String!,$repo:String!) {
            repository(owner: $owner, name: $repo) {
              pullRequests(states: OPEN, first: 100) {
                nodes {
                  title
                  isDraft
                  url
                }
              }
            }
          }

  pullRequest("MyOrg", "application")
  pullRequest("MyOrg", otherrepo-aws")

@MichaelCurrin
Copy link
Author

MichaelCurrin commented Dec 22, 2022

or just run with a shorter matrix list to track down the error.

One time as:

    matrix:
        repo: ["application"]

Then again as

    matrix:
        repo: ["application", "otherrepo-aws"]

@dadamsGS
Copy link

Cool. Thanks for validating my approach, @MichaelCurrin

I have tried just the otherrepo-aws and I get the same error. There must be a configuration issue in that repo. If I have a GITHUB_TOKEN that should cover all the repos in my org, right?

@MichaelCurrin
Copy link
Author

@dadamsGS Is it a private repo? Make sure your token includes private repos in scope.

You also run in the GH GraphQL explorer to see if it works there https://docs.github.com/en/graphql/overview/explorer

@elanzini
Copy link

Is it possible to get all the PRs, whose title startsWith some string?
I couldn't find it in the docs.

@MichaelCurrin
Copy link
Author

The search is limited to the search syntax (same in the APIs and in the UI as far as I know)

You can do advanced search here and generate syntax but there is nothing about PR name

https://github.com/search/advanced

@bivald
Copy link

bivald commented May 23, 2023

This gist saved me hours of work, thank you =)

@MichaelCurrin
Copy link
Author

@bivald glad to hear, you're welcome!

@ibrahim-vanak
Copy link

Hi @MichaelCurrin , I tried to run the query: https://gist.github.com/MichaelCurrin/f8a7a11451ce4ec055d41000c915b595?permalink_comment_id=4410721#gistcomment-4410721 but getting error.

I want to get the list of all PRs in list of repos in my ORG created after a specific date and created with specific base branch . Is it possible to get this info?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment