-
Notifications
You must be signed in to change notification settings - Fork 2
/
case2.sh
executable file
·196 lines (170 loc) · 6.04 KB
/
case2.sh
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
#! /bin/bash
# Test Case 2
# - pr-location: fork
# - commits: 1
# - merge-strategy: merge commit
# - workflow: backport-pr-target-closed.yml
# - expects: 1 backport pr opened
# This test is expected to be run in a checked out forked repo
# It also expects that the forked repo is in sync or at least close to origin
# When run this test will:
# - create a branch from main as backport target
# - create a branch from main for new changes
# - add a commit to new
# - open a pull request to merge it to main on origin
# - merge the pull request
# - find the commit sha of the commit that merged the pr
# - find the commit sha of the head of the pr
# - find the backport-pr-target-closed.yml workflow run on pull_request[closed]
# - wait for workflow to finish
# - check that backport pull request is opened to target
# - check that backport pull request contains cherry picked commits
# - cleanup: revert merge to main, close backport-pr and delete both new branches
# Non-zero exitcodes:
# 10: Unable to find backport workflow run caused by merging a PR after trying for 60 seconds
# 20: Unable to find backport pr (expected only 1, but is either none, or multiple)
# 30: Backport pr does not contain expected cherry picked commits
function main() {
name="github-actions[bot]"
email="github-actions[bot]@users.noreply.github.com"
export GIT_AUTHOR_NAME="$name"
export GIT_AUTHOR_EMAIL="$email"
export GIT_COMMITTER_NAME="$name"
export GIT_COMMITTER_EMAIL="$email"
# add the upstream repo as upstream
# the gh cli will use the knowledge of both origin and upstream remotes
# to determine where to create the pr
git remote add --fetch \
upstream https://github.com/korthout/backport-action-test.git
# assume that a branch exists on origin as backport target
# git branch case2-backport-target
# git push -u origin case2-backport-target
# create a branch from main for new changes
git branch case2-new-changes
git checkout case2-new-changes
# add a commit to new
mkdir case2
echo "A changed line is added" >> case2/file1
git add case2/file1
git commit -m "case(2): add changed line"
git push -u origin case2-new-changes
# open a pull request to upstream
gh pr create \
--head backport-action:case2-new-changes \
--title "Case(2): Add a changed line" \
--body "Adds a changed line" \
--label 'backport case2-backport-target' \
--label 'should_copy'
# merge the pull request
gh pr merge \
--merge \
--auto \
--subject "case(2): merge pull request"
# find the commit sha of the commit that merged the pr
mergeCommit=$(gh pr view --json mergeCommit --jq '.mergeCommit.oid')
# find the commit sha of the head of the pr
headSha=$(gh pr view --json commits --jq '.commits | map(.oid) | last' | cat)
# find the backport-pr-target-closed.yml workflow run on pull_request[closed]
local backport_run_id
local checks_index=0
while [ -z "$backport_run_id" ]; do
sleep 1
findBackportRun "$headSha"
(("checks_index+=1"))
if [ "$checks_index" -gt 60 ]; then
exit 10
fi
done
echo "found backport-pr-target-closed workflow run: $backport_run_id"
# wait for workflow to finish
gh run watch "$backport_run_id" \
&& echo "backport-pr-target-closed workflow run $backport_run_id finished"
# check that backport pull request is opened to target
local backport_prs
backport_prs=$(gh pr list --base case2-backport-target --json number --jq 'length')
if [ ! 1 -eq "$backport_prs" ]; then
echoerr "expected 1 open backport pr for case2, but found $backport_prs open prs"
exit 20
fi
# find the backport_branch for later cleanup
backport_branch=$(gh pr list --base case2-backport-target --json headRefName --jq 'first | .headRefName')
# check that backport pull request contains cherry picked commits
local backport_commit_matches
backport_commit_matches=$(gh pr list \
--base case2-backport-target \
--json commits \
--jq "first | .commits | map(.messageBody | match(\".*cherry picked from commit $headSha.*\")) | length")
if [ ! 1 -eq "$backport_commit_matches" ]; then
echoerr "expected 1 cherry picked commit for $headSha, but found $backport_commit_matches"
exit 30
fi
}
# Find the run of the backport workflow that was triggered for a specific head sha
# Usage findBackportRun $expectedHeadSha
# Sets the backport_run_id variable when found, otherwise does nothing
function findBackportRun() {
local wf_id
wf_id=$(gh run list \
--workflow backport-pr-target-closed.yml \
--json headSha,databaseId \
--limit 10 \
--jq "map(select(.headSha == \"$1\")) | first | \"\(.databaseId)\"")
if [ ! "$wf_id" = "null" ]; then
backport_run_id="$wf_id"
fi
}
function echoerr() {
printf "%s\n" "$*" >&2;
}
function cleanup() {
set +e
git checkout main
# dont delete the backport-target, this script has no permissions to recreate it
# deleteBranch case2-backport-target
revertCommit "$headSha"
# we have to close the backport pr directly
# we cannot automatically close it by deleting its branch
# because the branch exists on upstream
# #deleteBranch "$backport_branch"
deleteBranch case2-new-changes
gh pr close "$backport_branch" --delete-branch
}
function deleteBranch() {
if [ -n "$1" ]; then
git branch --delete "$1"
git push origin --delete "$1"
fi
}
function revertCommit() {
if [ -n "$1" ]; then
gh repo sync \
--force \
--source korthout/backport-action-test \
backport-action/backport-action-test
git checkout main
git pull
git branch case2-revert
git checkout case2-revert
git revert --mainline 1 "$1" --no-edit
git push -u origin HEAD
# open a pull request to upstream
gh pr create \
--head backport-action:case2-revert \
--title "Case(2): Revert" \
--body "Reverts the changes of case 2"
# merge the pull request
gh pr merge \
--merge \
--auto \
--subject "case(2): revert"
git checkout main
fi
}
# Initialise clean up
mergeCommit=""
headSha=""
backport_branch=""
trap 'cleanup' EXIT
# Run script
set -ex
main