Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 # Copyright 2015 The Chromium Authors. All rights reserved. | |
| 2 # Use of this source code is governed by a BSD-style license that can be | |
| 3 # found in the LICENSE file. | |
| 4 | |
| 5 """Build triggering via buildbucket.""" | |
| 6 | |
| 7 import json | |
| 8 | |
| 9 from twisted.internet import defer | |
| 10 | |
| 11 from . import client | |
| 12 from . import common | |
| 13 | |
| 14 | |
| 15 class TriggeringService(object): | |
| 16 """Schedules new builds on buildbucket.""" | |
| 17 | |
| 18 def __init__(self, active_master, buildbucket_service): | |
| 19 self.active_master = active_master | |
| 20 self.buildbucket_service = buildbucket_service | |
| 21 | |
| 22 @classmethod | |
| 23 @defer.inlineCallbacks | |
| 24 def create(cls, active_master): | |
| 25 buildbucket_service = yield client.create_buildbucket_service(active_master) | |
| 26 defer.returnValue(cls(active_master, buildbucket_service)) | |
| 27 | |
| 28 def start(self): | |
| 29 self.buildbucket_service.start() | |
| 30 | |
| 31 def stop(self): | |
| 32 self.buildbucket_service.stop() | |
| 33 | |
| 34 @staticmethod | |
| 35 def get_buildset(build_def): | |
| 36 tags = build_def.get('tags', []) | |
| 37 PREFIX = 'buildset:' | |
| 38 for t in tags: | |
| 39 if t.startswith(PREFIX): | |
| 40 return t[len(PREFIX):] | |
| 41 return None | |
| 42 | |
| 43 def get_build_url(self, build_id): | |
| 44 return 'https://%s/b/%s' % ( | |
| 45 client.get_default_buildbucktet_hostname(self.active_master), build_id) | |
| 46 | |
| 47 @defer.inlineCallbacks | |
| 48 def trigger( | |
| 49 self, source_build, bucket_name, builder_name, properties, changes=None): | |
| 50 """Schedules a build on buildbucket.""" | |
| 51 info = source_build.getProperties().getProperty(common.INFO_PROPERTY) or {} | |
| 52 build_def = info.get(common.BUILD_PROPERTY) or {} | |
| 53 bucket_name = bucket_name or build_def.get('bucket') | |
| 54 if not bucket_name: | |
| 55 # This function should not be called in this case. | |
| 56 raise common.Error( | |
| 57 'Neither bucket_name is specified, nor the build is from buildbucket') | |
|
ghost stip (do not use)
2015/03/04 23:07:30
this causes an exception in the build and doesn't
nodir
2015/03/04 23:52:10
it doesn't kill the master, but calls errback. In
| |
| 58 | |
| 59 tags = [] | |
| 60 if build_def: | |
| 61 tags.append('parent_build_id:%s' % build_def['id']) | |
| 62 buildset = self.get_buildset(build_def) | |
| 63 if buildset: | |
| 64 tags.append('buildset:%s' % buildset) | |
| 65 | |
| 66 response = yield self.buildbucket_service.api.put(body={ | |
| 67 'bucket': bucket_name, | |
| 68 'tags': tags, | |
| 69 'parameters_json': json.dumps({ | |
| 70 'builder_name': builder_name, | |
| 71 'properties': properties, | |
| 72 'changes': changes or [], | |
| 73 }), | |
| 74 }) | |
| 75 result = { | |
| 76 'response': response, | |
| 77 } | |
| 78 build_id = response.get('build', {}).get('id', {}) | |
| 79 if build_id: | |
| 80 result['build_url'] = self.get_build_url(build_id) | |
| 81 defer.returnValue(result) | |
| 82 | |
| 83 | |
| 84 _master_triggering_service_map = {} | |
| 85 | |
| 86 | |
| 87 def get_triggering_service(active_master): | |
| 88 """Returns a TriggeringService instance for active_master as Deferred.""" | |
| 89 d = _master_triggering_service_map.get(active_master) | |
| 90 if not d: | |
| 91 d = TriggeringService.create(active_master) | |
| 92 def start(service): | |
| 93 service.start() | |
| 94 return service | |
| 95 d.addCallback(start) | |
| 96 _master_triggering_service_map[active_master] = d | |
| 97 return d | |
| 98 | |
| 99 | |
| 100 def change_from_change_spec(self, change): | |
| 101 """Converts a change in change_spec format to buildbucket format. | |
| 102 | |
| 103 For more info on change_spec format, see | |
| 104 master.chromium_step.AnnotationObserver.insertSourceStamp. | |
| 105 | |
| 106 Buildbucket change format is described in README.md. | |
| 107 """ | |
| 108 create_ts = None | |
| 109 if 'when_timestamp' in change: | |
| 110 # Convert from seconds to milliseconds since Unix Epoch. | |
| 111 assert isinstance(change['when_timestamp'], (int, float)) | |
| 112 create_ts = change['when_timestamp'] * 1000 | |
| 113 | |
| 114 return { | |
| 115 'revision': change.get('revision'), | |
| 116 'author': { | |
| 117 # Assuming author is email. | |
| 118 'email': change.get('author'), | |
| 119 }, | |
| 120 'create_ts': create_ts, | |
| 121 'files': [{'path': f} for f in change.get('files', [])], | |
| 122 'message': change.get('comments'), | |
| 123 'branch': change.get('branch'), | |
| 124 'url': change.get('revlink'), | |
| 125 'project': change.get('project'), | |
| 126 } | |
| 127 | |
| OLD | NEW |