#!/bin/bash pushd $(dirname "$BASH_SOURCE") > /dev/null CUR_DIR=$(pwd) popd > /dev/null PR=$1 REVIEWER_CHECK=$2 if [ -z "$PR" ]; then echo "Usage: $0 " exit 1 fi function mergeable() { local PRN=$1 while true; do local STATE=$(hub api repos/{owner}/{repo}/pulls/$PRN | python -m json.tool | grep '"mergeable":' | cut -d ":" -f 2 | cut -d "," -f 1) STATE=$(eval "echo $STATE") echo "merge state is $STATE" case "$STATE" in true) return 0 ;; null) ;; *) return 1 ;; esac done } function pr_state() { local PRN=$1 hub api repos/{owner}/{repo}/pulls/$PRN | python -m json.tool | grep '"state"' | cut -d '"' -f 4 } function last_commits() { local PRN=$1 hub api repos/{owner}/{repo}/pulls/$PRN/commits | python -m json.tool | grep '"comments_url"' | awk '{ lifo[NR]=$0; lno=NR } END{ for(;lno>0;lno--){ print lifo[lno]; } }' | cut -d "/" -f 8 } function last_check() { local CMT=$1 hub api repos/{owner}/{repo}/commits/${CMT}/check-runs -H 'Accept: application/vnd.github.antiope-preview+json' | python -m json.tool | grep conclusion | cut -d '"' -f 4 } 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 } echo "#1. check status of pull request $PR" STATE=$(pr_state $PR) if [ "$STATE" != "open" ]; then echo "Pull request $PR state $STATE, exit..." exit 0 fi echo "Pull request state is open, continue..." echo "#2. check pull request $PR is mergeable" if ! mergeable $PR; then echo "Pull request $PR is not mergeable (DIRTY), exit..." exit 1 fi echo "#3. check all checks of pull request $PR have been passed" CHECKED= for COMMIT in $(last_commits $PR) do for RESULT in $(last_check $COMMIT) do echo "Commit $COMMIT check result: $RESULT" if [ "$RESULT" != "success" ]; then echo "Cannot approve before all checks success" exit 1 fi CHECKED=yes done if [ -n "$CHECKED" ]; then break fi done if [ -z "$CHECKED" ]; then echo "No check passed, give up and try later ..." exit 1 fi echo "All check passed, going to approve and lgtm the Pull Request #$PR..." if ! label "$PR" "/lgtm" "lgtm"; then echo "Label lgtm failed" 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 fi echo "Success!"