Modified: trunk/Tools/BuildSlaveSupport/ews-build/factories.py (239649 => 239650)
--- trunk/Tools/BuildSlaveSupport/ews-build/factories.py 2019-01-05 01:23:52 UTC (rev 239649)
+++ trunk/Tools/BuildSlaveSupport/ews-build/factories.py 2019-01-05 02:30:03 UTC (rev 239650)
@@ -35,6 +35,7 @@
self.addStep(ConfigureBuild(platform, configuration, architectures, buildOnly, additionalArguments))
if checkRelevance:
self.addStep(CheckPatchRelevance())
+ self.addStep(ValidatePatch())
self.addStep(CheckOutSource())
self.addStep(ApplyPatch())
Modified: trunk/Tools/BuildSlaveSupport/ews-build/steps.py (239649 => 239650)
--- trunk/Tools/BuildSlaveSupport/ews-build/steps.py 2019-01-05 01:23:52 UTC (rev 239649)
+++ trunk/Tools/BuildSlaveSupport/ews-build/steps.py 2019-01-05 02:30:03 UTC (rev 239650)
@@ -28,6 +28,7 @@
from twisted.internet import defer
import re
+import requests
BUG_SERVER_URL = 'https://bugs.webkit.org/'
EWS_URL = 'http://ews-build.webkit-uat.org/'
@@ -221,6 +222,137 @@
return None
+class ValidatePatch(buildstep.BuildStep):
+ name = 'validate-patch'
+ description = ['validate-patch running']
+ descriptionDone = ['validate-patch']
+ flunkOnFailure = True
+ haltOnFailure = True
+ bug_open_statuses = ["UNCONFIRMED", "NEW", "ASSIGNED", "REOPENED"]
+ bug_closed_statuses = ["RESOLVED", "VERIFIED", "CLOSED"]
+
+ @defer.inlineCallbacks
+ def _addToLog(self, logName, message):
+ try:
+ log = self.getLog(logName)
+ except KeyError:
+ log = yield self.addLog(logName)
+ log.addStdout(message)
+
+ def fetch_data_from_url(self, url):
+ response = None
+ try:
+ response = requests.get(url)
+ except Exception as e:
+ if response:
+ self._addToLog('stdio', 'Failed to access {url} with status code {status_code}.\n'.format(url="" status_code=response.status_code))
+ else:
+ self._addToLog('stdio', 'Failed to access {url} with exception: {exception}\n'.format(url="" exception=e))
+ return None
+ if response.status_code != 200:
+ self._addToLog('stdio', 'Accessed {url} with unexpected status code {status_code}.\n'.format(url="" status_code=response.status_code))
+ return None
+ return response
+
+ def get_patch_json(self, patch_id):
+ patch_url = '{}rest/bug/attachment/{}'.format(BUG_SERVER_URL, patch_id)
+ patch = self.fetch_data_from_url(patch_url)
+ if not patch:
+ return None
+ patch_json = patch.json().get('attachments')
+ if not patch_json or len(patch_json) == 0:
+ return None
+ return patch_json.get(str(patch_id))
+
+ def get_bug_json(self, bug_id):
+ bug_url = '{}rest/bug/{}'.format(BUG_SERVER_URL, bug_id)
+ bug = self.fetch_data_from_url(bug_url)
+ if not bug:
+ return None
+ bugs_json = bug.json().get('bugs')
+ if not bugs_json or len(bugs_json) == 0:
+ return None
+ return bugs_json[0]
+
+ def get_bug_id_from_patch(self, patch_id):
+ patch_json = self.get_patch_json(patch_id)
+ if not patch_json:
+ self._addToLog('stdio', 'Unable to fetch patch {}.\n'.format(patch_id))
+ return -1
+ return patch_json.get('bug_id')
+
+ def _is_patch_obsolete(self, patch_id):
+ patch_json = self.get_patch_json(patch_id)
+ if not patch_json:
+ self._addToLog('stdio', 'Unable to fetch patch {}.\n'.format(patch_id))
+ return -1
+
+ if patch_json.get('id') != self.getProperty('patch_id', ''):
+ self._addToLog('stdio', 'Fetched patch id {} does not match with requested patch id {}. Unable to validate.\n'.format(patch_json.get('id'), self.getProperty('patch_id', '')))
+ return -1
+
+ return patch_json.get('is_obsolete')
+
+ def _is_patch_review_denied(self, patch_id):
+ patch_json = self.get_patch_json(patch_id)
+ if not patch_json:
+ self._addToLog('stdio', 'Unable to fetch patch {}.\n'.format(patch_id))
+ return -1
+
+ for flag in patch_json.get('flags', []):
+ if flag.get('name') == 'review' and flag.get('status') == '-':
+ return 1
+ return 0
+
+ def _is_bug_closed(self, bug_id):
+ bug_json = self.get_bug_json(bug_id)
+ if not bug_json or not bug_json.get('status'):
+ self._addToLog('stdio', 'Unable to fetch bug {}.\n'.format(bug_id))
+ return -1
+
+ if bug_json.get('status') in self.bug_closed_statuses:
+ return 1
+ return 0
+
+ def skip_build(self, reason):
+ self._addToLog('stdio', reason)
+ self.finished(FAILURE)
+ self.build.results = SKIPPED
+ self.build.buildFinished([reason], SKIPPED)
+
+ def start(self):
+ patch_id = self.getProperty('patch_id', '')
+ if not patch_id:
+ self._addToLog('stdio', 'No patch_id found. Unable to proceed without patch_id.\n')
+ self.finished(FAILURE)
+ return None
+
+ bug_id = self.getProperty('bug_id', self.get_bug_id_from_patch(patch_id))
+
+ bug_closed = self._is_bug_closed(bug_id)
+ if bug_closed == 1:
+ self.skip_build('Bug {} is already closed'.format(bug_id))
+ return None
+
+ obsolete = self._is_patch_obsolete(patch_id)
+ if obsolete == 1:
+ self.skip_build('Patch {} is obsolete'.format(patch_id))
+ return None
+
+ review_denied = self._is_patch_review_denied(patch_id)
+ if review_denied == 1:
+ self.skip_build('Patch {} is marked r-'.format(patch_id))
+ return None
+
+ if obsolete == -1 or review_denied == -1 or bug_closed == -1:
+ self.finished(WARNINGS)
+ return None
+
+ self._addToLog('stdio', 'Bug is open.\nPatch is not obsolete.\nPatch is not marked r-.\n')
+ self.finished(SUCCESS)
+ return None
+
+
class UnApplyPatchIfRequired(CheckOutSource):
name = 'unapply-patch'
Modified: trunk/Tools/ChangeLog (239649 => 239650)
--- trunk/Tools/ChangeLog 2019-01-05 01:23:52 UTC (rev 239649)
+++ trunk/Tools/ChangeLog 2019-01-05 02:30:03 UTC (rev 239650)
@@ -1,3 +1,24 @@
+2019-01-04 Aakash Jain <aakash_j...@apple.com>
+
+ [ews-build] Add build step to validate the patch before processing it
+ https://bugs.webkit.org/show_bug.cgi?id=193140
+
+ Reviewed by Lucas Forschler.
+
+ * BuildSlaveSupport/ews-build/factories.py:
+ (Factory.__init__): Added ValidatePatch step.
+ * BuildSlaveSupport/ews-build/steps.py:
+ (ValidatePatch):
+ (ValidatePatch.fetch_data_from_url): Fetch data from a url.
+ (ValidatePatch.get_patch_json): Get patch json data.
+ (ValidatePatch.get_bug_json): Get bug json data.
+ (ValidatePatch.get_bug_id_from_patch): Get bug id from a patch id.
+ (ValidatePatch._is_patch_obsolete): Check if the patch is obsolete.
+ (ValidatePatch._is_patch_review_denied): Check if the patch is marked r-.
+ (ValidatePatch._is_bug_closed): Check if the bug is already closed.
+ (ValidatePatch.skip_build): Skip the build.
+ (ValidatePatch.start):
+
2019-01-04 Alex Christensen <achristen...@webkit.org>
Progress towards fixing Mac CMake build