Skip to content

Instantly share code, notes, and snippets.

@RichardBronosky
Created September 26, 2019 15:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save RichardBronosky/93c8b894e9d46c113956a4ebc6f54a12 to your computer and use it in GitHub Desktop.
Save RichardBronosky/93c8b894e9d46c113956a4ebc6f54a12 to your computer and use it in GitHub Desktop.
This is a WIP. Use at your own risk.
#!/bin/bash
usage(){
echo -e "\n""${FUNCNAME[1]} <github_pull_url> <oauth_token>""\n"
return 1
}
_prepare_vars(){
local IFS=$'\n'
regex=''
vars_array=($(<<<"$@" gawk -v FS=/ '
{
for (i = 1; i <= NF; i++){
split($i, chars, "");
if(chars[1] == ":"){
v=substr($i,2);
print(v);
}
}
}'));
for var in "${vars_array[@]}"; do
if [[ -z "${!var}" ]]; then
read -p "value for ${var}: " ${var}
fi
done;
for var in "${vars_array[@]}"; do
echo " ${var}='${!var}'" >&2;
regex+="s/:${var}/${!var}/g;"
done;
}
GET(){
local input="$*"
_prepare_vars "$@"
local call="$(sed "$regex" <<<"$input")"
echo "Calling: GET $call" >&2
curl -sH "Authorization: token $token" https://api.github.com$call | jq .
};
POST(){
local input="$*"
_prepare_vars "$@"
local call="$(sed "$regex" <<<"$input")"
echo "Calling: GET $call" >&2
echo curl -sH "Authorization: token $token" -X POST https://api.github.com$call | jq .
};
approve_pr(){
local pull_url=$1;
export token=$2;
local inputs=($(awk -v FS='[/#]' '{print $6, $4, $5, $7;}' <<<"$pull_url"))
if [[ ${inputs[0]} != 'pull' ]]; then usage; return; fi
export owner="${inputs[1]}"
export repo="${inputs[2]}"
export pull_number="${inputs[3]}"
local meta=($( (
GET '/user' | jq -r '.login';
GET '/repos/:owner/:repo/pulls/:pull_number' | jq -r '.head.ref, .base.ref, .user.login, .created_at, .base.repo.name, .commits, .mergeable_state';
) 2>/dev/null;
))
local i=0
for var_name in approver from to requester date repo_verify number_of_commits merge_state; do printf -v "$var_name" '%s' "${meta[$((i++))]}"; export $var_name; done
if [[ $date == null ]]; then _user_msg permission; return; fi
_user_msg info
_confirm || return 2
if [[ $number_of_commits -gt 1 ]]; then
_user_msg commits
_confirm || return 2
fi
if [[ $merge_state != clean ]]; then
_user_msg status
_confirm || return 2
if [[ $merge_state == dirty ]]; then
_user_msg dirty
_confirm || return 2
fi
fi
echo -e 'BOOM!'"\n"
}
_user_msg(){
case "$1" in
permission)
cat<<EOF
[FATAL]: Unable to fetch the PR. Are you sure to provided OAuth token has permission?
EOF
return 2
;;
info)
cat<<EOF
###############
# Warning!! #
###############
You are about to use the credentials of $approver
to approve pull request number $pull_number
from branch $from
into branch $to
requested by $requester
at $date
on repo $repo_verify
with a commit count of $number_of_commits
and the merge status is $merge_state
EOF
;;
commits)
local random_branch_name=master
if [[ $to == master ]]; then
random_branch_name=production
fi
cat <<EOF
Okay. I hear you. But did you notice that this PR has more than 1 commit?
Specifically, it has $number_of_commits
Do you know why that could be a problem?
If not, maybe you shouldn't be doing this.
Let me help you. If branch $from was not created from $to,
but was instead created from $random_branch_name, some feature branch you were working on
when this emergency happened, etc., you could be bringing untested/unintended
commits from that other branch into $to. Maybe take another look at
$pull_url
EOF
;;
status)
cat <<EOF
I know you are in a hurry. But, I can't imagine a situation where you would
really want to approve a PR with a mergability status of '$merge_state'.
The only status I would ever approve is 'clean'. Maybe you should read
https://developer.github.com/v4/enum/mergestatestatus/#mergestatestatus
EOF
;;
dirty)
cat <<EOF
Seriously? The mergability status is "$merge_state"! That means there are
merge conflicts. Why would you not resolve the conflicts before approving?
Think about it. Resolving the conflicts is going to require a code change.
That code change will result in code that not only, have you not even LOOKED AT
but code that does not yet EXIST. You are approving a unicorn.
EOF
;;
esac
}
_confirm(){
read -p $'\n'' Are you sure you want to do this? {y/N} '
echo
[[ $REPLY =~ ^[yY][eE]?[sS]?$ ]];
local status=$?
if [[ $status -ne 0 ]]; then
echo -e 'You're playing it safe. I don't blame you.'"\n"
return $status;
fi
}
_main(){ approve_pr "$@"; }
[ "$0" = "$BASH_SOURCE" ] && _main "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment