diff --git a/recipes/README.recipes.md b/recipes/README.recipes.md index 62032a18e..83b95e0d1 100644 --- a/recipes/README.recipes.md +++ b/recipes/README.recipes.md @@ -761,17 +761,29 @@ Return a presubmit step.   **@property**
— **def [presubmit\_support\_path](/recipes/recipe_modules/presubmit/api.py#8)(self):** ### *recipe_modules* / [tryserver](/recipes/recipe_modules/tryserver) -[DEPS](/recipes/recipe_modules/tryserver/__init__.py#5): [gerrit](#recipe_modules-gerrit), [git](#recipe_modules-git), [git\_cl](#recipe_modules-git_cl), [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/json][recipe_engine/recipe_modules/json], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/python][recipe_engine/recipe_modules/python], [recipe\_engine/raw\_io][recipe_engine/recipe_modules/raw_io], [recipe\_engine/step][recipe_engine/recipe_modules/step] +[DEPS](/recipes/recipe_modules/tryserver/__init__.py#5): [gerrit](#recipe_modules-gerrit), [git](#recipe_modules-git), [git\_cl](#recipe_modules-git_cl), [recipe\_engine/buildbucket][recipe_engine/recipe_modules/buildbucket], [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/json][recipe_engine/recipe_modules/json], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/python][recipe_engine/recipe_modules/python], [recipe\_engine/raw\_io][recipe_engine/recipe_modules/raw_io], [recipe\_engine/step][recipe_engine/recipe_modules/step] -#### **class [TryserverApi](/recipes/recipe_modules/tryserver/api.py#12)([RecipeApi][recipe_engine/wkt/RecipeApi]):** +#### **class [TryserverApi](/recipes/recipe_modules/tryserver/api.py#11)([RecipeApi][recipe_engine/wkt/RecipeApi]):** -— **def [add\_failure\_reason](/recipes/recipe_modules/tryserver/api.py#108)(self, reason):** +— **def [add\_failure\_reason](/recipes/recipe_modules/tryserver/api.py#137)(self, reason):** Records a more detailed reason why build is failing. The reason can be any JSON-serializable object. -— **def [get\_files\_affected\_by\_patch](/recipes/recipe_modules/tryserver/api.py#38)(self, patch_root, \*\*kwargs):** +  **@property**
— **def [gerrit\_change](/recipes/recipe_modules/tryserver/api.py#30)(self):** + +Returns current gerrit change, if there is exactly one. + +Returns a self.m.buildbucket.common_pb2.GerritChange or None. + +  **@property**
— **def [gerrit\_change\_repo\_url](/recipes/recipe_modules/tryserver/api.py#38)(self):** + +Returns canonical URL of the gitiles repo of the current Gerrit CL. + +Populated iff gerrit_change is populated. + +— **def [get\_files\_affected\_by\_patch](/recipes/recipe_modules/tryserver/api.py#67)(self, patch_root, \*\*kwargs):** Returns list of paths to files affected by the patch. @@ -781,34 +793,36 @@ Argument: Returned paths will be relative to to patch_root. -— **def [get\_footer](/recipes/recipe_modules/tryserver/api.py#162)(self, tag, patch_text=None):** +— **def [get\_footer](/recipes/recipe_modules/tryserver/api.py#192)(self, tag, patch_text=None):** Gets a specific tag from a CL description -— **def [get\_footers](/recipes/recipe_modules/tryserver/api.py#144)(self, patch_text=None):** +— **def [get\_footers](/recipes/recipe_modules/tryserver/api.py#173)(self, patch_text=None):** Retrieves footers from the patch description. footers are machine readable tags embedded in commit messages. See git-footers documentation for more information. -  **@property**
— **def [is\_gerrit\_issue](/recipes/recipe_modules/tryserver/api.py#22)(self):** +— **def [initialize](/recipes/recipe_modules/tryserver/api.py#19)(self):** + +  **@property**
— **def [is\_gerrit\_issue](/recipes/recipe_modules/tryserver/api.py#51)(self):** Returns true iff the properties exist to match a Gerrit issue. -  **@property**
— **def [is\_patch\_in\_git](/recipes/recipe_modules/tryserver/api.py#32)(self):** +  **@property**
— **def [is\_patch\_in\_git](/recipes/recipe_modules/tryserver/api.py#61)(self):** -  **@property**
— **def [is\_tryserver](/recipes/recipe_modules/tryserver/api.py#17)(self):** +  **@property**
— **def [is\_tryserver](/recipes/recipe_modules/tryserver/api.py#46)(self):** Returns true iff we have a change to check out. -— **def [normalize\_footer\_name](/recipes/recipe_modules/tryserver/api.py#166)(self, footer):** +— **def [normalize\_footer\_name](/recipes/recipe_modules/tryserver/api.py#196)(self, footer):** -— **def [set\_compile\_failure\_tryjob\_result](/recipes/recipe_modules/tryserver/api.py#87)(self):** +— **def [set\_compile\_failure\_tryjob\_result](/recipes/recipe_modules/tryserver/api.py#116)(self):** Mark the tryjob result as a compile failure. -  **@contextlib.contextmanager**
— **def [set\_failure\_hash](/recipes/recipe_modules/tryserver/api.py#117)(self):** +  **@contextlib.contextmanager**
— **def [set\_failure\_hash](/recipes/recipe_modules/tryserver/api.py#146)(self):** Context manager that sets a failure_hash build property on StepFailure. @@ -817,7 +831,7 @@ for the same reason. For example, if a patch is bad (breaks something), we'd expect it to always break in the same way. Different failures for the same patch are usually a sign of flakiness. -— **def [set\_invalid\_test\_results\_tryjob\_result](/recipes/recipe_modules/tryserver/api.py#99)(self):** +— **def [set\_invalid\_test\_results\_tryjob\_result](/recipes/recipe_modules/tryserver/api.py#128)(self):** Mark the tryjob result as having invalid test results. @@ -825,18 +839,18 @@ This means we run some tests, but the results were not valid (e.g. no list of specific test cases that failed, or too many tests failing, etc). -— **def [set\_patch\_failure\_tryjob\_result](/recipes/recipe_modules/tryserver/api.py#83)(self):** +— **def [set\_patch\_failure\_tryjob\_result](/recipes/recipe_modules/tryserver/api.py#112)(self):** Mark the tryjob result as failure to apply the patch. -— **def [set\_subproject\_tag](/recipes/recipe_modules/tryserver/api.py#65)(self, subproject_tag):** +— **def [set\_subproject\_tag](/recipes/recipe_modules/tryserver/api.py#94)(self, subproject_tag):** Adds a subproject tag to the build. This can be used to distinguish between builds that execute different steps depending on what was patched, e.g. blink vs. pure chromium patches. -— **def [set\_test\_failure\_tryjob\_result](/recipes/recipe_modules/tryserver/api.py#91)(self):** +— **def [set\_test\_failure\_tryjob\_result](/recipes/recipe_modules/tryserver/api.py#120)(self):** Mark the tryjob result as a test failure. @@ -959,9 +973,9 @@ Move things around in a loop! — **def [RunSteps](/recipes/recipe_modules/presubmit/examples/full.py#10)(api):** ### *recipes* / [tryserver:examples/full](/recipes/recipe_modules/tryserver/examples/full.py) -[DEPS](/recipes/recipe_modules/tryserver/examples/full.py#5): [tryserver](#recipe_modules-tryserver), [recipe\_engine/json][recipe_engine/recipe_modules/json], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/python][recipe_engine/recipe_modules/python], [recipe\_engine/raw\_io][recipe_engine/recipe_modules/raw_io], [recipe\_engine/step][recipe_engine/recipe_modules/step] +[DEPS](/recipes/recipe_modules/tryserver/examples/full.py#5): [tryserver](#recipe_modules-tryserver), [recipe\_engine/buildbucket][recipe_engine/recipe_modules/buildbucket], [recipe\_engine/json][recipe_engine/recipe_modules/json], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/python][recipe_engine/recipe_modules/python], [recipe\_engine/raw\_io][recipe_engine/recipe_modules/raw_io], [recipe\_engine/step][recipe_engine/recipe_modules/step] -— **def [RunSteps](/recipes/recipe_modules/tryserver/examples/full.py#17)(api):** +— **def [RunSteps](/recipes/recipe_modules/tryserver/examples/full.py#18)(api):** ### *recipes* / [windows\_sdk:examples/full](/recipes/recipe_modules/windows_sdk/examples/full.py) [DEPS](/recipes/recipe_modules/windows_sdk/examples/full.py#5): [windows\_sdk](#recipe_modules-windows_sdk), [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step] diff --git a/recipes/recipe_modules/tryserver/__init__.py b/recipes/recipe_modules/tryserver/__init__.py index 06c9d0b11..d40c8f490 100644 --- a/recipes/recipe_modules/tryserver/__init__.py +++ b/recipes/recipe_modules/tryserver/__init__.py @@ -6,6 +6,7 @@ DEPS = [ 'gerrit', 'git', 'git_cl', + 'recipe_engine/buildbucket', 'recipe_engine/context', 'recipe_engine/json', 'recipe_engine/path', diff --git a/recipes/recipe_modules/tryserver/api.py b/recipes/recipe_modules/tryserver/api.py index a970e1ffc..966d59b61 100644 --- a/recipes/recipe_modules/tryserver/api.py +++ b/recipes/recipe_modules/tryserver/api.py @@ -2,7 +2,6 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import collections import contextlib import hashlib @@ -14,6 +13,36 @@ class TryserverApi(recipe_api.RecipeApi): super(TryserverApi, self).__init__(*args, **kwargs) self._failure_reasons = [] + self._gerrit_change = None # self.m.buildbucket.common_pb2.GerritChange + self._gerrit_change_repo_url = None + + def initialize(self): + changes = self.m.buildbucket.build.input.gerrit_changes + if len(changes) == 1: + cl = changes[0] + self._gerrit_change = cl + git_host = cl.host + gs_suffix = '-review.googlesource.com' + if git_host.endswith(gs_suffix): + git_host = '%s.googlesource.com' % git_host[:-len(gs_suffix)] + self._gerrit_change_repo_url = 'https://%s/%s' % (git_host, cl.project) + + @property + def gerrit_change(self): + """Returns current gerrit change, if there is exactly one. + + Returns a self.m.buildbucket.common_pb2.GerritChange or None. + """ + return self._gerrit_change + + @property + def gerrit_change_repo_url(self): + """Returns canonical URL of the gitiles repo of the current Gerrit CL. + + Populated iff gerrit_change is populated. + """ + return self._gerrit_change_repo_url + @property def is_tryserver(self): """Returns true iff we have a change to check out.""" @@ -22,7 +51,7 @@ class TryserverApi(recipe_api.RecipeApi): @property def is_gerrit_issue(self): """Returns true iff the properties exist to match a Gerrit issue.""" - if self.m.properties.get('patch_storage') == 'gerrit': + if self.gerrit_change: return True # TODO(tandrii): remove this, once nobody is using buildbot Gerrit Poller. return ('event.patchSet.ref' in self.m.properties and @@ -148,10 +177,11 @@ class TryserverApi(recipe_api.RecipeApi): git-footers documentation for more information. """ if patch_text is None: - patch_text = self.m.gerrit.get_change_description( - self.m.properties['patch_gerrit_url'], - self.m.properties['patch_issue'], - self.m.properties['patch_set']) + if self.gerrit_change: + patch_text = self.m.gerrit.get_change_description( + 'https://%s' % self.gerrit_change.host, + int(self.gerrit_change.change), + int(self.gerrit_change.patchset)) result = self.m.python( 'parse description', self.package_repo_resource('git_footers.py'), diff --git a/recipes/recipe_modules/tryserver/examples/full.expected/with_gerrit_patch.json b/recipes/recipe_modules/tryserver/examples/full.expected/with_gerrit_patch.json index cf4e40ad8..d908b972e 100644 --- a/recipes/recipe_modules/tryserver/examples/full.expected/with_gerrit_patch.json +++ b/recipes/recipe_modules/tryserver/examples/full.expected/with_gerrit_patch.json @@ -12,7 +12,7 @@ "--limit", "1", "-p", - "change=456789", + "change=123456", "-o", "ALL_REVISIONS", "-o", @@ -49,7 +49,7 @@ }, { "name": "$result", - "reason": "Error querying for CL description: host:'https://chromium-review.googlesource.com' change:456789; patchset:12", + "reason": "Error querying for CL description: host:u'https://chromium-review.googlesource.com' change:123456; patchset:7", "recipe_result": null, "status_code": 1 } diff --git a/recipes/recipe_modules/tryserver/examples/full.py b/recipes/recipe_modules/tryserver/examples/full.py index d2548d7a4..b3a3ab3ee 100644 --- a/recipes/recipe_modules/tryserver/examples/full.py +++ b/recipes/recipe_modules/tryserver/examples/full.py @@ -3,6 +3,7 @@ # found in the LICENSE file. DEPS = [ + 'recipe_engine/buildbucket', 'recipe_engine/json', 'recipe_engine/raw_io', 'recipe_engine/path', @@ -28,6 +29,10 @@ def RunSteps(api): 'Foo', api.properties['patch_text']))]) return + if api.tryserver.gerrit_change: + assert (api.tryserver.gerrit_change_repo_url == + 'https://chromium.googlesource.com/chromium/src') + if api.tryserver.is_gerrit_issue: api.tryserver.get_footers() api.tryserver.get_files_affected_by_patch( @@ -75,7 +80,9 @@ def GenTests(api): api.properties(test_patch_root='')) yield (api.test('with_gerrit_patch') + - api.properties.tryserver(gerrit_project='infra/infra')) + api.buildbucket.try_build( + 'chromium', 'linux', + git_repo='https://chromium.googlesource.com/chromium/src')) yield (api.test('with_wrong_patch_new') + api.platform('win', 32) + api.properties(test_patch_root='sub\\project'))