GitHub notifications - failed pull requests

Ben Source

I'm a member of a few large repositories at work and would like to be able to set up a daily check (email probably / slackbot maybe) to send me and outstanding pull requests that I have open and the reason they are still open. We have 3 checks before the PR is merged, Linter check, code review and CI. I would like to see which of the 3 checks has failed (or is yet to be complete in the case of the code review).

Is this possible?

gitgithubgithub-api

Answers

answered 7 months ago Anton Sizikov #1

Yes, this is possible.

Take a look at GitHub API.

Getting a list of open PRs for the repository:

https://developer.github.com/v3/pulls/#list-pull-requests

GET /repos/:owner/:repo/pulls

You're interested in your open PRs, so use a state parameter set to Open and head to filter by your user reference.

CI checks are called "Statuses"

https://developer.github.com/v3/repos/statuses/

GET /repos/:owner/:repo/commits/:ref/statuses

where :ref is the latest commit's hash (the latest commit in your branch).

[
  {
    "created_at": "2012-07-20T01:19:13Z",
    "updated_at": "2012-07-20T01:19:13Z",
    "state": "success",
    "description": "Build has completed successfully",
    "id": 1,
    }
  }
]

latest commit SHA value could be found in /pulls response:

[
{
 "head": {
      "label": "new-topic",
      "ref": "new-topic",
      "sha": "6dcb09b5b57875f334f61aebed695e2e4193db5e"
}
]

Combining these you can poll your repos in the morning and build a fairly simple Slack/Email bot.

answered 5 months ago Sergei Rodionov #2

GitHub GraphQL API v4 should work well for this use case.

Here's a single query that retrieves repository fields, PR fields, and consolidated status, grouped by context, in one go:

query { repository(owner: "github", name:"fetch") 
  { 
    name
    pullRequests(first: 3, states: OPEN, orderBy: {field: UPDATED_AT, direction: DESC}) {
      nodes {
        url
        author {
          ... on User {
            login name
          }
        }        
        mergeable
        baseRefName
        headRefName
        title
        milestone { title }
        labels(first: 100) { nodes{name} }
        ... on PullRequest {
          pullRequestcommits: commits(last: 1) {
            totalCount
            nodes {
              commit {
                #url 
                status { state contexts { context description createdAt targetUrl } }
              }
            }
          }
        }
      }
    } 
  }
}

The sample query above returns three most recently updated pull requests with status checks for the https://github.com/github/fetch repository:

{
  "data": {
    "repository": {
      "name": "fetch",
      "pullRequests": {
        "nodes": [
          {
            "url": "https://github.com/github/fetch/pull/616",
            "author": {
              "login": "jayphelps",
              "name": "Jay Phelps"
            },
            "mergeable": "MERGEABLE",
            "baseRefName": "master",
            "headRefName": "umd",
            "title": "build/distribute as UMD",
            "milestone": null,
            "labels": {
              "nodes": []
            },
            "pullRequestcommits": {
              "totalCount": 1,
              "nodes": [
                {
                  "commit": {
                    "status": {
                      "state": "SUCCESS",
                      "contexts": [
                        {
                          "context": "continuous-integration/travis-ci/pr",
                          "description": "The Travis CI build passed",
                          "createdAt": "2018-04-09T17:39:00Z",
                          "targetUrl": "https://travis-ci.org/github/fetch/builds/364229647?utm_source=github_status&utm_medium=notification"
                        }
                      ]
                    }
                  }
                }
              ]
            }
          },
          {
            "url": "https://github.com/github/fetch/pull/592",
            "author": {
              "login": "jamesplease",
              "name": "James"
            },
            "mergeable": "MERGEABLE",
            "baseRefName": "master",
            "headRefName": "abort-polyfill",
            "title": "Support abort API",
            "milestone": null,
            "labels": {
              "nodes": []
            },
            "pullRequestcommits": {
              "totalCount": 23,
              "nodes": [
                {
                  "commit": {
                    "status": {
                      "state": "SUCCESS",
                      "contexts": [
                        {
                          "context": "GitHub CLA",
                          "description": "@jmeas has accepted the GitHub Contributor License Agreement.",
                          "createdAt": "2018-02-04T18:41:33Z",
                          "targetUrl": "https://cla.github.com/github/fetch/accept/jmeas"
                        },
                        {
                          "context": "continuous-integration/travis-ci/pr",
                          "description": "The Travis CI build passed",
                          "createdAt": "2018-02-04T18:42:51Z",
                          "targetUrl": "https://travis-ci.org/github/fetch/builds/337277553?utm_source=github_status&utm_medium=notification"
                        }
                      ]
                    }
                  }
                }
              ]
            }
          },
          {
            "url": "https://github.com/github/fetch/pull/575",
            "author": {
              "login": "CrOrc",
              "name": "Roman Yakubuk"
            },
            "mergeable": "MERGEABLE",
            "baseRefName": "master",
            "headRefName": "CrOrc-fix-resolve-IE-11",
            "title": "Fix issue #533",
            "milestone": null,
            "labels": {
              "nodes": []
            },
            "pullRequestcommits": {
              "totalCount": 1,
              "nodes": [
                {
                  "commit": {
                    "status": {
                      "state": "SUCCESS",
                      "contexts": [
                        {
                          "context": "GitHub CLA",
                          "description": "@CrOrc has accepted the GitHub Contributor License Agreement.",
                          "createdAt": "2017-10-27T16:29:56Z",
                          "targetUrl": "https://cla.github.com/github/fetch/accept/CrOrc"
                        },
                        {
                          "context": "continuous-integration/travis-ci/pr",
                          "description": "The Travis CI build passed",
                          "createdAt": "2017-10-23T14:07:55Z",
                          "targetUrl": "https://travis-ci.org/github/fetch/builds/291563522?utm_source=github_status&utm_medium=notification"
                        }
                      ]
                    }
                  }
                }
              ]
            }
          }
        ]
      }
    }
  }
}

The graphql json can then be flattened to a CSV report:

enter image description here

You can extend the above query to fetch pull requests from multiple repositories, for example, from all repositories belonging to your organization.

query { organization(login: "github") {
  repositories(first: 5) {
    nodes {
    # serialize repo and PR fields as displayed above
  }
}

comments powered by Disqus