From acc5c0aa859db2b13616f043e3dd4c545cd3586d Mon Sep 17 00:00:00 2001 From: YuanRisheng Date: Wed, 30 Jul 2025 16:50:20 +0800 Subject: [PATCH] add ci for custom op approve (#3079) --- scripts/check_approval.sh | 59 ++++++++++++++++++++++++++++++++++++ scripts/check_pr_approval.py | 55 +++++++++++++++++++++++++++++++++ 2 files changed, 114 insertions(+) create mode 100644 scripts/check_approval.sh create mode 100644 scripts/check_pr_approval.py diff --git a/scripts/check_approval.sh b/scripts/check_approval.sh new file mode 100644 index 000000000..2e8df23e4 --- /dev/null +++ b/scripts/check_approval.sh @@ -0,0 +1,59 @@ +# Copyright (c) 2025 PaddlePaddle Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +if [ -z ${BRANCH} ]; then + BRANCH="develop" +fi + +FD_ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}")/../" && pwd )" + +approval_line=`curl -H "Authorization: token ${GITHUB_TOKEN}" https://api.github.com/repos/PaddlePaddle/Paddle/pulls/${PR_ID}/reviews?per_page=10000` +failed_num=0 +echo_list=() + + +function check_approval(){ + person_num=`echo $@|awk '{for (i=2;i<=NF;i++)print $i}'` + APPROVALS=`echo ${approval_line}|python ${PADDLE_ROOT}/tools/check_pr_approval.py $1 $person_num` + if [[ "${APPROVALS}" == "FALSE" && "${echo_line}" != "" ]]; then + add_failed "${failed_num}. ${echo_line}" + fi +} + + +function add_failed(){ + failed_num=`expr $failed_num + 1` + echo_list="${echo_list[@]}$1" +} + + +HAS_CUSTOM_REGISTRER=`git diff -U0 upstream/$BRANCH | grep '^\+' | grep -zoE "PD_BUILD_(STATIC_)?OP" || true` +if [ ${HAS_CUSTOM_REGISTRER} ] && [ "${PR_ID}" != "" ]; then + echo_line="You must have one FastDeploy RD (qingqing01(dangqingqing), Jiang-Jia-Jun(jiangjiajun), heavengate(zhenkaipeng)) one QA(DDDivano(zhengtianyu)) one PaddlePaddle RD (XiaoguangHu01(huxiaoguang), jeff41404(gaoxiang), phlrain(liuhongyu)) approval for adding custom op.\n" + check_approval 1 qingqing01, Jiang-Jia-Jun, heavengate + check_approval 1 XiaoguangHu01 zhiqiu Xreki zhangbo9674 zyfncg phlrain + check_approval 1 XiaoguangHu01, jeff41404, phlrain +fi + + +if [ -n "${echo_list}" ];then + echo "****************" + echo -e "${echo_list[@]}" + echo "There are ${failed_num} approved errors." + echo "****************" +fi + +if [ -n "${echo_list}" ]; then + exit 6 +fi diff --git a/scripts/check_pr_approval.py b/scripts/check_pr_approval.py new file mode 100644 index 000000000..229699624 --- /dev/null +++ b/scripts/check_pr_approval.py @@ -0,0 +1,55 @@ +# Copyright (c) 2025 PaddlePaddle Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import json +import sys + + +def check_approval(count, required_reviewers): + json_buff = "" + for line in sys.stdin: + json_buff = "".join([json_buff, line]) + json_resp = json.loads(json_buff) + approves = 0 + approved_user_ids = [] + approved_user_logins = set() + for review in json_resp: + if review["state"] == "APPROVED": + approves += 1 + approved_user_ids.append(review["user"]["id"]) + approved_user_logins.add(review["user"]["login"]) + + # convert to int + required_reviewers_int = set() + required_reviewers_login = set() + for rr in required_reviewers: + if rr.isdigit(): + required_reviewers_int.add(int(rr)) + else: + required_reviewers_login.add(rr) + + if ( + len(set(approved_user_ids) & required_reviewers_int) + len(approved_user_logins & required_reviewers_login) + >= count + ): + print("TRUE") + else: + print("FALSE") + + +if __name__ == "__main__": + if len(sys.argv) > 1 and sys.argv[1].isdigit(): + check_approval(int(sys.argv[1]), sys.argv[2:]) + else: + print("Usage: python check_pr_approval.py [count] [required reviewer id] ...")