17
17
from queue import Queue
18
18
import os
19
19
import sys
20
- from enum import IntEnum
20
+ from enum import IntEnum , Enum
21
21
import subprocess
22
22
from .git_helper import SSH_KEY_FILE
23
23
import shlex
@@ -115,7 +115,7 @@ class PullReqState:
115
115
delegate = ''
116
116
117
117
def __init__ (self , num , head_sha , status , db , repo_label , mergeable_que ,
118
- gh , owner , name , repos ):
118
+ gh , owner , name , label_events , repos ):
119
119
self .head_advanced ('' , use_db = False )
120
120
121
121
self .num = num
@@ -130,6 +130,7 @@ def __init__(self, num, head_sha, status, db, repo_label, mergeable_que,
130
130
self .repos = repos
131
131
self .timeout_timer = None
132
132
self .test_started = time .time ()
133
+ self .label_events = label_events
133
134
134
135
def head_advanced (self , head_sha , * , use_db = True ):
135
136
self .head_sha = head_sha
@@ -178,6 +179,21 @@ def get_issue(self):
178
179
def add_comment (self , text ):
179
180
self .get_issue ().create_comment (text )
180
181
182
+ def change_labels (self , event ):
183
+ event = self .label_events .get (event .value , {})
184
+ removes = event .get ('remove' , [])
185
+ adds = event .get ('add' , [])
186
+ unless = event .get ('unless' , [])
187
+ if not removes and not adds :
188
+ return
189
+
190
+ issue = self .get_issue ()
191
+ labels = {label .name for label in issue .iter_labels ()}
192
+ if labels .isdisjoint (unless ):
193
+ labels .difference_update (removes )
194
+ labels .update (adds )
195
+ issue .replace_labels (list (labels ))
196
+
181
197
def set_status (self , status ):
182
198
self .status = status
183
199
if self .timeout_timer :
@@ -347,6 +363,7 @@ def timed_out(self):
347
363
desc ,
348
364
context = 'homu' )
349
365
self .add_comment (':boom: {}' .format (desc ))
366
+ self .change_labels (LabelEvent .TIMED_OUT )
350
367
351
368
352
369
def sha_cmp (short , full ):
@@ -364,6 +381,21 @@ class AuthState(IntEnum):
364
381
NONE = 1
365
382
366
383
384
+ class LabelEvent (Enum ):
385
+ APPROVED = 'approved'
386
+ REJECTED = 'rejected'
387
+ CONFLICT = 'conflict'
388
+ SUCCEED = 'succeed'
389
+ FAILED = 'failed'
390
+ TRY = 'try'
391
+ TRY_SUCCEED = 'try_succeed'
392
+ TRY_FAILED = 'try_failed'
393
+ EXEMPTED = 'exempted'
394
+ TIMED_OUT = 'timed_out'
395
+ INTERRUPTED = 'interrupted'
396
+ PUSHED = 'pushed'
397
+
398
+
367
399
def verify_auth (username , repo_cfg , state , auth , realtime , my_username ):
368
400
# In some cases (e.g. non-fully-qualified r+) we recursively talk to
369
401
# ourself via a hidden markdown comment in the message. This is so that
@@ -534,15 +566,17 @@ def parse_commands(body, username, repo_cfg, state, my_username, db, states,
534
566
':evergreen_tree: The tree is currently closed for pull requests below priority {}, this pull request will be tested once the tree is reopened' # noqa
535
567
.format (treeclosed )
536
568
)
569
+ state .change_labels (LabelEvent .APPROVED )
537
570
538
571
elif word == 'r-' :
539
572
if not verify_auth (username , repo_cfg , state , AuthState .REVIEWER ,
540
573
realtime , my_username ):
541
574
continue
542
575
543
576
state .approved_by = ''
544
-
545
577
state .save ()
578
+ if realtime :
579
+ state .change_labels (LabelEvent .REJECTED )
546
580
547
581
elif word .startswith ('p=' ):
548
582
if not verify_auth (username , repo_cfg , state , AuthState .TRY ,
@@ -601,6 +635,9 @@ def parse_commands(body, username, repo_cfg, state, my_username, db, states,
601
635
if not _try_auth_verified ():
602
636
continue
603
637
state .set_status ('' )
638
+ if realtime :
639
+ event = LabelEvent .TRY if state .try_ else LabelEvent .APPROVED
640
+ state .change_labels (event )
604
641
605
642
elif word in ['try' , 'try-' ] and realtime :
606
643
if not _try_auth_verified ():
@@ -611,6 +648,10 @@ def parse_commands(body, username, repo_cfg, state, my_username, db, states,
611
648
state .init_build_res ([])
612
649
613
650
state .save ()
651
+ if realtime and state .try_ :
652
+ # `try-` just resets the `try` bit and doesn't correspond to
653
+ # any meaningful labeling events.
654
+ state .change_labels (LabelEvent .TRY )
614
655
615
656
elif word in ['rollup' , 'rollup-' ]:
616
657
if not _try_auth_verified ():
@@ -924,6 +965,7 @@ def create_merge(state, repo_cfg, branch, logger, git_cfg,
924
965
context = 'homu' )
925
966
926
967
state .add_comment (':lock: ' + desc )
968
+ state .change_labels (LabelEvent .CONFLICT )
927
969
928
970
return ''
929
971
@@ -979,6 +1021,7 @@ def do_exemption_merge(state, logger, repo_cfg, git_cfg, url, check_merge,
979
1021
utils .github_create_status (state .get_repo (), state .head_sha , 'success' ,
980
1022
url , desc , context = 'homu' )
981
1023
state .add_comment (':zap: {}: {}.' .format (desc , reason ))
1024
+ state .change_labels (LabelEvent .EXEMPTED )
982
1025
983
1026
state .merge_sha = merge_sha
984
1027
state .save ()
@@ -1343,6 +1386,7 @@ def fetch_mergeability(mergeable_que):
1343
1386
state .add_comment (':umbrella: The latest upstream changes{} made this pull request unmergeable. Please resolve the merge conflicts.' .format ( # noqa
1344
1387
_blame
1345
1388
))
1389
+ state .change_labels (LabelEvent .CONFLICT )
1346
1390
1347
1391
state .set_mergeable (mergeable , que = False )
1348
1392
@@ -1388,7 +1432,7 @@ def synchronize(repo_label, repo_cfg, logger, gh, states, repos, db, mergeable_q
1388
1432
status = info .state
1389
1433
break
1390
1434
1391
- state = PullReqState (pull .number , pull .head .sha , status , db , repo_label , mergeable_que , gh , repo_cfg ['owner' ], repo_cfg ['name' ], repos ) # noqa
1435
+ state = PullReqState (pull .number , pull .head .sha , status , db , repo_label , mergeable_que , gh , repo_cfg ['owner' ], repo_cfg ['name' ], repo_cfg . get ( 'labels' , {}), repos ) # noqa
1392
1436
state .title = pull .title
1393
1437
state .body = pull .body
1394
1438
state .head_ref = pull .head .repo [0 ] + ':' + pull .head .ref
@@ -1557,7 +1601,7 @@ def main():
1557
1601
'SELECT num, head_sha, status, title, body, head_ref, base_ref, assignee, approved_by, priority, try_, rollup, delegate, merge_sha FROM pull WHERE repo = ?' , # noqa
1558
1602
[repo_label ])
1559
1603
for num , head_sha , status , title , body , head_ref , base_ref , assignee , approved_by , priority , try_ , rollup , delegate , merge_sha in db .fetchall (): # noqa
1560
- state = PullReqState (num , head_sha , status , db , repo_label , mergeable_que , gh , repo_cfg ['owner' ], repo_cfg ['name' ], repos ) # noqa
1604
+ state = PullReqState (num , head_sha , status , db , repo_label , mergeable_que , gh , repo_cfg ['owner' ], repo_cfg ['name' ], repo_cfg . get ( 'labels' , {}), repos ) # noqa
1561
1605
state .title = title
1562
1606
state .body = body
1563
1607
state .head_ref = head_ref
0 commit comments