Check out repo from only head_sha as delivered by check_run event

Is there any way to reliably check out the whole repository tree for testing given only the SHA of a commit?

The check_run event only delivers the head_sha in all cases. head_branch and associated PRs etc all are populated only when the PR is from the same repo, not when it is from a fork. The same holds true for the new APIs to get pulls and branches from a commit, associatedPullRequests, etc. All of those only work within a repo, not for forks.

As it is, there are only two ways I can see, both of which very awkward:

  • Check out the entire repo with +refs/pull//head:refs/remotes/origin/pull/ set, which makes it HUGE and take forever, seconds for larger repos to do a single fetch.
  • Listen to pull_request/synchronize events and remember the PR/branch for each head_sha in a local database.

There must be a better way? How is this supposed to work? I need the whole repo to do a check on a check_run, but in 99% of the real world cases I can’t check out the commit without jumping through a ton of hoops…

If you want the smallest possible download of the entire repository for a given commit without having to build any sort of caching infrastructure, you can use the following GraphQL query:

  repository(owner: "lee-dohm", name: "test-repo") {
    object(expression: "master") {
      ... on Commit {

And then download the file from the zipballUrl. It’s a zip of the contents of the repository at that point in time.

Of course, if you’re going to be running checks on the same repositories repeatedly, this system means you’re going to be transferring a lot of the same data over the wire again and again and again. So instead you could do a full clone of the repository once, then when you need to run a check, you can do:

git fetch [remote-name] [commit-id]
git checkout [commit-id]

This will fetch all objects that are required to complete the history of whatever commit you named that you don’t already have. Then it will update the working directory to the state at that commit.

There are other caching strategies that can be used depending on your specific architecture, but those two options should get you started.

Let us know if you have more questions.