Rerun: Get non-green source build for flaky builders
We have builders that we don't expect to be green ever but we still
want to rerun them.
Bug: 39904
Change-Id: I0ee717a34f38cf67a977d5b7412b414049598af7
diff --git a/recipe_modules/buildbucket_util/api.py b/recipe_modules/buildbucket_util/api.py
index 9b1855a..a4bb48c 100644
--- a/recipe_modules/buildbucket_util/api.py
+++ b/recipe_modules/buildbucket_util/api.py
@@ -88,7 +88,7 @@
failure_message,
)
- def last_green_build(self, project, bucket, builder, fields=None):
+ def last_build(self, project, bucket, builder, fields=None, status=None):
"""Returns the build proto for a builder's most recent successful build.
Returns None if no successful builds could be found.
@@ -99,12 +99,15 @@
builder (str): BuildBucket builder.
fields (seq of str): BuildBucket Build proto message fields to include in
the result. If None, defaults to api.buildbucket.DEFAULT_FIELDS.
+ status (common_pb2.Status enum member): If set, will return the
+ last build with this status.
"""
predicate = rpc_pb2.BuildPredicate()
predicate.builder.project = project
predicate.builder.bucket = bucket
predicate.builder.builder = builder
- predicate.status = common_pb2.SUCCESS
+ if status is not None:
+ predicate.status = status
fields = fields or self.m.buildbucket.DEFAULT_FIELDS
builds = self.m.buildbucket.search(predicate, limit=1, fields=fields)
diff --git a/recipe_modules/buildbucket_util/examples/full.expected/basic_tryjob.json b/recipe_modules/buildbucket_util/examples/full.expected/basic_tryjob.json
index ae484fb..40c1ee0 100644
--- a/recipe_modules/buildbucket_util/examples/full.expected/basic_tryjob.json
+++ b/recipe_modules/buildbucket_util/examples/full.expected/basic_tryjob.json
@@ -144,7 +144,7 @@
],
"infra_step": true,
"name": "buildbucket.search",
- "stdin": "{\"requests\": [{\"searchBuilds\": {\"fields\": \"builds.*.builder,builds.*.createTime,builds.*.createdBy,builds.*.critical,builds.*.endTime,builds.*.id,builds.*.input,builds.*.number,builds.*.output,builds.*.startTime,builds.*.status,builds.*.updateTime\", \"pageSize\": 1, \"predicate\": {\"builder\": {}, \"status\": \"SUCCESS\"}}}]}",
+ "stdin": "{\"requests\": [{\"searchBuilds\": {\"fields\": \"builds.*.builder,builds.*.createTime,builds.*.createdBy,builds.*.critical,builds.*.endTime,builds.*.id,builds.*.input,builds.*.number,builds.*.output,builds.*.startTime,builds.*.status,builds.*.updateTime\", \"pageSize\": 1, \"predicate\": {\"builder\": {}, \"status\": \"FAILURE\"}}}]}",
"~followup_annotations": [
"@@@STEP_LOG_LINE@json.output@{@@@",
"@@@STEP_LOG_LINE@json.output@ \"responses\": [@@@",
@@ -188,7 +188,7 @@
"@@@STEP_LOG_LINE@request@ \"pageSize\": 1, @@@",
"@@@STEP_LOG_LINE@request@ \"predicate\": {@@@",
"@@@STEP_LOG_LINE@request@ \"builder\": {}, @@@",
- "@@@STEP_LOG_LINE@request@ \"status\": \"SUCCESS\"@@@",
+ "@@@STEP_LOG_LINE@request@ \"status\": \"FAILURE\"@@@",
"@@@STEP_LOG_LINE@request@ }@@@",
"@@@STEP_LOG_LINE@request@ }@@@",
"@@@STEP_LOG_LINE@request@ }@@@",
diff --git a/recipe_modules/buildbucket_util/examples/full.expected/led_job.json b/recipe_modules/buildbucket_util/examples/full.expected/led_job.json
index 74683af..4fbe8c9 100644
--- a/recipe_modules/buildbucket_util/examples/full.expected/led_job.json
+++ b/recipe_modules/buildbucket_util/examples/full.expected/led_job.json
@@ -144,7 +144,7 @@
],
"infra_step": true,
"name": "buildbucket.search",
- "stdin": "{\"requests\": [{\"searchBuilds\": {\"fields\": \"builds.*.builder,builds.*.createTime,builds.*.createdBy,builds.*.critical,builds.*.endTime,builds.*.id,builds.*.input,builds.*.number,builds.*.output,builds.*.startTime,builds.*.status,builds.*.updateTime\", \"pageSize\": 1, \"predicate\": {\"builder\": {}, \"status\": \"SUCCESS\"}}}]}",
+ "stdin": "{\"requests\": [{\"searchBuilds\": {\"fields\": \"builds.*.builder,builds.*.createTime,builds.*.createdBy,builds.*.critical,builds.*.endTime,builds.*.id,builds.*.input,builds.*.number,builds.*.output,builds.*.startTime,builds.*.status,builds.*.updateTime\", \"pageSize\": 1, \"predicate\": {\"builder\": {}, \"status\": \"FAILURE\"}}}]}",
"~followup_annotations": [
"@@@STEP_LOG_LINE@json.output@{}@@@",
"@@@STEP_LOG_END@json.output@@@",
@@ -156,7 +156,7 @@
"@@@STEP_LOG_LINE@request@ \"pageSize\": 1, @@@",
"@@@STEP_LOG_LINE@request@ \"predicate\": {@@@",
"@@@STEP_LOG_LINE@request@ \"builder\": {}, @@@",
- "@@@STEP_LOG_LINE@request@ \"status\": \"SUCCESS\"@@@",
+ "@@@STEP_LOG_LINE@request@ \"status\": \"FAILURE\"@@@",
"@@@STEP_LOG_LINE@request@ }@@@",
"@@@STEP_LOG_LINE@request@ }@@@",
"@@@STEP_LOG_LINE@request@ }@@@",
diff --git a/recipe_modules/buildbucket_util/examples/full.py b/recipe_modules/buildbucket_util/examples/full.py
index c8eab61..71848eb 100644
--- a/recipe_modules/buildbucket_util/examples/full.py
+++ b/recipe_modules/buildbucket_util/examples/full.py
@@ -2,6 +2,8 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+from PB.go.chromium.org.luci.buildbucket.proto import common as common_pb2
+
DEPS = [
'fuchsia/buildbucket_util',
'fuchsia/status_check',
@@ -25,10 +27,11 @@
raise_on_failure=True,
)
build = builds.values()[0]
- api.buildbucket_util.last_green_build(
+ api.buildbucket_util.last_build(
build.builder.project,
build.builder.bucket,
build.builder.builder,
+ status=common_pb2.FAILURE,
)
# pylint: disable=pointless-statement
diff --git a/recipes/fuchsia/rerun.expected/no_search_results.json b/recipes/fuchsia/rerun.expected/no_search_results.json
index af2f8c4..afaab3b 100644
--- a/recipes/fuchsia/rerun.expected/no_search_results.json
+++ b/recipes/fuchsia/rerun.expected/no_search_results.json
@@ -8,7 +8,7 @@
],
"infra_step": true,
"name": "buildbucket.search",
- "stdin": "{\"requests\": [{\"searchBuilds\": {\"fields\": \"builds.*.builder,builds.*.createTime,builds.*.createdBy,builds.*.critical,builds.*.endTime,builds.*.id,builds.*.input,builds.*.number,builds.*.output,builds.*.startTime,builds.*.status,builds.*.updateTime\", \"pageSize\": 1, \"predicate\": {\"builder\": {\"bucket\": \"source-bucket\", \"builder\": \"source-builder\", \"project\": \"project\"}, \"status\": \"SUCCESS\"}}}]}",
+ "stdin": "{\"requests\": [{\"searchBuilds\": {\"fields\": \"builds.*.builder,builds.*.createTime,builds.*.createdBy,builds.*.critical,builds.*.endTime,builds.*.id,builds.*.input,builds.*.number,builds.*.output,builds.*.startTime,builds.*.status,builds.*.updateTime\", \"pageSize\": 1, \"predicate\": {\"builder\": {\"bucket\": \"source-bucket\", \"builder\": \"source-builder-flaky\", \"project\": \"project\"}}}}]}",
"~followup_annotations": [
"@@@STEP_LOG_LINE@json.output@{}@@@",
"@@@STEP_LOG_END@json.output@@@",
@@ -21,10 +21,9 @@
"@@@STEP_LOG_LINE@request@ \"predicate\": {@@@",
"@@@STEP_LOG_LINE@request@ \"builder\": {@@@",
"@@@STEP_LOG_LINE@request@ \"bucket\": \"source-bucket\", @@@",
- "@@@STEP_LOG_LINE@request@ \"builder\": \"source-builder\", @@@",
+ "@@@STEP_LOG_LINE@request@ \"builder\": \"source-builder-flaky\", @@@",
"@@@STEP_LOG_LINE@request@ \"project\": \"project\"@@@",
- "@@@STEP_LOG_LINE@request@ }, @@@",
- "@@@STEP_LOG_LINE@request@ \"status\": \"SUCCESS\"@@@",
+ "@@@STEP_LOG_LINE@request@ }@@@",
"@@@STEP_LOG_LINE@request@ }@@@",
"@@@STEP_LOG_LINE@request@ }@@@",
"@@@STEP_LOG_LINE@request@ }@@@",
@@ -35,7 +34,7 @@
},
{
"failure": {
- "humanReason": "Failed to find source_build for builder project/source-bucket/source-builder"
+ "humanReason": "Failed to find source_build for builder project/source-bucket/source-builder-flaky"
},
"name": "$result"
}
diff --git a/recipes/fuchsia/rerun.expected/success.json b/recipes/fuchsia/rerun.expected/success.json
index baaf957..f3a52eb 100644
--- a/recipes/fuchsia/rerun.expected/success.json
+++ b/recipes/fuchsia/rerun.expected/success.json
@@ -8,7 +8,7 @@
],
"infra_step": true,
"name": "buildbucket.search",
- "stdin": "{\"requests\": [{\"searchBuilds\": {\"fields\": \"builds.*.builder,builds.*.createTime,builds.*.createdBy,builds.*.critical,builds.*.endTime,builds.*.id,builds.*.input,builds.*.number,builds.*.output,builds.*.startTime,builds.*.status,builds.*.updateTime\", \"pageSize\": 1, \"predicate\": {\"builder\": {\"bucket\": \"source-bucket\", \"builder\": \"source-builder\", \"project\": \"project\"}, \"status\": \"SUCCESS\"}}}]}",
+ "stdin": "{\"requests\": [{\"searchBuilds\": {\"fields\": \"builds.*.builder,builds.*.createTime,builds.*.createdBy,builds.*.critical,builds.*.endTime,builds.*.id,builds.*.input,builds.*.number,builds.*.output,builds.*.startTime,builds.*.status,builds.*.updateTime\", \"pageSize\": 1, \"predicate\": {\"builder\": {\"bucket\": \"source-bucket\", \"builder\": \"source-builder-flaky\", \"project\": \"project\"}}}}]}",
"~followup_annotations": [
"@@@STEP_LOG_LINE@json.output@{@@@",
"@@@STEP_LOG_LINE@json.output@ \"responses\": [@@@",
@@ -58,10 +58,9 @@
"@@@STEP_LOG_LINE@request@ \"predicate\": {@@@",
"@@@STEP_LOG_LINE@request@ \"builder\": {@@@",
"@@@STEP_LOG_LINE@request@ \"bucket\": \"source-bucket\", @@@",
- "@@@STEP_LOG_LINE@request@ \"builder\": \"source-builder\", @@@",
+ "@@@STEP_LOG_LINE@request@ \"builder\": \"source-builder-flaky\", @@@",
"@@@STEP_LOG_LINE@request@ \"project\": \"project\"@@@",
- "@@@STEP_LOG_LINE@request@ }, @@@",
- "@@@STEP_LOG_LINE@request@ \"status\": \"SUCCESS\"@@@",
+ "@@@STEP_LOG_LINE@request@ }@@@",
"@@@STEP_LOG_LINE@request@ }@@@",
"@@@STEP_LOG_LINE@request@ }@@@",
"@@@STEP_LOG_LINE@request@ }@@@",
@@ -80,7 +79,7 @@
],
"infra_step": true,
"name": "buildbucket.schedule",
- "stdin": "{\"requests\": [{\"scheduleBuild\": {\"builder\": {\"bucket\": \"rerun\", \"builder\": \"source-builder\", \"project\": \"project\"}, \"experimental\": \"NO\", \"fields\": \"builder,createTime,createdBy,critical,endTime,id,input,number,output,startTime,status,updateTime\", \"gitilesCommit\": {\"host\": \"chromium.googlesource.com\", \"id\": \"2d72510e447ab60a9728aeea2362d8be2cbd7789\", \"project\": \"project\", \"ref\": \"refs/heads/master\"}, \"priority\": 30, \"properties\": {\"child_build_id\": 123}, \"requestId\": \"8945511751514863184-00000000-0000-0000-0000-000000001337\", \"tags\": [{\"key\": \"user_agent\", \"value\": \"recipe\"}]}}]}",
+ "stdin": "{\"requests\": [{\"scheduleBuild\": {\"builder\": {\"bucket\": \"rerun\", \"builder\": \"source-builder-flaky\", \"project\": \"project\"}, \"experimental\": \"NO\", \"fields\": \"builder,createTime,createdBy,critical,endTime,id,input,number,output,startTime,status,updateTime\", \"gitilesCommit\": {\"host\": \"chromium.googlesource.com\", \"id\": \"2d72510e447ab60a9728aeea2362d8be2cbd7789\", \"project\": \"project\", \"ref\": \"refs/heads/master\"}, \"priority\": 30, \"properties\": {\"child_build_id\": 123}, \"requestId\": \"8945511751514863184-00000000-0000-0000-0000-000000001337\", \"tags\": [{\"key\": \"user_agent\", \"value\": \"recipe\"}]}}]}",
"~followup_annotations": [
"@@@STEP_LOG_LINE@json.output@{@@@",
"@@@STEP_LOG_LINE@json.output@ \"responses\": [@@@",
@@ -88,7 +87,7 @@
"@@@STEP_LOG_LINE@json.output@ \"scheduleBuild\": {@@@",
"@@@STEP_LOG_LINE@json.output@ \"builder\": {@@@",
"@@@STEP_LOG_LINE@json.output@ \"bucket\": \"rerun\", @@@",
- "@@@STEP_LOG_LINE@json.output@ \"builder\": \"source-builder\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"builder\": \"source-builder-flaky\", @@@",
"@@@STEP_LOG_LINE@json.output@ \"project\": \"project\"@@@",
"@@@STEP_LOG_LINE@json.output@ }, @@@",
"@@@STEP_LOG_LINE@json.output@ \"id\": \"8922054662172514000\"@@@",
@@ -103,7 +102,7 @@
"@@@STEP_LOG_LINE@request@ \"scheduleBuild\": {@@@",
"@@@STEP_LOG_LINE@request@ \"builder\": {@@@",
"@@@STEP_LOG_LINE@request@ \"bucket\": \"rerun\", @@@",
- "@@@STEP_LOG_LINE@request@ \"builder\": \"source-builder\", @@@",
+ "@@@STEP_LOG_LINE@request@ \"builder\": \"source-builder-flaky\", @@@",
"@@@STEP_LOG_LINE@request@ \"project\": \"project\"@@@",
"@@@STEP_LOG_LINE@request@ }, @@@",
"@@@STEP_LOG_LINE@request@ \"experimental\": \"NO\", @@@",
diff --git a/recipes/fuchsia/rerun.py b/recipes/fuchsia/rerun.py
index 62d1c83..7a799c6 100644
--- a/recipes/fuchsia/rerun.py
+++ b/recipes/fuchsia/rerun.py
@@ -41,9 +41,15 @@
def RunSteps(api, source_bucket, source_builder):
my_build = api.buildbucket.build
- source_build = api.buildbucket_util.last_green_build(my_build.builder.project,
- source_bucket,
- source_builder)
+ last_build_status = common_pb2.SUCCESS
+ # Flaky builders are rarely successful, so we take any build.
+ if source_builder.endswith('-flaky'):
+ last_build_status = None
+ source_build = api.buildbucket_util.last_build(
+ my_build.builder.project,
+ source_bucket,
+ source_builder,
+ status=last_build_status)
if not source_build:
raise api.step.InfraFailure(
'Failed to find source_build for builder %s/%s/%s' %
@@ -64,7 +70,7 @@
def GenTests(api):
properties = api.properties(
- source_bucket='source-bucket', source_builder='source-builder')
+ source_bucket='source-bucket', source_builder='source-builder-flaky')
yield (api.status_check.test('no_search_results', status='infra_failure') +
properties + api.buildbucket.ci_build())
diff --git a/recipes/recipes.py b/recipes/recipes.py
index 5cba3e3..90ea66e 100644
--- a/recipes/recipes.py
+++ b/recipes/recipes.py
@@ -170,8 +170,12 @@
project, bucket, builder = builder.split('/')
# "infra.recipe" is not returned by default, so we have to specify it.
required_fields = {'infra.recipe'}.union(api.buildbucket.DEFAULT_FIELDS)
- build = api.buildbucket_util.last_green_build(
- project, bucket, builder, fields=required_fields)
+ build = api.buildbucket_util.last_build(
+ project,
+ bucket,
+ builder,
+ fields=required_fields,
+ status=common_pb2.SUCCESS)
if not build:
return None