From 0041e27669522ca2d76c7b82b0c8621d07cc1e57 Mon Sep 17 00:00:00 2001 From: alichinese Date: Wed, 13 Jul 2022 15:14:54 +0800 Subject: [PATCH] conf: alter gitlint title and body length alter gitlint title and body length Signed-off-by: lixinyu lixinyu44@huawei.com --- src/build/comment.yaml | 2 - src/build/gitee_comment_openeuler.py | 470 --------------------------- src/conf/.gitlint | 4 +- 3 files changed, 2 insertions(+), 474 deletions(-) delete mode 100644 src/build/comment.yaml delete mode 100644 src/build/gitee_comment_openeuler.py diff --git a/src/build/comment.yaml b/src/build/comment.yaml deleted file mode 100644 index 3eb8038..0000000 --- a/src/build/comment.yaml +++ /dev/null @@ -1,2 +0,0 @@ -openeuler: - arch_list: ['aarch64','arm'] \ No newline at end of file diff --git a/src/build/gitee_comment_openeuler.py b/src/build/gitee_comment_openeuler.py deleted file mode 100644 index 8b10616..0000000 --- a/src/build/gitee_comment_openeuler.py +++ /dev/null @@ -1,470 +0,0 @@ -# -*- coding: utf-8 -*- -""" -# ********************************************************************************** -# Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved. -# [openeuler-jenkins] is licensed under the Mulan PSL v2. -# You can use this software according to the terms and conditions of the Mulan PSL v2. -# You may obtain a copy of Mulan PSL v2 at: -# http://license.coscl.org.cn/MulanPSL2 -# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, -# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, -# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -# See the Mulan PSL v2 for more details. -# Author: -# Create: 2020-09-23 -# Description: comment pr with build result -# ********************************************************************************** -""" -import os -import re -import stat -import sys -import logging.config -import json -import argparse -import warnings -from urllib.parse import unquote -from cairo import Status -import yaml - -from yaml.error import YAMLError -from os.error import File -from src.ac.framework.ac_result import ACResult, SUCCESS -from src.proxy.gitee_proxy import GiteeProxy -from src.proxy.kafka_proxy import KafkaProducerProxy -from src.proxy.jenkins_proxy import JenkinsProxy -from src.utils.dist_dataset import DistDataset - - -class Comment(object): - """ - comments process - """ - - def __init__(self, pr, jenkins_proxy, *check_item_comment_files): - """ - - :param pr: pull request number - """ - self._pr = pr - self._check_item_comment_files = check_item_comment_files - self._up_builds = [] - self._up_up_builds = [] - self._get_upstream_builds(jenkins_proxy) - self.ac_result = {} - self.compare_package_result = {} - self.check_item_result = {} - self._arch_list = self.get_arch_list() - - @staticmethod - def get_arch_list(): - comment_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "comment.yaml") - arch_list = {} - try: - with open(comment_dir, "r") as f: - arch_list = yaml.safe_load(f) - arch_list = arch_list["openeuler"]["arch_list"] - except YAMLError: - logger.exception("illegal yaml format of check item comment file ") - except OSError: - logger.exception("file path is not exists") - return arch_list - - def comment_build(self, gitee_proxy): - """ - 构建结果 - :param jenkins_proxy: - :param gitee_proxy: - :return: - """ - comments = self._comment_build_html_format() - gitee_proxy.comment_pr(self._pr, "\n".join(comments)) - - return "\n".join(comments) - - def comment_at(self, committer, gitee_proxy): - """ - 通知committer - @committer - :param committer: - :param gitee_proxy: - :return: - """ - gitee_proxy.comment_pr(self._pr, "@{}".format(committer)) - - def check_build_result(self): - """ - build result check - :return: - """ - build_result = sum([ACResult.get_instance(build["result"]) for build in self._up_builds], SUCCESS) - return build_result - - def _get_upstream_builds(self, jenkins_proxy): - """ - get upstream builds - :param jenkins_proxy: - :return: - """ - base_job_name = os.environ.get("JOB_NAME") - base_build_id = os.environ.get("BUILD_ID") - base_build_id = int(base_build_id) - logger.debug("base_job_name: %s, base_build_id: %s", base_job_name, base_build_id) - base_build = jenkins_proxy.get_build_info(base_job_name, base_build_id) - logger.debug("get base build") - self._up_builds = jenkins_proxy.get_upstream_builds(base_build) - if self._up_builds: - logger.debug("get up_builds") - self._up_up_builds = jenkins_proxy.get_upstream_builds(self._up_builds[0]) - - def _comment_build_html_format(self): - """ - 组装构建信息,并评论pr - :param jenkins_proxy: JenkinsProxy object - :return: - """ - comments = ["", self.comment_html_table_th()] - - if self._up_up_builds: - logger.debug("get up_up_builds") - comments.extend(self._comment_of_ac(self._up_up_builds[0])) - if self._up_builds: - comments.extend(self._comment_of_check_item(self._up_builds)) - - comments.append("
") - return comments - - def _comment_of_ac(self, build): - """ - 组装门禁检查结果 - :param build: Jenkins Build object,门禁检查jenkins构建对象 - :return: - """ - if "ACL" not in os.environ: - logger.debug("no ac check") - return [] - - try: - acl = json.loads(os.environ["ACL"]) - logger.debug("ac result: %s", acl) - except ValueError: - logger.exception("invalid ac result format") - return [] - - comments = [] - - for index, item in enumerate(acl): - ac_result = ACResult.get_instance(item["result"]) - if index == 0: - build_url = build["url"] - conf_dict = {'name': item["name"], 'icon': ac_result.emoji, 'status': ac_result.hint, \ - 'href': "{}{}".format(build_url, "console"), 'build_no': build["number"], 'rowspan': len(acl)} - comments.append(self.__class__.comment_html_table_tr(conf_dict)) - else: - comments.append(self.__class__.comment_html_table_tr_rowspan( - item["name"], ac_result.emoji, ac_result.hint)) - self.ac_result[item["name"]] = ac_result.hint - logger.info("ac comment: %s", comments) - - return comments - - def _comment_of_check_item(self, builds): - """ - check item comment - :param builds: - :return: - """ - comment_file_dict = self._get_comment_file_dict() - build_dict = self._get_build_dict(builds) - tr_list = [] - for arch_name, arch_result in build_dict.items(): - arch_name_rows_span = 0 - arch_comment_dict = comment_file_dict.get(arch_name, {}) - is_first = True - first_image = "" - for image_name in arch_result: - image_rows_span = len(arch_comment_dict.get(image_name, {})) - arch_name_rows_span += 1 + image_rows_span - if is_first: - first_image = image_name - is_first = False - - for image_name, image_result in arch_result.items(): - image_name_rows_span = len(arch_comment_dict.get(image_name, {})) + 1 - if image_name == first_image: - tr_list.append({"arch_name": arch_name, "arch_name_rows_span": arch_name_rows_span, \ - "image_name": image_name, "image_name_rows_span": image_name_rows_span, \ - "check_name": "build", "status": image_result["result"], \ - "build_url": image_result["build_url"], "build_no": image_result["build_no"]}) - for check_name, check_result in arch_comment_dict.get(image_name, {}).items(): - tr_list.append({"check_name": check_name, "status": check_result}) - else: - tr_list.append({"image_name": image_name, "image_name_rows_span": image_name_rows_span, \ - "check_name": "build", "status": image_result["result"], \ - "build_url": image_result["build_url"], "build_no": image_result["build_no"]}) - for check_name, check_result in arch_comment_dict.get(image_name, {}).items(): - tr_list.append({"check_name": check_name, "status": check_result}) - - comments = [] - for tr in tr_list: - tr_str = "" - if "arch_name" in tr: - tr_str += "{}".format(tr.get("arch_name_rows_span"), tr.get("arch_name")) - if "image_name" in tr: - tr_str += "{}".format(tr.get("image_name_rows_span"), tr.get("image_name")) - tr_str += "{}".format(tr.get("check_name")) - ac_result = ACResult.get_instance(tr.get("status")) - tr_str += "{}{}".format(ac_result.emoji, ac_result.hint) - if "build_url" in tr: - tr_str += "#{}".format(\ - tr.get("image_name_rows_span"),\ - "{}{}".format(tr.get("build_url"), "console"),\ - tr.get("build_no")) - tr_str += "" - comments.append(tr_str) - - return comments - - @classmethod - def comment_html_table_th(cls): - """ - table header - """ - return "Check Name Build Result Build Details" - - @classmethod - def comment_html_table_tr(cls, conf_dict): - """ - one row or span row - """ - # name, icon, status, href, build_no, hashtag=True, rowspan=1 - name = conf_dict.get("name", "") - icon = conf_dict.get("icon") - status = conf_dict.get("status") - href = conf_dict.get("href") - build_no = conf_dict.get("build_no", 0) - hashtag = conf_dict.get("hashtag", True) - rowspan = conf_dict.get("rowspan", 1) - return "{} {}{} " \ - "{}{}".format( - name, icon, status, rowspan, href, "#" if hashtag else "", build_no) - - @classmethod - def comment_html_table_tr_rowspan(cls, name, icon, status): - """ - span row - """ - return "{} {}{}".format(name, icon, status) - - def _get_comment_file_dict(self): - res_dict = {} - for check_comment_file in self._check_item_comment_files: - current_name = "" - current_arch = {} - for arch in self._arch_list: - if "_" + arch + "_" in check_comment_file: - current_name = arch - current_arch = res_dict.get(arch, {}) - break - if os.path.exists(check_comment_file): - with open(check_comment_file, "r") as f: - image_name = re.compile(r'\((.+)\)').search(check_comment_file).group(1) - image_dict = current_arch.get(image_name, {}) - try: - content = yaml.safe_load(f) - except YAMLError: # yaml base exception - logger.exception("illegal yaml format of check item comment file ") - logger.debug("comment: %s", content) - for item in content: - image_dict[item.get("name")] = item.get("result") - current_arch[image_name] = image_dict - else: - logger.info(check_comment_file+" is not exists") - continue - res_dict[current_name] = current_arch - - return res_dict - - def _get_build_dict(self, builds): - res_dict = {} - for build in builds: - name, _ = JenkinsProxy.get_job_path_build_no_from_build_url(build["url"]) - status = build["result"] - build_url = build["url"] - - is_continue = True - arch = "" - for arch_name in self._arch_list: - if "/"+arch_name+"/" in name: - arch = arch_name - is_continue = False - break - if is_continue: - continue - current_arch = res_dict.get(arch, {}) - image_name = re.compile(r'\((.+)\)').search(unquote(name)).group(1) - current_arch[image_name] = {"result": status, "build_url": build_url, "build_no": build["number"]} - res_dict[arch] = current_arch - return res_dict - - def _get_job_url(self, comment_url): - """ - get_job_url - :param url: - :return: - """ - build_urls = {"trigger": self._up_up_builds[0]["url"], - "comment": os.path.join(comment_url, os.environ.get("BUILD_ID")) - } - for build in self._up_builds: - arch = "" - try: - arch_index = 3 - list_step = 2 - if build["url"]: - job_path = re.sub(r"http[s]?://", "", build["url"]) - arch = job_path.split("/")[::list_step][arch_index] - except IndexError: - logger.info("get arch from job failed, index error.") - except KeyError: - logger.info("not find build url key") - if arch: - build_urls[arch] = build["url"] - - return build_urls - - def _get_all_job_result(self, check_details): - """ - get_all_job_result - :return: - """ - - check_details["static_code"] = self.ac_result - for arch, arch_result in self.check_item_result.items(): - if self.compare_package_result.get(arch): - arch_result["compare_package"] = self.compare_package_result.get(arch) - check_details[arch] = arch_result - - return check_details - - def get_all_result_to_kafka(self, comment_url): - """ - 名称 类型 必选 说明 - build_urls 字典 是 包含多个门禁工程链接和显示文本 - check_total 字符串 是 门禁整体结果 - check_details 字典 是 门禁各个检查项结果 - :return: - """ - check_details = {} - build_urls = self._get_job_url(comment_url) - self._get_all_job_result(check_details) - - if self.check_build_result() == SUCCESS: - check_total = 'SUCCESS' - else: - check_total = 'FAILED' - - all_dict = {"build_urls": build_urls, - "check_total": check_total, - "check_details": check_details - } - logger.info("all_dict = %s", all_dict) - flags = os.O_WRONLY | os.O_CREAT | os.O_EXCL - modes = stat.S_IWUSR | stat.S_IRUSR - try: - with os.fdopen(os.open("build_result.yaml", flags, modes), "w") as f: - yaml.safe_dump(all_dict, f) - except IOError: - logger.exception("save build result file exception") - - -def init_args(): - """ - init args - :return: - """ - parser = argparse.ArgumentParser() - parser.add_argument("-p", type=int, dest="pr", help="pull request number") - parser.add_argument("-m", type=str, dest="comment_id", help="uniq comment id") - parser.add_argument("-c", type=str, dest="committer", help="commiter") - parser.add_argument("-o", type=str, dest="owner", help="gitee owner") - parser.add_argument("-r", type=str, dest="repo", help="repo name") - parser.add_argument("-t", type=str, dest="gitee_token", help="gitee api token") - - parser.add_argument("-b", type=str, dest="jenkins_base_url", default="https://openeulerjenkins.osinfra.cn/", - help="jenkins base url") - parser.add_argument("-u", type=str, dest="jenkins_user", help="repo name") - parser.add_argument("-j", type=str, dest="jenkins_api_token", help="jenkins api token") - parser.add_argument("-f", type=str, dest="check_result_file", default="", help="compare package check item result") - parser.add_argument("-a", type=str, dest="check_item_comment_files", nargs="*", help="check item comment files") - - parser.add_argument("--disable", dest="enable", default=True, action="store_false", help="comment to gitee switch") - - return parser.parse_args() - - -if "__main__" == __name__: - args = init_args() - if not args.enable: - sys.exit(0) - - _ = not os.path.exists("log") and os.mkdir("log") - logger_conf_path = os.path.realpath(os.path.join(os.path.realpath(__file__), "../../conf/logger.conf")) - logging.config.fileConfig(logger_conf_path) - logger = logging.getLogger("build") - - dd = DistDataset() - dd.set_attr_stime("comment.job.stime") - - # gitee pr tag - gp = GiteeProxy(args.owner, args.repo, args.gitee_token) - gp.delete_tag_of_pr(args.pr, "ci_processing") - - jp = JenkinsProxy(args.jenkins_base_url, args.jenkins_user, args.jenkins_api_token) - url, build_time, reason = jp.get_job_build_info(os.environ.get("JOB_NAME"), int(os.environ.get("BUILD_ID"))) - dd.set_attr_ctime("comment.job.ctime", build_time) - dd.set_attr("comment.job.link", url) - dd.set_attr("comment.trigger.reason", reason) - - dd.set_attr_stime("comment.build.stime") - - comment = {} - if args.check_item_comment_files: - comment = Comment(args.pr, jp, *args.check_item_comment_files) - else: - comment = Comment(args.pr, jp) - logger.info("comment: build result......") - comment_content = comment.comment_build(gp) - dd.set_attr_etime("comment.build.etime") - dd.set_attr("comment.build.content.html", comment_content) - - if comment.check_build_result() == SUCCESS: - gp.delete_tag_of_pr(args.pr, "ci_failed") - gp.create_tags_of_pr(args.pr, "ci_successful") - dd.set_attr("comment.build.tags", ["ci_successful"]) - dd.set_attr("comment.build.result", "successful") - if args.check_result_file: - comment.comment_compare_package_details(gp, args.check_result_file) - else: - gp.delete_tag_of_pr(args.pr, "ci_successful") - gp.create_tags_of_pr(args.pr, "ci_failed") - dd.set_attr("comment.build.tags", ["ci_failed"]) - dd.set_attr("comment.build.result", "failed") - if args.owner != "openeuler": - comment.get_all_result_to_kafka(url) - - logger.info("comment: at committer......") - comment.comment_at(args.committer, gp) - - dd.set_attr_etime("comment.job.etime") - - # suppress python warning - warnings.filterwarnings("ignore") - logging.getLogger("elasticsearch").setLevel(logging.WARNING) - logging.getLogger("kafka").setLevel(logging.WARNING) - - # upload to es - kp = KafkaProducerProxy(brokers=os.environ["KAFKAURL"].split(",")) - query = {"term": {"id": args.comment_id}} - script = {"lang": "painless", "source": "ctx._source.comment = params.comment", "params": dd.to_dict()} - kp.send("openeuler_statewall_ci_ac", key=args.comment_id, value=dd.to_dict()) diff --git a/src/conf/.gitlint b/src/conf/.gitlint index 87ffa18..67aa9f5 100644 --- a/src/conf/.gitlint +++ b/src/conf/.gitlint @@ -48,7 +48,7 @@ contrib=CC1 # This is an example of how to configure the "title-max-length" rule and # set the line-length it enforces to 50 [title-max-length] -line-length=80 +line-length=72 # Conversely, you can also enforce minimal length of a title with the # "title-min-length" rule: @@ -68,7 +68,7 @@ min-length=5 regex=^(([0-9a-zA-Z]|-|_){1,}(: ))(.){1,}$ [body-max-line-length] -line-length=72 +line-length=80 [body-min-length] min-length=5 -- Gitee