2021-10-21 14:41:07 +00:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
|
|
|
import json
|
2021-10-27 07:03:23 +00:00
|
|
|
import logging
|
|
|
|
import os
|
|
|
|
import sys
|
2021-10-21 14:41:07 +00:00
|
|
|
from github import Github
|
2021-11-26 14:00:09 +00:00
|
|
|
|
2022-03-22 16:39:58 +00:00
|
|
|
from env_helper import (
|
|
|
|
REPORTS_PATH,
|
|
|
|
TEMP_PATH,
|
|
|
|
GITHUB_REPOSITORY,
|
|
|
|
GITHUB_SERVER_URL,
|
2022-03-24 14:37:53 +00:00
|
|
|
GITHUB_RUN_URL,
|
2022-03-22 16:39:58 +00:00
|
|
|
)
|
2021-10-21 14:41:07 +00:00
|
|
|
from report import create_build_html_report
|
|
|
|
from s3_helper import S3Helper
|
|
|
|
from get_robot_token import get_best_robot_token
|
2021-11-26 14:00:09 +00:00
|
|
|
from pr_info import PRInfo
|
|
|
|
from commit_status_helper import get_commit
|
2021-11-30 15:33:29 +00:00
|
|
|
from ci_config import CI_CONFIG
|
2021-12-01 14:23:51 +00:00
|
|
|
from rerun_helper import RerunHelper
|
2021-10-21 14:41:07 +00:00
|
|
|
|
2022-03-22 16:39:58 +00:00
|
|
|
|
|
|
|
class BuildResult:
|
|
|
|
def __init__(
|
|
|
|
self,
|
|
|
|
compiler,
|
|
|
|
build_type,
|
|
|
|
sanitizer,
|
|
|
|
bundled,
|
|
|
|
splitted,
|
|
|
|
status,
|
|
|
|
elapsed_seconds,
|
|
|
|
with_coverage,
|
|
|
|
):
|
2021-10-21 14:41:07 +00:00
|
|
|
self.compiler = compiler
|
|
|
|
self.build_type = build_type
|
|
|
|
self.sanitizer = sanitizer
|
|
|
|
self.bundled = bundled
|
|
|
|
self.splitted = splitted
|
|
|
|
self.status = status
|
|
|
|
self.elapsed_seconds = elapsed_seconds
|
|
|
|
self.with_coverage = with_coverage
|
|
|
|
|
2022-03-22 16:39:58 +00:00
|
|
|
|
2021-10-21 14:41:07 +00:00
|
|
|
def group_by_artifacts(build_urls):
|
2022-03-22 16:39:58 +00:00
|
|
|
groups = {
|
|
|
|
"apk": [],
|
|
|
|
"deb": [],
|
|
|
|
"binary": [],
|
|
|
|
"tgz": [],
|
|
|
|
"rpm": [],
|
|
|
|
"performance": [],
|
|
|
|
}
|
2021-10-21 14:41:07 +00:00
|
|
|
for url in build_urls:
|
2022-03-22 16:39:58 +00:00
|
|
|
if url.endswith("performance.tgz"):
|
|
|
|
groups["performance"].append(url)
|
|
|
|
elif (
|
|
|
|
url.endswith(".deb")
|
|
|
|
or url.endswith(".buildinfo")
|
|
|
|
or url.endswith(".changes")
|
|
|
|
or url.endswith(".tar.gz")
|
|
|
|
):
|
|
|
|
groups["deb"].append(url)
|
|
|
|
elif url.endswith(".apk"):
|
|
|
|
groups["apk"].append(url)
|
|
|
|
elif url.endswith(".rpm"):
|
|
|
|
groups["rpm"].append(url)
|
|
|
|
elif url.endswith(".tgz"):
|
|
|
|
groups["tgz"].append(url)
|
2021-10-21 14:41:07 +00:00
|
|
|
else:
|
2022-03-22 16:39:58 +00:00
|
|
|
groups["binary"].append(url)
|
2021-10-21 14:41:07 +00:00
|
|
|
return groups
|
|
|
|
|
2022-03-22 16:39:58 +00:00
|
|
|
|
2021-10-21 14:41:07 +00:00
|
|
|
def process_report(build_report):
|
2022-03-22 16:39:58 +00:00
|
|
|
build_config = build_report["build_config"]
|
2021-10-21 14:41:07 +00:00
|
|
|
build_result = BuildResult(
|
2022-03-22 16:39:58 +00:00
|
|
|
compiler=build_config["compiler"],
|
|
|
|
build_type=build_config["build_type"],
|
|
|
|
sanitizer=build_config["sanitizer"],
|
|
|
|
bundled=build_config["bundled"],
|
|
|
|
splitted=build_config["splitted"],
|
|
|
|
status="success" if build_report["status"] else "failure",
|
|
|
|
elapsed_seconds=build_report["elapsed_seconds"],
|
|
|
|
with_coverage=False,
|
2021-10-21 14:41:07 +00:00
|
|
|
)
|
|
|
|
build_results = []
|
|
|
|
build_urls = []
|
|
|
|
build_logs_urls = []
|
2022-03-22 16:39:58 +00:00
|
|
|
urls_groups = group_by_artifacts(build_report["build_urls"])
|
2021-10-25 15:52:03 +00:00
|
|
|
found_group = False
|
2021-10-21 14:41:07 +00:00
|
|
|
for _, group_urls in urls_groups.items():
|
|
|
|
if group_urls:
|
|
|
|
build_results.append(build_result)
|
|
|
|
build_urls.append(group_urls)
|
2022-03-22 16:39:58 +00:00
|
|
|
build_logs_urls.append(build_report["log_url"])
|
2021-10-25 15:52:03 +00:00
|
|
|
found_group = True
|
|
|
|
|
|
|
|
if not found_group:
|
|
|
|
build_results.append(build_result)
|
|
|
|
build_urls.append([""])
|
2022-03-22 16:39:58 +00:00
|
|
|
build_logs_urls.append(build_report["log_url"])
|
2021-10-21 14:41:07 +00:00
|
|
|
|
|
|
|
return build_results, build_urls, build_logs_urls
|
|
|
|
|
2022-03-22 16:39:58 +00:00
|
|
|
|
2021-11-30 15:33:29 +00:00
|
|
|
def get_build_name_from_file_name(file_name):
|
2022-03-22 16:39:58 +00:00
|
|
|
return file_name.replace("build_urls_", "").replace(".json", "")
|
|
|
|
|
2021-10-21 14:41:07 +00:00
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
logging.basicConfig(level=logging.INFO)
|
2021-11-26 14:00:09 +00:00
|
|
|
reports_path = REPORTS_PATH
|
|
|
|
temp_path = TEMP_PATH
|
2021-10-21 14:41:07 +00:00
|
|
|
logging.info("Reports path %s", reports_path)
|
|
|
|
|
2021-10-21 15:32:15 +00:00
|
|
|
if not os.path.exists(temp_path):
|
|
|
|
os.makedirs(temp_path)
|
|
|
|
|
2021-10-21 14:41:07 +00:00
|
|
|
build_check_name = sys.argv[1]
|
2022-04-06 12:27:29 +00:00
|
|
|
reports_length = int(sys.argv[2]) if len(sys.argv) > 2 else 0
|
2021-10-21 14:41:07 +00:00
|
|
|
|
2021-12-01 14:23:51 +00:00
|
|
|
gh = Github(get_best_robot_token())
|
2021-11-26 14:00:09 +00:00
|
|
|
pr_info = PRInfo()
|
2021-12-01 14:23:51 +00:00
|
|
|
rerun_helper = RerunHelper(gh, pr_info, build_check_name)
|
|
|
|
if rerun_helper.is_already_finished_by_status():
|
|
|
|
logging.info("Check is already finished according to github status, exiting")
|
|
|
|
sys.exit(0)
|
|
|
|
|
2021-11-30 15:33:29 +00:00
|
|
|
reports_order = CI_CONFIG["builds_report_config"][build_check_name]
|
|
|
|
logging.info("My reports list %s", reports_order)
|
|
|
|
|
|
|
|
build_reports_map = {}
|
2021-10-21 14:41:07 +00:00
|
|
|
for root, dirs, files in os.walk(reports_path):
|
|
|
|
for f in files:
|
2022-03-22 16:39:58 +00:00
|
|
|
if f.startswith("build_urls_") and f.endswith(".json"):
|
2021-10-21 14:41:07 +00:00
|
|
|
logging.info("Found build report json %s", f)
|
2021-11-30 15:33:29 +00:00
|
|
|
build_name = get_build_name_from_file_name(f)
|
|
|
|
if build_name in reports_order:
|
2022-04-06 12:34:20 +00:00
|
|
|
with open(os.path.join(root, f), "rb") as file_handler:
|
2021-11-30 15:33:29 +00:00
|
|
|
build_report = json.load(file_handler)
|
|
|
|
build_reports_map[build_name] = build_report
|
|
|
|
else:
|
2022-03-22 16:39:58 +00:00
|
|
|
logging.info(
|
|
|
|
"Skipping report %s for build %s, it's not in our reports list",
|
|
|
|
f,
|
|
|
|
build_name,
|
|
|
|
)
|
|
|
|
|
2022-04-06 12:27:29 +00:00
|
|
|
reports_length = reports_length or len(reports_order)
|
|
|
|
some_builds_are_missing = len(build_reports_map) < reports_length
|
2022-03-26 21:45:45 +00:00
|
|
|
|
|
|
|
if some_builds_are_missing:
|
2022-03-28 12:43:15 +00:00
|
|
|
logging.info(
|
|
|
|
"Expected to get %s build results, got %s",
|
|
|
|
len(reports_order),
|
|
|
|
len(build_reports_map),
|
|
|
|
)
|
2022-03-26 21:45:45 +00:00
|
|
|
else:
|
|
|
|
logging.info("Got exactly %s builds", len(build_reports_map))
|
|
|
|
|
2022-03-22 16:39:58 +00:00
|
|
|
build_reports = [
|
|
|
|
build_reports_map[build_name]
|
|
|
|
for build_name in reports_order
|
|
|
|
if build_name in build_reports_map
|
|
|
|
]
|
2021-10-21 14:41:07 +00:00
|
|
|
|
|
|
|
build_results = []
|
|
|
|
build_artifacts = []
|
|
|
|
build_logs = []
|
|
|
|
|
|
|
|
for build_report in build_reports:
|
|
|
|
build_result, build_artifacts_url, build_logs_url = process_report(build_report)
|
|
|
|
logging.info("Got %s result for report", len(build_result))
|
|
|
|
build_results += build_result
|
|
|
|
build_artifacts += build_artifacts_url
|
|
|
|
build_logs += build_logs_url
|
|
|
|
|
|
|
|
logging.info("Totally got %s results", len(build_results))
|
2021-12-09 09:17:03 +00:00
|
|
|
if len(build_results) == 0:
|
|
|
|
logging.info("No builds, failing check")
|
|
|
|
sys.exit(1)
|
2021-10-21 14:41:07 +00:00
|
|
|
|
2022-03-22 16:39:58 +00:00
|
|
|
s3_helper = S3Helper("https://s3.amazonaws.com")
|
2021-10-21 14:41:07 +00:00
|
|
|
|
2021-11-26 14:00:09 +00:00
|
|
|
pr_info = PRInfo()
|
2021-10-21 14:41:07 +00:00
|
|
|
|
2021-11-26 14:00:09 +00:00
|
|
|
branch_url = f"{GITHUB_SERVER_URL}/{GITHUB_REPOSITORY}/commits/master"
|
2021-10-21 14:41:07 +00:00
|
|
|
branch_name = "master"
|
|
|
|
if pr_info.number != 0:
|
2022-04-06 12:34:20 +00:00
|
|
|
branch_name = f"PR #{pr_info.number}"
|
2021-11-26 14:00:09 +00:00
|
|
|
branch_url = f"{GITHUB_SERVER_URL}/{GITHUB_REPOSITORY}/pull/{pr_info.number}"
|
|
|
|
commit_url = f"{GITHUB_SERVER_URL}/{GITHUB_REPOSITORY}/commit/{pr_info.sha}"
|
2022-03-24 14:37:53 +00:00
|
|
|
task_url = GITHUB_RUN_URL
|
2021-10-21 14:41:07 +00:00
|
|
|
report = create_build_html_report(
|
|
|
|
build_check_name,
|
|
|
|
build_results,
|
|
|
|
build_logs,
|
|
|
|
build_artifacts,
|
|
|
|
task_url,
|
|
|
|
branch_url,
|
|
|
|
branch_name,
|
2022-03-22 16:39:58 +00:00
|
|
|
commit_url,
|
2021-10-21 14:41:07 +00:00
|
|
|
)
|
|
|
|
|
2022-03-22 16:39:58 +00:00
|
|
|
report_path = os.path.join(temp_path, "report.html")
|
2022-04-06 12:34:20 +00:00
|
|
|
with open(report_path, "w", encoding="utf-8") as fd:
|
|
|
|
fd.write(report)
|
2021-10-21 14:41:07 +00:00
|
|
|
|
|
|
|
logging.info("Going to upload prepared report")
|
2022-03-22 16:39:58 +00:00
|
|
|
context_name_for_path = build_check_name.lower().replace(" ", "_")
|
|
|
|
s3_path_prefix = (
|
|
|
|
str(pr_info.number) + "/" + pr_info.sha + "/" + context_name_for_path
|
|
|
|
)
|
2021-10-21 14:41:07 +00:00
|
|
|
|
2022-03-22 16:39:58 +00:00
|
|
|
url = s3_helper.upload_build_file_to_s3(
|
|
|
|
report_path, s3_path_prefix + "/report.html"
|
|
|
|
)
|
2021-10-21 14:41:07 +00:00
|
|
|
logging.info("Report url %s", url)
|
|
|
|
|
|
|
|
total_builds = len(build_results)
|
|
|
|
ok_builds = 0
|
|
|
|
summary_status = "success"
|
|
|
|
for build_result in build_results:
|
|
|
|
if build_result.status == "failure" and summary_status != "error":
|
|
|
|
summary_status = "failure"
|
|
|
|
if build_result.status == "error" or not build_result.status:
|
|
|
|
summary_status = "error"
|
|
|
|
|
|
|
|
if build_result.status == "success":
|
|
|
|
ok_builds += 1
|
|
|
|
|
2022-03-26 21:45:45 +00:00
|
|
|
if ok_builds == 0 or some_builds_are_missing:
|
2021-12-01 15:50:48 +00:00
|
|
|
summary_status = "error"
|
2021-11-30 15:33:29 +00:00
|
|
|
|
2022-03-30 09:15:54 +00:00
|
|
|
addition = ""
|
|
|
|
if some_builds_are_missing:
|
2022-04-06 12:39:23 +00:00
|
|
|
addition = f"({len(build_reports_map)} < {reports_length})"
|
2022-03-30 09:15:54 +00:00
|
|
|
|
|
|
|
description = f"{ok_builds}/{total_builds} builds are OK {addition}"
|
2021-10-21 14:41:07 +00:00
|
|
|
|
2022-04-06 12:34:20 +00:00
|
|
|
print(f"::notice ::Report url: {url}")
|
2021-10-21 14:41:07 +00:00
|
|
|
|
|
|
|
commit = get_commit(gh, pr_info.sha)
|
2022-03-22 16:39:58 +00:00
|
|
|
commit.create_status(
|
|
|
|
context=build_check_name,
|
|
|
|
description=description,
|
|
|
|
state=summary_status,
|
|
|
|
target_url=url,
|
|
|
|
)
|
2022-03-29 12:41:47 +00:00
|
|
|
|
|
|
|
if summary_status == "error":
|
|
|
|
sys.exit(1)
|