Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 # Copyright 2014 The Chromium Authors. All rights reserved. | 1 # Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 """This recipe module allows triggering builds within the same master. | 5 """This recipe module allows triggering builds within the same master. |
| 6 | 6 |
| 7 Example: | 7 Example: |
| 8 api.trigger({ | 8 api.trigger({ |
| 9 'buildername': 'My Builder', | 9 'buildername': 'My Builder', |
| 10 'another_property': 'value', | 10 'another_property': 'value', |
| 11 }) | 11 }) |
| 12 | 12 |
| 13 # This triggers a new build on "My Builder" builder with "another_property" | 13 # This triggers a new build on "My Builder" builder with "another_property" |
| 14 property set to "value". | 14 property set to "value". |
| 15 | 15 |
| 16 You can trigger multiple builds in one steps: | 16 You can trigger multiple builds in one steps: |
| 17 api.trigger({'buildername': 'Release'}, {'buildername': 'Debug'}) | 17 api.trigger({'buildername': 'Release'}, {'buildername': 'Debug'}) |
| 18 """ | 18 """ |
| 19 | 19 |
| 20 from slave import recipe_api | 20 from slave import recipe_api |
| 21 | 21 |
| 22 | 22 |
| 23 class TriggerApi(recipe_api.RecipeApi): | 23 class TriggerApi(recipe_api.RecipeApi): |
| 24 """APIs for triggering new builds.""" | 24 """APIs for triggering new builds.""" |
| 25 | 25 |
| 26 def __init__(self, **kwargs): | 26 def __init__(self, **kwargs): |
| 27 super(TriggerApi, self).__init__(**kwargs) | 27 super(TriggerApi, self).__init__(**kwargs) |
| 28 | 28 |
| 29 def __call__(self, *propertiesList, **kwargs): | 29 def _port_from_properties_only(self, trigger_spec): |
| 30 """Convert from prevoius "properties-only" mode to trigger spec.""" | |
|
smut
2015/02/28 01:49:42
s/prevouis/previous/
nodir
2015/03/02 02:26:11
Done.
| |
| 31 builder_name = trigger_spec.get('buildername') | |
| 32 if not builder_name: | |
| 33 return trigger_spec | |
| 34 | |
| 35 props = trigger_spec.copy() | |
| 36 del props['buildername'] | |
| 37 return { | |
| 38 'builder_name': builder_name, | |
| 39 'properties': props, | |
|
smut
2015/02/28 01:49:42
The old style might have buildbot.changes in prope
nodir
2015/03/02 02:26:11
I've updated build_internal as well https://chrome
| |
| 40 } | |
| 41 | |
| 42 def __call__(self, *trigger_specs, **kwargs): | |
| 30 """Triggers new builds by builder names. | 43 """Triggers new builds by builder names. |
| 31 | 44 |
| 32 Args: | 45 Args: |
| 33 propertiesList: a list of build property dicts for the builds to | 46 trigger_specs: a list of trigger dicts, where each dict specifies a build |
| 34 trigger. Each dict triggers a build. See "Known properties" below. | 47 to trigger. Supported keys: |
| 35 name: (in kwargs) name of the step. If not specified, it is generated | 48 builder_name (str): in BuildBot context, builder name |
| 36 automatically, its format may change in future. | 49 properties (dict): build properties for a new build. |
| 50 buildbot.changes (list of dict): list of Buildbot changes to create. | |
|
smut
2015/02/28 01:44:51
buildbot.changes -> buildbot_changes
nodir
2015/03/02 02:26:11
Done.
| |
| 51 See below. | |
| 52 name: name of the step. If not specified, it is generated | |
| 53 automatically. Its format may change in future. | |
| 37 | 54 |
| 38 Known properties: | 55 Buildbot changes: |
| 39 buildername (str): Buildbot-specific, required in Buildbot environment. | 56 buildbot_changes (a list of dicts) is a list of changes for the |
| 40 buildbot.changes (a list of dicts): Buildbot-specific, changes for the | 57 triggered builds. Each change is a dict with keys (all optional): |
| 41 triggered builds. Each change is a dict with keys (all optional): | 58 author (str) |
| 42 author (str) | 59 revision |
| 43 revision | 60 revlink (str): link to a web view of the revision. |
| 44 revlink (str): link to a web view of the revision. | 61 comment |
| 45 comment | 62 when_timestamp (int): timestamp of the change, in seconds since Unix |
| 46 when_timestamp (int): timestamp of the change, in seconds since Unix | 63 Epoch. |
| 47 Epoch. | 64 branch |
| 48 branch | 65 category (str): Buildbot change category |
| 49 category (str): Buildbot change category | 66 files (list of str): list of changed filenames |
| 50 files (list of str): list of changed filenames | 67 The first change is used to populate source stamp properties. |
| 51 The first change is used to populate source stamp properties. | |
| 52 | 68 |
| 53 Examples: | 69 Examples: |
| 70 Basic: | |
| 71 api.trigger({ | |
| 72 'builder_name': 'Release', | |
| 73 'properties': { | |
| 74 'my_prop': 123, | |
| 75 }, | |
| 76 }) | |
| 77 | |
| 54 Create Buildbot changes: | 78 Create Buildbot changes: |
| 55 api.trigger({ | 79 api.trigger({ |
| 56 'builderName': 'Release', | 80 'builder_name': 'Release', |
| 57 'my_prop': 123, | 81 'buildbot_changes': [{ |
| 58 'buildbot.changes': [{ | |
| 59 'author': 'someone@chromium.org', | 82 'author': 'someone@chromium.org', |
| 60 'branch': 'master', | 83 'branch': 'master', |
| 61 'files': ['a.txt.'], | 84 'files': ['a.txt.'], |
| 62 'comments': 'Refactoring', | 85 'comments': 'Refactoring', |
| 63 'revision': 'deadbeef', | 86 'revision': 'deadbeef', |
| 64 'revlink': | 87 'revlink': |
| 65 'http://chromium.googlesource.com/chromium/src/+/deadbeef', | 88 'http://chromium.googlesource.com/chromium/src/+/deadbeef', |
| 66 'when_timestamp': 1416859562, | 89 'when_timestamp': 1416859562, |
| 67 }] | 90 }] |
| 68 }) | 91 }) |
| 69 """ | 92 """ |
| 70 builder_names = [] | 93 # Backward-compatibility: |
| 71 for properties in propertiesList: | 94 trigger_specs = map(self._port_from_properties_only, trigger_specs) |
| 72 assert isinstance(properties, dict), ('properties must be a dict: %s' | |
| 73 % (properties,)) | |
| 74 builder_name = properties.get('buildername') | |
| 75 assert builder_name, 'buildername property is missing: %s' % (properties,) | |
| 76 if builder_name not in builder_names: | |
| 77 builder_names.append(builder_name) | |
| 78 | 95 |
| 79 name = kwargs.get('name') or ('trigger %s' % ', '.join(builder_names)) | 96 builder_names = set() |
| 80 trigger_specs = [ | 97 for trigger in trigger_specs: |
| 81 { | 98 assert isinstance(trigger, dict), ('trigger spec must be a dict: %s' |
| 82 'properties': properties, | 99 % (trigger,)) |
| 83 } for properties in propertiesList | 100 builder_name = trigger.get('builder_name') |
| 84 ] | 101 assert builder_name, 'builder_name is missing: %s' % (trigger,) |
| 102 builder_names.add(builder_name) | |
| 103 | |
| 104 name = ( | |
| 105 kwargs.get('name') or ('trigger %s' % ', '.join(sorted(builder_names)))) | |
| 85 return self.m.step( | 106 return self.m.step( |
| 86 name, | 107 name, |
| 87 cmd=[], | 108 cmd=[], |
| 88 trigger_specs=trigger_specs, | 109 trigger_specs=trigger_specs, |
| 89 ) | 110 ) |
| OLD | NEW |