Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do not reset all labels on commit #2110

Merged
merged 46 commits into from
Dec 13, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
a2740af
Do not reset all labels on commit
iarspider Nov 9, 2023
c54ca81
Add pyproject.toml with Black and pylint configs
iarspider Nov 9, 2023
da8903e
Changes from review
iarspider Nov 9, 2023
3c20811
Changes from review (1/2)
iarspider Nov 10, 2023
ec2bd46
Changes from review (2/2)
iarspider Nov 11, 2023
5942437
Code-style
iarspider Nov 11, 2023
161a818
Fixes after tests
iarspider Nov 13, 2023
015fa63
Fix style
iarspider Nov 13, 2023
18faffb
Fix initial comment generation (watchers + categories)
iarspider Nov 14, 2023
75f7817
Update process_pr.py
iarspider Nov 15, 2023
82f51ed
Move get_last_commit and get_pr_commits_reversed to github_utils
iarspider Nov 16, 2023
1fe6a65
Code-format
iarspider Nov 16, 2023
7a2145e
Code-format
iarspider Nov 16, 2023
995050b
Fix too-many-commits handling
iarspider Nov 20, 2023
d785a37
Convert packages to categories; fix timestamp handling
iarspider Nov 24, 2023
758e56a
Use API to get list of changed files
iarspider Nov 24, 2023
9ac15d3
Fix tests, code-checks signatures; restorre special handling for ORP …
iarspider Dec 1, 2023
c057d8e
Move code to determine signing-cats back to where it was
iarspider Dec 1, 2023
e5bc0f7
Remove extra check
iarspider Dec 1, 2023
0ee9c9e
Change wording
iarspider Dec 1, 2023
042b550
Remove extra formatting
iarspider Dec 4, 2023
1138c0b
Fix extra braces
iarspider Dec 4, 2023
417d609
Reset all signatures on commit in external/user repos
iarspider Dec 4, 2023
a223925
Do not trigger tests on code-checks signature
iarspider Dec 6, 2023
2657914
Exclude orp and tests as well
iarspider Dec 6, 2023
c97e309
Check for rate-limits before checking for / loading commit cache
iarspider Dec 6, 2023
3aee759
Apply suggestions from code-review
iarspider Dec 6, 2023
0cb4fe9
More changes from review
iarspider Dec 6, 2023
a39283a
Compress commit cache as needed; handle commits with many changed files
iarspider Dec 6, 2023
98e9500
Reset signatures for manually-assigned categories on commit; other ch…
iarspider Dec 6, 2023
5fcd33c
Missed one comment
iarspider Dec 6, 2023
5f4f844
Fix for github_utils
iarspider Dec 7, 2023
fc24b32
Fix for fix for github_utils
iarspider Dec 7, 2023
7539456
Check rates at every call to github_api()
iarspider Dec 7, 2023
77095be
Changes from review
iarspider Dec 7, 2023
4b453f0
Only check commits if the issue is a PR
iarspider Dec 7, 2023
6a22185
Hack to set tests signature to pending
iarspider Dec 7, 2023
c8530bb
Don't recalculate tests signature
iarspider Dec 11, 2023
524a16f
Remove dead branch
iarspider Dec 11, 2023
2e1d4ce
Changes from review
iarspider Dec 11, 2023
4f43741
Fix
iarspider Dec 12, 2023
2654bf7
Fix for fix
iarspider Dec 12, 2023
712cb46
Changes from review
iarspider Dec 12, 2023
377fa08
Add protection from printing non-ascii characters
iarspider Dec 12, 2023
d29f967
reset test_comment on every new commit
smuzaffar Dec 12, 2023
95d76a0
Update process-pull-request.py
smuzaffar Dec 12, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cms_static.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
CMSBUILD_GH_USER = "cmsbuild"
CMSBOT_IGNORE_MSG = "<cmsbot>\s*</cmsbot>"
CMSBOT_NO_NOTIFY_MSG = "<notify>\s*</notify>"
CMSBOT_TECHNICAL_MSG = "cms-bot internal usage"
VALID_CMS_SW_REPOS_FOR_TESTS = [
"cmssw",
"cmsdist",
Expand Down
182 changes: 144 additions & 38 deletions process_pr.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
CMSBOT_IGNORE_MSG,
VALID_CMS_SW_REPOS_FOR_TESTS,
CREATE_REPO,
CMSBOT_TECHNICAL_MSG,
)
from cms_static import BACKPORT_STR, GH_CMSSW_ORGANIZATION, CMSBOT_NO_NOTIFY_MSG
from githublabels import TYPE_COMMANDS, TEST_IGNORE_REASON
Expand All @@ -32,7 +33,7 @@
from github_utils import set_comment_emoji, get_comment_emojis, delete_comment_emoji, set_gh_user
from socket import setdefaulttimeout
from _py2with3compatibility import run_cmd
from json import dumps, load
from json import dumps, load, loads

try:
from categories import CMSSW_LABELS
Expand Down Expand Up @@ -125,6 +126,7 @@ def format(s, **kwds):
r"^\s*(?:(?:@|)cmsbuild\s*[,]*\s+|)(?:please\s*[,]*\s+|)ignore\s+tests-rejected\s+(?:with|)([a-z -]+)$",
re.I,
)
REGEX_COMMITS_SEEN = re.compile(r"<!-- commits cache: (.*) -->")
TEST_WAIT_GAP = 720
ALL_CHECK_FUNCTIONS = None
EXTRA_RELVALS_TESTS = ["threading", "gpu", "high-stats", "nano"]
Expand Down Expand Up @@ -204,18 +206,35 @@ def get_commenter_categories(commenter, comment_date):


def get_last_commit(pr):
last_commit = None
commits_ = get_pr_commits_reversed(pr)
if commits_:
return commits_[-1]
else:
return None


def get_changed_files_in_commit(repo, commit_obj):
commit = repo.get_commit(commit_obj.commit.sha)
return [x.filename for x in commit.files]


def get_pr_commits_reversed(pr):
"""

:param pr:
:return: PaginatedList[Commit] | List[Commit]
"""
try:
# This requires at least PyGithub 1.23.0. Making it optional for the moment.
last_commit = pr.get_commits().reversed[0]
except:
return pr.get_commits().reversed
except: # noqa
# This seems to fail for more than 250 commits. Not sure if the
# problem is github itself or the bindings.
try:
last_commit = pr.get_commits()[pr.commits - 1]
return reversed(list(pr.get_commits()))
except IndexError:
print("Index error: May be PR with no commits")
return last_commit
return []


def get_package_categories(package):
Expand Down Expand Up @@ -666,6 +685,10 @@ def get_status_state(context, statuses):
return ""


def dumps_compact(value):
return dumps(value, separators=(",", ":"))
iarspider marked this conversation as resolved.
Show resolved Hide resolved


def process_pr(repo_config, gh, repo, issue, dryRun, cmsbuild_user=None, force=False):
global L2_DATA
if (not force) and ignore_issue(repo_config, repo, issue):
Expand Down Expand Up @@ -740,6 +763,11 @@ def process_pr(repo_config, gh, repo, issue, dryRun, cmsbuild_user=None, force=F
# For future pre_checks
# if prId>=somePRNumber: default_pre_checks+=["some","new","checks"]
pre_checks_url = {}

events = {}
commit_cache = {}
all_commits = []

if issue.pull_request:
pr = repo.get_pull(prId)
if pr.changed_files == 0:
Expand Down Expand Up @@ -870,8 +898,12 @@ def process_pr(repo_config, gh, repo, issue, dryRun, cmsbuild_user=None, force=F
watchers.update(set(watchingGroups[watcher]))
watchers = set([gh_user_char + u for u in watchers])
print("Watchers " + ", ".join(watchers))
last_commit_obj = get_last_commit(pr)
if last_commit_obj is None:
all_commits = get_pr_commits_reversed(pr)
for commit in all_commits:
events[commit.commit.committer.date] = get_changed_files_in_commit(repo, commit)
if all_commits:
last_commit_obj = all_commits[0]
else:
return
last_commit = last_commit_obj.commit
commit_statuses = last_commit_obj.get_combined_status().statuses
Expand Down Expand Up @@ -944,6 +976,7 @@ def process_pr(repo_config, gh, repo, issue, dryRun, cmsbuild_user=None, force=F
)
print("Pre check status:", pre_checks_state)
already_seen = None
technical_comment = None
pull_request_updated = False
comparison_done = False
comparison_notrun = False
Expand Down Expand Up @@ -1003,6 +1036,9 @@ def process_pr(repo_config, gh, repo, issue, dryRun, cmsbuild_user=None, force=F
pull_request_updated = True
continue

if (commenter == cmsbuild_user) and re.match(CMSBOT_TECHNICAL_MSG, first_line):
iarspider marked this conversation as resolved.
Show resolved Hide resolved
technical_comment = comment

iarspider marked this conversation as resolved.
Show resolved Hide resolved
assign_type, new_cats = get_assign_categories(first_line)
if new_cats:
if (assign_type == "new categories assigned:") and (commenter == cmsbuild_user):
Expand Down Expand Up @@ -1115,6 +1151,40 @@ def process_pr(repo_config, gh, repo, issue, dryRun, cmsbuild_user=None, force=F
if m.group(2):
code_check_apply_patch = True

new_signatures = {}
# Check L2 signoff for users in this PR signing categories
if [x for x in commenter_categories if x in signing_categories]:
ctype = ""
selected_cats = []
if re.match("^([+]1|approve[d]?|sign|signed)$", first_line, re.I):
ctype = "+1"
selected_cats = commenter_categories
elif re.match("^([-]1|reject|rejected)$", first_line, re.I):
ctype = "-1"
selected_cats = commenter_categories
elif re.match("^[+-][a-z][a-z0-9-]+$", first_line, re.I):
category_name = first_line[1:].lower()
if category_name in commenter_categories:
ctype = first_line[0] + "1"
selected_cats = [category_name]
if ctype == "+1":
for sign in selected_cats:
new_signatures[sign] = "approved"
if (test_comment is None) and (
(repository in auto_test_repo) or ("*" in auto_test_repo)
):
test_comment = comment
if sign == "orp":
mustClose = False
elif ctype == "-1":
for sign in selected_cats:
new_signatures[sign] = "rejected"
if sign == "orp":
mustClose = False

if new_signatures:
events[comment.created_at] = {"type": "sign", "value": new_signatures}

# Ignore all other messages which are before last commit.
if issue.pull_request and (comment.created_at < last_commit_date):
continue
Expand Down Expand Up @@ -1255,38 +1325,74 @@ def process_pr(repo_config, gh, repo, issue, dryRun, cmsbuild_user=None, force=F
if not dryRun:
set_comment_emoji(comment.id, repository)

# Check L2 signoff for users in this PR signing categories
if [x for x in commenter_categories if x in signing_categories]:
ctype = ""
selected_cats = []
if re.match("^([+]1|approve[d]?|sign|signed)$", first_line, re.I):
ctype = "+1"
selected_cats = commenter_categories
elif re.match("^([-]1|reject|rejected)$", first_line, re.I):
ctype = "-1"
selected_cats = commenter_categories
elif re.match("^[+-][a-z][a-z0-9-]+$", first_line, re.I):
category_name = first_line[1:].lower()
if category_name in commenter_categories:
ctype = first_line[0] + "1"
selected_cats = [category_name]
if ctype == "+1":
for sign in selected_cats:
signatures[sign] = "approved"
if (test_comment is None) and (
(repository in auto_test_repo) or ("*" in auto_test_repo)
):
test_comment = comment
if sign == "orp":
mustClose = False
elif ctype == "-1":
for sign in selected_cats:
signatures[sign] = "rejected"
if sign == "orp":
mustClose = False

# end of parsing comments section

# Get the commit cache from `already_seen` commit or technical commit
print("Recalculating signatures")
cache_comment = None
new_comment = False
iarspider marked this conversation as resolved.
Show resolved Hide resolved

if technical_comment:
cache_comment = technical_comment
else:
if already_seen:
cache_comment = already_seen
else:
new_comment = True
# if not dryRun:
# cache_comment = issue.create_comment(CMSBOT_TECHNICAL_MSG + "\n")

if cache_comment:
print("Loading commit cache")
seen_commits_match = REGEX_COMMITS_SEEN.search(cache_comment.body)
if seen_commits_match:
commit_cache = loads(seen_commits_match[1])

old_body = cache_comment.body if cache_comment else CMSBOT_TECHNICAL_MSG
new_body = REGEX_COMMITS_SEEN.sub(
"<!-- commits cache: " + dumps_compact(commit_cache) + " -->", old_body
)

if not dryRun:
if new_comment:
issue.create_comment(new_body)
else:
cache_comment.edit(new_body)
iarspider marked this conversation as resolved.
Show resolved Hide resolved
else:
if new_comment:
print("DRY RUN: Creating technical comment with text")
print(new_body)
else:
print("DRY RUN: Updating existing comment with text")
print(new_body)

for commit in all_commits:
if commit.sha not in commit_cache:
commit_cache[commit.sha] = {
"time": int(commit.commit.committer.date.timestamp()),
"files": get_changed_files_in_commit(repo, commit),
}

iarspider marked this conversation as resolved.
Show resolved Hide resolved
cache_entry = commit_cache[commit.sha]
events[datetime.fromtimestamp(cache_entry["time"])] = {
"type": "commit",
"value": cache_entry["files"],
}

events = dict(sorted(events.items()))

for event in events.values():
if event["type"] == "sign":
for cat, sign in event["value"].items():
signatures[cat] = sign
elif event["type"] == "commit":
chg_categories = [
x for x in set(cmssw_file2Package(repo_config, f) for f in event["value"])
]
signatures["orp"] = "pending"
for cat in chg_categories:
signatures[cat] = "pending"

if push_test_issue:
auto_close_push_test_issue = True
try:
Expand Down
Loading
Loading