GraphQL: How to get a list of commits between tags or releases

I posted on StackOverflow as well: github-graphql-how-to-get-a-list-of-commits-between-tag

If possible, I would like to make a single query that would give me the commit list between releases or tags. If only 1 tag were provided it would be the list from current master (latest commit) until that tag, and if 2 were provided it would be the list between the 2 tags. I wasn’t sure of the best way to approach this without using more than 1 query. In truth, I only need commits from master to the most recent tag or between tags next to one another if that makes it easier.

This kind of query isn’t something that the GraphQL API is designed to be able to give you at this point. In theory, if you’re certain that tag-x is an ancestor of branch-y, and you have the commit hash of tag-x, then you could go from the Commit object pointed to by branch-y and paginate through all commits (using the history connection) until you find the commit hash you’re looking for. You could also use the since parameter on the history connection to prevent you from overwalking. But that doesn’t solve for the case where y is the ancestor of x or that x and y are not proper ancestors of one or the other.

For now, using git itself is probably the best way to get at the information you’re looking for.

I hope that helps!

Thanks @lee-dohm for the helpful response! In truth, I’m only ever concerned with the master branch, and reality is that I need to see a commit list from the last release to the current point in time, as a new release is about to be generated.  So even if am just getting a list of commits up to the last tag, or list of commits up to the last release that would be enough. Is that possible with the “Release” or “Tag” and … on Commit fragment? I’m just learning GraphQl (first couple of days) so forgive the ignorance. 

Even if there was a way for me to list a bunch of commits, and discern that one of them was tagged, that would be enough, but I can’t seem to get that info just from “Commit” history.

So if you only want to get the list of commits from the HEAD of the master branch back to some release tag, you could use this query:

{
  repository(owner: "lee-dohm", name: "octicons-ex") {
    object(expression: "v0.5.0") {
      ... on Commit {
        oid
        messageHeadline
        committedDate
        author {
          user {
            login
          }
        }
      }
    }
  }
}

to get the information on the commit pointed to by the given tag (“v0.5.0” in my example). From there you could get the committedDate value to supply to this query:

{
  repository(owner: "lee-dohm", name: "octicons-ex") {
    nameWithOwner
    object(expression: "master") {
      ... on Commit {
        oid
        history(first: 100, since: "2018-06-22T04:37:29Z") {
          nodes {
            oid
            messageHeadline
            author {
              user {
                login
              }
            }
            committedDate
          }
        }
      }
    }
  }
}

by placing the committedDate in the since parameter (replacing “2018-06-22T04:37:29Z” in my example). That will list all the commits between the tip of the master branch and the given tag.

I hope that helps!

4 Likes

@lee-dohm This is truly helpful.  I made it a little more dynamic by doing this:

{
  repository(owner: "CoolCompany", name: "awesome-ui") {
    releases(last: 1) {
      edges{
        node{
          tagName
          createdAt
        }
      }
    }
  }
}

Then I can use the createdAt you suggested in the same way and get my commit list since the last release. I really appreciate the help! It’s too bad I couldn’t do this all in a single query but it took me 3 requests with the v3 rest API so it’s still an improvement and the filtering logic is much easier now. Thank you!

You’re welcome :grinning:

One other thing to note is that you don’t need to do edges immediately followed by node in your queries unless you’re getting the pageInfo or totalCount from the edges connection. If you just want the stuff in node (as it appears you do in your query), it can be simplified to:

{
  repository(owner: "CoolCompany", name: "awesome-ui") {
    releases(last: 1) {
      nodes {
        tagName
        createdAt
      }
    }
  }
}

I hope that helps!

3 Likes