From 6e3de5b448ea704bc46368ece7b191a65d3f5500 Mon Sep 17 00:00:00 2001 From: Houssem Ben Ali Date: Thu, 2 Mar 2023 14:58:52 +0100 Subject: [PATCH 1/7] Add Backport PR Job --- github/backportPR.sh | 63 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100755 github/backportPR.sh diff --git a/github/backportPR.sh b/github/backportPR.sh new file mode 100755 index 00000000..d98c1ebf --- /dev/null +++ b/github/backportPR.sh @@ -0,0 +1,63 @@ +#!/bin/bash -eu +set -o pipefail +PR_JSON="" +getJsonItem() { + echo $PR_JSON | jq ".$1" | xargs -r echo +} + +if [ -z "${PR_URL:-}" ]; then + echo "Error: Please provide a valid PR URL!" + exit 1 +fi + +if [ -z "${TARGET_BASE_BRANCH:-}" ]; then + echo "Error: Please provide a valid target base branch!" + exit 1 +fi + +echo "Analyzing the supplied PR..." +PR_API_URI=$(echo ${PR_URL} | sed -e 's|https://github.com|/repos|g' -e 's|/pull/|/pulls/|g' ) +PR_CLONE_URL=$(echo ${PR_URL} | sed -e 's|https://github.com/|git@github.com:|g' -Ee 's|/pull/.*|.git|g' ) +echo $PR_API_URI $PR_CLONE_URL +PR_JSON=$(gh api ${PR_API_URI}) +echo "Checking PR merge status..." +PR_MERGED=$(getJsonItem merged) + +if ! ${PR_MERGED:-false}; then + echo "Error: You should pick a merged PR!" + exit 1 +fi +echo "OK PR is merged." +echo "Checking PR merge commit" +PR_MERGE_COMMIT=$(getJsonItem merge_commit_sha) +echo "OK PR merge status is ${PR_MERGE_COMMIT}" +PR_TITLE=$(getJsonItem title) +PR_BODY=$(getJsonItem body) +PR_OWNER=$(getJsonItem user.login) +PR_REPO=$(getJsonItem head.repo.name) +git clone $PR_CLONE_URL &>/dev/null +pushd ${PR_REPO} +git checkout ${TARGET_BASE_BRANCH} &>/dev/null +git checkout -b backport_$(date +%s) +if !git cherry-pick -x ${PR_MERGE_COMMIT}; then + git cherry-pick --abort &>/dev/null || true + echo "Cherry-pick failed! Performing patch method..." + PR_PATCH_URL=$(getJsonItem patch_url) + wget $PR_PATCH_URL -O ../patch.diff &>/dev/null + git apply ../patch.diff + commitFile=$(mktemp) + echo ${PR_TITLE} > $commitFile + echo >> $commitFile + echo ${PR_BODY} > $commitFile + echo >> $commitFile + echo "(Cherry-picked from ${PR_MERGE_COMMIT})" > $commitFile + rm ../patch.diff + git add . # not recommended + git commit -F $commitFile + rm $commitFile +fi +git push origin HEAD +if [ ${REVIEWERS:-} = "_OWNER_" ]; then + REVIEWERS=$PR_OWNER +fi +gh pr create --repo $PR_CLONE_URL --title "${PR_TITLE}" --body "${PR_BODY}" --reviewers "${REVIEWERS}" --assignee "${PR_OWNER}" --base "${TARGET_BASE_BRANCH}" --branch HEAD \ No newline at end of file From f390ce567633e541cc838db546f7f3a147b5b55d Mon Sep 17 00:00:00 2001 From: Houssem Ben Ali Date: Thu, 2 Mar 2023 15:14:25 +0100 Subject: [PATCH 2/7] Fix typo --- github/backportPR.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/github/backportPR.sh b/github/backportPR.sh index d98c1ebf..5e64b646 100755 --- a/github/backportPR.sh +++ b/github/backportPR.sh @@ -30,7 +30,7 @@ fi echo "OK PR is merged." echo "Checking PR merge commit" PR_MERGE_COMMIT=$(getJsonItem merge_commit_sha) -echo "OK PR merge status is ${PR_MERGE_COMMIT}" +echo "OK PR merge commit is ${PR_MERGE_COMMIT}" PR_TITLE=$(getJsonItem title) PR_BODY=$(getJsonItem body) PR_OWNER=$(getJsonItem user.login) @@ -38,8 +38,9 @@ PR_REPO=$(getJsonItem head.repo.name) git clone $PR_CLONE_URL &>/dev/null pushd ${PR_REPO} git checkout ${TARGET_BASE_BRANCH} &>/dev/null -git checkout -b backport_$(date +%s) -if !git cherry-pick -x ${PR_MERGE_COMMIT}; then +BRANCH_NAME=backport_$(date +%s) +git checkout -b ${BRANCH_NAME} +if ! git cherry-pick -x ${PR_MERGE_COMMIT}; then git cherry-pick --abort &>/dev/null || true echo "Cherry-pick failed! Performing patch method..." PR_PATCH_URL=$(getJsonItem patch_url) @@ -60,4 +61,4 @@ git push origin HEAD if [ ${REVIEWERS:-} = "_OWNER_" ]; then REVIEWERS=$PR_OWNER fi -gh pr create --repo $PR_CLONE_URL --title "${PR_TITLE}" --body "${PR_BODY}" --reviewers "${REVIEWERS}" --assignee "${PR_OWNER}" --base "${TARGET_BASE_BRANCH}" --branch HEAD \ No newline at end of file +gh pr create --repo $PR_CLONE_URL -f --reviewer "${REVIEWERS}" --assignee "${PR_OWNER}" --base "${TARGET_BASE_BRANCH}" --head ${BRANCH_NAME} \ No newline at end of file From 1851956a2599f1c049cd605cb71ed5edce375fa9 Mon Sep 17 00:00:00 2001 From: Houssem Ben Ali Date: Thu, 2 Mar 2023 15:29:41 +0100 Subject: [PATCH 3/7] Add PR URL sanitization + Auto Merge feature --- github/backportPR.sh | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/github/backportPR.sh b/github/backportPR.sh index 5e64b646..dac4c16c 100755 --- a/github/backportPR.sh +++ b/github/backportPR.sh @@ -5,7 +5,9 @@ getJsonItem() { echo $PR_JSON | jq ".$1" | xargs -r echo } -if [ -z "${PR_URL:-}" ]; then +# Sanitize PR URL +PR_URL=$(${PR_URL:-} | grep -oP 'https://github.com/[a-zA-Z0-9-_]+/[a-zA-Z0-9-_]+/pull/[0-9]+') +if [ -z "${PR_URL:-}"]; then echo "Error: Please provide a valid PR URL!" exit 1 fi @@ -61,4 +63,7 @@ git push origin HEAD if [ ${REVIEWERS:-} = "_OWNER_" ]; then REVIEWERS=$PR_OWNER fi -gh pr create --repo $PR_CLONE_URL -f --reviewer "${REVIEWERS}" --assignee "${PR_OWNER}" --base "${TARGET_BASE_BRANCH}" --head ${BRANCH_NAME} \ No newline at end of file +gh pr create --repo $PR_CLONE_URL -f --reviewer "${REVIEWERS}" --assignee "${PR_OWNER}" --base "${TARGET_BASE_BRANCH}" --head ${BRANCH_NAME} +if [ "${AUTO_MERGE:-DEFAULT}" != "DEFAULT" ]; then + gh pr merge --auto --${AUTO_MERGE} --repo $PR_CLONE_URL +fi \ No newline at end of file From c6b066026502bb36b004082774bf04cf54ed453c Mon Sep 17 00:00:00 2001 From: Houssem Ben Ali Date: Thu, 2 Mar 2023 15:44:34 +0100 Subject: [PATCH 4/7] Add support of creating PR with custom GH API token --- github/backportPR.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/github/backportPR.sh b/github/backportPR.sh index dac4c16c..a0e45f70 100755 --- a/github/backportPR.sh +++ b/github/backportPR.sh @@ -63,6 +63,9 @@ git push origin HEAD if [ ${REVIEWERS:-} = "_OWNER_" ]; then REVIEWERS=$PR_OWNER fi +if [ ! -z ${GH_ACTOR_TOKEN:-} ]; then + export GH_TOKEN=${GH_ACTOR_TOKEN} +fi gh pr create --repo $PR_CLONE_URL -f --reviewer "${REVIEWERS}" --assignee "${PR_OWNER}" --base "${TARGET_BASE_BRANCH}" --head ${BRANCH_NAME} if [ "${AUTO_MERGE:-DEFAULT}" != "DEFAULT" ]; then gh pr merge --auto --${AUTO_MERGE} --repo $PR_CLONE_URL From 4bacf1f4ab1f270ce9fb13136802ffaa0787f7da Mon Sep 17 00:00:00 2001 From: Houssem Ben Ali Date: Fri, 19 May 2023 12:04:29 +0200 Subject: [PATCH 5/7] Add logs + Reviewers OPT --- github/backportPR.sh | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/github/backportPR.sh b/github/backportPR.sh index a0e45f70..09093978 100755 --- a/github/backportPR.sh +++ b/github/backportPR.sh @@ -2,7 +2,11 @@ set -o pipefail PR_JSON="" getJsonItem() { - echo $PR_JSON | jq ".$1" | xargs -r echo + echo $PR_JSON | jq -r ".$1" +} + +getPRReviewers() { + echo $PR_JSON | jq -r '[ .requested_reviewers[].login ] | join(",")' } # Sanitize PR URL @@ -36,6 +40,7 @@ echo "OK PR merge commit is ${PR_MERGE_COMMIT}" PR_TITLE=$(getJsonItem title) PR_BODY=$(getJsonItem body) PR_OWNER=$(getJsonItem user.login) +PR_REVIEWERS=$(getPRReviewers) PR_REPO=$(getJsonItem head.repo.name) git clone $PR_CLONE_URL &>/dev/null pushd ${PR_REPO} @@ -63,10 +68,22 @@ git push origin HEAD if [ ${REVIEWERS:-} = "_OWNER_" ]; then REVIEWERS=$PR_OWNER fi +if [ ${REVIEWERS:-} = "_REVIEWERS_" ]; then + if [ -z "${PR_REVIEWERS:-}" ]; then + echo "Error: This PR does not have reviewers! Please select other reviewers. Abort" + exit 1 + else + REVIEWERS=$PR_REVIEWERS + fi +fi if [ ! -z ${GH_ACTOR_TOKEN:-} ]; then export GH_TOKEN=${GH_ACTOR_TOKEN} fi +echo "OK! Creating backport PR with base branch ${TARGET_BASE_BRANCH}, assignee ${PR_OWNER}, and reviewers ${REVIEWERS}..." gh pr create --repo $PR_CLONE_URL -f --reviewer "${REVIEWERS}" --assignee "${PR_OWNER}" --base "${TARGET_BASE_BRANCH}" --head ${BRANCH_NAME} +echo "Done." if [ "${AUTO_MERGE:-DEFAULT}" != "DEFAULT" ]; then + echo "Enabling ${AUTO_MERGE:-DEFAULT} auto merge..." gh pr merge --auto --${AUTO_MERGE} --repo $PR_CLONE_URL + echo "Done." fi \ No newline at end of file From 439f0e686085394dbc94ddba7348a84c67fc8300 Mon Sep 17 00:00:00 2001 From: Houssem Ben Ali Date: Wed, 11 Oct 2023 12:51:42 +0200 Subject: [PATCH 6/7] Fix typo --- github/backportPR.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/github/backportPR.sh b/github/backportPR.sh index 09093978..31b30f3a 100755 --- a/github/backportPR.sh +++ b/github/backportPR.sh @@ -10,7 +10,7 @@ getPRReviewers() { } # Sanitize PR URL -PR_URL=$(${PR_URL:-} | grep -oP 'https://github.com/[a-zA-Z0-9-_]+/[a-zA-Z0-9-_]+/pull/[0-9]+') +PR_URL=$(echo ${PR_URL:-} | grep -oP 'https://github.com/[a-zA-Z0-9-_]+/[a-zA-Z0-9-_]+/pull/[0-9]+') if [ -z "${PR_URL:-}"]; then echo "Error: Please provide a valid PR URL!" exit 1 From 69933ed7e1e8f565ab9cd014abeeea52400fcf62 Mon Sep 17 00:00:00 2001 From: Houssem Ben Ali Date: Wed, 11 Oct 2023 13:11:45 +0200 Subject: [PATCH 7/7] Remove PR reviewers case --- github/backportPR.sh | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/github/backportPR.sh b/github/backportPR.sh index 31b30f3a..cad5095f 100755 --- a/github/backportPR.sh +++ b/github/backportPR.sh @@ -5,10 +5,6 @@ getJsonItem() { echo $PR_JSON | jq -r ".$1" } -getPRReviewers() { - echo $PR_JSON | jq -r '[ .requested_reviewers[].login ] | join(",")' -} - # Sanitize PR URL PR_URL=$(echo ${PR_URL:-} | grep -oP 'https://github.com/[a-zA-Z0-9-_]+/[a-zA-Z0-9-_]+/pull/[0-9]+') if [ -z "${PR_URL:-}"]; then @@ -40,7 +36,6 @@ echo "OK PR merge commit is ${PR_MERGE_COMMIT}" PR_TITLE=$(getJsonItem title) PR_BODY=$(getJsonItem body) PR_OWNER=$(getJsonItem user.login) -PR_REVIEWERS=$(getPRReviewers) PR_REPO=$(getJsonItem head.repo.name) git clone $PR_CLONE_URL &>/dev/null pushd ${PR_REPO} @@ -68,14 +63,6 @@ git push origin HEAD if [ ${REVIEWERS:-} = "_OWNER_" ]; then REVIEWERS=$PR_OWNER fi -if [ ${REVIEWERS:-} = "_REVIEWERS_" ]; then - if [ -z "${PR_REVIEWERS:-}" ]; then - echo "Error: This PR does not have reviewers! Please select other reviewers. Abort" - exit 1 - else - REVIEWERS=$PR_REVIEWERS - fi -fi if [ ! -z ${GH_ACTOR_TOKEN:-} ]; then export GH_TOKEN=${GH_ACTOR_TOKEN} fi