forked from cms-sw/cms-bot
-
Notifications
You must be signed in to change notification settings - Fork 0
/
gh-teams.py
executable file
·199 lines (192 loc) · 7.85 KB
/
gh-teams.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
#!/usr/bin/env python
from copy import deepcopy
from github import Github
from os.path import expanduser
from argparse import ArgumentParser
from sys import exit
from socket import setdefaulttimeout
from github_utils import api_rate_limits, github_api,add_organization_member
setdefaulttimeout(120)
CMS_OWNERS = [ "smuzaffar", "cmsbuild", "davidlange6" ]
CMS_SDT = [ "iahmad-khan", "mrodozov" ]
CMS_ORGANIZATIONS = [ "cms-data", "cms-externals", "cms-sw" ]
REPO_OWNERS = {}
REPO_TEAMS = {}
for org in CMS_ORGANIZATIONS:
REPO_OWNERS[org] = CMS_OWNERS[:]
REPO_TEAMS[org] = {}
#################################
#Set Extra owners for repos #
#################################
REPO_OWNERS["cms-data"] += ["iahmad-khan"]
REPO_OWNERS["cms-externals"] += ["iahmad-khan"]
REPO_OWNERS["cms-sw"] += [ "davidlt", "sextonkennedy" ]
#################################
#Set Teams for organizations #
#################################
#Teams for cms-data
REPO_TEAMS["cms-data"]["Developers"] = {
"members" : [ "davidlt" ] + CMS_SDT,
"repositories" : { "*" : "push" }
}
#Teams for cms-externals
REPO_TEAMS["cms-externals"]["Developers"] = deepcopy(REPO_TEAMS["cms-data"]["Developers"])
REPO_TEAMS["cms-externals"]["boost-developers"] = { "members": ["fwyzard"], "repositories" : { "boost" : "push" } }
#Teams for cms-sw
REPO_TEAMS["cms-sw"]["RecoLuminosity-LumiDB-admins"] = {
"members" : ["xiezhen"],
"repositories" : { "RecoLuminosity-LumiDB": "admin"}
}
REPO_TEAMS["cms-sw"]["generators-l2"] = {
"members" : ["bendavid","covarell","govoni","vciulli"],
"repositories" : { "genproductions" : "admin",
"xsecdb" : "admin"}
}
REPO_TEAMS["cms-sw"]["Dqm-Integration-developers"] = {
"members" : ["rovere","deguio"],
"repositories" : { "DQM-Integration": "push"}
}
REPO_TEAMS["cms-sw"]["configdb-owners"] = {
"members" : ["fwyzard", "Martin-Grunewald", "vinnie87"],
"repositories" : { "hlt-confdb":"admin", "web-confdb":"admin"}
}
REPO_TEAMS["cms-sw"]["cmsdist-writers"] = {
"members" : [ "BrunoCoimbra", "h4d4" ],
"repositories" : { "cmsdist":"push" }
}
REPO_TEAMS["cms-sw"]["cmssw-l2"] = {
"members" : [ "*" ],
"repositories" : { "cmssw":"pull" }
}
REPO_TEAMS["cms-sw"]["cmssw-developers"] = {
"members" : [ "*" ],
"repositories" : { "cmssw":"pull" }
}
REPO_TEAMS["cms-sw"]["cms-sw-writers"] = {
"members" : CMS_SDT,
"repositories" : { "*":"push", "!cmssw" : "pull", "!cmsdist" : "pull" }
}
#################################
parser = ArgumentParser()
parser.add_argument("-o", "--organization", dest="organization", help="Github Organization name e.g. cms-sw. Default is * i.e. all cms origanizations", type=str, default="*")
parser.add_argument("-n", "-dry-run", dest="dryRun", default=False, action="store_true")
args = parser.parse_args()
GH_TOKEN = open(expanduser("~/.github-token")).read().strip()
gh = Github(login_or_token=GH_TOKEN)
cache = {"users" : {}}
total_changes=0
err_code=0
for org_name in CMS_ORGANIZATIONS:
if args.organization!="*" and org_name!=args.organization: continue
print "Wroking on Organization ",org_name
api_rate_limits(gh)
org = gh.get_organization(org_name)
ok_mems = []
print " Looking for owners:",REPO_OWNERS[org_name]
chg_flag=0
for mem in org.get_members(role="admin"):
login = mem.login.encode("ascii", "ignore")
if not login in cache["users"]: cache["users"][login] = mem
if not login in REPO_OWNERS[org_name]:
if not args.dryRun: add_organization_member(GH_TOKEN, org_name, login, role="member")
print " =>Remove owner:",login
chg_flag+=1
else:
ok_mems.append(login)
for login in [ l for l in REPO_OWNERS[org_name] if not l in ok_mems ]:
if not args.dryRun: add_organization_member(GH_TOKEN, org_name, login, role="admin")
print " =>Add owner:",login
chg_flag+=1
total_changes+=chg_flag
if not chg_flag: print " OK Owners"
print " Looking for teams:",REPO_TEAMS[org_name].keys()
org_repos = [ repo for repo in org.get_repos() ]
for team in org.get_teams():
print " Checking team:",team.name
api_rate_limits(gh,msg=False)
team_info = {}
try: team_info = REPO_TEAMS[org_name][team.name]
except:
print " WARNING: New team found on Github:",team.name
err_code=1
continue
members = team_info["members"]
tm_members = [ mem for mem in team.get_members()]
tm_members_login = [ mem.login.encode("ascii", "ignore") for mem in tm_members ]
print " Valid Members:",members
print " Existing Members:",tm_members_login
ok_mems = ["*"]
chg_flag=0
if not "*" in members:
for mem in tm_members:
api_rate_limits(gh,msg=False)
login = mem.login.encode("ascii", "ignore")
if not login in cache["users"]: cache["users"][login] = mem
if (login in members) or ("*" in members):
ok_mems.append(login)
else:
if not args.dryRun: team.remove_from_members(mem)
print " =>Removed member:",login
chg_flag+=1
for login in [ l for l in members if not l in ok_mems ]:
api_rate_limits(gh,msg=False)
if not login in cache["users"]: cache["users"][login] = gh.get_user(login)
if not args.dryRun: team.add_to_members(cache["users"][login])
print " =>Added member:",login
chg_flag+=1
total_changes+=chg_flag
if not chg_flag: print " OK Team members"
team_repos = [ repo for repo in team.get_repos() ]
team_repos_name = [ repo.name.encode("ascii", "ignore") for repo in team_repos ]
print " Checking team repositories"
print " Valid Repos:",team_info["repositories"].keys()
print " Existing Repos:",team_repos_name
repo_to_check = team_repos_name[:]
for repo in team_info["repositories"]:
if repo=="*": repo_to_check += [ r.name.encode("ascii", "ignore") for r in org_repos ]
elif repo.startswith("!"): repo_to_check += [repo[1:]]
else: repo_to_check += [repo]
chg_flag=0
for repo_name in set(repo_to_check):
api_rate_limits(gh, msg=False)
inv_repo = "!"+repo_name
repo = [ r for r in team_repos if r.name.encode("ascii", "ignore") == repo_name ]
if (repo_name in team_info["repositories"]) or \
("*" in team_info["repositories"] and (not inv_repo in team_info["repositories"])):
prem = "pull"
if repo_name in team_info["repositories"]: prem = team_info["repositories"][repo_name]
elif "*" in team_info["repositories"]: prem = team_info["repositories"]["*"]
if not repo_name in team_repos_name:
if not args.dryRun:
if not repo: repo.append(gh.get_repo(org_name+"/"+repo_name))
team.set_repo_permission(repo[0], prem)
print " =>Added repo:",repo_name,prem
chg_flag+=1
else:
curperm = repo[0].permissions
set_perm=False
curperm_name="pull"
if curperm.admin:
curperm_name="admin"
if not prem=="admin": set_perm=True
elif curperm.push:
curperm_name="push"
if not prem=="push": set_perm=True
elif curperm.pull:
if not prem=="pull": set_perm=True
if set_perm:
if not args.dryRun:
if not repo: repo.append(gh.get_repo(org_name+"/"+repo_name))
team.set_repo_permission(repo[0], prem)
print " =>Set Permission:",repo_name,curperm_name,"=>",prem
chg_flag+=1
elif repo_name in team_repos_name:
if not args.dryRun:
if not repo: repo.append(gh.get_repo(org_name+"/"+repo_name))
team.remove_from_repos(repo[0])
print " =>Removed repository:",repo_name
chg_flag+=1
if not chg_flag: print " OK Team Repositories"
total_changes+=chg_flag
print "Total Updates:",total_changes
exit(err_code)