Add GH status for PR formatting (#58050)

* add GH status for PR formatting
 #no-merge-commit
This commit is contained in:
Max K 2023-12-21 11:53:01 +01:00 committed by GitHub
parent 20c0347eef
commit cb53ee63be
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 75 additions and 74 deletions

10
.gitmessage Normal file
View File

@ -0,0 +1,10 @@
## To avoid merge commit in CI run (add a leading space to apply):
#no-merge-commit
## Running specified job (add a leading space to apply):
#job_<JOB NAME>
#job_stateless_tests_release
#job_package_debug
#job_integration_tests_asan

View File

@ -78,7 +78,7 @@ def main():
pr_info = PRInfo()
commit = get_commit(gh, pr_info.sha)
atexit.register(update_mergeable_check, gh, pr_info, build_check_name)
atexit.register(update_mergeable_check, commit, pr_info, build_check_name)
rerun_helper = RerunHelper(commit, build_check_name)
if rerun_helper.is_already_finished_by_status():

View File

@ -847,6 +847,7 @@ CI_CONFIG.validate()
# checks required by Mergeable Check
REQUIRED_CHECKS = [
"PR Check",
"ClickHouse build check",
"ClickHouse special build check",
"Docs Check",

View File

@ -133,7 +133,7 @@ def main():
pr_info = PRInfo()
commit = get_commit(gh, pr_info.sha)
atexit.register(update_mergeable_check, gh, pr_info, check_name)
atexit.register(update_mergeable_check, commit, pr_info, check_name)
rerun_helper = RerunHelper(commit, check_name)
if rerun_helper.is_already_finished_by_status():

View File

@ -15,11 +15,10 @@ from github.CommitStatus import CommitStatus
from github.GithubException import GithubException
from github.GithubObject import NotSet
from github.IssueComment import IssueComment
from github.PullRequest import PullRequest
from github.Repository import Repository
from ci_config import CI_CONFIG, REQUIRED_CHECKS, CHECK_DESCRIPTIONS, CheckDescription
from env_helper import GITHUB_REPOSITORY, GITHUB_RUN_URL, TEMP_PATH
from env_helper import GITHUB_JOB_URL, GITHUB_REPOSITORY, TEMP_PATH
from pr_info import PRInfo, SKIP_MERGEABLE_CHECK_LABEL
from report import (
ERROR,
@ -437,11 +436,11 @@ def set_mergeable_check(
context=MERGEABLE_NAME,
description=description,
state=state,
target_url=GITHUB_RUN_URL,
target_url=GITHUB_JOB_URL(),
)
def update_mergeable_check(gh: Github, pr_info: PRInfo, check_name: str) -> None:
def update_mergeable_check(commit: Commit, pr_info: PRInfo, check_name: str) -> None:
not_run = (
pr_info.labels.intersection({SKIP_MERGEABLE_CHECK_LABEL, "release"})
or check_name not in REQUIRED_CHECKS
@ -454,7 +453,6 @@ def update_mergeable_check(gh: Github, pr_info: PRInfo, check_name: str) -> None
logging.info("Update Mergeable Check by %s", check_name)
commit = get_commit(gh, pr_info.sha)
statuses = get_commit_filtered_statuses(commit)
required_checks = [
@ -475,14 +473,17 @@ def update_mergeable_check(gh: Github, pr_info: PRInfo, check_name: str) -> None
else:
fail.append(status.context)
state: StatusType = SUCCESS
if success:
description = ", ".join(success)
else:
description = "awaiting job statuses"
if fail:
description = "failed: " + ", ".join(fail)
description = format_description(description)
if mergeable_status is None or mergeable_status.description != description:
set_mergeable_check(commit, description, FAILURE)
return
description = ", ".join(success)
state = FAILURE
description = format_description(description)
if mergeable_status is None or mergeable_status.description != description:
set_mergeable_check(commit, description)
set_mergeable_check(commit, description, state)

View File

@ -67,7 +67,7 @@ def main():
if rerun_helper.is_already_finished_by_status():
logging.info("Check is already finished according to github status, exiting")
sys.exit(0)
atexit.register(update_mergeable_check, gh, pr_info, NAME)
atexit.register(update_mergeable_check, commit, pr_info, NAME)
if not pr_info.has_changes_in_documentation() and not args.force:
logging.info("No changes in documentation")

View File

@ -124,7 +124,7 @@ def main():
gh = Github(get_best_robot_token(), per_page=100)
commit = get_commit(gh, pr_info.sha)
atexit.register(update_mergeable_check, gh, pr_info, NAME)
atexit.register(update_mergeable_check, commit, pr_info, NAME)
rerun_helper = RerunHelper(commit, NAME)
if rerun_helper.is_already_finished_by_status():

View File

@ -18,9 +18,9 @@ def main():
pr_info = PRInfo(need_orgs=True)
gh = Github(get_best_robot_token(), per_page=100)
# Update the Mergeable Check at the final step
update_mergeable_check(gh, pr_info, CI_STATUS_NAME)
commit = get_commit(gh, pr_info.sha)
# Update the Mergeable Check at the final step
update_mergeable_check(commit, pr_info, CI_STATUS_NAME)
statuses = [
status

View File

@ -254,7 +254,7 @@ def main():
)
commit = get_commit(gh, pr_info.sha)
atexit.register(update_mergeable_check, gh, pr_info, check_name)
atexit.register(update_mergeable_check, commit, pr_info, check_name)
if validate_bugfix_check and "pr-bugfix" not in pr_info.labels:
if args.post_commit_status == "file":

View File

@ -279,7 +279,7 @@ def main():
if CI:
gh = Github(get_best_robot_token(), per_page=100)
commit = get_commit(gh, pr_info.sha)
atexit.register(update_mergeable_check, gh, pr_info, args.check_name)
atexit.register(update_mergeable_check, commit, pr_info, args.check_name)
rerun_helper = RerunHelper(commit, args.check_name)
if rerun_helper.is_already_finished_by_status():

View File

@ -118,7 +118,7 @@ def main():
gh = Github(get_best_robot_token(), per_page=100)
pr_info = PRInfo()
commit = get_commit(gh, pr_info.sha)
atexit.register(update_mergeable_check, gh, pr_info, check_name)
atexit.register(update_mergeable_check, commit, pr_info, check_name)
temp_path.mkdir(parents=True, exist_ok=True)

View File

@ -1,4 +1,5 @@
#!/usr/bin/env python3
import atexit
import sys
import logging
from typing import Tuple
@ -13,9 +14,8 @@ from commit_status_helper import (
post_commit_status,
post_labels,
remove_labels,
set_mergeable_check,
update_mergeable_check,
)
from docs_check import NAME as DOCS_NAME
from env_helper import GITHUB_REPOSITORY, GITHUB_SERVER_URL
from get_robot_token import get_best_robot_token
from pr_info import FORCE_TESTS_LABEL, PRInfo
@ -24,6 +24,7 @@ from lambda_shared_package.lambda_shared.pr import (
TRUSTED_CONTRIBUTORS,
check_pr_description,
)
from report import FAILURE
TRUSTED_ORG_IDS = {
54801242, # clickhouse
@ -34,6 +35,7 @@ CAN_BE_TESTED_LABEL = "can be tested"
DO_NOT_TEST_LABEL = "do not test"
FEATURE_LABEL = "pr-feature"
SUBMODULE_CHANGED_LABEL = "submodule changed"
PR_CHECK = "PR Check"
def pr_is_by_trusted_user(pr_user_login, pr_user_orgs):
@ -58,24 +60,20 @@ def pr_is_by_trusted_user(pr_user_login, pr_user_orgs):
# Returns whether we should look into individual checks for this PR. If not, it
# can be skipped entirely.
# Returns can_run, description, labels_state
def should_run_ci_for_pr(pr_info: PRInfo) -> Tuple[bool, str, str]:
# Returns can_run, description
def should_run_ci_for_pr(pr_info: PRInfo) -> Tuple[bool, str]:
# Consider the labels and whether the user is trusted.
print("Got labels", pr_info.labels)
if FORCE_TESTS_LABEL in pr_info.labels:
print(f"Label '{FORCE_TESTS_LABEL}' set, forcing remaining checks")
return True, f"Labeled '{FORCE_TESTS_LABEL}'", "pending"
return True, f"Labeled '{FORCE_TESTS_LABEL}'"
if DO_NOT_TEST_LABEL in pr_info.labels:
print(f"Label '{DO_NOT_TEST_LABEL}' set, skipping remaining checks")
return False, f"Labeled '{DO_NOT_TEST_LABEL}'", "success"
return False, f"Labeled '{DO_NOT_TEST_LABEL}'"
if OK_SKIP_LABELS.intersection(pr_info.labels):
return (
True,
"Don't try new checks for release/backports/cherry-picks",
"success",
)
return True, "Don't try new checks for release/backports/cherry-picks"
if CAN_BE_TESTED_LABEL not in pr_info.labels and not pr_is_by_trusted_user(
pr_info.user_login, pr_info.user_orgs
@ -83,9 +81,9 @@ def should_run_ci_for_pr(pr_info: PRInfo) -> Tuple[bool, str, str]:
print(
f"PRs by untrusted users need the '{CAN_BE_TESTED_LABEL}' label - please contact a member of the core team"
)
return False, "Needs 'can be tested' label", "failure"
return False, "Needs 'can be tested' label"
return True, "No special conditions apply", "pending"
return True, "No special conditions apply"
def main():
@ -98,7 +96,7 @@ def main():
print("::notice ::Cannot run, no PR exists for the commit")
sys.exit(1)
can_run, description, labels_state = should_run_ci_for_pr(pr_info)
can_run, description = should_run_ci_for_pr(pr_info)
if can_run and OK_SKIP_LABELS.intersection(pr_info.labels):
print("::notice :: Early finish the check, running in a special PR")
sys.exit(0)
@ -106,6 +104,7 @@ def main():
description = format_description(description)
gh = Github(get_best_robot_token(), per_page=100)
commit = get_commit(gh, pr_info.sha)
atexit.register(update_mergeable_check, commit, pr_info, PR_CHECK)
description_error, category = check_pr_description(pr_info.body, GITHUB_REPOSITORY)
pr_labels_to_add = []
@ -136,22 +135,6 @@ def main():
if pr_labels_to_remove:
remove_labels(gh, pr_info, pr_labels_to_remove)
# FIXME: it should rather be in finish check. no reason to stop ci run.
if FEATURE_LABEL in pr_info.labels and not pr_info.has_changes_in_documentation():
print(
f"The '{FEATURE_LABEL}' in the labels, "
"but there's no changed documentation"
)
post_commit_status( # do not pass pr_info here intentionally
commit,
"failure",
"",
f"expect adding docs for {FEATURE_LABEL}",
DOCS_NAME,
pr_info,
)
sys.exit(0)
if description_error:
print(
"::error ::Cannot run, PR description does not match the template: "
@ -171,34 +154,40 @@ def main():
"failure",
url,
format_description(description_error),
CI_STATUS_NAME,
PR_CHECK,
pr_info,
)
sys.exit(1)
set_mergeable_check(commit, "skipped")
ci_report_url = create_ci_report(pr_info, [])
if FEATURE_LABEL in pr_info.labels and not pr_info.has_changes_in_documentation():
print(
f"The '{FEATURE_LABEL}' in the labels, "
"but there's no changed documentation"
)
post_commit_status(
commit,
FAILURE,
"",
f"expect adding docs for {FEATURE_LABEL}",
PR_CHECK,
pr_info,
)
# allow the workflow to continue
if not can_run:
print("::notice ::Cannot run")
post_commit_status(
commit,
labels_state,
ci_report_url,
description,
CI_STATUS_NAME,
pr_info,
)
sys.exit(1)
else:
print("::notice ::Can run")
post_commit_status(
commit,
"pending",
ci_report_url,
description,
CI_STATUS_NAME,
pr_info,
)
ci_report_url = create_ci_report(pr_info, [])
print("::notice ::Can run")
post_commit_status(
commit,
"pending",
ci_report_url,
description,
CI_STATUS_NAME,
pr_info,
)
if __name__ == "__main__":

View File

@ -145,7 +145,7 @@ def main():
gh = GitHub(get_best_robot_token(), create_cache_dir=False)
commit = get_commit(gh, pr_info.sha)
atexit.register(update_mergeable_check, gh, pr_info, NAME)
atexit.register(update_mergeable_check, commit, pr_info, NAME)
rerun_helper = RerunHelper(commit, NAME)
if rerun_helper.is_already_finished_by_status():

View File

@ -187,7 +187,7 @@ def main():
gh = Github(get_best_robot_token(), per_page=100)
commit = get_commit(gh, pr_info.sha)
atexit.register(update_mergeable_check, gh, pr_info, check_name)
atexit.register(update_mergeable_check, commit, pr_info, check_name)
rerun_helper = RerunHelper(commit, check_name)
if rerun_helper.is_already_finished_by_status():