Add numeric version tag support to release script.
[openocd.git] / tools / release.sh
1 #!/bin/sh -e
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 ## set these to control the build process
7 #CONFIG_OPTS=""
8 #MAKE_OPTS=""
9
10 ## DO NOT PERFORM LIVE RELEASES UNLESS YOU ARE THE RELEASE MANAGER!!!
11 RELEASE_DRY_RUN=1
12 ## set this to perform individual steps on past releases
13 RELEASE_VERSION=
14
15 die() {
16 echo "$@" >&2
17 exit 1
18 }
19
20 svn_info_get() {
21 svn info | grep "$1" | cut -d':' -f2- | cut -c2-
22 }
23
24 svn_setup_load() {
25 SVN_ROOT="$(svn_info_get 'Repository Root')"
26 SVN_URL="$(svn_info_get 'URL')"
27
28 SVN_TRUNK="${SVN_ROOT}/trunk"
29
30 SVN_BRANCHES="${SVN_ROOT}/branches"
31 PACKAGE_BRANCH="${SVN_BRANCHES}/${PACKAGE_RELEASE}"
32
33 SVN_TAGS="${SVN_ROOT}/tags"
34 PACKAGE_TAG="${SVN_TAGS}/${PACKAGE_RELEASE}"
35
36 if [ "${SVN_URL}" = "${SVN_TRUNK}" ]; then
37 RELEASE_TYPE=minor
38 elif [ "${SVN_URL/${SVN_BRANCHES}/}" != "${SVN_URL}" ]; then
39 RELEASE_TYPE=micro
40 else
41 echo "error: bad URL: ${SVN_URL}" >&2
42 die "unable to branch from the current location"
43 fi
44 }
45 svn_setup_show() {
46 cat <<INFO
47 Release Type: ${RELEASE_TYPE}
48 Branch URL: ${PACKAGE_BRANCH}
49 Tag URL: ${PACKAGE_TAG}
50 INFO
51 }
52
53 do_svn_echo_msg() { echo "svn: $1: $3"; }
54 do_svn_echo() {
55 case "$1" in
56 commit)
57 do_svn_echo_msg "$@"
58 shift 3
59 [ "$*" ] && echo "Files: $@"
60 ;;
61 copy|move)
62 do_svn_echo_msg "$@"
63 echo "From: ${4:-$2}"
64 echo " To: ${5:-$3}"
65 ;;
66 *)
67 local ACTION="$1"
68 shift
69 echo "svn: ${ACTION}: $@"
70 ;;
71 esac
72 }
73 do_svn() {
74 do_svn_echo "$@"
75 [ "${RELEASE_DRY_RUN}" ] || svn "$@"
76 }
77 do_svn_switch() {
78 do_svn switch "$@"
79 package_info_load
80 }
81
82
83 package_info_load_name() {
84 grep AC_INIT configure.in | perl -ne 's/^.+\(\[([-\w]*)\],.+$/$1/ and print'
85 }
86 package_info_load_version() {
87 grep AC_INIT configure.in | perl -ne 's/^.+\[([-\w\.]*)\],$/$1/ and print'
88 }
89
90 package_info_load() {
91 [ -f "configure.in" ] || \
92 die "package_info_load: configure.in is missing"
93
94 PACKAGE_NAME="$(package_info_load_name)"
95 # todo: fix this
96 PACKAGE_TARNAME="${PACKAGE_NAME}"
97
98 PACKAGE_VERSION="$(package_info_load_version)"
99 [ "${RELEASE_VERSION}" ] || \
100 RELEASE_VERSION=${PACKAGE_VERSION/-in-development/}
101
102 [ "${PACKAGE_NAME}" -a "${PACKAGE_VERSION}" ] || \
103 die "package information is missing from configure script"
104
105 PACKAGE_VERSION_TAGS=
106 [ "${PACKAGE_VERSION/-/}" = "${PACKAGE_VERSION}" ] || \
107 PACKAGE_VERSION_TAGS="-${PACKAGE_VERSION#*-}"
108 PACKAGE_VERSION_BASE="${PACKAGE_VERSION%%-*}"
109 PACKAGE_MICRO="${PACKAGE_VERSION_BASE##*.}"
110 PACKAGE_MAJOR_AND_MINOR="${PACKAGE_VERSION_BASE%.*}"
111 PACKAGE_MAJOR="${PACKAGE_MAJOR_AND_MINOR%.*}"
112 PACKAGE_MINOR="${PACKAGE_MAJOR_AND_MINOR#*.}"
113
114 PACKAGE_STRING="${PACKAGE_NAME} ${PACKAGE_VERSION}"
115 if [ "${RELEASE_DRY_RUN}" ]; then
116 PACKAGE_RELEASE="${PACKAGE_TARNAME}-${PACKAGE_VERSION}"
117 else
118 PACKAGE_RELEASE="${PACKAGE_TARNAME}-${RELEASE_VERSION}"
119 fi
120 }
121
122 package_info_show() {
123 cat <<INFO
124 Name: ${PACKAGE_TARNAME}
125 Release: ${RELEASE_VERSION}
126 Version: ${PACKAGE_VERSION}
127 Number: ${PACKAGE_VERSION_BASE}
128 Series: ${PACKAGE_MAJOR_AND_MINOR}
129 Major: ${PACKAGE_MAJOR}
130 Minor: ${PACKAGE_MINOR}
131 Micro: ${PACKAGE_MICRO}
132 Tags: ${PACKAGE_VERSION_TAGS}
133 Branch: ${PACKAGE_RELEASE}
134 Release: ${PACKAGE_TARNAME}-${PACKAGE_VERSION_BASE}${PACKAGE_VERSION_TAGS}
135 INFO
136 }
137
138 usage() {
139 cat << USAGE
140 usage: $0 <command>
141
142 Main Commands:
143 info Show a summary of the next pending release.
144 release Release the current tree as an archive.
145 upload Upload archives to berliOS project site
146
147 Build Commands:
148 bootstrap Prepare the working copy for configuration and building.
149 configure Configures the package; runs bootstrap, if needed.
150 build Compiles the project; runs configure, if needed.
151
152 Packaging Commands:
153 changelog Generate a new ChangeLog using svn2cl.
154 package Produce new distributable source archives.
155 stage Move archives to staging area for upload.
156
157 Repository Commands:
158 commit Perform branch and tag, as appropriate for the version.
159 branch Create a release branch from the project trunk.
160 tag Create a tag for the current release branch.
161
162 Other Commands:
163 version ... Perform version number and tag manipulations.
164 maryslamb Mary had a little lamb, but no one noticed.
165 clean Forces regeneration of results.
166 clean_all Removes all traces of the release process.
167 help Provides this list of commands.
168
169 For more information about this script, see the Release Processes page
170 in the OpenOCD Developer's Manual (doc/manual/release.txt).
171
172 WARNING: This script should be used by the Release Manager ONLY.
173 USAGE
174 exit 0
175 }
176 do_usage() { usage; }
177 do_help() { usage; }
178
179 do_info_show() {
180 echo "Current Release Analysis:"
181 package_info_show
182 svn_setup_show
183 }
184
185 do_info() {
186 package_info_load
187 svn_setup_load
188 do_info_show
189 }
190
191 do_bootstrap() {
192 echo -n "Bootstrapping..."
193 ./bootstrap 2>&1 | perl tools/logger.pl > "release-bootstrap.log"
194 }
195 maybe_bootstrap() { [ -f "configure" ] || do_bootstrap; }
196
197 do_configure() {
198 maybe_bootstrap
199 echo -n "Configuring..."
200 ./configure ${CONFIG_OPTS} 2>&1 | perl tools/logger.pl > "release-config.log"
201 }
202 maybe_configure() { [ -f "Makefile" ] || do_configure; }
203
204 do_build() {
205 maybe_configure
206 echo -n "Compiling OpenOCD ${PACKAGE_VERSION}"
207 make ${MAKE_OPTS} -C doc stamp-vti 2>&1 \
208 | perl tools/logger.pl > "release-version.log"
209 make ${MAKE_OPTS} 2>&1 \
210 | perl tools/logger.pl > "release-make.log"
211 }
212 maybe_build() { [ -f "src/openocd" ] || do_build; }
213 do_build_clean() { [ -f Makefile ] && make maintainer-clean >/dev/null; }
214
215 do_changelog() {
216 echo "Updating working copy to HEAD..."
217 do_svn update
218 echo "Creating ChangeLog..."
219 svn2cl -i --authors AUTHORS.ChangeLog
220 }
221 maybe_changelog() {
222 if [ -z "${RELEASE_DRY_RUN}" ] \
223 || [ ! -f ChangeLog ] \
224 || [ "$(cat ChangeLog | wc -l)" -lt 2 ]
225 then
226 do_changelog
227 fi
228 }
229 do_changelog_clean() {
230 do_svn revert ChangeLog
231 }
232
233 do_package() {
234 package_info_load
235 maybe_changelog
236 maybe_build
237 echo "Building distribution packages..."
238 make ${MAKE_OPTS} distcheck 2>&1 | perl tools/logger.pl > "release-pkg.log"
239 }
240 maybe_package() { [ -f "${PACKAGE_RELEASE}.zip" ] || do_package; }
241 do_package_clean() {
242 for EXT in tar.gz tar.bz2 zip; do
243 rm -v -f *.${EXT}
244 done
245 }
246
247 do_stage() {
248 maybe_package
249 echo "Staging package archives:"
250 mkdir -p archives
251 for EXT in tar.gz tar.bz2 zip; do
252 local FILE="${PACKAGE_RELEASE}.${EXT}"
253 # create archive signatures
254 for HASH in md5 sha1; do
255 echo "sign: ${FILE}.${HASH}"
256 ${HASH}sum "${FILE}" > "archives/${FILE}.${HASH}"
257 done
258 # save archive
259 mv -v "${FILE}" archives/
260 done
261 cp -a NEWS archives/
262 cp -a ChangeLog archives/
263 }
264 do_stage_clean() { rm -v -f -r archives; }
265
266 do_clean() {
267 do_build_clean
268 do_package_clean
269 rm -v -f configure
270
271 svn revert configure.in
272 rm -v -f release-*.log
273 }
274 do_clean_all() {
275 do_clean
276 do_changelog_clean
277 do_stage_clean
278 }
279
280 do_version_usage() {
281 cat << USAGE
282 usage: $0 version <command>
283 Version Commands:
284 tag {add|remove} <label> Add or remove the specified tag.
285 bump {major|minor|micro|rc} Bump the specified version number;
286 resets less-significant numbers to zero.
287 All but 'rc' releases drop that tag.
288 USAGE
289 }
290
291 do_version_sed() {
292 local OLD_VERSION="${PACKAGE_VERSION}"
293 local NEW_VERSION="$1"
294 local MSG="$2"
295
296 sed -i -e "/AC_INIT/ s|${OLD_VERSION}|${NEW_VERSION}|" configure.in
297 package_info_load
298 echo "${MSG}: ${OLD_VERSION} -> ${NEW_VERSION}"
299 }
300 do_version_bump_sed() {
301 local NEW_VERSION="$1"
302 [ -z "${PACKAGE_VERSION_TAGS}" ] || \
303 NEW_VERSION="${NEW_VERSION}${PACKAGE_VERSION_TAGS}"
304
305 do_version_sed "${NEW_VERSION}" \
306 "Bump ${CMD} package version number"
307 }
308 do_version_bump_major() {
309 do_version_bump_sed "$((PACKAGE_MAJOR + 1)).0.0"
310 }
311 do_version_bump_minor() {
312 do_version_bump_sed "${PACKAGE_MAJOR}.$((PACKAGE_MINOR + 1)).0"
313 }
314 do_version_bump_micro() {
315 do_version_bump_sed "${PACKAGE_MAJOR_AND_MINOR}.$((PACKAGE_MICRO + 1))"
316 }
317 do_version_bump_tag() {
318 local TAG="$1"
319 [ "${TAG}" ] || die "TAG argument is missing"
320 local TAGS="${PACKAGE_VERSION_TAGS}"
321 if has_version_tag "${TAG}"; then
322 local RC=$(echo ${TAGS} | perl -ne "/-${TAG}"'(\d+)/ && print $1')
323 RC=$((${RC} + 1))
324 TAGS=$(echo ${TAGS} | perl -npe "s/-${TAG}[\\d]*/-${TAG}${RC}/")
325 else
326 TAGS="-${TAG}1${PACKAGE_VERSION_TAGS}"
327 fi
328 PACKAGE_VERSION_TAGS="${TAGS}"
329 do_version_bump_sed "${PACKAGE_VERSION_BASE}"
330 }
331 do_version_bump_rc() { do_version_bump_tag 'rc'; }
332 do_version_bump() {
333 CMD="$1"
334 shift
335 case "${CMD}" in
336 major|minor|micro|rc|tag)
337 eval "do_version_bump_${CMD}" "$@"
338 ;;
339 *)
340 do_version_usage
341 ;;
342 esac
343 }
344
345 has_version_tag() {
346 test "${PACKAGE_VERSION/-${1}/}" != "${PACKAGE_VERSION}"
347 }
348
349 do_version_tag_add() {
350 local TAG="$1"
351 has_version_tag "${TAG}" && \
352 die "error: tag '-${TAG}' exists in '${PACKAGE_VERSION}'"
353 do_version_sed "${PACKAGE_VERSION}-${TAG}" \
354 "Add '-${TAG}' version tag"
355 }
356 do_version_tag_remove() {
357 local TAG="$1"
358 has_version_tag "${TAG}" || \
359 die "error: tag '-${TAG}' missing from '${PACKAGE_VERSION}'"
360 do_version_sed "${PACKAGE_VERSION/-${TAG}/}" \
361 "Remove '-${TAG}' version tag"
362 }
363 do_version_tag() {
364 CMD="$1"
365 shift
366 case "${CMD}" in
367 add|remove)
368 local i=
369 for i in "$@"; do
370 eval "do_version_tag_${CMD}" "${i}"
371 done
372 ;;
373 *)
374 do_version_usage
375 ;;
376 esac
377 }
378
379 do_version_commit() {
380 [ "$(svn diff configure.in | wc -l)" -gt 0 ] || \
381 die "error: no version changes to commit"
382 do_svn commit -m "$1" configure.in
383 }
384
385 do_version() {
386 package_info_load
387 CMD="$1"
388 shift
389 case "${CMD}" in
390 tag|bump)
391 do_version_commit "$(eval "do_version_${CMD}" "$@")"
392 ;;
393 commit)
394 local MSG="$1"
395 [ "${MSG}" ] || die "usage: $0 version commit <message>"
396 do_version_commit "${MSG}"
397 ;;
398 *)
399 do_version_usage
400 ;;
401 esac
402 }
403
404
405 do_branch() {
406 package_info_load
407 svn_setup_load
408 do_svn copy -m "Branching version ${PACKAGE_VERSION}" \
409 "${SVN_TRUNK}" "${PACKAGE_BRANCH}"
410 }
411 do_tag() {
412 package_info_load
413 svn_setup_load
414 do_svn copy -m "Tagging version ${PACKAGE_VERSION}" \
415 "${PACKAGE_BRANCH}" "${PACKAGE_TAG}"
416 }
417 do_commit() {
418 package_info_load
419 svn_setup_load
420
421 [ "${PACKAGE_VERSION/in-development/}" = "${PACKAGE_VERSION}" ] || \
422 die "'${PACKAGE_NAME}-${PACKAGE_VERSION}' cannot be released"
423
424 [ "${PACKAGE_VERSION%.0}" = "${PACKAGE_VERSION}" ] || \
425 do_branch
426 do_tag
427 }
428
429
430 do_release_step_prep() {
431 do_version tag remove in-development
432 # reset RELEASE_VERSION now to allow release version to be detected
433 export RELEASE_VERSION=
434 }
435 do_release_step_commit() { do_commit; }
436
437 do_release_step_branch_bump() {
438 local TYPE="$1"
439 echo "Bump ${TYPE} version and add tag:"
440 do_version_bump ${TYPE}
441 do_version_tag_add in-development
442 }
443 do_release_step_branch() {
444 do_svn_switch "${PACKAGE_BRANCH}"
445 do_version_commit "$(do_release_step_branch_bump micro)"
446 do_svn_switch "${SVN_URL}"
447 }
448 do_release_step_news_msg() {
449 cat <<MSG
450 Archive released NEWS file: NEWS -> NEWS-${RELEASE_VERSION}
451 Create new NEWS file from relesse script template.
452 MSG
453 }
454 do_release_step_news() {
455 # archive NEWS and create new one from template
456 do_svn move "NEWS" "NEWS-${RELEASE_VERSION}"
457
458 [ "${RELEASE_DRY_RUN}" ] || cat >NEWS <<NEWS
459 This file should include items worth mentioning in the
460 OpenOCD ${PACKAGE_RELEASE} source archive release.
461
462 The following areas of OpenOCD functionality changed in this release:
463
464 JTAG Layer:
465 Target Layer:
466 Flash Layer:
467 Board, Target, and Interface Configuration Scripts:
468 Documentation:
469 Build and Release:
470
471 For more details about what has changed since the last release,
472 see the ChangeLog associated with this source archive. For older NEWS,
473 see the NEWS files associated with each release (i.e. NEWS-<version>).
474
475 For more information about contributing test reports, bug fixes, or new
476 features and device support, please read the new Developer Manual (or
477 the BUGS and PATCHES files in the source archive).
478 NEWS
479 do_svn add NEWS
480
481 local MSG="$(do_release_step_news_msg)"
482 do_svn commit -m "${MSG}" NEWS NEWS-${RELEASE_VERSION}
483 }
484 do_release_step_bump() {
485 # major and minor releases require branch version update too
486 [ "${RELEASE_TYPE}" = "micro" ] || do_release_step_branch
487 # bump the current tree version as required.
488 do_version_commit "$(do_release_step_branch_bump "${RELEASE_TYPE}")"
489
490 [ "${RELEASE_TYPE}" = "micro" ] || do_release_step_news
491 }
492 do_release_step_package() {
493 local A=${PACKAGE_TAG}
494 local B=${A/https/http}
495 local PACKAGE_BUILD=${B/${USER}@/}
496
497 do_svn_switch "${PACKAGE_TAG}"
498 do_svn_switch --relocate "${PACKAGE_TAG}" "${PACKAGE_BUILD}"
499
500 # required to force SVN to update the in-source URL keyword
501 [ "${RELEASE_DRY_RUN}" ] || rm -v -f src/openocd.c
502 do_svn revert src/openocd.c
503
504 do_stage
505 do_clean
506
507 do_svn_switch --relocate "${PACKAGE_BUILD}" "${PACKAGE_TAG}"
508 do_svn_switch "${SVN_URL}"
509 }
510
511 do_release_step_1() { do_release_step_prep; }
512 do_release_step_2() { do_release_step_commit; }
513 do_release_step_3() { do_release_step_bump; }
514 do_release_step_4() { do_release_step_package; }
515
516 do_release_check() {
517 echo -n "Are you sure you want to release '${PACKAGE_RELEASE}'?"
518 read ANSWER
519 if [ "${ANSWER}" != 'y' ]; then
520 echo "Live release aborted!"
521 exit 0
522 fi
523 }
524 do_countdown() {
525 echo -n "$1 in "
526 for i in $(seq 5 -1 1); do
527 echo -n "$i, "
528 done
529 echo "go!"
530 }
531
532 do_release() {
533 package_info_load
534 package_info_show
535
536 if [ -z "${RELEASE_DRY_RUN}" ]; then
537 do_release_check
538 do_countdown "Starting live release"
539 fi
540
541 local i=
542 for i in $(seq 1 4); do
543 eval "do_release_step_${i}"
544 done
545 }
546 do_all() { do_release "$@"; }
547
548 do_reset() {
549 maybe_bootstrap
550 maybe_configure
551 do_clean_all
552 svn revert configure.in
553 }
554
555 OPTIONS=$(getopt -o V --long live -n $0 -- "$@")
556 if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi
557 eval set -- "${OPTIONS}"
558 while true; do
559 case "$1" in
560 --live)
561 export RELEASE_DRY_RUN=
562 shift
563 ;;
564 -V)
565 exec $0 info
566 ;;
567 --)
568 shift
569 break
570 ;;
571 *)
572 echo "Internal error"
573 exit 1
574 ;;
575 esac
576 done
577
578 CMD=$1
579 [ "${CMD}" ] || usage
580 shift
581
582 ACTION_CMDS="bootstrap|configure|build|changelog|package|stage|clean"
583 MISC_CMDS="all|info|version|tag|branch|commit|release|reset|help|usage"
584 CLEAN_CMDS="build_clean|changelog_clean|package_clean|stage_clean|clean_all"
585 CMDS="|${ACTION_CMDS}|${CLEAN_CMDS}|${MISC_CMDS}|"
586 is_command() { echo "${CMDS}" | grep "|$1|" >/dev/null; }
587
588 if is_command "${CMD}"; then
589 eval "do_${CMD}" "$@"
590 else
591 echo "error: unknown command: '${CMD}'"
592 usage
593 fi

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)