| # Copyright 2020 The Fuchsia Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| """Recipe for triggering toolchain buildbucket builds.""" |
| |
| from recipe_engine.config import List |
| from recipe_engine.recipe_api import Property |
| from PB.go.chromium.org.luci.buildbucket.proto import ( |
| builds_service as builds_service_pb2, |
| ) |
| from PB.recipes.fuchsia.toolchain_trigger import InputProps |
| |
| DEPS = [ |
| "fuchsia/display_util", |
| "fuchsia/status_check", |
| "recipe_engine/buildbucket", |
| "recipe_engine/properties", |
| "recipe_engine/scheduler", |
| "recipe_engine/step", |
| "recipe_engine/swarming", |
| ] |
| |
| PROPERTIES = InputProps |
| |
| |
| def retrieve_revision(api, results): |
| revision = None |
| for result in results: |
| output = result.output.properties |
| if "git_revision" not in output: |
| raise api.step.StepFailure("revision not found in build") |
| output_revision = output["git_revision"] |
| if revision is None: |
| revision = output_revision |
| elif revision != output_revision: |
| raise api.step.StepFailure( |
| "revisions not unified: %s:%s" % (revision, output_revision) |
| ) |
| return revision |
| |
| |
| def RunSteps(api, props): |
| # Trigger the builders. |
| build_results = api.buildbucket.run( |
| [ |
| api.buildbucket.schedule_request( |
| builder, |
| bucket=props.bucket, |
| swarming_parent_run_id=api.swarming.task_id, |
| ) |
| for builder in props.builders |
| ], |
| collect_interval=props.interval, |
| timeout=props.timeout, |
| step_name="schedule builders", |
| ) |
| api.display_util.display_builds( |
| step_name="display builds", builds=build_results, raise_on_failure=True |
| ) |
| |
| properties = {} |
| if props.enforce_output: |
| revision = retrieve_revision(api, build_results) |
| properties = {"version": "git_revision:" + revision} |
| |
| # Trigger next stage builders |
| api.scheduler.emit_trigger( |
| api.scheduler.BuildbucketTrigger(properties=properties), |
| project="fuchsia", |
| jobs=props.triggers, |
| ) |
| |
| |
| def GenTests(api): |
| default_properties = api.properties( |
| builders=["clang-linux-x64", "clang-mac-x64"], |
| triggers=["clang-trigger"], |
| enforce_output=True, |
| ) |
| |
| test_build = api.buildbucket.ci_build_message(status="SUCCESS") |
| test_build.output.properties["git_revision"] = "a" * 40 |
| mock_schedule_data = api.buildbucket.simulated_schedule_output( |
| step_name="schedule builders.schedule", |
| batch_response=builds_service_pb2.BatchResponse( |
| responses=[dict(schedule_build=dict(id=test_build.id))], |
| ), |
| ) |
| mock_collect_data = api.buildbucket.simulated_collect_output( |
| step_name="schedule builders.collect", builds=[test_build], |
| ) |
| |
| yield ( |
| api.status_check.test("default") |
| + api.buildbucket.ci_build( |
| bucket="ci", |
| git_repo="https://fuchsia.googlesource.com/example", |
| revision="a" * 40, |
| ) |
| ) + default_properties + mock_collect_data + mock_schedule_data |
| |
| test_build_mismatch = api.buildbucket.ci_build_message( |
| build_id=test_build.id + 1, status="SUCCESS" |
| ) |
| test_build_mismatch.output.properties["git_revision"] = "b" * 40 |
| mock_schedule_data_mismatch = api.buildbucket.simulated_schedule_output( |
| step_name="schedule builders.schedule", |
| batch_response=builds_service_pb2.BatchResponse( |
| responses=[ |
| dict(schedule_build=dict(id=test_build.id)), |
| dict(schedule_build=dict(id=test_build_mismatch.id)), |
| ], |
| ), |
| ) |
| mock_collect_data_mismatch = api.buildbucket.simulated_collect_output( |
| step_name="schedule builders.collect", builds=[test_build, test_build_mismatch], |
| ) |
| |
| yield ( |
| api.status_check.test("mismatch", status="failure") |
| + api.buildbucket.ci_build( |
| bucket="ci", |
| git_repo="https://fuchsia.googlesource.com/example", |
| revision="a" * 40, |
| ) |
| ) + default_properties + mock_schedule_data_mismatch + mock_collect_data_mismatch |
| |
| test_build_no_output = api.buildbucket.ci_build_message(status="SUCCESS") |
| mock_schedule_data_no_output = api.buildbucket.simulated_schedule_output( |
| step_name="schedule builders.schedule", |
| batch_response=builds_service_pb2.BatchResponse( |
| responses=[dict(schedule_build=dict(id=test_build_no_output.id))], |
| ), |
| ) |
| mock_collect_data_no_output = api.buildbucket.simulated_collect_output( |
| step_name="schedule builders.collect", builds=[test_build_no_output], |
| ) |
| |
| no_output_properties = api.properties( |
| builders=["clang-linux-x64", "clang-mac-x64"], |
| triggers=["clang-trigger"], |
| enforce_output=False, |
| ) |
| yield ( |
| api.status_check.test("no_output") |
| + api.buildbucket.ci_build( |
| bucket="ci", |
| git_repo="https://fuchsia.googlesource.com/example", |
| revision="a" * 40, |
| ) |
| ) + no_output_properties + mock_schedule_data_no_output + mock_collect_data_no_output |
| |
| yield ( |
| api.status_check.test("no_output_with_enforce", status="failure") |
| + api.buildbucket.ci_build( |
| bucket="ci", |
| git_repo="https://fuchsia.googlesource.com/example", |
| revision="a" * 40, |
| ) |
| ) + default_properties + mock_schedule_data_no_output + mock_collect_data_no_output |
| |
| test_build_failure = api.buildbucket.ci_build_message(status="FAILURE") |
| mock_failure_schedule_data = api.buildbucket.simulated_schedule_output( |
| step_name="schedule builders.schedule", |
| batch_response=builds_service_pb2.BatchResponse( |
| responses=[dict(schedule_build=dict(id=test_build_failure.id))], |
| ), |
| ) |
| mock_failure_collect_data = api.buildbucket.simulated_collect_output( |
| step_name="schedule builders.collect", builds=[test_build_failure], |
| ) |
| |
| yield ( |
| api.status_check.test("default_fail", status="failure") |
| + api.buildbucket.ci_build( |
| bucket="ci", |
| git_repo="https://fuchsia.googlesource.com/example", |
| revision="a" * 40, |
| ) |
| ) + default_properties + mock_failure_schedule_data + mock_failure_collect_data |