Make bot_update and tryserver module not crash for multiple changes

Currently bot_update and tryserver crashes at initialization step if
the input contains multiple gerrit changes. This is not friendly for
CrOS CLs, e.g. crrev.com/c/2536761.

This CL moves the “crash” out of initialization, thus the consumer
of these modules could control which gerrit change to pass to bot_update
and tryserver.

This CL does NOT enable the modules here to support multiple patchset,
but allows consumers to choose one.

Bug:1146487
Change-Id: Iec46a8041189912e34da9bc5e8ff4611123ec9e0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/tools/depot_tools/+/2528670
Commit-Queue: Xinan Lin <linxinan@chromium.org>
Reviewed-by: Josip Sokcevic <sokcevic@google.com>
changes/70/2528670/14
Xinan Lin 5 years ago committed by LUCI CQ
parent fd5c198347
commit da73999f79

@ -54,16 +54,16 @@ Recipe module to ensure a checkout is consistent on a bot.
#### **class [BotUpdateApi](/recipes/recipe_modules/bot_update/api.py#12)([RecipeApi][recipe_engine/wkt/RecipeApi]):** #### **class [BotUpdateApi](/recipes/recipe_modules/bot_update/api.py#12)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
&mdash; **def [\_\_call\_\_](/recipes/recipe_modules/bot_update/api.py#27)(self, name, cmd, \*\*kwargs):** &mdash; **def [\_\_call\_\_](/recipes/recipe_modules/bot_update/api.py#22)(self, name, cmd, \*\*kwargs):**
Wrapper for easy calling of bot_update. Wrapper for easy calling of bot_update.
&mdash; **def [deapply\_patch](/recipes/recipe_modules/bot_update/api.py#524)(self, bot_update_step):** &mdash; **def [deapply\_patch](/recipes/recipe_modules/bot_update/api.py#529)(self, bot_update_step):**
Deapplies a patch, taking care of DEPS and solution revisions properly. Deapplies a patch, taking care of DEPS and solution revisions properly.
&mdash; **def [ensure\_checkout](/recipes/recipe_modules/bot_update/api.py#76)(self, gclient_config=None, suffix=None, patch=True, update_presentation=True, patch_root=None, with_branch_heads=False, with_tags=False, no_fetch_tags=False, refs=None, patch_oauth2=None, oauth2_json=None, use_site_config_creds=None, clobber=False, root_solution_revision=None, rietveld=None, issue=None, patchset=None, gerrit_no_reset=False, gerrit_no_rebase_patch_ref=False, disable_syntax_validation=False, patch_refs=None, ignore_input_commit=False, add_blamelists=False, set_output_commit=False, step_test_data=None, enforce_fetch=False, \*\*kwargs):** &mdash; **def [ensure\_checkout](/recipes/recipe_modules/bot_update/api.py#71)(self, gclient_config=None, suffix=None, patch=True, update_presentation=True, patch_root=None, with_branch_heads=False, with_tags=False, no_fetch_tags=False, refs=None, patch_oauth2=None, oauth2_json=None, use_site_config_creds=None, clobber=False, root_solution_revision=None, rietveld=None, issue=None, patchset=None, gerrit_no_reset=False, gerrit_no_rebase_patch_ref=False, accept_buildbucket_input=True, disable_syntax_validation=False, patch_refs=None, ignore_input_commit=False, add_blamelists=False, set_output_commit=False, step_test_data=None, enforce_fetch=False, \*\*kwargs):**
Args: Args:
* gclient_config: The gclient configuration to use when running bot_update. * gclient_config: The gclient configuration to use when running bot_update.
@ -90,8 +90,13 @@ Args:
Use test_api.output_json to generate test data. Use test_api.output_json to generate test data.
* enforce_fetch: Enforce a new fetch to refresh the git cache, even if the * enforce_fetch: Enforce a new fetch to refresh the git cache, even if the
solution revision passed in already exists in the current git cache. solution revision passed in already exists in the current git cache.
* accept_buildbucket_input: should get the patchset from
buildbucket.build.input.gerrit_changes. If True, the input size is
asserted to be one, because bot_update module ONLY supports one CL.
Users may specify a CL via tryserver.set_change() and explicitly set
this flag False.
&mdash; **def [get\_project\_revision\_properties](/recipes/recipe_modules/bot_update/api.py#501)(self, project_name, gclient_config=None):** &mdash; **def [get\_project\_revision\_properties](/recipes/recipe_modules/bot_update/api.py#506)(self, project_name, gclient_config=None):**
Returns all property names used for storing the checked-out revision of Returns all property names used for storing the checked-out revision of
a given project. a given project.
@ -105,11 +110,9 @@ Args:
Returns (list of str): All properties that'll hold the checked-out revision Returns (list of str): All properties that'll hold the checked-out revision
of the given project. An empty list if no such properties exist. of the given project. An empty list if no such properties exist.
&mdash; **def [initialize](/recipes/recipe_modules/bot_update/api.py#22)(self):** &emsp; **@property**<br>&mdash; **def [last\_returned\_properties](/recipes/recipe_modules/bot_update/api.py#39)(self):**
&emsp; **@property**<br>&mdash; **def [last\_returned\_properties](/recipes/recipe_modules/bot_update/api.py#44)(self):** &mdash; **def [resolve\_fixed\_revision](/recipes/recipe_modules/bot_update/api.py#457)(self, bot_update_json, name):**
&mdash; **def [resolve\_fixed\_revision](/recipes/recipe_modules/bot_update/api.py#452)(self, bot_update_json, name):**
Sets a fixed revision for a single dependency using project revision Sets a fixed revision for a single dependency using project revision
properties. properties.
@ -795,38 +798,38 @@ Returns:
#### **class [TryserverApi](/recipes/recipe_modules/tryserver/api.py#11)([RecipeApi][recipe_engine/wkt/RecipeApi]):** #### **class [TryserverApi](/recipes/recipe_modules/tryserver/api.py#11)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
&emsp; **@property**<br>&mdash; **def [gerrit\_change](/recipes/recipe_modules/tryserver/api.py#33)(self):** &emsp; **@property**<br>&mdash; **def [gerrit\_change](/recipes/recipe_modules/tryserver/api.py#27)(self):**
Returns current gerrit change, if there is exactly one. Returns current gerrit change, if there is exactly one.
Returns a self.m.buildbucket.common_pb2.GerritChange or None. Returns a self.m.buildbucket.common_pb2.GerritChange or None.
&emsp; **@property**<br>&mdash; **def [gerrit\_change\_fetch\_ref](/recipes/recipe_modules/tryserver/api.py#110)(self):** &emsp; **@property**<br>&mdash; **def [gerrit\_change\_fetch\_ref](/recipes/recipe_modules/tryserver/api.py#104)(self):**
Returns gerrit patch ref, e.g. "refs/heads/45/12345/6, or None. Returns gerrit patch ref, e.g. "refs/heads/45/12345/6, or None.
Populated iff gerrit_change is populated. Populated iff gerrit_change is populated.
&emsp; **@property**<br>&mdash; **def [gerrit\_change\_owner](/recipes/recipe_modules/tryserver/api.py#49)(self):** &emsp; **@property**<br>&mdash; **def [gerrit\_change\_owner](/recipes/recipe_modules/tryserver/api.py#43)(self):**
Returns owner of the current Gerrit CL. Returns owner of the current Gerrit CL.
Populated iff gerrit_change is populated. Populated iff gerrit_change is populated.
Is a dictionary with keys like "name". Is a dictionary with keys like "name".
&emsp; **@property**<br>&mdash; **def [gerrit\_change\_repo\_url](/recipes/recipe_modules/tryserver/api.py#41)(self):** &emsp; **@property**<br>&mdash; **def [gerrit\_change\_repo\_url](/recipes/recipe_modules/tryserver/api.py#35)(self):**
Returns canonical URL of the gitiles repo of the current Gerrit CL. Returns canonical URL of the gitiles repo of the current Gerrit CL.
Populated iff gerrit_change is populated. Populated iff gerrit_change is populated.
&emsp; **@property**<br>&mdash; **def [gerrit\_change\_target\_ref](/recipes/recipe_modules/tryserver/api.py#119)(self):** &emsp; **@property**<br>&mdash; **def [gerrit\_change\_target\_ref](/recipes/recipe_modules/tryserver/api.py#113)(self):**
Returns gerrit change destination ref, e.g. "refs/heads/master". Returns gerrit change destination ref, e.g. "refs/heads/master".
Populated iff gerrit_change is populated. Populated iff gerrit_change is populated.
&mdash; **def [get\_files\_affected\_by\_patch](/recipes/recipe_modules/tryserver/api.py#149)(self, patch_root, \*\*kwargs):** &mdash; **def [get\_files\_affected\_by\_patch](/recipes/recipe_modules/tryserver/api.py#143)(self, patch_root, \*\*kwargs):**
Returns list of paths to files affected by the patch. Returns list of paths to files affected by the patch.
@ -836,11 +839,11 @@ Args:
Returned paths will be relative to to patch_root. Returned paths will be relative to to patch_root.
&mdash; **def [get\_footer](/recipes/recipe_modules/tryserver/api.py#259)(self, tag, patch_text=None):** &mdash; **def [get\_footer](/recipes/recipe_modules/tryserver/api.py#253)(self, tag, patch_text=None):**
Gets a specific tag from a CL description Gets a specific tag from a CL description
&mdash; **def [get\_footers](/recipes/recipe_modules/tryserver/api.py#239)(self, patch_text=None):** &mdash; **def [get\_footers](/recipes/recipe_modules/tryserver/api.py#233)(self, patch_text=None):**
Retrieves footers from the patch description. Retrieves footers from the patch description.
@ -849,23 +852,30 @@ git-footers documentation for more information.
&mdash; **def [initialize](/recipes/recipe_modules/tryserver/api.py#22)(self):** &mdash; **def [initialize](/recipes/recipe_modules/tryserver/api.py#22)(self):**
&emsp; **@property**<br>&mdash; **def [is\_gerrit\_issue](/recipes/recipe_modules/tryserver/api.py#133)(self):** &emsp; **@property**<br>&mdash; **def [is\_gerrit\_issue](/recipes/recipe_modules/tryserver/api.py#127)(self):**
Returns true iff the properties exist to match a Gerrit issue. Returns true iff the properties exist to match a Gerrit issue.
&emsp; **@property**<br>&mdash; **def [is\_patch\_in\_git](/recipes/recipe_modules/tryserver/api.py#143)(self):** &emsp; **@property**<br>&mdash; **def [is\_patch\_in\_git](/recipes/recipe_modules/tryserver/api.py#137)(self):**
&emsp; **@property**<br>&mdash; **def [is\_tryserver](/recipes/recipe_modules/tryserver/api.py#128)(self):** &emsp; **@property**<br>&mdash; **def [is\_tryserver](/recipes/recipe_modules/tryserver/api.py#122)(self):**
Returns true iff we have a change to check out. Returns true iff we have a change to check out.
&mdash; **def [normalize\_footer\_name](/recipes/recipe_modules/tryserver/api.py#263)(self, footer):** &mdash; **def [normalize\_footer\_name](/recipes/recipe_modules/tryserver/api.py#257)(self, footer):**
&mdash; **def [set\_change](/recipes/recipe_modules/tryserver/api.py#260)(self, change):**
Set the gerrit change for this module.
Args:
* cl: a GerritChange object.
&mdash; **def [set\_compile\_failure\_tryjob\_result](/recipes/recipe_modules/tryserver/api.py#202)(self):** &mdash; **def [set\_compile\_failure\_tryjob\_result](/recipes/recipe_modules/tryserver/api.py#196)(self):**
Mark the tryjob result as a compile failure. Mark the tryjob result as a compile failure.
&mdash; **def [set\_invalid\_test\_results\_tryjob\_result](/recipes/recipe_modules/tryserver/api.py#214)(self):** &mdash; **def [set\_invalid\_test\_results\_tryjob\_result](/recipes/recipe_modules/tryserver/api.py#208)(self):**
Mark the tryjob result as having invalid test results. Mark the tryjob result as having invalid test results.
@ -873,32 +883,32 @@ 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 (e.g. no list of specific test cases that failed, or too many
tests failing, etc). tests failing, etc).
&mdash; **def [set\_patch\_failure\_tryjob\_result](/recipes/recipe_modules/tryserver/api.py#198)(self):** &mdash; **def [set\_patch\_failure\_tryjob\_result](/recipes/recipe_modules/tryserver/api.py#192)(self):**
Mark the tryjob result as failure to apply the patch. Mark the tryjob result as failure to apply the patch.
&mdash; **def [set\_subproject\_tag](/recipes/recipe_modules/tryserver/api.py#176)(self, subproject_tag):** &mdash; **def [set\_subproject\_tag](/recipes/recipe_modules/tryserver/api.py#170)(self, subproject_tag):**
Adds a subproject tag to the build. Adds a subproject tag to the build.
This can be used to distinguish between builds that execute different steps This can be used to distinguish between builds that execute different steps
depending on what was patched, e.g. blink vs. pure chromium patches. depending on what was patched, e.g. blink vs. pure chromium patches.
&mdash; **def [set\_test\_expired\_tryjob\_result](/recipes/recipe_modules/tryserver/api.py#231)(self):** &mdash; **def [set\_test\_expired\_tryjob\_result](/recipes/recipe_modules/tryserver/api.py#225)(self):**
Mark the tryjob result as a test expiration. Mark the tryjob result as a test expiration.
This means a test task expired and was never scheduled, most likely due to This means a test task expired and was never scheduled, most likely due to
lack of capacity. lack of capacity.
&mdash; **def [set\_test\_failure\_tryjob\_result](/recipes/recipe_modules/tryserver/api.py#206)(self):** &mdash; **def [set\_test\_failure\_tryjob\_result](/recipes/recipe_modules/tryserver/api.py#200)(self):**
Mark the tryjob result as a test failure. Mark the tryjob result as a test failure.
This means we started running actual tests (not prerequisite steps This means we started running actual tests (not prerequisite steps
like checkout or compile), and some of these tests have failed. like checkout or compile), and some of these tests have failed.
&mdash; **def [set\_test\_timeout\_tryjob\_result](/recipes/recipe_modules/tryserver/api.py#223)(self):** &mdash; **def [set\_test\_timeout\_tryjob\_result](/recipes/recipe_modules/tryserver/api.py#217)(self):**
Mark the tryjob result as a test timeout. Mark the tryjob result as a test timeout.
@ -1051,7 +1061,7 @@ Move things around in a loop!
[DEPS](/recipes/recipe_modules/tryserver/examples/full.py#5): [gerrit](#recipe_modules-gerrit), [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] [DEPS](/recipes/recipe_modules/tryserver/examples/full.py#5): [gerrit](#recipe_modules-gerrit), [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]
&mdash; **def [RunSteps](/recipes/recipe_modules/tryserver/examples/full.py#19)(api):** &mdash; **def [RunSteps](/recipes/recipe_modules/tryserver/examples/full.py#21)(api):**
### *recipes* / [tryserver:tests/gerrit\_change\_fetch\_ref\_timeout](/recipes/recipe_modules/tryserver/tests/gerrit_change_fetch_ref_timeout.py) ### *recipes* / [tryserver:tests/gerrit\_change\_fetch\_ref\_timeout](/recipes/recipe_modules/tryserver/tests/gerrit_change_fetch_ref_timeout.py)
[DEPS](/recipes/recipe_modules/tryserver/tests/gerrit_change_fetch_ref_timeout.py#7): [gerrit](#recipe_modules-gerrit), [tryserver](#recipe_modules-tryserver), [recipe\_engine/buildbucket][recipe_engine/recipe_modules/buildbucket], [recipe\_engine/properties][recipe_engine/recipe_modules/properties] [DEPS](/recipes/recipe_modules/tryserver/tests/gerrit_change_fetch_ref_timeout.py#7): [gerrit](#recipe_modules-gerrit), [tryserver](#recipe_modules-tryserver), [recipe\_engine/buildbucket][recipe_engine/recipe_modules/buildbucket], [recipe\_engine/properties][recipe_engine/recipe_modules/properties]

@ -19,11 +19,6 @@ class BotUpdateApi(recipe_api.RecipeApi):
self._last_returned_properties = {} self._last_returned_properties = {}
super(BotUpdateApi, self).__init__(*args, **kwargs) super(BotUpdateApi, self).__init__(*args, **kwargs)
def initialize(self):
assert len(self.m.buildbucket.build.input.gerrit_changes) <= 1, (
'bot_update does not support more than one '
'buildbucket.build.input.gerrit_changes')
def __call__(self, name, cmd, **kwargs): def __call__(self, name, cmd, **kwargs):
"""Wrapper for easy calling of bot_update.""" """Wrapper for easy calling of bot_update."""
assert isinstance(cmd, (list, tuple)) assert isinstance(cmd, (list, tuple))
@ -93,6 +88,7 @@ class BotUpdateApi(recipe_api.RecipeApi):
patchset=None, patchset=None,
gerrit_no_reset=False, gerrit_no_reset=False,
gerrit_no_rebase_patch_ref=False, gerrit_no_rebase_patch_ref=False,
accept_buildbucket_input=True,
disable_syntax_validation=False, disable_syntax_validation=False,
patch_refs=None, patch_refs=None,
ignore_input_commit=False, ignore_input_commit=False,
@ -127,6 +123,11 @@ class BotUpdateApi(recipe_api.RecipeApi):
Use test_api.output_json to generate test data. Use test_api.output_json to generate test data.
* enforce_fetch: Enforce a new fetch to refresh the git cache, even if the * enforce_fetch: Enforce a new fetch to refresh the git cache, even if the
solution revision passed in already exists in the current git cache. solution revision passed in already exists in the current git cache.
* accept_buildbucket_input: should get the patchset from
buildbucket.build.input.gerrit_changes. If True, the input size is
asserted to be one, because bot_update module ONLY supports one CL.
Users may specify a CL via tryserver.set_change() and explicitly set
this flag False.
""" """
assert use_site_config_creds is None, "use_site_config_creds is deprecated" assert use_site_config_creds is None, "use_site_config_creds is deprecated"
assert rietveld is None, "rietveld is deprecated" assert rietveld is None, "rietveld is deprecated"
@ -135,6 +136,10 @@ class BotUpdateApi(recipe_api.RecipeApi):
assert patch_oauth2 is None, "patch_oauth2 is deprecated" assert patch_oauth2 is None, "patch_oauth2 is deprecated"
assert oauth2_json is None, "oauth2_json is deprecated" assert oauth2_json is None, "oauth2_json is deprecated"
assert not (ignore_input_commit and set_output_commit) assert not (ignore_input_commit and set_output_commit)
if accept_buildbucket_input:
assert len(self.m.buildbucket.build.input.gerrit_changes) <= 1, (
'bot_update does not support more than one '
'buildbucket.build.input.gerrit_changes')
refs = refs or [] refs = refs or []
# We can re-use the gclient spec from the gclient module, since all the # We can re-use the gclient spec from the gclient module, since all the

@ -22,13 +22,7 @@ class TryserverApi(recipe_api.RecipeApi):
def initialize(self): def initialize(self):
changes = self.m.buildbucket.build.input.gerrit_changes changes = self.m.buildbucket.build.input.gerrit_changes
if len(changes) == 1: if len(changes) == 1:
cl = changes[0] self.set_change(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 @property
def gerrit_change(self): def gerrit_change(self):
@ -262,3 +256,17 @@ class TryserverApi(recipe_api.RecipeApi):
def normalize_footer_name(self, footer): def normalize_footer_name(self, footer):
return '-'.join([ word.title() for word in footer.strip().split('-') ]) return '-'.join([ word.title() for word in footer.strip().split('-') ])
def set_change(self, change):
"""Set the gerrit change for this module.
Args:
* cl: a GerritChange object.
"""
self._gerrit_info_initialized = False
self._gerrit_change = change
git_host = change.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, change.project)

@ -184,6 +184,49 @@
"@@@STEP_FAILURE@@@" "@@@STEP_FAILURE@@@"
] ]
}, },
{
"cmd": [
"vpython",
"-u",
"RECIPE_REPO[depot_tools]/gerrit_client.py",
"changes",
"--host",
"https://chromium-review.googlesource.com",
"--json_file",
"/path/to/tmp/json",
"--limit",
"1",
"-p",
"change=1234567",
"-o",
"ALL_REVISIONS",
"-o",
"DOWNLOAD_COMMANDS"
],
"env": {
"PATH": "<PATH>:RECIPE_REPO[depot_tools]"
},
"infra_step": true,
"name": "gerrit fetch current CL info (2)",
"timeout": 600,
"~followup_annotations": [
"@@@STEP_LOG_LINE@json.output@[@@@",
"@@@STEP_LOG_LINE@json.output@ {@@@",
"@@@STEP_LOG_LINE@json.output@ \"branch\": \"master\", @@@",
"@@@STEP_LOG_LINE@json.output@ \"owner\": {@@@",
"@@@STEP_LOG_LINE@json.output@ \"name\": \"John Doe\"@@@",
"@@@STEP_LOG_LINE@json.output@ }, @@@",
"@@@STEP_LOG_LINE@json.output@ \"revisions\": {@@@",
"@@@STEP_LOG_LINE@json.output@ \"184ebe53805e102605d11f6b143486d15c23a09c\": {@@@",
"@@@STEP_LOG_LINE@json.output@ \"_number\": \"1\", @@@",
"@@@STEP_LOG_LINE@json.output@ \"ref\": \"refs/changes/67/1234567/1\"@@@",
"@@@STEP_LOG_LINE@json.output@ }@@@",
"@@@STEP_LOG_LINE@json.output@ }@@@",
"@@@STEP_LOG_LINE@json.output@ }@@@",
"@@@STEP_LOG_LINE@json.output@]@@@",
"@@@STEP_LOG_END@json.output@@@"
]
},
{ {
"name": "$result" "name": "$result"
} }

@ -184,6 +184,49 @@
"@@@STEP_FAILURE@@@" "@@@STEP_FAILURE@@@"
] ]
}, },
{
"cmd": [
"vpython",
"-u",
"RECIPE_REPO[depot_tools]/gerrit_client.py",
"changes",
"--host",
"https://chromium-review.googlesource.com",
"--json_file",
"/path/to/tmp/json",
"--limit",
"1",
"-p",
"change=1234567",
"-o",
"ALL_REVISIONS",
"-o",
"DOWNLOAD_COMMANDS"
],
"env": {
"PATH": "<PATH>:RECIPE_REPO[depot_tools]"
},
"infra_step": true,
"name": "gerrit fetch current CL info (2)",
"timeout": 600,
"~followup_annotations": [
"@@@STEP_LOG_LINE@json.output@[@@@",
"@@@STEP_LOG_LINE@json.output@ {@@@",
"@@@STEP_LOG_LINE@json.output@ \"branch\": \"refs/heads/experiment\", @@@",
"@@@STEP_LOG_LINE@json.output@ \"owner\": {@@@",
"@@@STEP_LOG_LINE@json.output@ \"name\": \"John Doe\"@@@",
"@@@STEP_LOG_LINE@json.output@ }, @@@",
"@@@STEP_LOG_LINE@json.output@ \"revisions\": {@@@",
"@@@STEP_LOG_LINE@json.output@ \"184ebe53805e102605d11f6b143486d15c23a09c\": {@@@",
"@@@STEP_LOG_LINE@json.output@ \"_number\": \"1\", @@@",
"@@@STEP_LOG_LINE@json.output@ \"ref\": \"refs/changes/67/1234567/1\"@@@",
"@@@STEP_LOG_LINE@json.output@ }@@@",
"@@@STEP_LOG_LINE@json.output@ }@@@",
"@@@STEP_LOG_LINE@json.output@ }@@@",
"@@@STEP_LOG_LINE@json.output@]@@@",
"@@@STEP_LOG_END@json.output@@@"
]
},
{ {
"name": "$result" "name": "$result"
} }

@ -15,6 +15,49 @@
"@@@STEP_LOG_END@files@@@" "@@@STEP_LOG_END@files@@@"
] ]
}, },
{
"cmd": [
"vpython",
"-u",
"RECIPE_REPO[depot_tools]\\gerrit_client.py",
"changes",
"--host",
"https://chromium-review.googlesource.com",
"--json_file",
"/path/to/tmp/json",
"--limit",
"1",
"-p",
"change=1234567",
"-o",
"ALL_REVISIONS",
"-o",
"DOWNLOAD_COMMANDS"
],
"env": {
"PATH": "<PATH>;RECIPE_REPO[depot_tools]"
},
"infra_step": true,
"name": "gerrit fetch current CL info",
"timeout": 600,
"~followup_annotations": [
"@@@STEP_LOG_LINE@json.output@[@@@",
"@@@STEP_LOG_LINE@json.output@ {@@@",
"@@@STEP_LOG_LINE@json.output@ \"branch\": \"master\", @@@",
"@@@STEP_LOG_LINE@json.output@ \"owner\": {@@@",
"@@@STEP_LOG_LINE@json.output@ \"name\": \"John Doe\"@@@",
"@@@STEP_LOG_LINE@json.output@ }, @@@",
"@@@STEP_LOG_LINE@json.output@ \"revisions\": {@@@",
"@@@STEP_LOG_LINE@json.output@ \"184ebe53805e102605d11f6b143486d15c23a09c\": {@@@",
"@@@STEP_LOG_LINE@json.output@ \"_number\": \"1\", @@@",
"@@@STEP_LOG_LINE@json.output@ \"ref\": \"refs/changes/67/1234567/1\"@@@",
"@@@STEP_LOG_LINE@json.output@ }@@@",
"@@@STEP_LOG_LINE@json.output@ }@@@",
"@@@STEP_LOG_LINE@json.output@ }@@@",
"@@@STEP_LOG_LINE@json.output@]@@@",
"@@@STEP_LOG_END@json.output@@@"
]
},
{ {
"name": "$result" "name": "$result"
} }

@ -16,6 +16,49 @@
"@@@STEP_LOG_END@files@@@" "@@@STEP_LOG_END@files@@@"
] ]
}, },
{
"cmd": [
"vpython",
"-u",
"RECIPE_REPO[depot_tools]\\gerrit_client.py",
"changes",
"--host",
"https://chromium-review.googlesource.com",
"--json_file",
"/path/to/tmp/json",
"--limit",
"1",
"-p",
"change=1234567",
"-o",
"ALL_REVISIONS",
"-o",
"DOWNLOAD_COMMANDS"
],
"env": {
"PATH": "<PATH>;RECIPE_REPO[depot_tools]"
},
"infra_step": true,
"name": "gerrit fetch current CL info",
"timeout": 600,
"~followup_annotations": [
"@@@STEP_LOG_LINE@json.output@[@@@",
"@@@STEP_LOG_LINE@json.output@ {@@@",
"@@@STEP_LOG_LINE@json.output@ \"branch\": \"master\", @@@",
"@@@STEP_LOG_LINE@json.output@ \"owner\": {@@@",
"@@@STEP_LOG_LINE@json.output@ \"name\": \"John Doe\"@@@",
"@@@STEP_LOG_LINE@json.output@ }, @@@",
"@@@STEP_LOG_LINE@json.output@ \"revisions\": {@@@",
"@@@STEP_LOG_LINE@json.output@ \"184ebe53805e102605d11f6b143486d15c23a09c\": {@@@",
"@@@STEP_LOG_LINE@json.output@ \"_number\": \"1\", @@@",
"@@@STEP_LOG_LINE@json.output@ \"ref\": \"refs/changes/67/1234567/1\"@@@",
"@@@STEP_LOG_LINE@json.output@ }@@@",
"@@@STEP_LOG_LINE@json.output@ }@@@",
"@@@STEP_LOG_LINE@json.output@ }@@@",
"@@@STEP_LOG_LINE@json.output@]@@@",
"@@@STEP_LOG_END@json.output@@@"
]
},
{ {
"name": "$result" "name": "$result"
} }

@ -15,6 +15,8 @@ DEPS = [
'tryserver', 'tryserver',
] ]
from PB.go.chromium.org.luci.buildbucket.proto.common import GerritChange
def RunSteps(api): def RunSteps(api):
api.path['checkout'] = api.path['start_dir'] api.path['checkout'] = api.path['start_dir']
@ -51,6 +53,15 @@ def RunSteps(api):
api.tryserver.normalize_footer_name('Cr-Commit-Position') api.tryserver.normalize_footer_name('Cr-Commit-Position')
api.tryserver.set_change(
GerritChange(host='chromium-review.googlesource.com',
project='infra/luci/recipes-py',
change=1234567,
patchset=1))
assert (api.tryserver.gerrit_change_repo_url ==
'https://chromium.googlesource.com/infra/luci/recipes-py')
assert api.tryserver.gerrit_change_fetch_ref == 'refs/changes/67/1234567/1'
def GenTests(api): def GenTests(api):
# The 'test_patch_root' property used below is just so that these # The 'test_patch_root' property used below is just so that these

Loading…
Cancel
Save