forked from cms-sw/cms-bot
-
Notifications
You must be signed in to change notification settings - Fork 0
/
create-github-hooks
executable file
·129 lines (121 loc) · 4.86 KB
/
create-github-hooks
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
#!/usr/bin/env python
from github import Github
from os.path import expanduser , exists
from optparse import OptionParser
#from process_pr import process_pr
from github_hooks_config import GITHUB_HOOKS as hk_conf
from github_hooks_config import REPO_HOOK_MAP
from github_utils import api_rate_limits
import hashlib, re
from categories import EXTERNAL_REPOS, CMSSW_REPOS, CMSDIST_REPOS
from sys import exit
from socket import setdefaulttimeout
setdefaulttimeout(120)
#Get secret from file
def get_secret(hook_name):
secret_file = '/data/secrets/' + hook_name
if not exists(secret_file):
secret_file = '/data/secrets/github_hook_secret_cmsbot'
return open(secret_file,'r').read().split('\n')[0].strip()
#match hook config
def match_config(new,old):
if new["active"] != old.active:
return False
elif new["events"] != old.events:
return False
for key in new["config"]:
if (not key in old.config) or (key!='secret' and new["config"][key] != old.config[key]):
return False
return True
#main section
if __name__ == "__main__":
parser = OptionParser(usage="%prog [-k|--hook <name>] [-r|--repository <repo>] [-f|--force] [-n|--dry-run]")
parser.add_option("-n", "--dry-run", dest="dryRun", action="store_true", help="Do not modify Github", default=False)
parser.add_option("-f", "--force", dest="force", action="store_true", help="Force update github hook", default=False)
parser.add_option("-r", "--repository",dest="repository", help="Github Repositoy name e.g. cms-sw/cmssw.", type=str, default=None)
parser.add_option("-e", "--externals", dest="externals", action="store_true", help="Only process CMS externals repositories", default=False)
parser.add_option("-c", "--cmssw", dest="cmssw", action="store_true", help="Only process "+",".join(CMSSW_REPOS)+" repository", default=False)
parser.add_option("-d", "--cmsdist", dest="cmsdist", action="store_true", help="Only process "+",".join(CMSDIST_REPOS)+" repository", default=False)
parser.add_option("-a", "--all", dest="all", action="store_true", help="Process all CMS repository i.e. externals, cmsdist and cmssw", default=False)
parser.add_option("-k", "--hook", dest="hook", help="Github Hook name", type=str, default="")
opts, args = parser.parse_args()
repos_names = []
if opts.repository:
repos_names.append(opts.repository)
elif opts.all:
opts.externals = True
opts.cmssw = True
opts.cmsdist = True
elif (not opts.externals) and (not opts.cmssw) and (not opts.cmsdist):
parser.error("Too few arguments, please use either -e, -c or -d")
if not repos_names:
if opts.externals: repos_names = repos_names + EXTERNAL_REPOS
if opts.cmssw: repos_names = repos_names + CMSSW_REPOS
if opts.cmsdist: repos_names = repos_names + CMSDIST_REPOS
gh = Github(login_or_token = open(expanduser("~/.github-token")).read().strip())
api_rate_limits(gh)
#get repos to be processed
repos = {}
for r in set(repos_names):
if not "/" in r:
for repo in gh.get_user(r).get_repos():
repos[repo.full_name]=repo
api_rate_limits(gh)
else:
repos[r]=None
#process repos
error = 0
for repo_name in repos:
print "Checking for repo ",repo_name
hooks = []
for r in REPO_HOOK_MAP:
if re.match(r[0],repo_name):
if opts.hook and opts.hook in r[1]:
hooks.append(opts.hook)
break
elif not opts.hook:
for h in r[1]: hooks.append(h)
break
if not hooks:
print "==>Warning: No hook found for repository",repo_name
error = 1
continue
err = 0
for h in hooks:
if not h in hk_conf:
print "==>Error: No hook name ",h," found for repository ",repo_name
err = 1
if err:
error = 1
continue
print "Found hooks:",hooks
repo = repos[repo_name]
if not repo: repo = gh.get_repo(repo_name)
repo_hooks_all = {}
for hook in repo.get_hooks():
if "name" in hook.config:
repo_hooks_all[ hook.config['name'] ] = hook
api_rate_limits(gh)
for hook in hooks:
print "checking for web hook" , hook
hook_conf = hk_conf[hook]
hook_conf["name"] = "web"
hook_conf["config"]["insecure_ssl"] = "1"
hook_conf["config"]["secret"] = get_secret(hook)
hook_conf["config"]["name"] = hook
hook_conf["config"]["data"] = hashlib.sha256(hook_conf["config"]["secret"].encode()).hexdigest()
if hook in repo_hooks_all:
old_hook = repo_hooks_all[hook]
if opts.force or not match_config(hook_conf,old_hook):
if not opts.dryRun:
old_hook.edit(**hook_conf)
api_rate_limits(gh)
print "hook updated"
else:
print "Hook configuration is same"
else:
if not opts.dryRun:
repo.create_hook(**hook_conf)
api_rate_limits(gh)
print "Hook created in github.....success"
exit(error)