Release scripts: comments, run on Ubuntu
[openocd.git] / tools / release.sh
1 #!/bin/bash
2 # release.sh: openocd release process automation
3 # Copyright (C) 2009 by Zachary T Welch <zw@superlucidity.net>
4 # Release under the GNU GPL v2 (or later versions).
5
6 # FIXME Remove more bash-isms. Fix errors making "ash -e" lose.
7
8 ## set these to control the build process
9 #CONFIG_OPTS=""
10 #MAKE_OPTS=""
11
12 ## specifies the --next release type: major, minor, micro, rc, tag
13 #RELEASE_TYPE=tag
14 ## For tag release type, specifies the name of the tag (e.g. "foo").
15 ## The default is the current user name, as found by the 'id' command.
16 #RELEASE_TAG="$(id -un)"
17
18 . "tools/release/helpers.sh"
19
20 VERSION_SH="tools/release/version.sh"
21
22 usage() {
23 cat << USAGE
24 usage: $0 <command> ...
25 Command Options:
26 --next name The branch's next release type: major, minor, micro, rc, tag.
27 --next-tag name The name for the package version tag.
28 --live Perform the actions in the repository.
29
30 Main Commands:
31 info Show a summary of the next pending release.
32 release Release the current tree as an archive.
33
34 Build Commands:
35 bootstrap Prepare the working copy for configuration and building.
36 configure Configures the package; runs bootstrap, if needed.
37 build Compiles the project; runs configure, if needed.
38
39 Packaging Commands:
40 changelog Generate a new ChangeLog using ${SCM}2cl.
41 package Produce new distributable source archives.
42 stage Move archives to staging area for upload.
43
44 Other Commands:
45 clean Forces regeneration of results.
46 clean_all Removes all traces of the release process.
47 help Provides this list of commands.
48
49 For more information about this script, see the Release Processes page
50 in the OpenOCD Developer's Manual (doc/manual/release.txt).
51 USAGE
52 exit 0
53 }
54 do_usage() { usage; }
55 do_help() { usage; }
56
57 do_info() {
58 echo "Current Release Analysis:"
59 package_info_show
60 }
61
62 do_bootstrap() {
63 echo -n "Bootstrapping..."
64 ./bootstrap 2>&1 | perl tools/logger.pl > "release-bootstrap.log"
65 }
66 maybe_bootstrap() { [ -f "configure" ] || do_bootstrap; }
67
68 do_configure() {
69 maybe_bootstrap
70 echo -n "Configuring..."
71 ./configure ${CONFIG_OPTS} 2>&1 | perl tools/logger.pl > "release-config.log"
72 }
73 maybe_configure() { [ -f "Makefile" ] || do_configure; }
74
75 do_build() {
76 maybe_configure
77 echo -n "Compiling OpenOCD ${PACKAGE_VERSION}"
78 make ${MAKE_OPTS} -C doc stamp-vti 2>&1 \
79 | perl tools/logger.pl > "release-version.log"
80 make ${MAKE_OPTS} 2>&1 \
81 | perl tools/logger.pl > "release-make.log"
82 }
83 maybe_build() { [ -f "src/openocd" ] || do_build; }
84 do_build_clean() { [ -f Makefile ] && make maintainer-clean >/dev/null; }
85
86 do_changelog() {
87 echo "Creating ChangeLog..."
88 local CMD=tools/git2cl/git2cl
89 eval ${CMD} ${OPTS} > ChangeLog
90 }
91 do_changelog_clean() {
92 git checkout ChangeLog
93 }
94
95 do_package() {
96 do_changelog
97 maybe_build
98 echo "Building distribution packages..."
99 make ${MAKE_OPTS} distcheck 2>&1 | perl tools/logger.pl > "release-pkg.log"
100 }
101 maybe_package() { [ -f "${PACKAGE_RELEASE}.zip" ] || do_package; }
102 do_package_clean() {
103 for EXT in tar.gz tar.bz2 zip; do
104 rm -v -f *.${EXT}
105 done
106 }
107
108 do_stage() {
109 maybe_package
110 echo "Staging package archives:"
111 mkdir -p archives
112 for EXT in tar.gz tar.bz2 zip; do
113 local FILE="${PACKAGE_RELEASE}.${EXT}"
114 # create archive signatures
115 for HASH in md5 sha1; do
116 echo "sign: ${FILE}.${HASH}"
117 ${HASH}sum "${FILE}" > "archives/${FILE}.${HASH}"
118 done
119 # save archive
120 mv -v "${FILE}" archives/
121 done
122 cp -a NEWS archives/
123 cp -a ChangeLog archives/
124 }
125 do_stage_clean() { rm -v -f -r archives; }
126
127 do_clean() {
128 do_build_clean
129 do_package_clean
130 do_changelog_clean
131 rm -v -f release-*.log
132 }
133 do_clean_all() {
134 do_clean
135 do_stage_clean
136 }
137
138 do_version_commit() {
139 [ "$*" ] || die "usage: $0 commit <message>"
140 git add configure.in || die "error: no version changes to commit"
141 git commit -q -m "$*" configure.in
142 }
143
144 do_version_finalize() {
145 echo "The ${PACKAGE_NAME} ${RELEASE_VERSION} release."
146 echo
147 ${VERSION_SH} tag remove dev
148 [ -z "${RELEASE_FINAL}" ] || ${VERSION_SH} bump final rc
149 }
150 has_dev_tag() {
151 [ "${PACKAGE_VERSION/dev/}" != "${PACKAGE_VERSION}" ]
152 }
153 do_release_step_branch() {
154 git checkout -b "v${RELEASE_VERSION}-release"
155 }
156
157 do_release_step_tag() {
158 do_version_commit "$(do_version_finalize)"
159 package_info_load
160 [ "${PACKAGE_VERSION/dev/}" = "${PACKAGE_VERSION}" ] || \
161 die "'${PACKAGE_NAME}-${PACKAGE_VERSION}' should not be tagged"
162 local MSG="The ${PACKAGE_STRING} release."
163 git tag -m "${MSG}" "v${PACKAGE_VERSION}"
164 }
165
166 do_bump_version() {
167 echo -n "Bump ${RELEASE_TYPE} "
168 [ -z "${RELEASE_TAG}" ] || echo -n "-${RELEASE_TAG} "
169 echo -n "version and add "
170 [ -z "${RELEASE_START_RC}" ] || echo -n "-rc0"
171 echo "-dev tag."
172 echo
173 ${VERSION_SH} bump "${RELEASE_TYPE}" "${RELEASE_TAG}"
174 [ -z "${RELEASE_START_RC}" ] || ${VERSION_SH} bump tag rc
175 ${VERSION_SH} tag add dev
176 }
177 do_release_step_bump() {
178 # bump the version number
179 do_version_commit "$(do_bump_version)"
180 }
181
182 do_release_step_news_msg() {
183 cat <<MSG
184 Archive and recreate NEWS file.
185
186 Archive released NEWS file as NEWS-${RELEASE_VERSION}.
187 Create new NEWS file from release script template.
188 MSG
189 }
190 do_release_step_news() {
191 # only archive the NEWS file for major/minor releases
192 [ "${RELEASE_TYPE}" = "major" -o "${RELEASE_TYPE}" = "minor" ] || \
193 return 0
194 # archive NEWS and create new one from template
195 git mv "NEWS" "NEWS-${RELEASE_VERSION}"
196
197 cat >NEWS <<NEWS
198 This file should include items worth mentioning in the
199 OpenOCD ${NEXT_RELEASE_VERSION} source archive release.
200
201 The following areas of OpenOCD functionality changed in this release:
202
203 JTAG Layer:
204 Target Layer:
205 Flash Layer:
206 Board, Target, and Interface Configuration Scripts:
207 Documentation:
208 Build and Release:
209
210 For more details about what has changed since the last release,
211 see the ChangeLog associated with this source archive. For older NEWS,
212 see the NEWS files associated with each release (i.e. NEWS-<version>).
213
214 For more information about contributing test reports, bug fixes, or new
215 features and device support, please read the new Developer Manual (or
216 the BUGS and PATCHES files in the source archive).
217 NEWS
218 git add NEWS
219
220 local MSG="$(do_release_step_news_msg)"
221 git commit -q -m "${MSG}" NEWS "NEWS-${RELEASE_VERSION}"
222 }
223
224 do_release_step_package() {
225 [ -z "${RELEASE_FAST}" ] || return 0
226
227 git checkout -q "v${RELEASE_VERSION}"
228 do_stage
229 do_clean
230 }
231
232 do_release_step_rebranch() {
233 # return to the new development head
234 local OLD_BRANCH="v${RELEASE_VERSION}-release"
235 git checkout "${OLD_BRANCH}"
236
237 # create new branch with new version information
238 package_info_load
239 git checkout -b "v${PACKAGE_VERSION}"
240 git branch -d "${OLD_BRANCH}"
241 }
242
243 do_release_setup() {
244 echo "Starting $CMD for ${RELEASE_VERSION}..."
245 [ "${RELEASE_TYPE}" ] || \
246 die "The --next release type must be provided. See --help."
247 }
248
249 do_release_check() {
250 [ -z "${RELEASE_FAST}" ] || return 0
251 echo "Are you sure you want to ${CMD} '${PACKAGE_RELEASE}', "
252 echo -n " to start a new ${RELEASE_TYPE} development cycle? (y/N) "
253 read ANSWER
254 if [ "${ANSWER}" != 'y' ]; then
255 echo "Live release aborted!"
256 exit 0
257 fi
258 do_countdown "Starting live release"
259 }
260 do_countdown() {
261 echo -n "$1 in "
262 for i in $(seq 5 -1 1); do
263 echo -n "$i, "
264 sleep 1
265 done
266 echo "go!"
267 }
268
269 do_branch() {
270 do_release_setup
271 local i=
272 for i in branch bump rebranch; do
273 "do_release_step_${i}"
274 done
275 }
276
277 do_release() {
278 local CMD='release'
279 do_release_setup
280 do_release_check
281 local i=
282 for i in branch tag bump news package rebranch; do
283 "do_release_step_${i}"
284 done
285 }
286 do_all() { do_release "$@"; }
287
288 do_reset() {
289 maybe_bootstrap
290 maybe_configure
291 do_clean_all
292 git checkout configure.in
293 }
294
295 LONGOPTS="fast,final,start-rc,next-tag:,next:,help"
296 OPTIONS=$(getopt -o 'V,n:' --long "${LONGOPTS}" -n $0 -- "$@")
297 if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi
298 eval set -- "${OPTIONS}"
299 while true; do
300 case "$1" in
301 --fast)
302 RELEASE_FAST=yes
303 shift
304 ;;
305 --final)
306 RELEASE_FINAL=yes
307 shift
308 ;;
309 --start-rc)
310 RELEASE_START_RC=yes
311 shift
312 ;;
313 -n|--next)
314 export RELEASE_TYPE="$2"
315 shift 2
316 ;;
317 --next-tag)
318 export RELEASE_TAG="$2"
319 shift 2
320 ;;
321 -V)
322 exec $0 info
323 ;;
324 --)
325 shift
326 break
327 ;;
328 --help)
329 usage
330 shift
331 ;;
332 *)
333 echo "Internal error"
334 exit 1
335 ;;
336 esac
337 done
338
339 case "${RELEASE_TYPE}" in
340 major|minor|micro|rc)
341 ;;
342 tag)
343 [ "${RELEASE_TAG}" ] || RELEASE_TAG="$(id -u -n)"
344 ;;
345 '')
346 ;;
347 *)
348 die "Unknown release type '${RELEASE_TYPE}'"
349 ;;
350 esac
351
352 CMD=$1
353 [ "${CMD}" ] || usage
354 shift
355
356 ACTION_CMDS="bootstrap|configure|build|changelog|package|stage|clean"
357 MISC_CMDS="all|info|release|branch|reset|help|usage"
358 CLEAN_CMDS="build_clean|changelog_clean|package_clean|stage_clean|clean_all"
359 CMDS="|${ACTION_CMDS}|${CLEAN_CMDS}|${MISC_CMDS}|"
360 is_command() { echo "${CMDS}" | grep "|$1|" >/dev/null; }
361
362 package_info_load
363 if is_command "${CMD}"; then
364 "do_${CMD}" "$@"
365 echo "Done with '${CMD}'." >&2
366 else
367 echo "error: unknown command: '${CMD}'"
368 usage
369 fi