Dan Albert | 7c78d24 | 2015-01-09 14:12:52 -0800 | [diff] [blame] | 1 | #!/usr/bin/env python2 |
Dan Albert | c02df47 | 2015-01-09 17:22:00 -0800 | [diff] [blame] | 2 | # |
| 3 | # Copyright (C) 2015 The Android Open Source Project |
| 4 | # |
| 5 | # Licensed under the Apache License, Version 2.0 (the 'License'); |
| 6 | # you may not use this file except in compliance with the License. |
| 7 | # You may obtain a copy of the License at |
| 8 | # |
| 9 | # http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | # |
| 11 | # Unless required by applicable law or agreed to in writing, software |
| 12 | # distributed under the License is distributed on an 'AS IS' BASIS, |
| 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 14 | # See the License for the specific language governing permissions and |
| 15 | # limitations under the License. |
| 16 | # |
Dan Albert | 7c78d24 | 2015-01-09 14:12:52 -0800 | [diff] [blame] | 17 | import json |
Dan Albert | a4061cd | 2015-04-16 14:20:13 -0700 | [diff] [blame] | 18 | import logging |
Dan Albert | d3fe4f1 | 2015-04-17 13:01:29 -0700 | [diff] [blame] | 19 | import os |
| 20 | |
| 21 | from apscheduler.schedulers.background import BackgroundScheduler |
| 22 | from flask import Flask, request |
Dan Albert | 7c78d24 | 2015-01-09 14:12:52 -0800 | [diff] [blame] | 23 | import requests |
Dan Albert | 7c78d24 | 2015-01-09 14:12:52 -0800 | [diff] [blame] | 24 | |
Dan Albert | 8a15a4e | 2015-01-09 16:52:07 -0800 | [diff] [blame] | 25 | import gerrit |
Dan Albert | d3fe4f1 | 2015-04-17 13:01:29 -0700 | [diff] [blame] | 26 | import tasks |
Dan Albert | 7c78d24 | 2015-01-09 14:12:52 -0800 | [diff] [blame] | 27 | |
Dan Albert | 7c78d24 | 2015-01-09 14:12:52 -0800 | [diff] [blame] | 28 | app = Flask(__name__) |
| 29 | |
| 30 | |
| 31 | def gerrit_url(endpoint): |
Dan Albert | c02df47 | 2015-01-09 17:22:00 -0800 | [diff] [blame] | 32 | gerrit_base_url = 'https://android-review.googlesource.com' |
| 33 | return gerrit_base_url + endpoint |
Dan Albert | 7c78d24 | 2015-01-09 14:12:52 -0800 | [diff] [blame] | 34 | |
| 35 | |
| 36 | @app.route('/', methods=['POST']) |
| 37 | def handle_build_message(): |
Dan Albert | c02df47 | 2015-01-09 17:22:00 -0800 | [diff] [blame] | 38 | result = json.loads(request.data) |
Dan Albert | 7c78d24 | 2015-01-09 14:12:52 -0800 | [diff] [blame] | 39 | |
Dan Albert | c02df47 | 2015-01-09 17:22:00 -0800 | [diff] [blame] | 40 | name = result['name'] |
| 41 | number = result['build']['number'] |
| 42 | status = result['build']['status'] |
| 43 | go_url = 'http://go/bionicbb/' + result['build']['url'] |
| 44 | full_url = result['build']['full_url'] |
| 45 | params = result['build']['parameters'] |
| 46 | change_id = params['CHANGE_ID'] |
| 47 | ref = params['REF'] |
| 48 | patch_set = ref.split('/')[-1] |
Dan Albert | 7c78d24 | 2015-01-09 14:12:52 -0800 | [diff] [blame] | 49 | |
Dan Albert | a4061cd | 2015-04-16 14:20:13 -0700 | [diff] [blame] | 50 | logging.debug('%s #%s %s: %s', name, number, status, full_url) |
Dan Albert | 7c78d24 | 2015-01-09 14:12:52 -0800 | [diff] [blame] | 51 | |
Dan Albert | c02df47 | 2015-01-09 17:22:00 -0800 | [diff] [blame] | 52 | # bionic-lint is always broken, so we don't want to reject changes for |
| 53 | # those failures until we clean things up. |
| 54 | if name == 'bionic-presubmit': |
| 55 | message_lines = ['{} #{} checkbuild {}: {}'.format( |
| 56 | name, number, status, go_url)] |
| 57 | if status == 'FAILURE': |
| 58 | message_lines += ['If you believe this Verified-1 was in error, ' |
| 59 | '+1 the change and bionicbb will remove the -1 ' |
| 60 | 'shortly.'] |
Dan Albert | 7c78d24 | 2015-01-09 14:12:52 -0800 | [diff] [blame] | 61 | |
Dan Albert | c02df47 | 2015-01-09 17:22:00 -0800 | [diff] [blame] | 62 | request_data = { |
| 63 | 'message': '\n'.join(message_lines) |
| 64 | } |
Dan Albert | 7c78d24 | 2015-01-09 14:12:52 -0800 | [diff] [blame] | 65 | |
Dan Albert | c02df47 | 2015-01-09 17:22:00 -0800 | [diff] [blame] | 66 | label = 'Verified' |
| 67 | if status == 'FAILURE': |
| 68 | request_data['labels'] = {label: -1} |
| 69 | elif status == 'SUCCESS': |
| 70 | request_data['labels'] = {label: +1} |
Dan Albert | 7c78d24 | 2015-01-09 14:12:52 -0800 | [diff] [blame] | 71 | |
Dan Albert | c02df47 | 2015-01-09 17:22:00 -0800 | [diff] [blame] | 72 | url = gerrit_url('/a/changes/{}/revisions/{}/review'.format(change_id, |
| 73 | patch_set)) |
Dan Albert | 7c78d24 | 2015-01-09 14:12:52 -0800 | [diff] [blame] | 74 | |
Dan Albert | c02df47 | 2015-01-09 17:22:00 -0800 | [diff] [blame] | 75 | headers = {'Content-Type': 'application/json;charset=UTF-8'} |
Dan Albert | a4061cd | 2015-04-16 14:20:13 -0700 | [diff] [blame] | 76 | logging.debug('POST %s: %s', url, request_data) |
| 77 | requests.post(url, headers=headers, json=request_data) |
Dan Albert | c02df47 | 2015-01-09 17:22:00 -0800 | [diff] [blame] | 78 | elif name == 'clean-bionic-presubmit': |
| 79 | request_data = {'message': 'out/ directory removed'} |
| 80 | url = gerrit_url('/a/changes/{}/revisions/{}/review'.format(change_id, |
| 81 | patch_set)) |
| 82 | headers = {'Content-Type': 'application/json;charset=UTF-8'} |
Dan Albert | a4061cd | 2015-04-16 14:20:13 -0700 | [diff] [blame] | 83 | logging.debug('POST %s: %s', url, request_data) |
| 84 | requests.post(url, headers=headers, json=request_data) |
Dan Albert | c02df47 | 2015-01-09 17:22:00 -0800 | [diff] [blame] | 85 | elif name == 'bionic-lint': |
Dan Albert | a4061cd | 2015-04-16 14:20:13 -0700 | [diff] [blame] | 86 | logging.warning('Result for bionic-lint ignored') |
Dan Albert | c02df47 | 2015-01-09 17:22:00 -0800 | [diff] [blame] | 87 | else: |
Dan Albert | a4061cd | 2015-04-16 14:20:13 -0700 | [diff] [blame] | 88 | logging.error('Unknown project: %s', name) |
Dan Albert | c02df47 | 2015-01-09 17:22:00 -0800 | [diff] [blame] | 89 | return '' |
Dan Albert | 7c78d24 | 2015-01-09 14:12:52 -0800 | [diff] [blame] | 90 | |
| 91 | |
| 92 | @app.route('/drop-rejection', methods=['POST']) |
| 93 | def drop_rejection(): |
Dan Albert | c02df47 | 2015-01-09 17:22:00 -0800 | [diff] [blame] | 94 | revision_info = json.loads(request.data) |
Dan Albert | 7c78d24 | 2015-01-09 14:12:52 -0800 | [diff] [blame] | 95 | |
Dan Albert | c02df47 | 2015-01-09 17:22:00 -0800 | [diff] [blame] | 96 | change_id = revision_info['changeid'] |
| 97 | patch_set = revision_info['patchset'] |
Dan Albert | 7c78d24 | 2015-01-09 14:12:52 -0800 | [diff] [blame] | 98 | |
Dan Albert | c02df47 | 2015-01-09 17:22:00 -0800 | [diff] [blame] | 99 | bb_email = 'bionicbb@android.com' |
| 100 | labels = gerrit.get_labels(change_id, patch_set) |
| 101 | if bb_email in labels['Verified']: |
| 102 | bb_review = labels['Verified'][bb_email] |
| 103 | else: |
| 104 | bb_review = 0 |
Dan Albert | 7c78d24 | 2015-01-09 14:12:52 -0800 | [diff] [blame] | 105 | |
Dan Albert | c02df47 | 2015-01-09 17:22:00 -0800 | [diff] [blame] | 106 | if bb_review >= 0: |
Dan Albert | a4061cd | 2015-04-16 14:20:13 -0700 | [diff] [blame] | 107 | logging.info('No rejection to drop: %s %s', change_id, patch_set) |
Dan Albert | c02df47 | 2015-01-09 17:22:00 -0800 | [diff] [blame] | 108 | return '' |
| 109 | |
Dan Albert | a4061cd | 2015-04-16 14:20:13 -0700 | [diff] [blame] | 110 | logging.info('Dropping rejection: %s %s', change_id, patch_set) |
Dan Albert | c02df47 | 2015-01-09 17:22:00 -0800 | [diff] [blame] | 111 | |
| 112 | request_data = {'labels': {'Verified': 0}} |
| 113 | url = gerrit_url('/a/changes/{}/revisions/{}/review'.format(change_id, |
| 114 | patch_set)) |
| 115 | headers = {'Content-Type': 'application/json;charset=UTF-8'} |
Dan Albert | a4061cd | 2015-04-16 14:20:13 -0700 | [diff] [blame] | 116 | logging.debug('POST %s: %s', url, request_data) |
| 117 | requests.post(url, headers=headers, json=request_data) |
Dan Albert | 7c78d24 | 2015-01-09 14:12:52 -0800 | [diff] [blame] | 118 | return '' |
| 119 | |
Dan Albert | 7c78d24 | 2015-01-09 14:12:52 -0800 | [diff] [blame] | 120 | |
| 121 | if __name__ == "__main__": |
Dan Albert | d3fe4f1 | 2015-04-17 13:01:29 -0700 | [diff] [blame] | 122 | logging.basicConfig(level=logging.INFO) |
Dan Albert | 21988a3 | 2015-04-17 17:51:39 -0700 | [diff] [blame] | 123 | logger = logging.getLogger() |
| 124 | fh = logging.FileHandler('bionicbb.log') |
| 125 | fh.setLevel(logging.INFO) |
| 126 | logger.addHandler(fh) |
Dan Albert | d3fe4f1 | 2015-04-17 13:01:29 -0700 | [diff] [blame] | 127 | |
| 128 | # Prevent the job from being rescheduled by the reloader. |
| 129 | if os.environ.get('WERKZEUG_RUN_MAIN') == 'true': |
| 130 | scheduler = BackgroundScheduler() |
| 131 | scheduler.start() |
| 132 | scheduler.add_job(tasks.get_and_process_jobs, 'interval', minutes=5) |
| 133 | |
Dan Albert | c02df47 | 2015-01-09 17:22:00 -0800 | [diff] [blame] | 134 | app.run(host='0.0.0.0', debug=True) |