diff --git a/eventhandler.py b/eventhandler.py index 3ec77a9..6c45cc4 100644 --- a/eventhandler.py +++ b/eventhandler.py @@ -10,7 +10,8 @@ 'synchronize': 'on_pr_updated', 'created': 'on_new_comment', 'closed': 'on_pr_closed', - 'labeled': 'on_issue_labeled' + 'labeled': 'on_issue_labeled', + 'status': 'on_build_status' } @@ -30,10 +31,14 @@ def on_pr_closed(self, api, payload): def on_issue_labeled(self, api, payload): pass + def on_build_status(self, api, payload): + pass + def handle_payload(self, api, payload): def callback(action): getattr(self, _payload_actions[action])(api, payload) - payload_action = payload['action'] + payload_action = 'status' if 'context' in payload \ + else payload['action'] linear_search(_payload_actions, payload_action, callback) def warn(self, msg): @@ -41,8 +46,8 @@ def warn(self, msg): _warnings += [msg] def is_open_pr(self, payload): - return (payload['issue']['state'] == 'open' and - 'pull_request' in payload['issue']) + return ('pull_request' in payload['issue'] and + payload['issue']['state'] == 'open') def reset_test_state(): diff --git a/handlers/status_update/__init__.py b/handlers/status_update/__init__.py index 31f504d..fdc1868 100644 --- a/handlers/status_update/__init__.py +++ b/handlers/status_update/__init__.py @@ -45,4 +45,9 @@ def on_pr_closed(self, api, payload): if payload['pull_request']['merged']: api.remove_label("S-awaiting-merge") + def on_build_status(self, api, payload): + if 'travis' in payload['context']: + if payload['state'] == 'failure' or payload['state'] == 'error': + api.add_label("S-needs-code-changes") + handler_interface = StatusUpdateHandler diff --git a/handlers/status_update/tests/api.travis-ci.org/build.json b/handlers/status_update/tests/api.travis-ci.org/build.json new file mode 100644 index 0000000..cdd2a75 --- /dev/null +++ b/handlers/status_update/tests/api.travis-ci.org/build.json @@ -0,0 +1,3 @@ +{ + "compare_url": "https://github.com/servo/servo/pull/11000" +} diff --git a/handlers/status_update/tests/build_status.json b/handlers/status_update/tests/build_status.json new file mode 100644 index 0000000..56c2e3a --- /dev/null +++ b/handlers/status_update/tests/build_status.json @@ -0,0 +1,21 @@ +{ + "expected": { + "labels": [ + "S-needs-code-changes" + ] + }, + "initial": { + "labels": [] + }, + "payload": { + "target_url": "handlers/status_update/tests/travis-ci.org/build.json", + "context": "continuous-integration/travis-ci/pr", + "repository": { + "owner": { + "login": "servo" + }, + "name": "servo" + }, + "state": "failure" + } +} diff --git a/json_cleanup.py b/json_cleanup.py index 0669094..7980c1d 100644 --- a/json_cleanup.py +++ b/json_cleanup.py @@ -70,6 +70,9 @@ def __str__(self): def __int__(self): return int(self._node) + def split(self, sep): + return self._node.split(sep) + class JsonCleaner(object): def __init__(self, json_obj): diff --git a/newpr.py b/newpr.py index b0224b1..7d85758 100755 --- a/newpr.py +++ b/newpr.py @@ -8,6 +8,7 @@ import ConfigParser import contextlib import gzip +import re try: import simplejson as json except: @@ -20,12 +21,27 @@ class APIProvider(object): def __init__(self, payload, user): - (owner, repo, issue) = extract_globals_from_payload(payload) + (owner, repo, issue) = self._extract_globals(payload) self.owner = owner self.repo = repo self.issue = issue self.user = user + def _extract_globals(self, payload): + if 'context' in payload: + owner = payload['repository']['owner']['login'] + repo = payload['repository']['name'] + issue = self.get_pull_number_from_travis(payload['target_url']) + elif payload['action'] == 'created' or payload['action'] == 'labeled': + owner = payload['repository']['owner']['login'] + repo = payload['repository']['name'] + issue = str(payload['issue']['number']) + else: + owner = payload['pull_request']['base']['repo']['owner']['login'] + repo = payload['pull_request']['base']['repo']['name'] + issue = str(payload["number"]) + return (owner, repo, issue) + def is_new_contributor(self, username): raise NotImplementedError @@ -53,6 +69,13 @@ def get_pull(self): def get_page_content(self, url): raise NotImplementedError + def get_pull_number_from_travis(self, target_url): + regex = r'(.*)(travis-ci.org/).*(build.*)' + build_url = re.sub(regex, r'\1api.\2\3', str(target_url)) + build_data = self.get_page_content(build_url) + build_json = json.loads(build_data) + return int(build_json['compare_url'].split('/')[-1]) + class GithubAPIProvider(APIProvider): BASE_URL = "https://api.github.com/repos/" @@ -214,18 +237,6 @@ def get_page_content(self, url): warning_summary = warning_header + '\n\n%s' -def extract_globals_from_payload(payload): - if payload["action"] == "created" or payload["action"] == "labeled": - owner = payload['repository']['owner']['login'] - repo = payload['repository']['name'] - issue = str(payload['issue']['number']) - else: - owner = payload['pull_request']['base']['repo']['owner']['login'] - repo = payload['pull_request']['base']['repo']['name'] - issue = str(payload["number"]) - return (owner, repo, issue) - - def handle_payload(api, payload, handlers=None): if not handlers: modules, handlers = eventhandler.get_handlers()