-
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathrelease-branch-hygiene.sh
More file actions
executable file
·217 lines (188 loc) · 7.68 KB
/
Copy pathrelease-branch-hygiene.sh
File metadata and controls
executable file
·217 lines (188 loc) · 7.68 KB
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
216
217
#!/usr/bin/env bash
#
# See README.adoc
#
set -euo pipefail
# set -x
REMOTE="origin"
# Collects "<repo>|<title>|<url>" entries for every PR raised during the run,
# so we can print a consolidated summary at the end.
CREATED_PRS=()
#----------------------------------------------------------------------------------------------------
# tags should be semver-compatible e.g. 23.1 and not 23.01
# this is needed for cargo commands to work properly: although it is not strictly needed
# for the name of the release branch, the branch naming will be consistent with the cargo versioning.
#----------------------------------------------------------------------------------------------------
RELEASE_REGEX="^[0-9][0-9]\.([1-9]|[1][0-2])$"
update_products() {
if [ -d "$BASE_DIR/$DOCKER_IMAGES_REPO" ]; then
echo "Directory exists. Switching to ${RELEASE_BRANCH} branch and Updating..."
cd "$BASE_DIR/$DOCKER_IMAGES_REPO"
git switch "${RELEASE_BRANCH}" && git pull
else
echo "Repo directory ($BASE_DIR/$DOCKER_IMAGES_REPO) doesn't exist. Cloning and switching to ${RELEASE_BRANCH} branch"
git clone --branch ${RELEASE_BRANCH} --depth 1 "git@github.com:stackabletech/${DOCKER_IMAGES_REPO}.git" "$BASE_DIR/$DOCKER_IMAGES_REPO"
cd "$BASE_DIR/$DOCKER_IMAGES_REPO"
# try to switch to the release branch (if continuing from someone else), or create it
git switch "${RELEASE_BRANCH}" 2> /dev/null || git switch -c "${RELEASE_BRANCH}"
fi
# Create the work branch from the release branch so changes go through a PR
# rather than being pushed directly to the release branch.
git switch -c "${WORK_BRANCH}"
echo "Pls manually bump the UBI base images in $BASE_DIR/$DOCKER_IMAGES_REPO"
echo 'Tip: I found the following images when searching for "registry.access.redhat.com/ubi" in Dockerfiles:'
grep -r 'FROM registry.access.redhat.com/ubi' **/Dockerfile
read -r -p "Press Enter once you have updated the UBI base images (or Ctrl+C to abort)... "
# Pick up any edits the user made. Skip if they already committed themselves
# or if they made no changes at all.
if ! git diff --quiet || ! git diff --cached --quiet; then
echo "Staging and committing UBI base image bumps..."
git add --update
git commit -m "chore: UBI base image bumps"
fi
raise_pr "$DOCKER_IMAGES_REPO" "chore: UBI base image bumps"
echo
echo "Check $BASE_DIR/$DOCKER_IMAGES_REPO"
}
update_operators() {
while IFS="" read -r operator || [ -n "$operator" ]
do
echo ">>> Now working on ${operator}"
if [ -d "$BASE_DIR/${operator}" ]; then
echo "Directory exists. Switching to ${RELEASE_BRANCH} branch and Updating..."
cd "$BASE_DIR/${operator}"
git switch "${RELEASE_BRANCH}" && git pull
else
echo "Repo directory ($BASE_DIR/$operator) doesn't exist. Cloning and switching to ${RELEASE_BRANCH} branch"
git clone --branch ${RELEASE_BRANCH} --depth 1 "git@github.com:stackabletech/${operator}.git" "$BASE_DIR/${operator}"
cd "$BASE_DIR/${operator}"
# try to switch to the release branch (if continuing from someone else), or create it
git switch "${RELEASE_BRANCH}" || git switch -c "${RELEASE_BRANCH}"
fi
# Create the work branch from the release branch so changes go through a PR
# rather than being pushed directly to the release branch.
git switch -c "${WORK_BRANCH}"
cargo update
# cargo test # Will be done by CI and takes too long
make regenerate-nix
# We are explicitly not regenerating the CRDs, as we don't want CRD changes to sneak in.
# We rather let the CI checks fail and inspect manually.
git add Cargo.lock Cargo.nix
git commit -m "chore: Rust dependency patch level updates"
echo "FYI, these are the major/minor bumps we did't do:"
cargo +nightly -Z unstable-options update --breaking --dry-run
raise_pr "$operator" "chore: Rust dependency patch level updates"
done < <(yq '... comments="" | .operators[] ' "$INITIAL_DIR"/release/config.yaml)
}
update_repos() {
local BASE_DIR="$1";
if [ "products" == "$WHAT" ] || [ "all" == "$WHAT" ]; then
update_products
fi
if [ "operators" == "$WHAT" ] || [ "all" == "$WHAT" ]; then
update_operators
fi
}
raise_pr() {
local REPOSITORY="$1";
local PR_TITLE="$2";
# Skip when nothing was committed on the work branch (e.g. products flow without manual edits)
local COMMITS_AHEAD
COMMITS_AHEAD=$(git rev-list --count "${RELEASE_BRANCH}..${WORK_BRANCH}")
if [ "$COMMITS_AHEAD" -eq 0 ]; then
echo "No commits on ${WORK_BRANCH} relative to ${RELEASE_BRANCH} for ${REPOSITORY}, skipping push and PR creation"
return
fi
if $PUSH; then
echo "Pushing ${WORK_BRANCH} to ${REPOSITORY}"
git push -u "$REMOTE" "$WORK_BRANCH"
echo "Creating PR ${WORK_BRANCH} -> ${RELEASE_BRANCH} on ${REPOSITORY}"
local PR_URL
PR_URL=$(gh pr create \
--base "$RELEASE_BRANCH" \
--head "$WORK_BRANCH" \
--title "$PR_TITLE" \
--body "Patch level maintenance updates for \`${RELEASE_BRANCH}\` (created by release-branch-hygiene.sh).")
CREATED_PRS+=("${REPOSITORY}|${PR_TITLE}|${PR_URL}")
else
echo "Dry-run: not pushing ${WORK_BRANCH} or creating PR for ${REPOSITORY}"
git push --dry-run -u "$REMOTE" "$WORK_BRANCH"
fi
}
print_summary() {
echo
echo "================ PR Summary ================"
if [ ${#CREATED_PRS[@]} -eq 0 ]; then
if $PUSH; then
echo "No PRs were created."
else
echo "Dry-run: no PRs were created (re-run with --push to actually open PRs)."
fi
return
fi
echo "Created ${#CREATED_PRS[@]} PR(s):"
for entry in "${CREATED_PRS[@]}"; do
IFS='|' read -r repo title url <<<"$entry"
echo " - ${repo}: ${title}"
echo " ${url}"
done
}
cleanup() {
local BASE_DIR="$1";
if $CLEANUP; then
echo "Cleaning up..."
rm -rf "$BASE_DIR"
fi
}
parse_inputs() {
RELEASE=""
PUSH=false
CLEANUP=false
WHAT=""
while [[ "$#" -gt 0 ]]; do
case $1 in
-b|--branch) RELEASE="$2"; shift ;;
-w|--what) WHAT="$2"; shift ;;
-p|--push) PUSH=true ;;
-c|--cleanup) CLEANUP=true ;;
*) echo "Unknown parameter passed: $1"; exit 1 ;;
esac
shift
done
#-----------------------------------------------------------
# remove leading and trailing quotes
#-----------------------------------------------------------
RELEASE="${RELEASE%\"}"
RELEASE="${RELEASE#\"}"
RELEASE_BRANCH="release-$RELEASE"
# A single timestamp is shared across all repos in this run so the work
# branches are easy to correlate.
WORK_BRANCH="${RELEASE_BRANCH}-maintenance-$(date +%s)"
INITIAL_DIR="$PWD"
DOCKER_IMAGES_REPO=$(yq '... comments="" | .images-repo ' "$INITIAL_DIR"/release/config.yaml)
TEMP_RELEASE_FOLDER="/tmp/stackable-$RELEASE_BRANCH"
echo "Settings: ${RELEASE_BRANCH}: Work branch: ${WORK_BRANCH}: Push: $PUSH: Cleanup: $CLEANUP"
}
main() {
parse_inputs "$@"
#-----------------------------------------------------------
# check if tag argument provided
#-----------------------------------------------------------
if [ -z "${RELEASE}" ]; then
echo "Usage: create-release-branch.sh -b <branch> [-p] [-c] [-w products|operators|demos|all]"
exit 1
fi
#-----------------------------------------------------------
# check if argument matches our tag regex
#-----------------------------------------------------------
if [[ ! $RELEASE =~ $RELEASE_REGEX ]]; then
echo "Provided branch name [$RELEASE] does not match the required regex pattern [$RELEASE_REGEX]"
exit 1
fi
echo "Creating temporary working directory if it doesn't exist [$TEMP_RELEASE_FOLDER]"
mkdir -p "$TEMP_RELEASE_FOLDER"
update_repos "$TEMP_RELEASE_FOLDER"
cleanup "$TEMP_RELEASE_FOLDER"
print_summary
}
main "$@"