forked from bareos/bareos
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathprepare-release.sh
executable file
·252 lines (208 loc) · 7.01 KB
/
prepare-release.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
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
#!/bin/bash
set -e
set -u
# this will match a version or pre-release version e.g.
# "19.2.4" or "19.2.4~pre13.xyz"
version_regexp='([[:digit:]]+\.){2}[[:digit:]]+(~[[:alnum:]]+)?'
# this will only match a stable version e.g.
# "18.2.7"
stable_version_regexp='([[:digit:]]+\.){2}[[:digit:]]+'
topdir="$(dirname "$0")"
prog="$(basename "$0")"
git="${GIT:-$(type -p git)}"
cmake="${CMAKE:-$(type -p cmake)}"
pushd "$topdir" >/dev/null
log_info() {
echo -e "\e[36m$prog: INFO: $*\e[0m" >&2
}
log_warn() {
echo -e "\e[33m$prog: WARN: $*\e[0m" >&2
}
log_fatal() {
echo -e "\e[31m$prog: FATAL: $*\e[0m" >&2
exit 1
}
# wrap stdin in a nice blue box
print_block() {
local s='\e[44m\e[97m' e='\e[0m'
printf "\n%b┏" "$s"; printf -- "━%.0s" {1..77}; printf "┓%b\n" "$e"
printf "%b┃ %-73s ┃%b\n" "$s" '' "$e"
while read line; do
printf "%b┃ %-73s ┃%b\n" "$s" "$line" "$e"
done
printf "%b┃ %-73s ┃%b\n" "$s" '' "$e"
printf "%b┗" "$s"; printf -- "━%.0s" {1..77}; printf "┛%b\n\n" "$e"
}
# get_next_version accepts a stable version as its only parameter.
# it will then return the patch-version that follows after the provided version.
get_next_version() {
local in_parts out_parts last
IFS=. in_parts=($1) # split into an array
((last=${#in_parts[@]} - 1 )) # get index of last element
out_parts=()
# concatenate up to, but not including last element
for (( i=0; i<last; i++ )); do
out_parts+=("${in_parts[i]}")
done
out_parts+=($(( in_parts[i]+1 ))) # add last element incremented by one
IFS=. echo "${out_parts[*]}" # join array to string
}
confirm() {
echo -ne " \e[44m\e[97m $* (y/n) \e[0m"
read -n 1 -r
echo -e "\n"
[[ $REPLY =~ ^[Yy]$ ]]
}
if [ -z "$git" -o ! -x "$git" ]; then
log_fatal "git not found."
elif [ -z "$cmake" -o ! -x "$cmake" ]; then
log_fatal "cmake not found."
elif [ ! -e .git ]; then
log_fatal "This is not a git working copy."
elif [ -n "$("$git" status --short)" ]; then
log_fatal "This script must be run in a clean working copy."
fi
# get the git remote name for the upstream GitHub repository
git_remote="$("$git" remote -v | \
awk '/[email protected]:\/?bareos\/bareos.git \(push\)/ { print $1 }')"
if [ -z "$git_remote" ]; then
# warn if not found and set a default for sane messages"
log_warn "Could not find the upstream repository in your git remotes."
git_remote="<remote>"
fi
# we try to detect the version that should be released.
# for this we retrieve the version of the source-tree we're running in and strip
# any prerelease suffix.
autodetect_version=$("$cmake" -P get_version.cmake \
| sed --expression='s/^-- //' --expression='s/~.*$//')
if [ -n "${1:-}" ]; then
log_info "Using provided version $1."
version="$1"
elif [ -n "$autodetect_version" ]; then
log_info "Autodetected version $autodetect_version based on WIP-tag."
version="$autodetect_version"
else
log_fatal Cannot autodetect version and no version passed on cmdline
fi
if ! grep --quiet --extended-regexp "^$version_regexp\$" <<< "$version"; then
log_fatal "Version $1 does not match the expected pattern"
fi
git_branch="$(git rev-parse --abbrev-ref=strict HEAD)"
if ! grep --quiet --fixed-strings "$git_branch" <<< "bareos-$version"; then
log_warn "Git branch $git_branch is not the release branch for $version."
fi
release_tag="Release/${version/\~/-}"
release_ts="$(date --utc --iso-8601=seconds | sed --expression='s/T/ /;s/+.*$//')"
release_message="Release $version"
# Only if we are preparing a stable release
if grep --quiet --extended-regexp "^$stable_version_regexp\$" <<< "$version"; then
wip_enable=1
wip_version="$(get_next_version "$version")"
wip_tag="WIP/$wip_version-pre"
wip_message="Start development of $wip_version"
else
log_info "Will not generate a new WIP tag for a pre-release"
wip_enable=0
wip_version="(none)"
wip_tag="(none)"
wip_message="(none)"
fi
print_block << EOT
You are preparing a release of Bareos. As soon as you push the results of
this script to the official git repository, the new version is released.
If you decide not to push, nothing will be released.
The release you are preparing will have the following settings:
Version: "$version"
Release tag: "$release_tag"
Release time: "$release_ts"
Release msg: "$release_message"
If this is not a pre-release a new work-in-progress tag will be created:
Next version: "$wip_version"
WIP tag: "$wip_tag"
WIP message: "$wip_message"
This script will do the following:
1. Create an empty git commit with the version timestamp
2. Generate and add */cmake/BareosVersion.cmake
3. Amend the previous commit with the version files
4. Remove */cmake/BareosVersion.cmake
5. Commit the removed version files.
6. Add an empty commit for a WIP tag (not for pre-releases)
7. Set the release tag
8. Set the WIP tag (not for pre-releases)
Please make sure you're on the right branch before continuing and review
the commits, tags and branch pointers before you push!
For a major release you should be on the release-branch, not the master
branch. While you can move around branch pointers later, it is a lot
easier to branch first.
EOT
if ! confirm "Do you want to proceed?"; then
log_info "Exiting due to user request."
exit 0
fi
original_commit="$(git rev-parse HEAD)"
log_info "if you want to rollback the commits" \
"you can run 'git reset --soft $original_commit'"
# we start with a temporary commit so write_version_files.cmake will then see
# the timestamp of that commit. This makes sure we have $release_ts written to
# the BareosVersion.cmake files
"$git" commit \
--quiet \
--allow-empty \
--date="$release_ts" \
-m "TEMPORARY COMMIT MESSAGE"
"$cmake" -DVERSION_STRING="$version" -P write_version_files.cmake
"$git" add \
--no-all \
--force \
-- \
./*/cmake/BareosVersion.cmake
"$git" commit \
--quiet \
--amend \
--only \
--date="$release_ts" \
-m "$release_message" \
-- \
./*/cmake/BareosVersion.cmake
release_commit="$(git rev-parse HEAD)"
log_info "commit for release tag will be $release_commit"
"$git" rm \
-- \
./*/cmake/BareosVersion.cmake
"$git" commit \
--quiet \
--date="$release_ts" \
-m "Remove */cmake/BareosVersion.cmake after release"
if [ "$wip_enable" -eq 1 ]; then
"$git" commit \
--quiet \
--allow-empty \
--date="$release_ts" \
-m "$wip_message"
wip_commit="$(git rev-parse HEAD)"
log_info "commit for WIP tag will be $wip_commit"
fi
echo
echo The log for the new commits is:
echo
"$git" log \
--decorate \
--graph \
"${original_commit}..HEAD"
echo
log_info "Creating release tag for $release_commit named $release_tag"
"$git" tag "$release_tag" "$release_commit"
if [ -n "${wip_commit:-}" ]; then
log_info "Creating WIP tag for $wip_commit named $wip_tag"
"$git" tag "$wip_tag" "$wip_commit"
fi
(
cat <<EOT
To publish your new release, you need to do the follwing git push steps:
git push $git_remote HEAD
git push $git_remote $release_tag
EOT
if [ -n "${wip_commit:-}" ]; then
echo "git push $git_remote $wip_tag"
fi
) | print_block