Last active
April 21, 2020 14:34
-
-
Save soofstad/68e2e0694c25adf60b61fce2e8427207 to your computer and use it in GitHub Desktop.
Python script getting owners of repos with outside collaborators
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import csv | |
import json | |
from urllib import request | |
usage = """ | |
------------------------ | |
Usage | |
------------------------ | |
Add your Github Access Token with "read_user, user:email, public_repo, repo:invite" scopes like so; | |
token = "ksdjhkglkfjhløaksjbli378gblaup" | |
Usage; | |
$ python3 ./outside_collaborators.py | |
This will create a .csv file with every owner of a repository which has outside collaborators. | |
""" | |
github_admins = ("knut-erik", "ingvald", "pgdr", "solomson", "StigNil", "roar-statoil", "MerMyhr") | |
token = "" | |
if not token: | |
print(f"ERROR: Access token not given.") | |
print(usage) | |
print("Exiting...") | |
exit(1) | |
def collabs_query(end_cursor): | |
graphql_query = f""" | |
query{{organization(login: "equinor"){{ | |
repositories(first: 100{end_cursor}){{ | |
nodes{{ | |
name, | |
description, | |
url, | |
collaborators(affiliation: OUTSIDE){{ | |
nodes{{ | |
login, | |
company, | |
name, | |
}} | |
}} | |
}}, | |
pageInfo{{ | |
endCursor, | |
hasNextPage | |
}} | |
}} | |
}} | |
}} | |
""" | |
post_data = json.dumps({"query": graphql_query}).encode() | |
return post_data | |
def owners_query(repo): | |
graphql_query = f""" | |
{{ | |
organization(login: "equinor") {{ | |
repository(name: "{repo}") {{ | |
name | |
description | |
url | |
collaborators(affiliation: ALL) {{ | |
edges {{ | |
node {{ | |
login | |
}} | |
permission | |
}} | |
totalCount | |
}} | |
}} | |
}} | |
}} | |
""" | |
post_data = json.dumps({"query": graphql_query}).encode() | |
return post_data | |
def get_outside_colabs(): | |
print("Getting all outside collaborators in the Equinor organization") | |
url = 'https://api.github.com/graphql' | |
headers = {'Accept': 'application/vnd.github.v3+json', | |
'Authorization': 'Bearer ' + token} | |
end_cursor = "" | |
outsiders = {} | |
while True: | |
req = request.Request(url=url, headers=headers, data=collabs_query(end_cursor)) | |
response = request.urlopen(req).read().decode() | |
users_page = json.loads(response) | |
cursor = users_page['data']['organization']['repositories']['pageInfo']['endCursor'] | |
end_cursor = ", after: \"" + cursor + "\"" | |
repositories = [r for r in users_page["data"]["organization"]["repositories"]["nodes"]] | |
for repo in repositories: | |
collaborators = repo.get('collaborators') | |
users = collaborators.get("nodes") if collaborators else None | |
if users: | |
for user in users: | |
outsiders[user["login"]] = { | |
"repo": repo["name"], | |
"email": user["email"], | |
"login": user["login"], | |
"name": user["name"], | |
"company": user["company"] | |
} | |
if not users_page['data']['organization']['repositories']['pageInfo']['hasNextPage']: | |
break | |
print(f"{len(outsiders)} total outside collaborators in the Equinor Org") | |
return outsiders | |
def get_repo_owners(repo_list): | |
print("Getting all owners of every repository with an outside collaborator") | |
url = 'https://api.github.com/graphql' | |
headers = {'Accept': 'application/vnd.github.v3+json', | |
'Authorization': 'Bearer ' + token} | |
repo_owners_w_outsiders = [] | |
for repo in repo_list: | |
req = request.Request(url=url, headers=headers, data=owners_query(repo)) | |
response = request.urlopen(req).read().decode() | |
users_page = json.loads(response) | |
collaborators = [c for c in users_page["data"]["organization"]["repository"]["collaborators"]["edges"]] | |
for user in collaborators: | |
login = user["node"]["login"] | |
role = user["permission"] | |
email = user["node"]["email"] | |
if login not in github_admins and role is "ADMIN": | |
repo_owners_w_outsiders.append({"repo": repo, "role": role, "login": login, "email": email}) | |
return repo_owners_w_outsiders | |
if __name__ == "__main__": | |
with open("collab_repo_owners.csv", "w") as file: | |
fieldnames = ['repo', "role", 'email', 'login'] | |
writer = csv.DictWriter(file, fieldnames=fieldnames) | |
writer.writeheader() | |
outsiders = get_outside_colabs() | |
repos_with_outsiders = [] | |
[repos_with_outsiders.append(o["repo"]) for o in outsiders.values() if o["repo"] not in repos_with_outsiders] | |
repo_owners = get_repo_owners(repos_with_outsiders) | |
for user in repo_owners: | |
writer.writerow(user) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Notes