forked from cms-sw/cms-bot
-
Notifications
You must be signed in to change notification settings - Fork 0
/
process-cmsdist-request
executable file
·144 lines (123 loc) · 4.71 KB
/
process-cmsdist-request
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
#!/usr/bin/env python
from github import Github
from os.path import expanduser
from optparse import OptionParser
import yaml
import re
from sys import exit
from releases import RELEASE_MANAGERS
import itertools
# Prepare various comments regardless of whether they will be made or not.
def format(s, **kwds):
return s % kwds
#
# Update the labels settint the ones that the issue should have
# If the issue has no labels, it assings the label 'tests-pending'
#
def updateLabels( issue, pr ):
old_labels = set([ l.name for l in issue.get_labels() ])
new_labels = set( old_labels )
if not old_labels:
new_labels.add( "tests-pending" )
# Copied from process-pull-request
last_commit_date = None
try:
# This requires at least PyGithub 1.23.0. Making it optional for the moment.
last_commit_date = pr.get_commits().reversed[0].commit.committer.date
except:
# This seems to fail for more than 250 commits. Not sure if the
# problem is github itself or the bindings.
last_commit_date = pr.get_commits()[pr.commits - 1].commit.committer.date
new_tests_label = None
for comment in issue.get_comments():
comment_date = comment.created_at
commenter = comment.user.login
if comment_date < last_commit_date:
print "Ignoring comment done before the last commit."
pull_request_updated = True
continue
first_line = str(comment.body.encode("ascii", "ignore").split("\n")[0].strip("\n\t\r "))
all_release_managers = set( list(itertools.chain.from_iterable(RELEASE_MANAGERS.values())) + [ 'cmsbuild' ] )
if commenter in all_release_managers:
if re.match("^[+](1|test|tested)$", first_line):
new_labels.discard( "tests-pending" )
new_labels.discard( "tests-rejected" )
new_labels.add( "tests-approved" )
elif re.match("^[-](1|test|tested)$", first_line):
new_labels.discard( "tests-pending" )
new_labels.discard( "tests-approved" )
new_labels.add( "tests-rejected" )
if old_labels == new_labels:
print 'labels unchanged'
else:
remove_labels( issue )
add_labels_list( issue, list( new_labels ) )
# Update the milestone for a given issue.
# - If the issue already has a milestone, do not bother.
# - Get the name of the release queue and construct a milestone name
# - Get the list of all milestones and check if the milestone name is already there.
# - If not create a milestone
# - If yes assign the issue to the milestone.
def updateMilestone(repo, issue, pr):
if issue.milestone:
return
branch = pr.base.label.split(":")[1]
IS_CMSDIST_RE="IB/(CMSSW[^/]*)/[^/]+$"
m = re.match(IS_CMSDIST_RE, branch)
if not m:
return
milestoneName = "Next " + m.group(1)
milestones = repo.get_milestones(state="open")
for milestone in milestones:
if milestone.title == milestoneName:
if opts.dryRun:
print "Not assigning to milestone (dry-run): " + str(milestone.number)
return
print "Assign to milestone " + str(milestone.number)
issue.edit(milestone=milestone)
return
print "Creating milestone " + milestoneName
milestone = repo.create_milestone(title=milestoneName)
issue.edit(milestone=milestone)
# Adds a label to the issue in github
# if dry-run is selected it doesn't add the label and just prints it
def add_label( issue, label ):
if opts.dryRun:
print 'Not adding label (dry-run):\n %s' % label
return
print 'Adding label:\n %s' % label
issue.add_to_labels( label )
# Adds the labels to the issue on gthub from the list passed as parameter
def add_labels_list( issue, new_labels_list ):
if opts.dryRun:
print 'Not adding labels (dry-run):\n %s' % ",".join( new_labels_list )
return
print 'Adding labels:\n %s' % ",".join( new_labels_list )
issue.add_to_labels( *new_labels_list )
#
# removes all the labels of the issue
#
def remove_labels( issue ):
if opts.dryRun:
print 'Not removing issue labels (dry-run)'
return
print 'Removing Labels'
issue.delete_labels()
IS_CMSDIST_RE="IB/(CMSSW[^/]*)/[^/]+$"
if __name__ == "__main__":
parser = OptionParser(usage="%prog [-n|--dry-run] <pull-request-id>")
parser.add_option("-n", "--dry-run", dest="dryRun", action="store_true", help="Do not modify Github", default=False)
opts, args = parser.parse_args()
if len(args) != 1:
parser.error("Too many arguments")
prId = int(args[0])
gh = Github(login_or_token=open(expanduser("~/.github-token")).read().strip())
try:
pr = gh.get_organization("cms-sw").get_repo("cmsdist").get_pull(prId)
except:
print "Could not find pull request. Maybe this is an issue"
exit(0)
repo = gh.get_organization("cms-sw").get_repo("cmsdist")
issue = repo.get_issue(prId)
updateMilestone(repo, issue, pr)
updateLabels( issue, pr )