-
Notifications
You must be signed in to change notification settings - Fork 2
/
case4.sh
executable file
·163 lines (141 loc) · 4.86 KB
/
case4.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
#! /bin/bash
# Test Case 4
# - pr-location: non-fork
# - commits: 1
# - merge-strategy: rebase
# - workflow: backport-pr-closed.yml
# - expects: 1 backport pr opened
# When run this test will:
# - create a branch from main as backport target
# - create a branch from main for new changes
# - add one commit to new
# - open a pull request to merge it to main
# - merge the pull request using rebase
# - 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-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"
# create a branch from main as backport target
git branch case4-backport-target
git push -u origin case4-backport-target
# create a branch from main for new changes
git branch case4-new-changes
git checkout case4-new-changes
# add a commit to new
mkdir case4
echo "A changed line is added" >> case4/file1
git add case4/file1
git commit -m "case(4): add changed line"
git push -u origin case4-new-changes
# open a pull request to merge it to main
gh pr create \
--head case4-new-changes \
--base main \
--title "case(4): Rebase and merge" \
--body "Adds a changed line" \
--label 'backport case4-backport-target' \
--label 'should_copy'
# rebase and merge the pull request
gh pr merge \
--rebase \
--auto
# 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
local headSha
headSha=$(gh pr view --json commits --jq '.commits | map(.oid) | last' | cat)
# find the backport-pr-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-closed workflow run: $backport_run_id"
# wait for workflow to finish
gh run watch "$backport_run_id" \
&& echo "backport-pr-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 case4-backport-target --json number --jq 'length')
if [ ! 1 -eq "$backport_prs" ]; then
echoerr "expected 1 open backport pr for case4, but found $backport_prs open prs"
exit 20
fi
# find the backport_branch for later cleanup
backport_branch=$(gh pr list --base case4-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 case4-backport-target \
--json commits \
--jq "first | .commits | map(.messageBody | match(\".*cherry picked from commit $mergeCommit.*\")) | length")
if [ ! 1 -eq "$backport_commit_matches" ]; then
echoerr "expected 1 cherry picked commit for $mergeCommit, 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-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
deleteBranch case4-backport-target
deleteBranch "$backport_branch"
revertCommit "$mergeCommit"
# we do not have to close the backport pr
# it closes automatically when we delete its target branch
}
function deleteBranch() {
if [ -n "$1" ]; then
git branch --delete "$1"
git push origin --delete "$1"
fi
}
function revertCommit() {
if [ -n "$1" ]; then
git pull
git revert --mainline 1 "$1" --no-edit
git push
fi
}
# Initialise clean up
mergeCommit=""
backport_branch=""
trap 'cleanup' EXIT
# Run script
set -ex
main