Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get count of pull requests made by a user on any repo belonging to an organization?

I am trying to develop a rating system which can list the individuals who have contributed most to my organization on GitHub. I am trying to do that by counting the number of "merged" pull requests created by an user in any of the org's repo.

I am somewhat familiar with GitHub APIs, but I am facing difficulty figuring out the proper requests to make. Any help will be appreciated. Thank you all. Also, it will be nicer if contributions counted this way include those in private repos also.

PS: I don't want to use number of commits as a count, because that is not a precise measure, as in developing a feature some users keep committing one file at time, while others commit after creating a bunch of them. So, please don't suggest that.

Also, there are invalid pull requests also, or some which turn stale, I don't wanna count those in number of contributions.

like image 456
noobie Avatar asked Dec 06 '25 06:12

noobie


1 Answers

You can use a search query to look for issues :

  • with type pr : type:pr
  • authored by: author:{some user}
  • merged: is:merged
  • in a specific org: org:{some org}

The search query :

org:mui-org author:eps1lon type:pr is:merged

The call would be :

https://api.github.com/search/issues?q=org:mui-org%20author:eps1lon%20type:pr%20is:merged

Then filter the total count, an example using curl and jq :

curl -s "https://api.github.com/search/issues?q=org:mui-org%20author:eps1lon%20type:pr%20is:merged" | \
     jq '.total_count'

Output:

715

What you could do is using GraphQL API to :

  • get the list of users in your organization
  • build a request dynamically using aliases for each user to perform the search query

So you end up with only 2 requests

An example in python :

import requests

token = "YOUR_TOKEN"
org = "mui-org"

userQuery = """
{ 
  organization(login: "%s"){
    membersWithRole(first: 100){
      nodes {
        login
      }
    }
  }
}
"""
pullRequestQuery = """
  %s: search(query: "org:%s author:%s type:pr is:merged", type: ISSUE){
    issueCount
  } 
"""

def makeCall(query):
    r = requests.post("https://api.github.com/graphql",
        headers = {
            "Authorization": f"Bearer {token}"
        },
        json = {
            "query": query
        }
    )
    return r.json()["data"]

userList = makeCall(userQuery % org)

#build a list of keys matching user (user0: johndoe ....)
keyList = {}
for idx, user in enumerate(userList["organization"]["membersWithRole"]["nodes"]):
    keyList[f"user{idx}"] = user["login"]

#build the query
builtQuery = "".join([
    pullRequestQuery % (t, org, keyList[t]) 
    for t in keyList.keys()
])
result = makeCall("{%s}" % builtQuery)

#match the original user login
stats = {}
for it in result.keys():
    stats[keyList[it]] = result[it]["issueCount"]

print(stats)

output :

{'kof': 1, 'pelotom': 57, 'mbrookes': 487, 'dtassone': 78, 'sebald': 29, 'hai-cea': 14, 'kgregory': 21, 'oliviertassinari': 2077, 'merceyz': 70, 'nathanmarks': 80, 'mnajdova': 56, 'leMaik': 45, 'DanailH': 4, 'alitaheri': 98, 'm2mathew': 6, 'eps1lon': 715, 'DDDDDanica': 13, 'joshwooding': 110, 'dimitropoulos': 2, 'dmtrKovalenko': 352}
like image 99
Bertrand Martel Avatar answered Dec 10 '25 00:12

Bertrand Martel



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!