예제 #1
0
    def _get_main_build_result(self):
        build_info_list = self.client.get_build_info_list([
            ("branch", "master"),
            ("page", "1"),
            ("per_page", "1"),
            ("state[]", "failed"),
            ("state[]", "passed"),
        ])
        if not build_info_list:
            error = f"Cannot find finished build for pipeline {self.pipeline}, please try to rerun the pipeline first."
            self._log("SERIOUS", error)
            raise bazelci.BuildkiteException(error)
        main_build_info = build_info_list[0]

        self.main_result = {}
        self.main_result["commit"] = main_build_info["commit"]
        self.main_result["build_number"] = main_build_info["number"]
        job_infos = filter(lambda x: bool(x),
                           (extract_job_info_by_key(job)
                            for job in main_build_info["jobs"]))
        self.main_result["tasks"] = group_job_info_by_task(job_infos)
        self.main_result["state"] = get_project_state(
            self.main_result["tasks"])

        last_green_commit_url = bazelci.bazelci_last_green_commit_url(
            bazelci.DOWNSTREAM_PROJECTS[self.project]["git_repository"],
            self.pipeline)
        self.main_result["last_green_commit"] = bazelci.get_last_green_commit(
            last_green_commit_url)
def clone_git_repository(project_name, task_name):
    platform_name = get_platform(project_name, task_name)
    git_repository = bazelci.DOWNSTREAM_PROJECTS[project_name][
        "git_repository"]
    git_commit = bazelci.get_last_green_commit(
        git_repository,
        bazelci.DOWNSTREAM_PROJECTS[project_name]["pipeline_slug"])
    return bazelci.clone_git_repository(git_repository, platform_name,
                                        git_commit)
def main(argv=None):
    if argv is None:
        argv = sys.argv[1:]

    parser = argparse.ArgumentParser(description="Bazel Culprit Finder Script")

    subparsers = parser.add_subparsers(dest="subparsers_name")

    subparsers.add_parser("culprit_finder")

    runner = subparsers.add_parser("runner")
    runner.add_argument("--project_name", type=str)
    runner.add_argument("--task_name", type=str)
    runner.add_argument("--good_bazel_commit", type=str)
    runner.add_argument("--bad_bazel_commit", type=str)
    runner.add_argument("--needs_clean", type=bool, nargs="?", const=True)
    runner.add_argument("--repeat_times", type=int, default=1)

    args = parser.parse_args(argv)
    if args.subparsers_name == "culprit_finder":
        try:
            project_name = os.environ["PROJECT_NAME"]

            # For old config file, we can still set PLATFORM_NAME as task name.
            task = os.environ.get("PLATFORM_NAME") or os.environ.get(
                "TASK_NAME")
            if task:
                tasks = [task]
            else:
                tasks = get_tasks(project_name)

            good_bazel_commit = os.environ.get("GOOD_BAZEL_COMMIT")
            if not good_bazel_commit:
                # If GOOD_BAZEL_COMMIT is not set, use recorded last bazel green commit for downstream project
                last_green_commit_url = bazelci.bazelci_last_green_downstream_commit_url(
                )
                good_bazel_commit = bazelci.get_last_green_commit(
                    last_green_commit_url)

            bad_bazel_commit = os.environ.get("BAD_BAZEL_COMMIT")
            if not bad_bazel_commit:
                # If BAD_BAZEL_COMMIT is not set, use HEAD commit.
                bad_bazel_commit = (subprocess.check_output(
                    ["git", "rev-parse", "HEAD"]).decode("utf-8").strip())
        except KeyError as e:
            raise Exception("Environment variable %s must be set" % str(e))

        needs_clean = False
        if "NEEDS_CLEAN" in os.environ:
            needs_clean = True

        repeat_times = 1
        if "REPEAT_TIMES" in os.environ:
            repeat_times = int(os.environ["REPEAT_TIMES"])

        if project_name not in bazelci.DOWNSTREAM_PROJECTS:
            raise Exception(
                "Project name '%s' not recognized, available projects are %s" %
                (project_name, str((bazelci.DOWNSTREAM_PROJECTS.keys()))))

        print_culprit_finder_pipeline(
            project_name=project_name,
            tasks=tasks,
            good_bazel_commit=good_bazel_commit,
            bad_bazel_commit=bad_bazel_commit,
            needs_clean=needs_clean,
            repeat_times=repeat_times,
        )
    elif args.subparsers_name == "runner":
        git_repo_location = clone_git_repository(args.project_name,
                                                 args.task_name)
        bazelci.print_collapsed_group("Check good bazel commit " +
                                      args.good_bazel_commit)
        if not test_with_bazel_at_commit(
                project_name=args.project_name,
                task_name=args.task_name,
                git_repo_location=git_repo_location,
                bazel_commit=args.good_bazel_commit,
                needs_clean=args.needs_clean,
                repeat_times=args.repeat_times,
        ):
            raise Exception(
                "Given good commit (%s) is not actually good, abort bisecting."
                % args.good_bazel_commit)
        start_bisecting(
            project_name=args.project_name,
            task_name=args.task_name,
            git_repo_location=git_repo_location,
            commits_list=get_bazel_commits_between(args.good_bazel_commit,
                                                   args.bad_bazel_commit),
            needs_clean=args.needs_clean,
            repeat_times=args.repeat_times,
        )
    else:
        parser.print_help()
        return 2
    return 0