mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-08-29 03:51:54 +08:00
feature: approve.sh check whether all assigned reviews lgtm the PR
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
Github Pull Request Helper Scripts
|
||||
======================================
|
||||
|
||||
这里提供一些脚本辅助github CI机器人,方便标签和合并代码:
|
||||
|
||||
|
||||
* approve.sh
|
||||
|
||||
合并一个PR,使用方法:
|
||||
|
||||
./scripts/approve.sh <PRN> [check_reviewers]
|
||||
|
||||
合并一个PR之前,将会做如下检查:
|
||||
|
||||
1. 该PR的状态为open
|
||||
2. 该PR的mergeable状态为true (如果有冲突,则mergeable=false)
|
||||
3. 该PR的所有CI检查都通过
|
||||
4. 如果命令行的check_reviewers为非空字符串,则还会检查是否所有requested reviewers都lgtm了这个PR
|
||||
|
||||
需要注意的是,在执行脚本之前,请确认已经人肉review过代码,并且认为可以合并了再执行。脚本只是为了方便合并,并且确保合并前没有忽略的检查,并不是为了替代人肉code review。
|
||||
|
||||
|
||||
* approve_all.sh
|
||||
|
||||
合并一组PR,使用方法:
|
||||
|
||||
./scripts/approve_all.sh <PRN>
|
||||
|
||||
这组PR由master上的主PR和backport到各个分支的cherry pick PR组成。对Master上的PR会做所有4项检查,对其他PR只做前3项检查。
|
||||
|
||||
|
||||
* lgtm.sh
|
||||
|
||||
给一个PR打上lgtm的标签。使用方法:
|
||||
|
||||
./scripts/lgtm.sh <PRN>
|
||||
Executable
+43
@@ -0,0 +1,43 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import json
|
||||
|
||||
def find_lgtms(comments):
|
||||
commenters = []
|
||||
for comment in comments:
|
||||
body = comment["body"].strip()
|
||||
if body == "/lgtm":
|
||||
commenters.append("%s(%s)" % (comment["user"]["login"], comment["user"]["id"]))
|
||||
return commenters
|
||||
|
||||
def find_reviewers(pulls):
|
||||
reviewers = []
|
||||
for reviewer in pulls["requested_reviewers"]:
|
||||
reviewers.append("%s(%s)" % (reviewer["login"], reviewer["id"]))
|
||||
return reviewers
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
|
||||
if len(sys.argv) < 3:
|
||||
print(sys.argv[0], "<pull>", "<comment>")
|
||||
sys.exit(-1)
|
||||
|
||||
with open(sys.argv[1]) as pullfile:
|
||||
pulls = json.load(pullfile)
|
||||
with open(sys.argv[2]) as commentfile:
|
||||
comments = json.load(commentfile)
|
||||
rvs = find_reviewers(pulls)
|
||||
cms = find_lgtms(comments)
|
||||
if len(rvs) == 0:
|
||||
print("No reviwer is assigned, give up check...")
|
||||
os.exit(-1)
|
||||
print("Assigned reviwers: %s" % ", ".join(rvs))
|
||||
print("Lgtm reviwers: %s" % ", ".join(cms))
|
||||
req = []
|
||||
for rv in rvs:
|
||||
if rv not in cms:
|
||||
req.append(rv)
|
||||
if len(req) > 0:
|
||||
print("Reviewers %s needs /lgtm" % ",".join(req))
|
||||
sys.exit(-1)
|
||||
+26
-1
@@ -1,7 +1,11 @@
|
||||
#!/bin/bash
|
||||
|
||||
pushd $(dirname "$BASH_SOURCE") > /dev/null
|
||||
CUR_DIR=$(pwd)
|
||||
popd > /dev/null
|
||||
|
||||
PR=$1
|
||||
MSG=$2
|
||||
REVIEWER_CHECK=$2
|
||||
|
||||
if [ -z "$PR" ]; then
|
||||
echo "Usage: $0 <pr_number>"
|
||||
@@ -53,6 +57,10 @@ function label() {
|
||||
local MSG=$2
|
||||
local LABEL=$3
|
||||
|
||||
if check_label $PRN $LABEL > /dev/null; then
|
||||
echo "Label $LABEL success!"
|
||||
return 0
|
||||
fi
|
||||
for try in $(seq 3)
|
||||
do
|
||||
echo "Send $MSG ..."
|
||||
@@ -121,6 +129,23 @@ if ! label "$PR" "/lgtm" "lgtm"; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -n "$REVIEWER_CHECK" ]; then
|
||||
echo "Check all requested reviwers /lgtm the pull request: "
|
||||
pullfile=$(mktemp)
|
||||
commentfile=$(mktemp)
|
||||
function cleanup {
|
||||
rm -rf "$pullfile" "$commentfile"
|
||||
}
|
||||
trap cleanup EXIT
|
||||
hub api repos/{owner}/{repo}/pulls/$PR > $pullfile
|
||||
hub api repos/{owner}/{repo}/issues/$PR/comments > $commentfile
|
||||
if ! $CUR_DIR/advchecks.py $pullfile $commentfile; then
|
||||
echo "Not all assigned reviwers comment lgtm, give up..."
|
||||
exit 1
|
||||
fi
|
||||
echo "passed!"
|
||||
fi
|
||||
|
||||
if ! label "$PR" "/approve" "approved"; then
|
||||
echo "Label approved failed"
|
||||
exit 1
|
||||
|
||||
@@ -34,12 +34,15 @@ done
|
||||
|
||||
echo "Going to merge the following pull requests ${PRNS[@]}:"
|
||||
|
||||
REVIEWER_CHECK=yes
|
||||
for PRN in "${PRNS[@]}"
|
||||
do
|
||||
$CUR_DIR/approve.sh $PRN
|
||||
$CUR_DIR/approve.sh $PRN $REVIEWER_CHECK
|
||||
if [ "$?" -ne "0" ]; then
|
||||
echo "Merge failed, exit."
|
||||
exit 1
|
||||
fi
|
||||
if [ -n "$REVIEWER_CHECK" ]; then
|
||||
REVIEWER_CHECK=
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
Executable
+43
@@ -0,0 +1,43 @@
|
||||
#!/bin/bash
|
||||
|
||||
PRN=$1
|
||||
MSG=$2
|
||||
LABEL=$3
|
||||
|
||||
function check_label() {
|
||||
local PRN=$1
|
||||
local LABEL=$2
|
||||
hub api repos/{owner}/{repo}/issues/${PRN}/labels | python -m json.tool | grep '"name": "'$LABEL'"'
|
||||
}
|
||||
|
||||
function label() {
|
||||
local PRN=$1
|
||||
local MSG=$2
|
||||
local LABEL=$3
|
||||
|
||||
for try in $(seq 3)
|
||||
do
|
||||
echo "Send $MSG ..."
|
||||
hub api repos/{owner}/{repo}/issues/$PRN/comments -f "body=$MSG" > /dev/null
|
||||
if [ "$?" -ne "0" ]; then
|
||||
echo "Send $MSG fail!"
|
||||
return 1
|
||||
fi
|
||||
for chk in $(seq 30)
|
||||
do
|
||||
sleep 1
|
||||
if check_label $PRN $LABEL > /dev/null; then
|
||||
echo "Label $LABEL success!"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
if [ -z "$LABEL" ]; then
|
||||
echo "Usage: $0 <pr_number> <msg> <label>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
label "$PRN" "$MSG" "$LABEL"
|
||||
Executable
+13
@@ -0,0 +1,13 @@
|
||||
#!/bin/bash
|
||||
|
||||
pushd $(dirname "$BASH_SOURCE") > /dev/null
|
||||
CUR_DIR=$(pwd)
|
||||
popd > /dev/null
|
||||
|
||||
PRN=$1
|
||||
if [ -z "$PRN" ]; then
|
||||
echo "$0 <PRN>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
$CUR_DIR/label.sh $PRN /lgtm lgtm
|
||||
Reference in New Issue
Block a user