-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathbackport
executable file
·215 lines (182 loc) · 7.61 KB
/
backport
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
#!/bin/bash
## Bash script to automate BAISC MongoDB backports.
## Backports to ONE previous (or future) version
## branch at a time. If a conflict is encountered in
## the course of a cherry-pick, notifies the user and
## terminates, else completes the backport and presents
## the user with the relevant PR URL.
## Requirements:
##
## - Must be called from within a git repo
## - Must have committed the change you wish
## to backport
## - Must be in the appropriate branch, or one of its
## backport branchs as created by this program
## Supports the following usage:
##
## backport <version>
## backports commit to specified major version, like:
## v4.0, v3.6, v3.2
## or minor revison if to future branches, like:
## v4.0.14, v3.6.16, v3.4.24
## or the master branch if "up-porting", like:
## master
## where commit message contains the jira ticket that
## starts your current branchname. Only accepts ONE
## target version at a time.
## backport resume
## if previous invocation of this utility met with
## a conflict in the cherry-pick stage, and you have
## since manually corrected it, use this to resume
## the cherry pick and publish as normal. Don't forget
## to save your changes in VSCode! No need to run
## git add or git commit, however.
## backport edit
## if you have already created the PR to the previous
## branch, wish to make a last minute change, and
## have not completed the PR in GitHub, you may use
## this option to edit the PR. Don't forget
## to save your changes in VSCode! No need to run
## git add or git commit, however.
############################################################
## YOUR VALUES ##
#################
## Your github username:
GITUSER=your_git_user
############################################################
## BEGIN SCRIPT ##
##################
TMPFILE=/tmp/backport$$.tmp
## Check for provided parameter:
PARAMETER=$1
# Parse user-provided parameter and determine what to do:
if [ -z $PARAMETER ]; then
echo -e "\nERROR: No parameter provided. You must provide one of:"
echo -e " - <vers>: ONE of major version like: v4.0, v3.6, v3.4"
echo -e " or minor revision like: v4.0.14, v3.6.16, v3.4.24"
echo -e " - resume: to resume an in-progress backport"
echo -e " - edit: to edit an already pushed backport"
echo -e " Exiting ...\n"
exit;
elif [ ! -z $2 ]; then
echo -e "\nERROR: Too many parameters provided. You must provide one of:"
echo -e " - <vers>: ONE of major version like: v4.0, v3.6, v3.4"
echo -e " or minor revision like: v4.0.14, v3.6.16, v3.4.24"
echo -e " - resume: to resume an in-progress backport"
echo -e " - edit: to edit an already pushed backport"
echo -e " Exiting ...\n"
exit;
elif [[ "$PARAMETER" =~ ^(resume|RESUME|Resume)$ ]]; then
RESUME=1
echo "Resuming existing cherry-pick ..."
elif [[ "$PARAMETER" =~ ^(edit|EDIT|Edit)$ ]]; then
EDIT=1
echo "Editing existing backport ..."
elif [[ "$PARAMETER" =~ ^(master|MASTER|master)$ ]]; then
TARGETVERS="master"
elif [ `echo $PARAMETER | sed 's%^v%%g' | egrep -c '^[0-9]\.[0-9]{1,2}\.{0,1}[0-9]{0,2}$'` -lt 1 ]; then
echo -e "\nERROR: Invalid backport version provided."
echo -e " Must be ONE of major version like: v4.0, v3.6, v3.4"
echo -e " or minor revision like: v4.0.14, v3.6.16, v3.4.24"
echo -e " This script only supports one backport at a time."
echo -e " Exiting ...\n"
exit;
else
TARGETVERS=$PARAMETER
fi
# Determine BRANCHNAME:
BRANCHNAME=`git rev-parse --abbrev-ref HEAD 2>&1`
## Exit if not in a valid git repo:
if [ `echo $BRANCHNAME | grep -c '^fatal: not a git repository'` -gt 0 ]; then
echo -e "\nERROR: Not in a git repo!"
echo -e " Aborting...\n"
exit;
fi
## IF RESUMING OR EDITING:
if [[ ! -z $RESUME || ! -z $EDIT ]]; then
## Sanity check: did we forget to resolve any conflicts?
grep -R '<<<<<<< HEAD' source/* | awk -F':' '{print $1}' | sort -u > $TMPFILE.missed
## If so, notify the user and abort!
if [ -s $TMPFILE.missed ]; then
echo -e "\nWARNING: Conflicts still detected in the following file(s):\n"
echo -e "#############################################################"
cat $TMPFILE.missed
echo -e "#############################################################"
echo -e "\nAborting...\n"
rm -f $TMPFILE.*
exit;
fi
## We no longer have a user-provided $PARAMETER,
## but can now determine $TARGETVERS directly via git:
TARGETVERS=`git rev-parse --abbrev-ref --symbolic-full-name @{u} | awk -F'/' '{print $2}'`
## Get exiting GIT_EDITOR, to restore later:
OLD_GIT_EDITOR=`echo $GIT_EDITOR`
## Set custom giteditor_autoamend as GIT_EDITOR:
export GIT_EDITOR=giteditor_autoamend
git status
git add source/*
if [ ! -z $RESUME ]; then
# Performing a $RESUME:
git cherry-pick --continue
else
# Must be an $EDIT then:
git commit --amend
fi
git pull --rebase
git push -f origin $BRANCHNAME
# Build URL:
PR_URL="https://github.com/mongodb/docs/compare/$TARGETVERS...andf-mongodb:$BRANCHNAME?expand=1"
# Provide links (clickable in VS Code and iTerm2):
echo -e "\n############################## BACKPORT READY! #############################"
echo -e "\n PULL REQUEST: $PR_URL"
echo -e "\n##############################################################################\n"
# Replace GIT_EDITOR with original value:
GIT_EDITOR=`echo $OLD_GIT_EDITOR`
rm -f $TMPFILE.*
exit;
fi
## IF NOT RESUMING OR EDITING, check current branch:
## - If branch does not start with $JIRA, likely in different backport branch
## (like v4.0, etc). Switch to parent branch containing original commit
## - If branch does start with $JIRA, continue as normal.
if [ `echo $BRANCHNAME | awk -F\- '{print $1}' | sed 's%^v%%g' | egrep -c '^[0-9]\.[0-9]{1,2}\.{0,1}[0-9]{0,2}$'` -eq 1 ]; then
SWITCHTO_JIRA=`echo $BRANCHNAME | awk -F\- '{print $2"-"$3}'`
SWITCHTO_BRANCH=`git for-each-ref refs/heads | cut -d/ -f3- | grep ^$SWITCHTO_JIRA`
git checkout $SWITCHTO_BRANCH
BRANCHNAME=$SWITCHTO_BRANCH
fi
## Determine commit to backport. Only handles one at a time:
JIRA=`echo $BRANCHNAME | awk -F\- '{print $1"-"$2}'`
COMMIT_LINE=`git log --pretty=format:'%h | %s %d' | grep $JIRA`
COMMIT=`echo $COMMIT_LINE | awk -F' | ' {'print $1'}`
if [ -z $COMMIT ]; then
echo -e "\nERROR: Could not determine commit to backport!"
echo -e " You must have committed your fix in order to backport"
echo -e " Aborting...\n"
exit;
fi
## Perform work:
git checkout -b $TARGETVERS-$JIRA upstream/$TARGETVERS
git pull --rebase
git cherry-pick $COMMIT 2>&1 | tee $TMPFILE.out 2>&1 > /dev/null
## Determine if there is a conflict:
if [ `grep -c 'error: could not apply' $TMPFILE.out` -gt 0 ]; then
echo -e "\nALERT: CONFLICTS DETECTED"
echo -e " You must now manually correct conflicts."
echo -e " When ready, use 'backport resume' to return to this step."
echo -e " Exiting...\n"
rm -f $TMPFILE.*
exit;
else
echo -e "\nNo conflicts detected! Huzzah!"
echo -e " Continuing ...\n"
fi
git pull --rebase
git push -f origin $TARGETVERS-$JIRA
# Build URL:
PR_URL="https://github.com/mongodb/docs/compare/$TARGETVERS...andf-mongodb:$TARGETVERS-$JIRA?expand=1"
# Provide links (clickable in VS Code and iTerm2):
echo -e "\n############################## BACKPORT READY! #############################"
echo -e "\n PULL REQUEST: $PR_URL"
echo -e "\n##############################################################################\n"
rm -f $TMPFILE.*