Skip to content

Commit d23e08c

Browse files
authored
Script to mass-update bot cache in all issues (#2165)
* Script to mass-update bot cache in all open issues * Change logic after review * Add 'force' flag * Add comment * Changes from review * Fixes * Fix cache detection logic
1 parent 17f6a8e commit d23e08c

File tree

1 file changed

+135
-0
lines changed

1 file changed

+135
-0
lines changed

mass-update-cache.py

+135
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
#!/usr/bin/env python3
2+
import re
3+
import sys
4+
from argparse import ArgumentParser
5+
from os.path import dirname, abspath, join, exists
6+
from socket import setdefaulttimeout
7+
8+
import github
9+
10+
from cms_static import VALID_CMS_SW_REPOS_FOR_TESTS
11+
from github_utils import api_rate_limits, get_gh_token, set_gh_user
12+
from process_pr import (
13+
ISSUE_SEEN_MSG,
14+
CMSBOT_TECHNICAL_MSG,
15+
REGEX_COMMITS_CACHE,
16+
loads_maybe_decompress,
17+
)
18+
19+
# Copied from gh-teams.py
20+
CMS_ORGANIZATIONS = ["cms-data", "cms-externals", "cms-sw"]
21+
22+
setdefaulttimeout(120)
23+
24+
SCRIPT_DIR = dirname(abspath(sys.argv[0]))
25+
26+
27+
# Notice: can't use `process_pr.read_bot_cache` since it modifies bot cache before returning.
28+
# Another solution is to add a flag to `read_bot_cache` to load cache without adding missing keys
29+
def load_bot_cache_local(comment_msg):
30+
seen_commits_match = REGEX_COMMITS_CACHE.search(comment_msg)
31+
if seen_commits_match:
32+
print("Loading bot cache")
33+
res = loads_maybe_decompress(seen_commits_match[1])
34+
return res
35+
return {}
36+
37+
38+
def process_repo(gh, repo, args):
39+
res = []
40+
print("Using repository", repo.full_name)
41+
repo_name = repo.full_name
42+
repo_dir = join(SCRIPT_DIR, "repos", repo_name.replace("-", "_"))
43+
if exists(repo_dir):
44+
sys.path.insert(0, repo_dir)
45+
import repo_config
46+
47+
cmsbuild_user = repo_config.CMSBUILD_USER
48+
set_gh_user(cmsbuild_user)
49+
50+
if not getattr(repo_config, "RUN_DEFAULT_CMS_BOT", True):
51+
sys.exit(0)
52+
53+
for issue in repo.get_pulls(sort="updated", direction="desc", state="all"):
54+
print(" Processing PR#{0}: {1}".format(issue.number, issue.title))
55+
api_rate_limits(gh)
56+
bot_cache = None
57+
for comment in issue.get_issue_comments():
58+
if comment.user.login.encode("ascii", "ignore").decode() != cmsbuild_user:
59+
continue
60+
comment_msg = comment.body.encode("ascii", "ignore").decode() if comment.body else ""
61+
first_line = "".join(
62+
[line.strip() for line in comment_msg.split("\n") if line.strip()][0:1]
63+
)
64+
if re.match(CMSBOT_TECHNICAL_MSG, first_line):
65+
bot_cache = load_bot_cache_local(comment_msg)
66+
if bot_cache:
67+
print(" Read bot cache from already seen comment:", comment)
68+
break
69+
elif re.match(ISSUE_SEEN_MSG, first_line):
70+
bot_cache = load_bot_cache_local(comment_msg)
71+
if bot_cache:
72+
print(" Read bot cache from technical comment:", comment)
73+
break
74+
if bot_cache and ("commits" not in bot_cache):
75+
print(" PR needs to be reprocessed")
76+
# Notice: can't "just" call process_pr, since it modifies global variables :(
77+
# process_pr(repo_config, gh, repo, issue, args.dryrun, cmsbuild_user=None, force=False)
78+
res.append(
79+
"python3 process-pull-request.py --force "
80+
+ (" --dry-run " if args.dryrun else " ")
81+
+ "--repository "
82+
+ repo.full_name
83+
+ " "
84+
+ str(issue.number)
85+
)
86+
87+
if not bot_cache:
88+
print("No bot cache, stopping here")
89+
break
90+
91+
return res
92+
93+
94+
def main():
95+
parser = ArgumentParser()
96+
parser.add_argument("-n", "--dry-run", dest="dryrun", action="store_true")
97+
args = parser.parse_args()
98+
99+
gh = github.Github(login_or_token=get_gh_token())
100+
api_rate_limits(gh)
101+
cnt = 0
102+
103+
all_repos = []
104+
105+
for name in VALID_CMS_SW_REPOS_FOR_TESTS:
106+
all_repos.append("cms-sw/" + name)
107+
108+
for org in CMS_ORGANIZATIONS:
109+
if org == "cms-sw":
110+
continue
111+
112+
all_repos.extend(r.full_name for r in gh.get_organization(org).get_repos())
113+
114+
with open("runme.sh", "w") as f:
115+
for repo_name in all_repos:
116+
print("Getting repo", repo_name)
117+
try:
118+
repo = gh.get_repo(repo_name)
119+
except github.UnknownObjectException:
120+
continue
121+
res = process_repo(gh, repo, args)
122+
print("Writing {0} line(s) to script".format(len(res)))
123+
for line in res:
124+
print(line, file=f)
125+
126+
cnt += len(res)
127+
128+
if args.dryrun:
129+
print("Would update {0} PRs/Issues".format(cnt))
130+
else:
131+
print("Updated {0} PRs/Issues".format(cnt))
132+
133+
134+
if __name__ == "__main__":
135+
main()

0 commit comments

Comments
 (0)