def print_steps_for_failing_jobs(build_number):
    build_info = get_build_info(build_number)
    failing_jobs = get_failing_jobs(build_info)
    incompatible_flags = list(fetch_incompatible_flags().keys())
    pipeline_steps = []
    for incompatible_flag in incompatible_flags:
        for job in failing_jobs:
            label = "%s: %s" % (incompatible_flag, job["name"])
            command = list(job["command"])
            command[1] = command[1] + " --incompatible_flag=" + incompatible_flag
            pipeline_steps.append(create_step(label, command, job["platform"]))
    print(yaml.dump({"steps": pipeline_steps}))
def print_incompatible_flags_info_box_step(incompatible_flags_map):
    info_text = ["Build and test with the following incompatible flags:"]

    for flag in incompatible_flags_map:
        info_text.append("* **%s**: %s" % (flag, incompatible_flags_map[flag]))

    if len(info_text) == 1:
        return None
    return create_step(
        label="Incompatible flags info",
        commands=[
            'buildkite-agent annotate --append --style=info "\n' + "\n".join(info_text) + '\n"'
        ],
    )
def print_disabled_projects_info_box_step():
    info_text = ["Downstream testing is disabled for the following projects :sadpanda:"]
    for project, config in DOWNSTREAM_PROJECTS.items():
        disabled_reason = config.get("disabled_reason", None)
        if disabled_reason:
            info_text.append("* **%s**: %s" % (project, disabled_reason))

    if len(info_text) == 1:
        return None
    return create_step(
        label=":sadpanda:",
        commands=[
            'buildkite-agent annotate --append --style=info "\n' + "\n".join(info_text) + '\n"'
        ],
    )
def print_culprit_finder_pipeline(
    project_name, platform_name, good_bazel_commit, bad_bazel_commit, needs_clean
):
    label = PLATFORMS[platform_name]["emoji-name"] + " Bisecting for {0}".format(project_name)
    command = (
        '%s culprit_finder.py runner --project_name="%s" --platform_name=%s --good_bazel_commit=%s --bad_bazel_commit=%s %s'
        % (
            python_binary(platform_name),
            project_name,
            platform_name,
            good_bazel_commit,
            bad_bazel_commit,
            "--needs_clean" if needs_clean else "",
        )
    )
    commands = [fetch_bazelcipy_command(), fetch_culprit_finder_py_command(), command]
    pipeline_steps = []
    pipeline_steps.append(create_step(label, commands, platform_name))
    print(yaml.dump({"steps": pipeline_steps}))
示例#5
0
def main(configs, http_config, file_config):
    if not configs:
        raise Exception(
            "Bazel publish binaries pipeline configuration is empty.")

    for platform in configs.copy():
        if platform not in PLATFORMS:
            raise Exception("Unknown platform '{}'".format(platform))
        if not PLATFORMS[platform]["publish_binary"]:
            del configs[platform]

    if set(configs) != set(name for name, platform in PLATFORMS.items()
                           if platform["publish_binary"]):
        raise Exception(
            "Bazel publish binaries pipeline needs to build Bazel for every commit on all publish_binary-enabled platforms."
        )

    # Build Bazel
    pipeline_steps = []

    for platform in configs:
        pipeline_steps.append(
            bazel_build_step(platform,
                             "Bazel",
                             http_config,
                             file_config,
                             build_only=True))

    pipeline_steps.append("wait")

    # If all builds succeed, publish the Bazel binaries to GCS.
    pipeline_steps.append(
        create_step(
            label="Publish Bazel Binaries",
            commands=[
                fetch_bazelcipy_command(),
                python_binary() + " bazelci.py publish_binaries"
            ],
        ))

    print(yaml.dump({"steps": pipeline_steps}))
def upload_project_pipeline_step(
    project_name, git_repository, http_config, file_config, incompatible_flags
):
    pipeline_command = (
        '{0} bazelci.py project_pipeline --project_name="{1}" ' + "--git_repository={2}"
    ).format(python_binary(), project_name, git_repository)
    if incompatible_flags is None:
        pipeline_command += " --use_but"
    else:
        for flag in incompatible_flags:
            pipeline_command += " --incompatible_flag=" + flag
    if http_config:
        pipeline_command += " --http_config=" + http_config
    if file_config:
        pipeline_command += " --file_config=" + file_config
    pipeline_command += " | buildkite-agent pipeline upload"

    return create_step(
        label="Setup {0}".format(project_name),
        commands=[fetch_bazelcipy_command(), pipeline_command],
    )
示例#7
0
def main(
    configs,
    project_name,
    http_config,
    file_config,
    git_repository,
    monitor_flaky_tests,
    use_but,
    incompatible_flags,
):
    platform_configs = configs.get("platforms", None)
    if not platform_configs:
        raise Exception(
            "{0} pipeline configuration is empty.".format(project_name))

    pipeline_steps = []

    if configs.get("buildifier"):
        pipeline_steps.append(
            create_docker_step("Buildifier",
                               image=f"gcr.io/{CLOUD_PROJECT}/buildifier"))

    # In Bazel Downstream Project pipelines, git_repository and project_name must be specified,
    # and we should test the project at the last green commit.
    git_commit = None
    if (use_but or incompatible_flags) and git_repository and project_name:
        git_commit = get_last_green_commit(
            git_repository, DOWNSTREAM_PROJECTS[project_name]["pipeline_slug"])
    for platform in platform_configs:
        step = runner_step(
            platform,
            project_name,
            http_config,
            file_config,
            git_repository,
            git_commit,
            monitor_flaky_tests,
            use_but,
            incompatible_flags,
        )
        pipeline_steps.append(step)

    pipeline_slug = os.getenv("BUILDKITE_PIPELINE_SLUG")
    all_downstream_pipeline_slugs = []
    for _, config in DOWNSTREAM_PROJECTS.items():
        all_downstream_pipeline_slugs.append(config["pipeline_slug"])
    # We don't need to update last green commit in the following cases:
    #   1. This job is a github pull request
    #   2. This job uses a custom built Bazel binary (In Bazel Downstream Projects pipeline)
    #   3. This job doesn't run on master branch (Could be a custom build launched manually)
    #   4. We don't intend to run the same job in downstream with Bazel@HEAD (eg. google-bazel-presubmit)
    #   5. We are testing incompatible flags
    if not (is_pull_request() or use_but
            or os.getenv("BUILDKITE_BRANCH") != "master" or pipeline_slug
            not in all_downstream_pipeline_slugs or incompatible_flags):
        pipeline_steps.append("wait")

        # If all builds succeed, update the last green commit of this project
        pipeline_steps.append(
            create_step(
                label="Try Update Last Green Commit",
                commands=[
                    fetch_bazelcipy_command(),
                    python_binary() +
                    " bazelci.py try_update_last_green_commit",
                ],
            ))

    print(yaml.dump({"steps": pipeline_steps}))
def main(configs, http_config, file_config, test_incompatible_flags, test_disabled_projects):
    if not configs:
        raise Exception("Bazel downstream pipeline configuration is empty.")

    if set(configs) != set(PLATFORMS):
        raise Exception(
            "Bazel downstream pipeline needs to build Bazel on all supported platforms (has=%s vs. want=%s)."
            % (sorted(set(configs)), sorted(set(PLATFORMS)))
        )

    pipeline_steps = []

    info_box_step = print_disabled_projects_info_box_step()
    if info_box_step is not None:
        pipeline_steps.append(info_box_step)

    if not test_incompatible_flags:
        for platform in configs:
            pipeline_steps.append(
                bazel_build_step(platform, "Bazel", http_config, file_config, build_only=True)
            )

        pipeline_steps.append("wait")

    incompatible_flags = None
    if test_incompatible_flags:
        incompatible_flags_map = fetch_incompatible_flags()
        info_box_step = print_incompatible_flags_info_box_step(incompatible_flags_map)
        if info_box_step is not None:
            pipeline_steps.append(info_box_step)
        incompatible_flags = list(incompatible_flags_map.keys())

    for project, config in DOWNSTREAM_PROJECTS.items():
        disabled_reason = config.get("disabled_reason", None)
        # If test_disabled_projects is true, we add configs for disabled projects.
        # If test_disabled_projects is false, we add configs for not disbaled projects.
        if (test_disabled_projects and disabled_reason) or (
            not test_disabled_projects and not disabled_reason
        ):
            pipeline_steps.append(
                upload_project_pipeline_step(
                    project_name=project,
                    git_repository=config["git_repository"],
                    http_config=config.get("http_config", None),
                    file_config=config.get("file_config", None),
                    incompatible_flags=incompatible_flags,
                )
            )

    if test_incompatible_flags:
        pipeline_steps.append({"wait": "~", "continue_on_failure": "true"})
        current_build_number = os.environ.get("BUILDKITE_BUILD_NUMBER", None)
        if not current_build_number:
            raise Exception("Not running inside Buildkite")
        pipeline_steps.append(
            create_step(
                label="Test failing jobs with incompatible flag separately",
                commands=[
                    fetch_bazelcipy_command(),
                    fetch_incompatible_flag_verbose_failures_command(),
                    python_binary()
                    + " incompatible_flag_verbose_failures.py --build_number=%s | buildkite-agent pipeline upload"
                    % current_build_number,
                ],
            )
        )

    print(yaml.dump({"steps": pipeline_steps}))