Question

Assuming that I've got the necessary GitHub authentication credentials, how can I get all commits made by a certain user from GitHub API?

Working Code

Beneath you'll find a simplified CoffeeScript extract of a Meteor application I wrote that implements the strategy suggested in the accepted answer. Left out of this snippet, the code expects a global variable Configuration, which should contain a property user being the GitHub username, and a property token being a GitHub authentication token for said user. The code also stores discovered commits in a global Meteor collection Commits. There are probably bugs in this code, but it works to some degree at least. Suggested improvements are welcomed.

logger = new Logger("github")

getResource = (uri, done) ->
  options =
    auth: "token:#{Configuration.token}"
    headers:
      "User-Agent": "GitHub Comments"
  HTTP.call("get", uri, options, done)

getCommits = (user, userUrl, time, done, page=1, numCommits=0) ->
  eventsUrl = "#{userUrl}/events?page=#{page}"
  logger.debug("Getting events page #{page} for user #{Configuration.user}", eventsUrl)
  getResource(eventsUrl, (error, result) ->
    if error?
      logger.warn("Error", error)
      throw new Error("Couldn't get events for user #{Configuration.user}")

    events = (event for event in result.data when event.type == "PushEvent" && event.payload.commits.length > 0)
    commits = []
    for event in events
      for commit in event.payload.commits when commit.author.email == user.email
        commits.push(
          sha: commit.sha
          url: commit.url
        )

    logger.debug("Found #{commits.length} commits attributable to user #{user.email} on events page #{page}")
    for commit in commits
      logger.debug("Getting details for commit #{commit.sha}", commit.url)
      try
        commitDetails = getResource(commit.url).data
      catch err
        logger.warn("Couldn't get details for commit #{commit.url}", err)
        continue

      Commits.insert(commit)
      ++numCommits

    if result.data.length > 0
      logger.debug("Calling getCommits for next page with numCommits #{numCommits}")
      getCommits(user, userUrl, time, done, page+1, numCommits)
    else
      done(numCommits)
  )

pollGitHub = ->
  logger.info("Polling GitHub for data")

  start = moment()

  userUrl = "https://api.github.com/users/#{Configuration.user}"
  getResource(userUrl, (error, result) ->
    if error?
      throw new Error("Couldn't get data for user #{Configuration.user}")

    user = result.data
    if !user.email
      throw new Error("Need to be able to identify user by email")

    logger.debug("Removing all previous commits belonging to #{Configuration.user}")
    Commits.remove(user: Configuration.user)
    numCommits = 0
    getCommits(user, userUrl, start, (numCommits) ->
      taken = moment().diff(start, "seconds")
      logger.info("Inserted #{numCommits} commits for user #{Configuration.user} in #{taken} seconds")
    )
  )

Meteor.startup(->
  pollGitHub()
)
Was it helpful?

Solution

You can probably go a few different routes:

Repos/Commits

Iterate through a users repos and getting commits for each

GET /users/:user/repos
GET /repos/:owner/:repo/commits

http://developer.github.com/v3/repos/#list-user-repositories http://developer.github.com/v3/repos/commits/#list-commits-on-a-repository

Push Events

GET /users/:user/events

http://developer.github.com/v3/activity/events/types/#pushevent http://developer.github.com/v3/activity/events/#list-events-that-a-user-has-received

Anytime someone pushes, a push event is triggered, since to see a commit it needs to be pushed, if you look at a users push events, then you will see the associated commits!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top