Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(301)

Unified Diff: scripts/master/buildbucket/trigger.py

Issue 968053003: BuildBucket-based build triggering (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/build
Patch Set: added build_url Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: scripts/master/buildbucket/trigger.py
diff --git a/scripts/master/buildbucket/trigger.py b/scripts/master/buildbucket/trigger.py
new file mode 100644
index 0000000000000000000000000000000000000000..63246f568f3638ef68a672bb5c5d6ee3385c4ebf
--- /dev/null
+++ b/scripts/master/buildbucket/trigger.py
@@ -0,0 +1,127 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Build triggering via buildbucket."""
+
+import json
+
+from twisted.internet import defer
+
+from . import client
+from . import common
+
+
+class TriggeringService(object):
+ """Schedules new builds on buildbucket."""
+
+ def __init__(self, active_master, buildbucket_service):
+ self.active_master = active_master
+ self.buildbucket_service = buildbucket_service
+
+ @classmethod
+ @defer.inlineCallbacks
+ def create(cls, active_master):
+ buildbucket_service = yield client.create_buildbucket_service(active_master)
+ defer.returnValue(cls(active_master, buildbucket_service))
+
+ def start(self):
+ self.buildbucket_service.start()
+
+ def stop(self):
+ self.buildbucket_service.stop()
+
+ @staticmethod
+ def get_buildset(build_def):
+ tags = build_def.get('tags', [])
+ PREFIX = 'buildset:'
+ for t in tags:
+ if t.startswith(PREFIX):
+ return t[len(PREFIX):]
+ return None
+
+ def get_build_url(self, build_id):
+ return 'https://%s/b/%s' % (
+ client.get_default_buildbucktet_hostname(self.active_master), build_id)
+
+ @defer.inlineCallbacks
+ def trigger(
+ self, source_build, bucket_name, builder_name, properties, changes=None):
+ """Schedules a build on buildbucket."""
+ info = source_build.getProperties().getProperty(common.INFO_PROPERTY) or {}
+ build_def = info.get(common.BUILD_PROPERTY) or {}
+ bucket_name = bucket_name or build_def.get('bucket')
+ if not bucket_name:
+ # This function should not be called in this case.
+ raise common.Error(
+ '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
+
+ tags = []
+ if build_def:
+ tags.append('parent_build_id:%s' % build_def['id'])
+ buildset = self.get_buildset(build_def)
+ if buildset:
+ tags.append('buildset:%s' % buildset)
+
+ response = yield self.buildbucket_service.api.put(body={
+ 'bucket': bucket_name,
+ 'tags': tags,
+ 'parameters_json': json.dumps({
+ 'builder_name': builder_name,
+ 'properties': properties,
+ 'changes': changes or [],
+ }),
+ })
+ result = {
+ 'response': response,
+ }
+ build_id = response.get('build', {}).get('id', {})
+ if build_id:
+ result['build_url'] = self.get_build_url(build_id)
+ defer.returnValue(result)
+
+
+_master_triggering_service_map = {}
+
+
+def get_triggering_service(active_master):
+ """Returns a TriggeringService instance for active_master as Deferred."""
+ d = _master_triggering_service_map.get(active_master)
+ if not d:
+ d = TriggeringService.create(active_master)
+ def start(service):
+ service.start()
+ return service
+ d.addCallback(start)
+ _master_triggering_service_map[active_master] = d
+ return d
+
+
+def change_from_change_spec(self, change):
+ """Converts a change in change_spec format to buildbucket format.
+
+ For more info on change_spec format, see
+ master.chromium_step.AnnotationObserver.insertSourceStamp.
+
+ Buildbucket change format is described in README.md.
+ """
+ create_ts = None
+ if 'when_timestamp' in change:
+ # Convert from seconds to milliseconds since Unix Epoch.
+ assert isinstance(change['when_timestamp'], (int, float))
+ create_ts = change['when_timestamp'] * 1000
+
+ return {
+ 'revision': change.get('revision'),
+ 'author': {
+ # Assuming author is email.
+ 'email': change.get('author'),
+ },
+ 'create_ts': create_ts,
+ 'files': [{'path': f} for f in change.get('files', [])],
+ 'message': change.get('comments'),
+ 'branch': change.get('branch'),
+ 'url': change.get('revlink'),
+ 'project': change.get('project'),
+ }
+

Powered by Google App Engine
This is Rietveld 408576698