2021-11-12 12:36:25 +00:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
2022-03-18 12:36:45 +00:00
|
|
|
import csv
|
2022-07-21 16:12:07 +00:00
|
|
|
import os
|
|
|
|
import time
|
|
|
|
from typing import Optional
|
2022-07-30 05:07:22 +00:00
|
|
|
import logging
|
2022-07-21 16:12:07 +00:00
|
|
|
|
2022-07-30 05:07:22 +00:00
|
|
|
from ci_config import CI_CONFIG, REQUIRED_CHECKS
|
2022-07-21 16:12:07 +00:00
|
|
|
from env_helper import GITHUB_REPOSITORY, GITHUB_RUN_URL
|
|
|
|
from github import Github
|
|
|
|
from github.Commit import Commit
|
2022-07-30 05:07:22 +00:00
|
|
|
from pr_info import SKIP_MERGEABLE_CHECK_LABEL
|
2021-11-26 14:00:09 +00:00
|
|
|
|
2021-12-28 10:13:51 +00:00
|
|
|
RETRY = 5
|
|
|
|
|
|
|
|
|
2022-03-10 16:39:18 +00:00
|
|
|
def override_status(status, check_name, invert=False):
|
|
|
|
if CI_CONFIG["tests_config"].get(check_name, {}).get("force_tests", False):
|
2022-01-10 16:45:17 +00:00
|
|
|
return "success"
|
2022-03-10 16:39:18 +00:00
|
|
|
|
|
|
|
if invert:
|
2022-03-22 16:39:58 +00:00
|
|
|
if status == "success":
|
|
|
|
return "error"
|
|
|
|
return "success"
|
2022-03-10 16:39:18 +00:00
|
|
|
|
2022-01-10 16:45:17 +00:00
|
|
|
return status
|
|
|
|
|
|
|
|
|
2022-07-21 16:12:07 +00:00
|
|
|
def get_commit(
|
|
|
|
gh: Github, commit_sha: str, retry_count: int = RETRY
|
|
|
|
) -> Optional[Commit]:
|
2021-12-28 10:13:51 +00:00
|
|
|
for i in range(retry_count):
|
|
|
|
try:
|
|
|
|
repo = gh.get_repo(GITHUB_REPOSITORY)
|
|
|
|
commit = repo.get_commit(commit_sha)
|
|
|
|
return commit
|
|
|
|
except Exception as ex:
|
|
|
|
if i == retry_count - 1:
|
|
|
|
raise ex
|
|
|
|
time.sleep(i)
|
|
|
|
|
|
|
|
# just suppress warning
|
|
|
|
return None
|
2021-11-12 12:36:25 +00:00
|
|
|
|
|
|
|
|
|
|
|
def post_commit_status(gh, sha, check_name, description, state, report_url):
|
2021-12-28 10:13:51 +00:00
|
|
|
for i in range(RETRY):
|
|
|
|
try:
|
|
|
|
commit = get_commit(gh, sha, 1)
|
2022-01-10 16:37:38 +00:00
|
|
|
commit.create_status(
|
|
|
|
context=check_name,
|
|
|
|
description=description,
|
|
|
|
state=state,
|
|
|
|
target_url=report_url,
|
|
|
|
)
|
2021-12-28 10:13:51 +00:00
|
|
|
break
|
|
|
|
except Exception as ex:
|
|
|
|
if i == RETRY - 1:
|
|
|
|
raise ex
|
|
|
|
time.sleep(i)
|
2022-03-18 12:36:45 +00:00
|
|
|
|
|
|
|
|
|
|
|
def post_commit_status_to_file(file_path, description, state, report_url):
|
|
|
|
if os.path.exists(file_path):
|
|
|
|
raise Exception(f'File "{file_path}" already exists!')
|
2022-03-22 16:39:58 +00:00
|
|
|
with open(file_path, "w", encoding="utf-8") as f:
|
|
|
|
out = csv.writer(f, delimiter="\t")
|
2022-03-18 12:36:45 +00:00
|
|
|
out.writerow([state, report_url, description])
|
2022-03-29 13:48:57 +00:00
|
|
|
|
2022-03-29 17:15:25 +00:00
|
|
|
|
2022-03-29 17:50:06 +00:00
|
|
|
def remove_labels(gh, pr_info, labels_names):
|
|
|
|
repo = gh.get_repo(GITHUB_REPOSITORY)
|
|
|
|
pull_request = repo.get_pull(pr_info.number)
|
|
|
|
for label in labels_names:
|
|
|
|
pull_request.remove_from_labels(label)
|
|
|
|
|
|
|
|
|
2022-03-29 17:28:18 +00:00
|
|
|
def post_labels(gh, pr_info, labels_names):
|
2022-03-29 13:48:57 +00:00
|
|
|
repo = gh.get_repo(GITHUB_REPOSITORY)
|
|
|
|
pull_request = repo.get_pull(pr_info.number)
|
2022-03-29 17:28:18 +00:00
|
|
|
for label in labels_names:
|
|
|
|
pull_request.add_to_labels(label)
|
2022-07-19 12:57:03 +00:00
|
|
|
|
|
|
|
|
2022-07-30 05:07:22 +00:00
|
|
|
def fail_mergeable_check(commit, description):
|
2022-07-19 12:57:03 +00:00
|
|
|
commit.create_status(
|
2022-07-30 05:07:22 +00:00
|
|
|
context="Mergeable Check",
|
2022-07-19 12:57:03 +00:00
|
|
|
description=description,
|
|
|
|
state="failure",
|
|
|
|
target_url=GITHUB_RUN_URL,
|
|
|
|
)
|
2022-07-18 19:15:21 +00:00
|
|
|
|
|
|
|
|
2022-07-30 05:07:22 +00:00
|
|
|
def reset_mergeable_check(commit, description=""):
|
2022-07-18 19:15:21 +00:00
|
|
|
commit.create_status(
|
2022-07-30 05:07:22 +00:00
|
|
|
context="Mergeable Check",
|
|
|
|
description=description,
|
2022-07-18 19:15:21 +00:00
|
|
|
state="success",
|
|
|
|
target_url=GITHUB_RUN_URL,
|
|
|
|
)
|
2022-07-30 05:07:22 +00:00
|
|
|
|
|
|
|
|
|
|
|
def update_mergeable_check(gh, pr_info, check_name):
|
|
|
|
if SKIP_MERGEABLE_CHECK_LABEL in pr_info.labels:
|
|
|
|
return
|
|
|
|
|
|
|
|
logging.info("Update Mergeable Check by %s", check_name)
|
|
|
|
|
|
|
|
commit = get_commit(gh, pr_info.sha)
|
|
|
|
checks = {
|
|
|
|
check.context: check.state
|
|
|
|
for check in filter(
|
|
|
|
lambda check: (check.context in REQUIRED_CHECKS),
|
|
|
|
# get_statuses() returns generator, which cannot be reversed - we need comprehension
|
|
|
|
# pylint: disable=unnecessary-comprehension
|
|
|
|
reversed([status for status in commit.get_statuses()]),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
success = []
|
|
|
|
fail = []
|
|
|
|
for name, state in checks.items():
|
|
|
|
if state == "success":
|
|
|
|
success.append(name)
|
|
|
|
else:
|
|
|
|
fail.append(name)
|
|
|
|
|
|
|
|
if fail:
|
|
|
|
description = "failed: " + ", ".join(fail)
|
|
|
|
if success:
|
|
|
|
description += "; succeeded: " + ", ".join(success)
|
|
|
|
if len(description) > 140:
|
|
|
|
description = description[:137] + "..."
|
|
|
|
fail_mergeable_check(commit, description)
|
|
|
|
return
|
|
|
|
|
|
|
|
description = ", ".join(success)
|
|
|
|
if len(description) > 140:
|
|
|
|
description = description[:137] + "..."
|
|
|
|
reset_mergeable_check(commit, description)
|