Title: [291186] trunk/Tools
Revision
291186
Author
jbed...@apple.com
Date
2022-03-11 13:51:35 -0800 (Fri, 11 Mar 2022)

Log Message

[Merge-Queue] Check for merge-queue labels
https://bugs.webkit.org/show_bug.cgi?id=237690
<rdar://problem/90064892>

Reviewed by Aakash Jain.

* Tools/CISupport/ews-build/steps.py:
(GitHubMixin):
(GitHubMixin.get_pr_json): Add retry.
(GitHubMixin._is_pr_in_merge_queue): Check for merge-queue label.
(GitHubMixin.should_send_email_for_pr): get_pr_json now owns logging.
(ValidateChange.__init__): Add verifyMergeQueue flag.
(ValidateChange):
(ValidateChange.start): Add log to indicate PR has a merge-queue flag.
(ValidateChange.validate_github): Add retry when getting PR json, add merge queue check.
* Tools/CISupport/ews-build/steps_unittest.py:

Canonical link: https://commits.webkit.org/248345@main

Modified Paths

Diff

Modified: trunk/Tools/CISupport/ews-build/steps.py (291185 => 291186)


--- trunk/Tools/CISupport/ews-build/steps.py	2022-03-11 21:25:32 UTC (rev 291185)
+++ trunk/Tools/CISupport/ews-build/steps.py	2022-03-11 21:51:35 UTC (rev 291186)
@@ -141,6 +141,8 @@
     pr_open_states = ['open']
     pr_closed_states = ['closed']
     BLOCKED_LABEL = 'merging-blocked'
+    MERGE_QUEUE_LABEL = 'merge-queue'
+    FAST_MERGE_QUEUE_LABEL = 'fast-merge-queue'
 
     def fetch_data_from_url_with_authentication(self, url):
         response = None
@@ -160,7 +162,7 @@
             return None
         return response
 
-    def get_pr_json(self, pr_number, repository_url=None):
+    def get_pr_json(self, pr_number, repository_url=None, retry=0):
         api_url = GitHub.api_url(repository_url)
         if not api_url:
             return None
@@ -169,15 +171,24 @@
         content = self.fetch_data_from_url_with_authentication(pr_url)
         if not content:
             return None
-        try:
-            pr_json = content.json()
-        except Exception as e:
-            print('Failed to get pull request data from {}, error: {}'.format(pr_url, e))
-            return None
-        if not pr_json or len(pr_json) == 0:
-            return None
-        return pr_json
 
+        for attempt in range(retry + 1):
+            try:
+                pr_json = content.json()
+                if pr_json and len(pr_json):
+                    return pr_json
+            except Exception as e:
+                self._addToLog('stdio', 'Failed to get pull request data from {}, error: {}'.format(pr_url, e))
+            
+            self._addToLog('stdio', 'Unable to fetch pull request {}.\n'.format(pr_number))
+            if attempt > retry:
+                return None
+            wait_for = (index + 1) * 15
+            self._addToLog('stdio', 'Backing off for {} seconds before retrying.\n'.format(wait_for))
+            time.sleep(wait_for)
+
+        return None
+
     def _is_pr_closed(self, pr_json):
         if not pr_json or not pr_json.get('state'):
             self._addToLog('stdio', 'Cannot determine pull request status.\n')
@@ -199,10 +210,15 @@
                 return 1
         return 0
 
+    def _is_pr_in_merge_queue(self, pr_json):
+        for label in (pr_json or {}).get('labels', {}):
+            if label.get('name', '') in (self.MERGE_QUEUE_LABEL, self.FAST_MERGE_QUEUE_LABEL):
+                return 1
+        return 0
+
     def should_send_email_for_pr(self, pr_number):
         pr_json = self.get_pr_json(pr_number)
         if not pr_json:
-            self._addToLog('stdio', 'Unable to fetch PR #{}\n'.format(pr_number))
             return True
 
         if 1 == self._is_hash_outdated(pr_json):
@@ -1218,11 +1234,20 @@
     flunkOnFailure = True
     haltOnFailure = True
 
-    def __init__(self, verifyObsolete=True, verifyBugClosed=True, verifyReviewDenied=True, addURLs=True, verifycqplus=False):
+    def __init__(
+        self,
+        verifyObsolete=True,
+        verifyBugClosed=True,
+        verifyReviewDenied=True,
+        addURLs=True,
+        verifycqplus=False,
+        verifyMergeQueue=False,
+    ):
         self.verifyObsolete = verifyObsolete
         self.verifyBugClosed = verifyBugClosed
         self.verifyReviewDenied = verifyReviewDenied
         self.verifycqplus = verifycqplus
+        self.verifyMergeQueue = verifyMergeQueue
         self.addURLs = addURLs
         buildstep.BuildStep.__init__(self)
 
@@ -1271,6 +1296,8 @@
         if self.verifycqplus and patch_id:
             self._addToLog('stdio', 'Change is in commit queue.\n')
             self._addToLog('stdio', 'Change has been reviewed.\n')
+        if self.verifyMergeQueue and pr_number:
+            self._addToLog('stdio', 'Change is in merge queue.\n')
         self.finished(SUCCESS)
         return None
 
@@ -1312,11 +1339,8 @@
             return False
 
         repository_url = self.getProperty('repository', '')
+        pr_json = self.get_pr_json(pr_number, repository_url, retry=3)
 
-        pr_json = self.get_pr_json(pr_number, repository_url)
-        if not pr_json:
-            self._addToLog('stdio', 'Unable to fetch pull request {}.\n'.format(pr_number))
-
         pr_closed = self._is_pr_closed(pr_json) if self.verifyBugClosed else 0
         if pr_closed == 1:
             self.skip_build('Pull request {} is already closed'.format(pr_number))
@@ -1332,7 +1356,12 @@
             self.skip_build("PR {} has been marked as '{}'".format(pr_number, self.BLOCKED_LABEL))
             return False
 
-        if -1 in (obsolete, pr_closed, blocked):
+        merge_queue = self._is_pr_in_merge_queue(pr_json) if self.verifyMergeQueue else 1
+        if merge_queue == 0:
+            self.skip_build("PR {} does not have a merge queue label".format(pr_number))
+            return False
+
+        if -1 in (obsolete, pr_closed, blocked, merge_queue):
             self.finished(WARNINGS)
             return False
 

Modified: trunk/Tools/CISupport/ews-build/steps_unittest.py (291185 => 291186)


--- trunk/Tools/CISupport/ews-build/steps_unittest.py	2022-03-11 21:25:32 UTC (rev 291185)
+++ trunk/Tools/CISupport/ews-build/steps_unittest.py	2022-03-11 21:51:35 UTC (rev 291186)
@@ -5001,7 +5001,7 @@
                      "is_patch": 1,
                      "summary": "{}"}}'''.format(obsolete, title))
 
-    def get_pr(self, pr_number, title='Sample pull request', closed=False):
+    def get_pr(self, pr_number, title='Sample pull request', closed=False, labels=None):
         return dict(
             number=pr_number,
             state='closed' if closed else 'open',
@@ -5021,7 +5021,7 @@
                     name='WebKit',
                     full_name='WebKit/WebKit',
                 ),
-            ),
+            ), labels=[dict(name=label) for label in labels or []],
         )
 
     def test_skipped_patch(self):
@@ -5051,7 +5051,7 @@
 
     def test_success_pr(self):
         self.setupStep(ValidateChange(verifyBugClosed=False))
-        ValidateChange.get_pr_json = lambda x, pull_request, repository_url=None: self.get_pr(pr_number=pull_request)
+        ValidateChange.get_pr_json = lambda x, pull_request, repository_url=None, retry=None: self.get_pr(pr_number=pull_request)
         self.setProperty('github.number', '1234')
         self.setProperty('repository', 'https://github.com/WebKit/WebKit')
         self.setProperty('github.head.sha', '7496f8ecc4cc8011f19c8cc1bc7b18fe4a88ad5c')
@@ -5071,7 +5071,7 @@
 
     def test_obsolete_pr(self):
         self.setupStep(ValidateChange(verifyBugClosed=False))
-        ValidateChange.get_pr_json = lambda x, pull_request, repository_url=None: self.get_pr(pr_number=pull_request)
+        ValidateChange.get_pr_json = lambda x, pull_request, repository_url=None, retry=None: self.get_pr(pr_number=pull_request)
         self.setProperty('github.number', '1234')
         self.setProperty('repository', 'https://github.com/WebKit/WebKit')
         self.setProperty('github.head.sha', '1ad60d45a112301f7b9f93dac06134524dae8480')
@@ -5091,7 +5091,29 @@
             self.assertEqual(self.getProperty('fast_commit_queue'), True, f'fast_commit_queue is not set, patch title: {fast_cq_patch_title}')
         return rc
 
+    def test_merge_queue(self):
+        self.setupStep(ValidateChange(verifyMergeQueue=True))
+        ValidateChange.get_pr_json = lambda x, pull_request, repository_url=None, retry=None: self.get_pr(pr_number=pull_request, labels=['merge-queue'])
+        self.setProperty('github.number', '1234')
+        self.setProperty('repository', 'https://github.com/WebKit/WebKit')
+        self.setProperty('github.head.sha', '7496f8ecc4cc8011f19c8cc1bc7b18fe4a88ad5c')
+        self.expectOutcome(result=SUCCESS, state_string='Validated change')
+        rc = self.runStep()
+        self.assertEqual(self.getProperty('fast_commit_queue'), None, 'fast_commit_queue is unexpectedly set')
+        return rc
 
+    def test_no_merge_queue(self):
+        self.setupStep(ValidateChange(verifyMergeQueue=True))
+        ValidateChange.get_pr_json = lambda x, pull_request, repository_url=None, retry=None: self.get_pr(pr_number=pull_request)
+        self.setProperty('github.number', '1234')
+        self.setProperty('repository', 'https://github.com/WebKit/WebKit')
+        self.setProperty('github.head.sha', '7496f8ecc4cc8011f19c8cc1bc7b18fe4a88ad5c')
+        self.expectOutcome(result=FAILURE, state_string='PR 1234 does not have a merge queue label')
+        rc = self.runStep()
+        self.assertEqual(self.getProperty('fast_commit_queue'), None, 'fast_commit_queue is unexpectedly set')
+        return rc
+
+
 class TestValidateCommiterAndReviewer(BuildStepMixinAdditions, unittest.TestCase):
     def setUp(self):
         self.longMessage = True

Modified: trunk/Tools/ChangeLog (291185 => 291186)


--- trunk/Tools/ChangeLog	2022-03-11 21:25:32 UTC (rev 291185)
+++ trunk/Tools/ChangeLog	2022-03-11 21:51:35 UTC (rev 291186)
@@ -1,3 +1,22 @@
+2022-03-11  Jonathan Bedard  <jbed...@apple.com>
+
+        [Merge-Queue] Check for merge-queue labels
+        https://bugs.webkit.org/show_bug.cgi?id=237690
+        <rdar://problem/90064892>
+
+        Reviewed by Aakash Jain.
+
+        * CISupport/ews-build/steps.py:
+        (GitHubMixin):
+        (GitHubMixin.get_pr_json): Add retry.
+        (GitHubMixin._is_pr_in_merge_queue): Check for merge-queue label.
+        (GitHubMixin.should_send_email_for_pr): get_pr_json now owns logging.
+        (ValidateChange.__init__): Add verifyMergeQueue flag.
+        (ValidateChange):
+        (ValidateChange.start): Add log to indicate PR has a merge-queue flag.
+        (ValidateChange.validate_github): Add retry when getting PR json, add merge queue check.
+        * CISupport/ews-build/steps_unittest.py:
+
 2022-03-11  Wenson Hsieh  <wenson_hs...@apple.com>
 
         [iOS] Add support for -[UITextInput removeEmojiAlternatives] on WKContentView
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to