Skip to content

Commit 31ba719

Browse files
authored
chore: add local backporting script (#5118)
We are adding in a helper `scripts/backport PR_NUMBER BRANCH_NAME` to aid in backporting merged PR to older release branches. ``` Usage: ./scripts/backport PR_NUMBER BRANCH_NAME [, BRANCH_NAME, ...] PR_NUMBER - the GitHub PR number to backport. example: 4376 BRANCH_NAME - the name of the branch to backport PR_NUMBER to. example: 1.8 Examples: Backport PR #3489 to branch 0.61 ./scripts/backport 3489 0.61 Backport PR #4376 to branches 1.8, 1.7, and 1.5 ./scripts/backport 4376 1.8 1.7 1.5 ``` This script cannot yet help people when/if the cherry-pick has a conflict. ## Testing strategy "works on my machine". Here is an example PR created from this script: #5107 ## Checklist - [x] Change(s) are motivated and described in the PR description. - [x] Testing strategy is described if automated tests are not included in the PR. - [x] Risk is outlined (performance impact, potential for breakage, maintainability, etc). - [x] Change is maintainable (easy to change, telemetry, documentation). - [x] [Library release note guidelines](https://ddtrace.readthedocs.io/en/stable/contributing.html#Release-Note-Guidelines) are followed. - [x] Documentation is included (in-code, generated user docs, [public corp docs](https://github.com/DataDog/documentation/)). - [x] Author is aware of the performance implications of this PR as reported in the benchmarks PR comment. ## Reviewer Checklist - [x] Title is accurate. - [x] No unnecessary changes are introduced. - [x] Description motivates each change. - [x] Avoids breaking [API](https://ddtrace.readthedocs.io/en/stable/versioning.html#interfaces) changes unless absolutely necessary. - [x] Testing strategy adequately addresses listed risk(s). - [x] Change is maintainable (easy to change, telemetry, documentation). - [x] Release note makes sense to a user of the library. - [x] Reviewer is aware of, and discussed the performance implications of this PR as reported in the benchmarks PR comment.
1 parent a665ffe commit 31ba719

File tree

1 file changed

+123
-0
lines changed

1 file changed

+123
-0
lines changed

scripts/backport

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
#!/usr/bin/env bash
2+
3+
if ! which gh &>/dev/null;
4+
then
5+
echo "gh cli tool is required in order to continue"
6+
echo "MacOS install via: brew install gh"
7+
echo "https://github.com/cli/cli#installation"
8+
exit 1
9+
fi
10+
11+
if ! which jq &>/dev/null;
12+
then
13+
echo "jq tool is required in order to continue"
14+
echo "MacOS install via: brew install jq"
15+
echo "https://stedolan.github.io/jq/"
16+
exit 1
17+
fi
18+
19+
PR_NUMBER="${1}"
20+
shift 1
21+
TO_BRANCHES="$@"
22+
23+
usage () {
24+
echo "Usage:"
25+
echo " $0 PR_NUMBER BRANCH_NAME [, BRANCH_NAME, ...]"
26+
echo ""
27+
echo " PR_NUMBER - the GitHub PR number to backport. example: 4376"
28+
echo " BRANCH_NAME - the name of the branch to backport PR_NUMBER to. example: 1.8"
29+
echo ""
30+
echo "Examples:"
31+
echo ""
32+
33+
echo " Backport PR #3489 to branch 0.61"
34+
echo " $0 3489 0.61"
35+
echo ""
36+
echo " Backport PR #4376 to branches 1.8, 1.7, and 1.5"
37+
echo " $0 4376 1.8 1.7 1.5"
38+
}
39+
40+
if [[ -z "${PR_NUMBER}" ]];
41+
then
42+
echo "Error:"
43+
echo " Must supply a PR number to backport"
44+
echo ""
45+
usage
46+
exit 1
47+
fi
48+
49+
if [[ -z "${TO_BRANCHES}" ]];
50+
then
51+
echo "Error:"
52+
echo " Must supply at least 1 branch to backport to"
53+
echo ""
54+
usage
55+
exit 1
56+
fi
57+
58+
59+
# Download data about the PR
60+
echo "Fetching data for PR ${PR_NUMBER}"
61+
pr_data="$(gh pr view --json "state,title,mergeCommit,author,labels,body" ${PR_NUMBER})"
62+
63+
# Verify that we are going to have a merge commit
64+
if "$(echo "${pr_data}" | jq -e '.state != "MERGED"')";
65+
then
66+
echo "PR ${PR_NUMBER} has not been merged yet"
67+
exit 1
68+
fi
69+
70+
# Extract data from the original PR
71+
merge_commit_sha="$(echo "${pr_data}" | jq -r '.mergeCommit.oid')"
72+
original_title="$(echo "${pr_data}" | jq -r '.title')"
73+
original_body="$(echo "${pr_data}" | jq -r '.body')"
74+
original_author="$(echo "${pr_data}" | jq -r '.author.login')"
75+
original_labels="$(echo "${pr_data}" | jq -r '[.labels[].name] | join(",")')"
76+
77+
# Get the current branch so we can switch back to it when we are done
78+
current_branch="$(git rev-parse --abbrev-ref HEAD)"
79+
80+
# Try to make sure we have the latest data from remote
81+
git fetch &>/dev/null || true
82+
83+
for base_branch in "$@";
84+
do
85+
echo "Backporting ${PR_NUMBER} (sha: ${merge_commit_sha}) to ${base_branch}"
86+
branch_name="backport-${PR_NUMBER}-to-${base_branch}"
87+
git switch --detach "origin/${base_branch}"
88+
git switch -c "${branch_name}"
89+
90+
echo "Cherry-picking ${merge_commit_sha} (git commit signing required here)"
91+
if ! git cherry-pick -x "${merge_commit_sha}";
92+
then
93+
git cherry-pick --abort
94+
echo "Cherry-pick failed, exiting"
95+
echo ""
96+
echo "Backporting must be done manually to resolve merge-conflict"
97+
echo ""
98+
echo " git cherry-pick -x ${merge_commit_sha}"
99+
exit 1
100+
fi
101+
echo "Pushing branch ${branch_name}"
102+
git push --set-upstream origin "${branch_name}"
103+
104+
echo "Creating pull request"
105+
IFS='' read -r -d '' new_body <<EOF
106+
Backport of #${PR_NUMBER} to ${base_branch}
107+
108+
${original_body}
109+
EOF
110+
new_title="${original_title} [backport #${PR_NUMBER} to ${base_branch}]"
111+
gh pr create --base "${base_branch}" --title "${new_title}" --body "${new_body}" --assignee "@me,${original_author}" --label "${original_labels}"
112+
113+
echo "Enabling auto-merge on PR"
114+
gh pr merge --auto "${branch_name}"
115+
116+
echo "Opening PR in the browser for review"
117+
gh pr view --web "${branch_name}"
118+
119+
# Back to the original branch and delete the temporary branch
120+
echo "Switching back to ${current_branch} and deleting temporary branch ${branch_name}"
121+
git switch "${current_branch}"
122+
git branch -D "${branch_name}"
123+
done

0 commit comments

Comments
 (0)