Add workaround to release script to update source code URL keyword.
[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 maybe_rebuild() {
216 if [ -f "configure" ]; then
217 echo "Re-running autoconf..."
218 autoconf
219 echo "Re-running automake..."
220 automake
221 fi
222 if [ -f "Makefile" ]; then
223 do_configure
224 do_build
225 fi
226 }
227
228 do_changelog() {
229 echo "Updating working copy to HEAD..."
230 do_svn update
231 echo "Creating ChangeLog..."
232 svn2cl -i --authors AUTHORS.ChangeLog
233 }
234 maybe_changelog() {
235 if [ -z "${RELEASE_DRY_RUN}" ] \
236 || [ ! -f ChangeLog ] \
237 || [ "$(cat ChangeLog | wc -l)" -lt 2 ]
238 then
239 do_changelog
240 fi
241 }
242 do_changelog_clean() {
243 do_svn revert ChangeLog
244 }
245
246 do_package() {
247 package_info_load
248 maybe_changelog
249 maybe_build
250 echo "Building distribution packages..."
251 make ${MAKE_OPTS} distcheck 2>&1 | perl tools/logger.pl > "release-pkg.log"
252 }
253 maybe_package() { [ -f "${PACKAGE_RELEASE}.zip" ] || do_package; }
254 do_package_clean() {
255 for EXT in tar.gz tar.bz2 zip; do
256 rm -v -f *.${EXT}
257 done
258 }
259
260 do_stage() {
261 maybe_package
262 echo "Staging package archives:"
263 mkdir -p archives
264 for EXT in tar.gz tar.bz2 zip; do
265 local FILE="${PACKAGE_RELEASE}.${EXT}"
266 # create archive signatures
267 for HASH in md5 sha1; do
268 echo "sign: ${FILE}.${HASH}"
269 ${HASH}sum "${FILE}" > "archives/${FILE}.${HASH}"
270 done
271 # save archive
272 mv -v "${FILE}" archives/
273 done
274 cp -a NEWS archives/
275 cp -a ChangeLog archives/
276 }
277 do_stage_clean() { rm -v -f -r archives; }
278
279 do_clean() {
280 do_build_clean
281 do_package_clean
282 rm -v -f configure
283
284 svn revert configure.in
285 rm -v -f release-*.log
286 }
287 do_clean_all() {
288 do_clean
289 do_changelog_clean
290 do_stage_clean
291 }
292
293 do_version_usage() {
294 cat << USAGE
295 usage: $0 version <command>
296 Version Commands:
297 tag {add|remove} <label> Add or remove the specified tag.
298 bump {major|minor|micro|rc} Bump the specified version number;
299 resets less-significant numbers to zero.
300 All but 'rc' releases drop that tag.
301 USAGE
302 }
303
304 do_version_sed() {
305 local OLD_VERSION="${PACKAGE_VERSION}"
306 local NEW_VERSION="$1"
307 local MSG="$2"
308
309 sed -i -e "/AC_INIT/ s|${OLD_VERSION}|${NEW_VERSION}|" configure.in
310 package_info_load
311 echo "${MSG}: ${OLD_VERSION} -> ${NEW_VERSION}"
312 }
313 do_version_bump_sed() {
314 local NEW_VERSION="$1"
315 [ -z "${PACKAGE_VERSION_TAGS}" ] || \
316 NEW_VERSION="${NEW_VERSION}${PACKAGE_VERSION_TAGS}"
317
318 do_version_sed "${NEW_VERSION}" \
319 "Bump ${CMD} package version number"
320 }
321 do_version_bump_major() {
322 has_version_tag 'rc\d' do_version_
323 do_version_bump_sed "$((PACKAGE_MAJOR + 1)).0.0"
324 }
325 do_version_bump_minor() {
326 do_version_bump_sed "${PACKAGE_MAJOR}.$((PACKAGE_MINOR + 1)).0"
327 }
328 do_version_bump_micro() {
329 do_version_bump_sed "${PACKAGE_MAJOR_AND_MINOR}.$((PACKAGE_MICRO + 1))"
330 }
331 do_version_bump_rc() {
332 die "patch missing: -rc support is not implemented"
333 }
334 do_version_bump() {
335 CMD="$1"
336 shift
337 case "${CMD}" in
338 major|minor|micro|rc)
339 eval "do_version_bump_${CMD}"
340 ;;
341 *)
342 do_version_usage
343 ;;
344 esac
345 }
346
347 has_version_tag() {
348 test "${PACKAGE_VERSION/-${TAG}/}" != "${PACKAGE_VERSION}"
349 }
350
351 do_version_tag_add() {
352 local TAG="$1"
353 has_version_tag && die "error: tag '-${TAG}' exists in '${PACKAGE_VERSION}'"
354 do_version_sed "${PACKAGE_VERSION}-${TAG}" \
355 "Add '-${TAG}' version tag"
356 }
357 do_version_tag_remove() {
358 local TAG="$1"
359 has_version_tag || 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 maybe_rebuild
393 ;;
394 commit)
395 local MSG="$1"
396 [ "${MSG}" ] || die "usage: $0 version commit <message>"
397 do_version_commit "${MSG}"
398 maybe_rebuild
399 ;;
400 *)
401 do_version_usage
402 ;;
403 esac
404 }
405
406
407 do_branch() {
408 package_info_load
409 svn_setup_load
410 do_svn copy -m "Branching version ${PACKAGE_VERSION}" \
411 "${SVN_TRUNK}" "${PACKAGE_BRANCH}"
412 }
413 do_tag() {
414 package_info_load
415 svn_setup_load
416 do_svn copy -m "Tagging version ${PACKAGE_VERSION}" \
417 "${PACKAGE_BRANCH}" "${PACKAGE_TAG}"
418 }
419 do_commit() {
420 package_info_load
421 svn_setup_load
422
423 [ "${PACKAGE_VERSION/in-development/}" = "${PACKAGE_VERSION}" ] || \
424 die "'${PACKAGE_NAME}-${PACKAGE_VERSION}' cannot be released"
425
426 [ "${PACKAGE_VERSION%.0}" = "${PACKAGE_VERSION}" ] || \
427 do_branch
428 do_tag
429 }
430
431
432 do_release_step_prep() {
433 do_version tag remove in-development
434 # reset RELEASE_VERSION now to allow release version to be detected
435 export RELEASE_VERSION=
436 }
437 do_release_step_commit() { do_commit; }
438
439 do_release_step_branch_bump() {
440 local TYPE="$1"
441 echo "Bump ${TYPE} version and add tag:"
442 do_version_bump ${TYPE}
443 do_version_tag_add in-development
444 }
445 do_release_step_branch() {
446 do_svn_switch "${PACKAGE_BRANCH}"
447 do_version_commit "$(do_release_step_branch_bump micro)"
448 do_svn_switch "${SVN_URL}"
449 }
450 do_release_step_news_msg() {
451 cat <<MSG
452 Archive released NEWS file: NEWS -> NEWS-${RELEASE_VERSION}
453 Create new NEWS file from relesse script template.
454 MSG
455 }
456 do_release_step_news() {
457 # archive NEWS and create new one from template
458 do_svn move "NEWS" "NEWS-${RELEASE_VERSION}"
459
460 [ "${RELEASE_DRY_RUN}" ] || cat >NEWS <<NEWS
461 This file should include items worth mentioning in the
462 OpenOCD ${PACKAGE_RELEASE} source archive release.
463
464 The following areas of OpenOCD functionality changed in this release:
465
466 JTAG Layer:
467 Target Layer:
468 Flash Layer:
469 Board, Target, and Interface Configuration Scripts:
470 Documentation:
471 Build and Release:
472
473 For more details about what has changed since the last release,
474 see the ChangeLog associated with this source archive. For older NEWS,
475 see the NEWS files associated with each release (i.e. NEWS-<version>).
476
477 For more information about contributing test reports, bug fixes, or new
478 features and device support, please read the new Developer Manual (or
479 the BUGS and PATCHES files in the source archive).
480 NEWS
481 do_svn add NEWS
482
483 local MSG="$(do_release_step_news_msg)"
484 do_svn commit -m "${MSG}" NEWS NEWS-${RELEASE_VERSION}
485 }
486 do_release_step_bump() {
487 # major and minor releases require branch version update too
488 [ "${RELEASE_TYPE}" = "micro" ] || do_release_step_branch
489 # bump the current tree version as required.
490 do_version_commit "$(do_release_step_branch_bump "${RELEASE_TYPE}")"
491
492 [ "${RELEASE_TYPE}" = "micro" ] || do_release_step_news
493 }
494 do_release_step_package() {
495 local A=${PACKAGE_TAG}
496 local B=${A/https/http}
497 local PACKAGE_BUILD=${B/${USER}@/}
498
499 do_svn_switch "${PACKAGE_TAG}"
500 do_svn_switch --relocate "${PACKAGE_TAG}" "${PACKAGE_BUILD}"
501
502 # required to force SVN to update the in-source URL keyword
503 [ "${RELEASE_DRY_RUN}" ] || rm -v -f src/openocd.c
504 do_svn revert src/openocd.c
505
506 do_stage
507 do_clean
508
509 do_svn_switch --relocate "${PACKAGE_BUILD}" "${PACKAGE_TAG}"
510 do_svn_switch "${SVN_URL}"
511 }
512
513 do_release_step_1() { do_release_step_prep; }
514 do_release_step_2() { do_release_step_commit; }
515 do_release_step_3() { do_release_step_bump; }
516 do_release_step_4() { do_release_step_package; }
517
518 do_release_check() {
519 echo -n "Are you sure you want to release '${PACKAGE_RELEASE}'?"
520 read ANSWER
521 if [ "${ANSWER}" != 'y' ]; then
522 echo "Live release aborted!"
523 exit 0
524 fi
525 }
526 do_countdown() {
527 echo -n "$1 in "
528 for i in $(seq 5 -1 1); do
529 echo -n "$i, "
530 done
531 echo "go!"
532 }
533
534 do_release() {
535 package_info_load
536 package_info_show
537
538 if [ -z "${RELEASE_DRY_RUN}" ]; then
539 do_release_check
540 do_countdown "Starting live release"
541 fi
542
543 local i=
544 for i in $(seq 1 4); do
545 eval "do_release_step_${i}"
546 done
547 }
548 do_all() { do_release "$@"; }
549
550 do_reset() {
551 maybe_bootstrap
552 maybe_configure
553 do_clean_all
554 svn revert configure.in
555 }
556
557 OPTIONS=$(getopt -o V --long live -n $0 -- "$@")
558 if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi
559 eval set -- "${OPTIONS}"
560 while true; do
561 case "$1" in
562 --live)
563 export RELEASE_DRY_RUN=
564 shift
565 ;;
566 -V)
567 exec $0 info
568 ;;
569 --)
570 shift
571 break
572 ;;
573 *)
574 echo "Internal error"
575 exit 1
576 ;;
577 esac
578 done
579
580 CMD=$1
581 [ "${CMD}" ] || usage
582 shift
583
584 ACTION_CMDS="bootstrap|configure|build|changelog|package|stage|clean"
585 MISC_CMDS="all|info|version|tag|branch|commit|release|reset|help|usage"
586 CLEAN_CMDS="build_clean|changelog_clean|package_clean|stage_clean|clean_all"
587 CMDS="|${ACTION_CMDS}|${CLEAN_CMDS}|${MISC_CMDS}|"
588 is_command() { echo "${CMDS}" | grep "|$1|" >/dev/null; }
589
590 if is_command "${CMD}"; then
591 eval "do_${CMD}" "$@"
592 else
593 echo "error: unknown command: '${CMD}'"
594 usage
595 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)