diff --git "a/doc/\351\227\250\347\246\201\346\243\200\346\237\245commit_msg\350\247\204\350\214\203.md" "b/doc/\351\227\250\347\246\201\346\243\200\346\237\245commit_msg\350\247\204\350\214\203.md" new file mode 100644 index 0000000000000000000000000000000000000000..dc8a11851447b3d37c281666bc53974e45002392 --- /dev/null +++ "b/doc/\351\227\250\347\246\201\346\243\200\346\237\245commit_msg\350\247\204\350\214\203.md" @@ -0,0 +1,47 @@ +# 门禁检查规范及处理规则 + +## 门禁检查规范 + +规范遵循以下范例: + +script: xxx + + +this is msg body + + +Signed-off-by: username example@email.com + +================================= + +script->跟模块名,作为标题 + +紧接着为提交说明 + +末尾为个人签名信息 + +## 门禁检查分支范围 + +门禁检查指列出原分支和目标分支之间的业务提交log,并不会检查merge带有特殊标记的log + +例如: + +b -> c (c是b的分支) + +c中添加两次提交c-1,c-2,则检查项仅为c-1与c-2的commit msg信息,并不会检查c->b的merge log + +## 门禁检查结果处理 + +门禁检查合格与否都会对原分支进行评论,并且检查合格会进行下一步操作,检查不合格则停止,评论内容如下: + +合格内容: + +| Check Name | Build Result | Build Details | +| ---------------- | -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| commit-msg check | **×** SUCCESS | [#xxx](https://gitee.com/link?target=https%3A%2F%2Fopeneulerjenkins.osinfra.cn%2Fjob%2Ftest_directory_temporary%2Fjob%2Flixinyu_test%2Fjob%2Flisir_test%2F944%2F) | + +不合格内容: + +| Check Name | Build Result | Build Details | +| ---------------- | ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| commit-msg check | **×** FAILED | [#](https://gitee.com/link?target=https%3A%2F%2Fopeneulerjenkins.osinfra.cn%2Fjob%2Ftest_directory_temporary%2Fjob%2Flixinyu_test%2Fjob%2Flisir_test%2F944%2F)xxx | diff --git a/src/ac/acl/commit_msg/__init__.py b/src/ac/acl/commit_msg/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..60fc9c4fa75a9a286851448688e79fd222895e3e --- /dev/null +++ b/src/ac/acl/commit_msg/__init__.py @@ -0,0 +1,17 @@ +# -*- encoding=utf-8 -*- +""" +# ********************************************************************************** +# Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved. +# [openeuler-jenkins] is licensed under the Mulan PSL v1. +# You can use this software according to the terms and conditions of the Mulan PSL v1. +# You may obtain a copy of Mulan PSL v1 at: +# http://license.coscl.org.cn/MulanPSL +# 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 v1 for more details. +# Author: +# Create: 2021-08-03 +# Description: check code static +# ********************************************************************************** +""" \ No newline at end of file diff --git a/src/ac/acl/commit_msg/check_commit_msg.py b/src/ac/acl/commit_msg/check_commit_msg.py new file mode 100644 index 0000000000000000000000000000000000000000..52b219d236e7645c9ea61edfd1730bd8136c478a --- /dev/null +++ b/src/ac/acl/commit_msg/check_commit_msg.py @@ -0,0 +1,125 @@ +import logging +import subprocess +import os + +from src.ac.framework.ac_base import BaseCheck +from src.ac.framework.ac_result import FAILED,SUCCESS,WARNING +from src.proxy.gitee_proxy import GiteeProxy + +logger = logging.getLogger("ac") + + +class CheckCommitMsg(BaseCheck): + """ + check commit msg + """ + + def __init__(self, workspace, repo, conf=None): + """ + + :param workspace: + :param repo: + :param conf: + """ + super(CheckCommitMsg,self).__init__(workspace, repo, conf) + + # wait to initial + self._pr_number = None + self._tbranch = None + self._community = None + self._repo = repo + self._token = None + self._work_dir = workspace + + def __call__(self, *args, **kwargs): + """ + 入口函数 + :param args: + :param kwargs: + :return: + """ + logger.info("check %s commit msg ...", self._repo) + logger.debug("args: %s, kwargs: %s", args, kwargs) + checkcommit = kwargs.get("codecheck", {}) + + self._pr_number = checkcommit.get("pr_number", "") + self._tbranch = kwargs.get("tbranch", None) + self._community = checkcommit.get("community", "") + self._token = checkcommit.get("token", "") + return self.start_check() + + @staticmethod + def check_commit_msg_result(commit_list, work_dir, gitlint_dir): + commitCheckDist = {} + for commit in commit_list: + try: + commit = str(commit, encoding='utf-8') + commit = commit.replace('\r','') + commit = commit.replace('\n','') + # get commit and add to dist for follow using + command = "gitlint --commit " + commit + " -C " + gitlint_dir + "/.gitlint" + res = subprocess.Popen(command, cwd=work_dir, shell=True, stderr=subprocess.PIPE) + out = res.stderr.readlines() + if len(out) > 0 : + outStr = "" + for line in out: + outStr += str(line, encoding='utf-8') + commitCheckDist[commit] = outStr + except Exception as e: + logger.warning(e) + return commitCheckDist + + def check_commit_msg(self): + """ + 开始进行commitmsgcheck检查 + """ + # get exvironment param + build_id = os.environ.get("BUILD_ID") + build_url = os.environ.get("BUILD_URL") + # prepare git branch environment + repoDir = self._work_dir + "/" + self._repo + logger.info("repoDir: %s", repoDir) + branchLogCmd = "git fetch origin +refs/heads/{}:refs/remotes/origin/{}".format(self._tbranch, self._tbranch) + branchLogPro = subprocess.Popen(branchLogCmd, cwd=repoDir, shell=True, stdout=subprocess.PIPE) + logger.info("git featch res: ") + logger.info(branchLogPro.stdout.read()) + branchLogCmd = "git log HEAD...origin/" + self._tbranch + " --no-merges --pretty=%H" + branchLogPro = subprocess.Popen(branchLogCmd, cwd=repoDir, shell=True, stdout=subprocess.PIPE) + branchLogRes = branchLogPro.stdout.readlines() + pr_comment=""" +|Check Name|Build Result|Build Details| +|----------|------------|-------------| +|commit-msg check|**{label}**{status}|[#{id}]({url})| + """ + gitee_proxy_inst = GiteeProxy(self._community, self._repo, self._token) + conf_dir = os.path.realpath(os.path.join(os.path.dirname(os.path.realpath(__file__)), "../../../conf/")) + commitCheckDist = self.check_commit_msg_result(branchLogRes, repoDir, conf_dir) + if len(commitCheckDist) > 0: + logFormat=""" +commit specifications is: +script: title + +this is commit body + +Signed-off-by: example example@xx.com +the folowint commits do not conform to the specifications: + """ + logger.info(logFormat) + logger.info("==============================================================") + for commit,checkRes in commitCheckDist.items(): + logger.info("commit: %s", commit) + logger.info("check result: \n\r %s", checkRes) + logger.info("==============================================================") + try: + # send comment api request to this pr + pr_comment = pr_comment.format(label="×",status="FAILED",id=build_id,url=build_url) + gitee_proxy_inst.comment_pr(self._pr_number,pr_comment) + except Exception as e: + logger.warning(e) + return False + try: + pr_comment = pr_comment.format(label="√",status="SUCCESS",id=build_id,url=build_url) + gitee_proxy_inst.comment_pr(self._pr_number,pr_comment) + except Exception as e: + logger.warning(e) + return True diff --git a/src/ac/framework/ac.py b/src/ac/framework/ac.py index 8b981c7ddf9b1058a9f88c13bf51b8b3e1b55f4c..0c9f2d5412903298cfea0fb670edd9222a649157 100644 --- a/src/ac/framework/ac.py +++ b/src/ac/framework/ac.py @@ -327,8 +327,10 @@ if "__main__" == __name__: scanoss = {"output": args.scanoss_output} codecheck = {"pr_url": "https://gitee.com/{}/{}/pulls/{}".format(args.community, args.repo, args.pr), - "pr_number": args.pr, "codecheck_api_url": args.codecheck_api_url, "codecheck_api_key": args.codecheck_api_key - } + "pr_number": args.pr, "codecheck_api_url": args.codecheck_api_url, "codecheck_api_key": args.codecheck_api_key, "token": args.token, + "community": args.community + } + # build ac = AC(os.path.join(os.path.dirname(os.path.realpath(__file__)), "ac.yaml"), args.community) diff --git a/src/ac/framework/ac.yaml b/src/ac/framework/ac.yaml index 250043089845ec6846580ed378894e8fac428c48..be6d41816f1541624404f96d28eb4a19462728eb 100644 --- a/src/ac/framework/ac.yaml +++ b/src/ac/framework/ac.yaml @@ -54,5 +54,8 @@ openeuler: "isula-build", "cve-manager", "attest-tools", "oec-hardware", "itrustee_sdk", "wisdom-advisor", "isula-transform", " itrustee_client", "A-Tune-Collector", "itrustee_tzdriver", "website-v2", "yocto-poky"] - - + commit_msg: + hint: commit_msg + module: commit_msg.check_commit_msg + entry: CheckCommitMsg + allow_list: ["yocto-meta-openeuler"] diff --git a/src/conf/.gitlint b/src/conf/.gitlint new file mode 100644 index 0000000000000000000000000000000000000000..0fe745ae0c66efa19cb7e179eb643f54c4f61ddf --- /dev/null +++ b/src/conf/.gitlint @@ -0,0 +1,135 @@ +# Edit this file as you like. +# +# All these sections are optional. Each section with the exception of [general] represents +# one rule and each key in it is an option for that specific rule. +# +# Rules and sections can be referenced by their full name or by id. For example +# section "[body-max-line-length]" could also be written as "[B1]". Full section names are +# used in here for clarity. +# +[general] +# Ignore certain rules, this example uses both full name and id +# ignore=title-trailing-punctuation, T3 + +# verbosity should be a value between 1 and 3, the commandline -v flags take precedence over this +# verbosity = 2 + +# By default gitlint will ignore merge, revert, fixup and squash commits. +# ignore-merge-commits=true +# ignore-revert-commits=true +# ignore-fixup-commits=true +# ignore-squash-commits=true + +# Ignore any data send to gitlint via stdin +# ignore-stdin=true + +# Fetch additional meta-data from the local repository when manually passing a +# commit message to gitlint via stdin or --commit-msg. Disabled by default. +# staged=true + +# Hard fail when the target commit range is empty. Note that gitlint will +# already fail by default on invalid commit ranges. This option is specifically +# to tell gitlint to fail on *valid but empty* commit ranges. +# Disabled by default. +# fail-without-commits=true + +# Enable debug mode (prints more output). Disabled by default. +# debug=true + +# Enable community contributed rules +# See http://jorisroovers.github.io/gitlint/contrib_rules for details +#contrib=contrib-title-conventional-commits,CC1 +contrib=CC1 + +# Set the extra-path where gitlint will search for user defined rules +# See http://jorisroovers.github.io/gitlint/user_defined_rules for details +# extra-path=examples/ + +# 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 + +# Conversely, you can also enforce minimal length of a title with the +# "title-min-length" rule: +[title-min-length] +min-length=5 + +# [title-must-not-contain-word] +# Comma-separated list of words that should not occur in the title. Matching is case +# insensitive. It's fine if the keyword occurs as part of a larger word (so "WIPING" +# will not cause a violation, but "WIP: my title" will. +# words=wip + +[title-match-regex] +# python-style regex that the commit-msg title must match +# Note that the regex can contradict with other rules if not used correctly +# (e.g. title-must-not-contain-word). +regex=^([0-9a-zA-Z]{1,}(: ))(.){1,}$ + +[body-max-line-length] +line-length=72 + +[body-min-length] +min-length=5 + +# [body-is-missing] +# Whether to ignore this rule on merge commits (which typically only have a title) +# default = True +# ignore-merge-commits=false + +# [body-changed-file-mention] +# List of files that need to be explicitly mentioned in the body when they are changed +# This is useful for when developers often erroneously edit certain files or git submodules. +# By specifying this rule, developers can only change the file when they explicitly reference +# it in the commit message. +# files=gitlint-core/gitlint/rules.py,README.md + +# [body-match-regex] +# python-style regex that the commit-msg body must match. +# E.g. body must end in My-Commit-Tag: foo +# regex=My-Commit-Tag: foo$ + +# [author-valid-email] +# python-style regex that the commit author email address must match. +# For example, use the following regex if you only want to allow email addresses from foo.com +# regex=[^@]+@foo.com + +# [ignore-by-title] +# Ignore certain rules for commits of which the title matches a regex +# E.g. Match commit titles that start with "Release" +# regex=^Release(.*) + +# Ignore certain rules, you can reference them by their id or by their full name +# Use 'all' to ignore all rules +# ignore=T1,body-min-length + +# [ignore-by-body] +# Ignore certain rules for commits of which the body has a line that matches a regex +# E.g. Match bodies that have a line that that contain "release" +# regex=(.*)release(.*) +# +# Ignore certain rules, you can reference them by their id or by their full name +# Use 'all' to ignore all rules +# ignore=T1,body-min-length + +# [ignore-body-lines] +# Ignore certain lines in a commit body that match a regex. +# E.g. Ignore all lines that start with 'Co-Authored-By' +# regex=^Co-Authored-By + +# [ignore-by-author-name] +# Ignore certain rules for commits of which the author name matches a regex +# E.g. Match commits made by dependabot +# regex=(.*)dependabot(.*) +# +# Ignore certain rules, you can reference them by their id or by their full name +# Use 'all' to ignore all rules +# ignore=T1,body-min-length + +# This is a contrib rule - a community contributed rule. These are disabled by default. +# You need to explicitly enable them one-by-one by adding them to the "contrib" option +# under [general] section above. +# [contrib-title-conventional-commits] +# Specify allowed commit types. For details see: https://www.conventionalcommits.org/ +# types = bugfix,user-story,epic \ No newline at end of file