diff --git a/scripts/merge-external-pr.sh b/scripts/merge-external-pr.sh deleted file mode 100755 index 37611adf19..0000000000 --- a/scripts/merge-external-pr.sh +++ /dev/null @@ -1,152 +0,0 @@ -#!/bin/bash - -set -eof pipefail - -trap cleanup EXIT - -fatal() { - echo "FATAL: $@" >&2 - exit 1 -} - -warn() { - echo "$@" -} - -confirm() { - read -p "$1 (type 'yes' to continue) " r - if [[ $r != yes ]]; then - exit 3 - fi -} - -load_config() { - [[ -f merge-external-pr.conf ]] && . merge-external-pr.conf - : ${OWNER:=status-im} - : ${REPO:=status-react} - : ${REMOTE:=origin} - : ${BRANCH:=develop} -} - -check_pr_prereq() { - if ! command -v jq >/dev/null; then - fatal "jq(1) is not found, PR cannot be queried. Use REPO BRANCH" - fi - if ! command -v curl >/dev/null; then - fatal "curl(1) is not found, PR cannot be queried. Use REPO BRANCH" - fi -} - -GH_URL_BASE="https://api.github.com" - -get_pr_info() { - echo '[ Reading PR info ]' - if [ $# -eq 1 ]; then - check_pr_prereq - local pr=$1 - local pr_info_url="$GH_URL_BASE/repos/${OWNER}/${REPO}/pulls/$pr" - set +e - local pr_info - pr_info=$(curl -fsS "$pr_info_url") - if [ $? -ne 0 ]; then - fatal "Unable to get PR info from $pr_info_url" - fi - set -e - if [[ $(echo "$pr_info" | jq -r .state) == closed ]]; then - fatal "PR $pr is closed, will not merge" - fi - if [[ $(echo "$pr_info" | jq -r .maintainer_can_modify) == true ]]; then - RW_PR_REPO=1 - else - warn "PR does not allow 'edits from maintainers', so it will be kept open" - fi - PR_URL=$(echo "$pr_info" | jq -r .head.repo.ssh_url) - PR_REMOTE_NAME=pr-$pr - PR_BRANCH=$(echo "$pr_info" | jq -r .head.ref) - PR_LOCAL_BRANCH=pr-$pr - else - PR_URL="$1" - PR_REMOTE_NAME=${PR_URL##*/} - PR_REMOTE_NAME=pr-${PR_REMOTE_NAME%.git} - PR_REMOTE_NAME=pr-${PR_REPO_NAME} - PR_BRANCH="$2" - PR_LOCAL_BRANCH=pr-${PR_REPO_NAME} - fi -} - -fetch_pr() { - echo '[ Fetching PR ]' - git remote add $PR_REMOTE_NAME $PR_URL - git fetch $PR_REMOTE_NAME $PR_BRANCH -} - -refresh_base_branch() { - git fetch $REMOTE $BRANCH -} - -rebase_pr() { - git checkout -B $PR_LOCAL_BRANCH $PR_REMOTE_NAME/$PR_BRANCH - git rebase $BRANCH -} - -check_is_pr_single_commit() { - if [[ $(git rev-list $BRANCH..$PR_LOCAL_BRACNCH | wc -l) -ne 1 ]] ;then - fatal "Only squashed/single-commit PRs can be merged" - fi -} - -confirm_pr() { - git log -p $BRANCH..$PR_LOCAL_BRANCH - confirm "Do you like this PR?" -} - -sign_pr() { - git commit --amend --gpg-sign --signoff -} - -verify_pr() { - git show --show-signature $PR_LOCAL_BRANCH - confirm "Is the signature on the commit correct?" -} - -merge_pr() { - # If PR is specified and can be pushed into, do it to mark PR as closed - if [[ -n $RW_PR_REPO ]]; then - git push -f $PR_REMOTE_NAME $PR_LOCAL_BRANCH:$PR_BRANCH - fi - git checkout $BRANCH - git merge --ff-only $PR_LOCAL_BRANCH - git push $REMOTE $BRANCH -} - -cleanup() { - if [[ -z $DEBUG ]]; then - git checkout -q $BRANCH - git branch -q -D $PR_LOCAL_BRANCH 2>/dev/null || : - git remote remove $PR_REMOTE_NAME 2>/dev/null || : - fi -} - -run() { - if [[ $# -lt 1 ]] || [[ $# -gt 2 ]]; then - cat <&2 -Usage: - ./merge-external-pr.sh REPO_URL BRANCH - ./merge-external.pr.sh PR (if jq(1) and curl(1) are available) -EOF - exit 2 - fi - load_config - get_pr_info "$@" - cleanup - fetch_pr - refresh_base_branch - rebase_pr - check_is_pr_single_commit - confirm_pr - sign_pr - verify_pr - merge_pr -} - -run "$@" diff --git a/scripts/merge-pr.sh b/scripts/merge-pr.sh index 17e3967dff..d18e6f6b7c 100755 --- a/scripts/merge-pr.sh +++ b/scripts/merge-pr.sh @@ -2,11 +2,16 @@ set -eof pipefail -BRANCH=$1 -if [[ $# -eq 0 ]] ; then - echo 'Branch required as first argument' - exit 0 -fi +trap cleanup EXIT + +fatal() { + echo "FATAL: $@" >&2 + exit 1 +} + +warn() { + echo "$@" +} confirm() { read -p "$1 (type 'yes' to continue) " r @@ -15,30 +20,127 @@ confirm() { fi } -echo "[Merge PR from ${BRANCH}]" +load_config() { + [[ -f merge-pr.conf ]] && . merge-pr.conf + : ${OWNER:=status-im} + : ${REPO:=status-react} + : ${REMOTE:=origin} + : ${BRANCH:=develop} +} -echo "[Update remote and checkout branch]" -git remote update origin -git checkout -B $BRANCH origin/$BRANCH && git pull +check_pr_prereq() { + if ! command -v jq >/dev/null; then + fatal "jq(1) is not found, PR cannot be queried." + fi + if ! command -v curl >/dev/null; then + fatal "curl(1) is not found, PR cannot be queried." + fi +} -echo "[Rebase and squash to one commit (manual)]" -git rebase -i origin/develop -if [[ $(git rev-list $BRANCH..$PR_LOCAL_BRACNCH | wc -l) -ne 1 ]] ;then - confirm "There are multiple commits in this PR. Are you sure you wish to continue without squashing?" -fi +GH_URL_BASE="https://api.github.com" -echo "[Verify signature and commit (manual), update PR]" -git show --show-signature -git push -f +get_pr_info() { + echo '[ Reading PR info ]' + local pr=$1 + local pr_info_url="$GH_URL_BASE/repos/${OWNER}/${REPO}/pulls/$pr" + set +e + local pr_info + pr_info=$(curl -fsS "$pr_info_url") + if [ $? -ne 0 ]; then + fatal "Unable to get PR info from $pr_info_url" + fi + set -e + if [[ $(echo "$pr_info" | jq -r .state) == closed ]]; then + fatal "PR $pr is closed, will not merge" + fi + if [[ $(echo "$pr_info" | jq -r .maintainer_can_modify) == true ]]; then + RW_PR_REPO=1 + else + warn "PR does not allow 'edits from maintainers', so it will be kept open" + fi + PR_URL=$(echo "$pr_info" | jq -r .head.repo.ssh_url) + PR_REMOTE_NAME=pr-$pr + PR_BRANCH=$(echo "$pr_info" | jq -r .head.ref) + PR_LOCAL_BRANCH=pr-$pr +} -echo "[Checkout develop and merge with same SHA]" -git checkout develop && git pull -git merge --ff-only $BRANCH +fetch_pr() { + echo '[ Fetching PR ]' + git remote add $PR_REMOTE_NAME $PR_URL + git fetch $PR_REMOTE_NAME $PR_BRANCH +} -echo "[Push to protected develop branch]" -git push +refresh_base_branch() { + git fetch $REMOTE $BRANCH +} -echo "[Clean up remote branch]" -git push origin --delete $BRANCH +rebase_pr() { + git checkout -B $PR_LOCAL_BRANCH $PR_REMOTE_NAME/$PR_BRANCH + git rebase $BRANCH +} -echo "[Done]" +check_is_pr_single_commit() { + if [[ $(git rev-list $BRANCH..$PR_LOCAL_BRANCH | wc -l) -ne 1 ]] ;then + confirm "PR has multiple commits, continue merging without squashing them?" + fi +} + +confirm_pr() { + git log -p $BRANCH..$PR_LOCAL_BRANCH + confirm "Do you like this PR?" +} + +sign_pr() { + git commit --amend --gpg-sign --signoff +} + +verify_pr() { + git show --show-signature $PR_LOCAL_BRANCH + confirm "Is the signature on the commit correct?" +} + +merge_pr() { + # If PR is specified and can be pushed into, do it to mark PR as closed + if [[ -n $RW_PR_REPO ]]; then + git push -f $PR_REMOTE_NAME $PR_LOCAL_BRANCH:$PR_BRANCH + fi + git checkout $BRANCH + git merge --ff-only $PR_LOCAL_BRANCH + git push $REMOTE $BRANCH +} + +cleanup() { + if [[ -z $DEBUG ]]; then + git checkout -q $BRANCH + git branch -q -D $PR_LOCAL_BRANCH 2>/dev/null || : + git remote remove $PR_REMOTE_NAME 2>/dev/null || : + fi +} + +run() { + if [[ $# -ne 1 ]] ; then + cat <&2 +Requirements: + jq + curl +Usage: + ./merge-pr.sh + +EOF + exit 2 + fi + load_config + check_pr_prereq + get_pr_info "$@" + cleanup + fetch_pr + refresh_base_branch + rebase_pr + check_is_pr_single_commit + confirm_pr + sign_pr + verify_pr + merge_pr +} + +run "$@"