2 # Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
4 # Licensed under the Apache License 2.0 (the "License"). You may not use
5 # this file except in compliance with the License. You can obtain a copy
6 # in the file LICENSE in the source distribution or at
7 # https://www.openssl.org/source/license.html
9 # This is the most shell agnostic way to specify that POSIX rules.
14 Usage: release.sh [ options ... ]
16 --alpha Start or increase the "alpha" pre-release tag.
17 --next-beta Switch to the "beta" pre-release tag after alpha release.
18 It can only be given with --alpha.
19 --beta Start or increase the "beta" pre-release tag.
20 --final Get out of "alpha" or "beta" and make a final release.
23 --branch Create a release branch 'openssl-{major}.{minor}.x',
24 where '{major}' and '{minor}' are the major and minor
28 For the purpose of signing tags and tar files, use this
29 key (default: use the default e-mail address’ key).
31 --no-upload Don't upload to upload@dev.openssl.org.
32 --no-update Don't perform 'make update'.
33 --verbose Verbose output.
34 --debug Include debug output. Implies --no-upload.
36 --force Force execution
41 If none of --alpha, --beta, or --final are given, this script tries to
42 figure out the next step.
47 # Set to one of 'major', 'minor', 'alpha', 'beta' or 'final'
69 upload_address=upload@dev.openssl.org
71 TEMP=$(getopt -l 'alpha,next-beta,beta,final' \
73 -l 'no-upload,no-update' \
78 -n release.sh -- - "$@")
82 --alpha | --beta | --final )
83 next_method=$(echo "x$1" | sed -e 's|^x--||')
84 if [ -z "$next_method2" ]; then
85 next_method2=$next_method
88 if [ "$next_method" = 'final' ]; then
93 next_method2=$(echo "x$1" | sed -e 's|^x--next-||')
134 sed -e '1,/^### BEGIN MANUAL/d' \
135 -e '/^### END MANUAL/,$d' \
146 echo >&2 "Unknown option $1"
153 $DEBUG >&2 "DEBUG: \$next_method=$next_method"
154 $DEBUG >&2 "DEBUG: \$next_method2=$next_method2"
156 $DEBUG >&2 "DEBUG: \$do_branch=$do_branch"
158 $DEBUG >&2 "DEBUG: \$do_upload=$do_upload"
159 $DEBUG >&2 "DEBUG: \$do_update=$do_update"
160 $DEBUG >&2 "DEBUG: \$DEBUG=$DEBUG"
161 $DEBUG >&2 "DEBUG: \$VERBOSE=$VERBOSE"
162 $DEBUG >&2 "DEBUG: \$git_quiet=$git_quiet"
164 case "$next_method+$next_method2" in
165 major+major | minor+minor )
168 alpha+alpha | alpha+beta | beta+beta | final+final | + | +beta )
172 echo >&2 "Internal option error ($next_method, $next_method2)"
177 # Verbosity feed for certain commands
178 VERBOSITY_FIFO=/tmp/openssl-$$.fifo
179 mkfifo -m 600 $VERBOSITY_FIFO
180 ( cat $VERBOSITY_FIFO | while read L; do $VERBOSE "> $L"; done ) &
181 exec 42>$VERBOSITY_FIFO
182 trap "exec 42>&-; rm $VERBOSITY_FIFO" 0 2
184 # Setup ##############################################################
186 # Make sure we're in the work directory
190 # Check that we have the scripts that define functions we use
192 for fn in "$HERE/dev/release-aux/release-version-fn.sh" \
193 "$HERE/dev/release-aux/release-state-fn.sh"; do
194 if ! [ -f "$fn" ]; then
195 echo >&2 "'$fn' is missing"
203 # Load version functions
204 . $HERE/dev/release-aux/release-version-fn.sh
205 . $HERE/dev/release-aux/release-state-fn.sh
207 # Make sure it's a branch we recognise
208 orig_branch=$(git rev-parse --abbrev-ref HEAD)
209 if (echo "$orig_branch" \
212 -e '^OpenSSL_[0-9]+_[0-9]+_[0-9]+[a-z]*-stable$' \
213 -e '^openssl-[0-9]+\.[0-9]+\.x$'); then
218 echo >&2 "Not in master or any recognised release branch"
219 echo >&2 "Please 'git checkout' an approprite branch"
223 # Initialize #########################################################
225 echo "== Initializing work tree"
229 # Generate a cloned directory name
230 clone_branch="openssl-$SERIES.x"
231 release_clone="$clone_branch-release-tmp"
233 echo "== Work tree will be in $release_clone"
235 # Make a clone in a subdirectory and move there
236 if ! [ -d "$release_clone" ]; then
237 $VERBOSE "== Cloning to $release_clone"
238 git clone $git_quiet -b "$orig_branch" . "$release_clone"
244 current_branch="$(git rev-parse --abbrev-ref HEAD)"
245 new_branch="openssl-$SERIES.x"
247 # Check that we're still on the same branch, or on a release branch
248 if [ "$current_branch" = "$orig_branch" ]; then
250 elif [ "$current_branch" = "$new_branch" ]; then
253 echo >&2 "The cloned sub-directory '$release_clone' is on a branch"
254 echo >&2 "other than '$current_branch' or '$new_branch'"
255 echo >&2 "Please 'cd \"$(pwd)\"; git checkout $current_branch'"
260 if [ "$current_branch" = "$new_branch" ]; then
263 if ! $do_branch && $warn_branch; then
264 echo >&2 "Warning: --branch ignored, we're already in a release branch"
269 $DEBUG >&2 "DEBUG: Source directory is $SOURCEDIR"
271 # Release ############################################################
273 # We always expect to start from a state of development
274 if [ "$TYPE" != 'dev' ]; then
275 echo >&2 "Not in a development branch"
276 echo >&2 "Have a look at the git log in $release_clone, it may be that"
277 echo >&2 "a previous crash left it in an intermediate state and that"
278 echo >&2 "need to drop the top commit:"
280 echo >&2 "(cd $release_clone; git reset --hard HEAD^)"
281 echo >&2 "# WARNING! LOOK BEFORE YOU ACT"
285 # We only create a release branch if the patch number is zero
286 if [ $PATCH -ne 0 ]; then
288 echo >&2 "Warning! We're already in a release branch; --branch ignored"
293 # Update the version information. This won't save anything anywhere, yet,
294 # but does check for possible next_method errors before we do bigger work.
295 next_release_state "$next_method"
298 $VERBOSE "== Creating a release branch: $new_branch"
299 git checkout $git_quiet -b "$new_branch"
302 echo "== Configuring OpenSSL for update and release. This may take a bit of time"
306 $VERBOSE "== Checking source file updates"
310 if [ -n "$(git status --porcelain)" ]; then
311 $VERBOSE "== Committing updates"
313 git commit $git_quiet -m 'make update'
316 # Write the version information we updated
319 if [ -n "$PRE_LABEL" ]; then
320 release="$VERSION-$PRE_RELEASE_TAG$BUILD_METADATA"
321 release_text="$SERIES$BUILD_METADATA $PRE_LABEL $PRE_NUM"
322 announce_template=openssl-announce-pre-release.tmpl
324 release="$VERSION$BUILD_METADATA"
325 release_text="$release"
326 announce_template=openssl-announce-release.tmpl
328 tag="openssl-$release"
329 $VERBOSE "== Updated version information to $release"
331 $VERBOSE "== Updating files with release date for $release : $RELEASE_DATE"
332 for fixup in "$HERE/dev/release-aux"/fixup-*-release.pl; do
333 file="$(basename "$fixup" | sed -e 's|^fixup-||' -e 's|-release\.pl$||')"
335 RELEASE="$release" RELEASE_TEXT="$release_text" RELEASE_DATE="$RELEASE_DATE" \
336 perl -pi $fixup $file
339 $VERBOSE "== Comitting updates and tagging"
341 git commit $git_quiet -m "Prepare for release of $release_text"
342 echo "Tagging release with tag $tag. You may need to enter a pass phrase"
343 git tag$tagkey "$tag" -m "OpenSSL $release release tag"
345 tarfile=openssl-$release.tar
347 announce=openssl-$release.txt
349 echo "== Generating tar, hash and announcement files. This make take a bit of time"
351 $VERBOSE "== Making tarfile: $tgzfile"
352 # Unfortunately, util/mktar.sh does verbose output on STDERR... for good
353 # reason, but it means we don't display errors unless --verbose
354 ./util/mktar.sh --tarfile="../$tarfile" 2>&1 \
355 | while read L; do $VERBOSE "> $L"; done
357 if ! [ -f "../$tgzfile" ]; then
358 echo >&2 "Where did the tarball end up? (../$tgzfile)"
362 $VERBOSE "== Generating checksums: $tgzfile.sha1 $tgzfile.sha256"
363 openssl sha1 < "../$tgzfile" | \
364 (IFS='='; while read X H; do echo $H; done) > "../$tgzfile.sha1"
365 openssl sha256 < "../$tgzfile" | \
366 (IFS='='; while read X H; do echo $H; done) > "../$tgzfile.sha256"
367 length=$(wc -c < "../$tgzfile")
368 sha1hash=$(cat "../$tgzfile.sha1")
369 sha256hash=$(cat "../$tgzfile.sha256")
371 $VERBOSE "== Generating announcement text: $announce"
372 # Hack the announcement template
373 cat "$HERE/dev/release-aux/$announce_template" \
374 | sed -e "s|\\\$release_text|$release_text|g" \
375 -e "s|\\\$release|$release|g" \
376 -e "s|\\\$series|$SERIES|g" \
377 -e "s|\\\$label|$PRE_LABEL|g" \
378 -e "s|\\\$tarfile|$tgzfile|" \
379 -e "s|\\\$length|$length|" \
380 -e "s|\\\$sha1hash|$sha1hash|" \
381 -e "s|\\\$sha256hash|$sha256hash|" \
382 | perl -p "$HERE/dev/release-aux/fix-title.pl" \
385 $VERBOSE "== Generating signatures: $tgzfile.asc $announce.asc"
386 rm -f "../$tgzfile.asc" "../$announce.asc"
387 echo "Signing the release files. You may need to enter a pass phrase"
388 gpg$gpgkey --use-agent -sba "../$tgzfile"
389 gpg$gpgkey --use-agent -sta --clearsign "../$announce"
391 # We finish off by resetting all files, so we don't have to update
392 # files with release dates again
393 $VERBOSE "== Reset all files to their pre-commit contents"
394 git reset $git_quiet HEAD^ -- .
399 if [ "$VERBOSE" != ':' ]; then
402 echo "put ../$tgzfile"
403 echo "put ../$tgzfile.sha1"
404 echo "put ../$tgzfile.sha256"
405 echo "put ../$tgzfile.asc"
406 echo "put ../$announce.asc"
408 | sftp "$upload_address"
411 # Post-release #######################################################
413 prev_release_text="$release_text"
414 prev_release_date="$RELEASE_DATE"
416 next_release_state "$next_method2"
419 release="$VERSION-$PRE_RELEASE_TAG$BUILD_METADATA"
420 release_text="$VERSION$BUILD_METADATA"
421 if [ -n "$PRE_LABEL" ]; then
422 release_text="$SERIES$BUILD_METADATA $PRE_LABEL $PRE_NUM"
424 $VERBOSE "== Updated version information to $release"
426 $VERBOSE "== Updating files for $release :"
427 for fixup in "$HERE/dev/release-aux"/fixup-*-postrelease.pl; do
428 file="$(basename "$fixup" | sed -e 's|^fixup-||' -e 's|-postrelease\.pl$||')"
430 RELEASE="$release" RELEASE_TEXT="$release_text" \
431 PREV_RELEASE_TEXT="$prev_release_text" \
432 PREV_RELEASE_DATE="$prev_release_date" \
433 perl -pi $fixup $file
436 $VERBOSE "== Comitting updates"
438 git commit $git_quiet -m "Prepare for $release_text"
441 $VERBOSE "== Going back to the main branch $current_branch"
442 git checkout $git_quiet "$current_branch"
445 next_release_state "minor"
448 release="$VERSION-$PRE_RELEASE_TAG$BUILD_METADATA"
449 release_text="$SERIES$BUILD_METADATA"
450 $VERBOSE "== Updated version information to $release"
452 $VERBOSE "== Updating files for $release :"
453 for fixup in "$HERE/dev/release-aux"/fixup-*-postrelease.pl; do
454 file="$(basename "$fixup" | sed -e 's|^fixup-||' -e 's|-postrelease\.pl$||')"
456 RELEASE="$release" RELEASE_TEXT="$release_text" \
457 perl -pi $fixup $file
460 $VERBOSE "== Comitting updates"
462 git commit $git_quiet -m "Prepare for $release_text"
465 # Done ###############################################################
471 ======================================================================
472 The release is done, and involves a few commits for you to deal with.
473 It has all been done in a clone of this workspace, see details below.
477 Additionally, a release branch has been created for you, so you need
478 to look for new commits in two places.
485 These files were uploaded to $upload_address:
497 Release worktree: $release_clone
499 if [ "$current_branch" != "$new_branch" ]; then
501 Current branch: $current_branch
506 New release branch: $new_branch
511 ======================================================================
515 If something went wrong and you want to start over, all you need is to
516 remove the release worktree:
518 rm -rf $release_clone
520 If a tarball was uploaded, you must also clean that away, or ask you
521 kind OpenSSL sysadmin to do so.
526 # cat is inconsequential, it's only there to fend off zealous shell parsers
527 # that parse all the way here.
534 release.sh - OpenSSL release script
545 B<--local-user>=I<keyid> |
556 B<release.sh> creates an OpenSSL release, given current worktree conditions.
557 It will refuse to work unless the current branch is C<master> or a release
558 branch (see L</RELEASE BRANCHES AND TAGS> below for a discussion on those).
560 B<release.sh> tries to be smart and figure out the next release if no hints
561 are given through options, and will exit with an error in ambiguous cases.
563 B<release.sh> always clones the current workspace into a sub-directory
564 named C<< openssl-I<SERIES>-tmp >>, where C<< I<SERIES> >> is taken from
565 the available version information in the source.
571 =item B<--alpha>, B<--beta>
573 Set the state of this branch to indicate that alpha or beta releases are
576 B<--alpha> is only acceptable if the I<PATCH> version number is zero and
577 the current state is "in development" or that alpha releases are ongoing.
579 B<--beta> is only acceptable if the I<PATCH> version number is zero and
580 that alpha or beta releases are ongoing.
584 Use together with B<--alpha> to switch to beta releases after the current
589 Set the state of this branch to indicate that regular releases are to be
590 done. This is only valid if alpha or beta releases are currently ongoing.
592 This implies B<--branch>.
596 Create a branch specific for the I<SERIES>.x release series, if it doesn't
597 already exist, and switch to it. The exact branch name will be
598 C<< openssl-I<SERIES>.x >>.
602 Don't upload the produced files.
606 Don't run C<make update>.
614 Display extra debug output. Implies B<--no-upload>
616 =item B<--local-user>=I<keyid>
618 Use I<keyid> as the local user for C<git tag> and for signing with C<gpg>.
620 If not given, then the default e-mail address' key is used.
624 Force execution. Precisely, the check that the current branch is C<master>
625 or a release branch is not done.
629 Display a quick help text and exit.
633 Display this manual and exit.
637 =head1 RELEASE BRANCHES AND TAGS
639 Prior to OpenSSL 3.0, the release branches were named
640 C<< OpenSSL_I<SERIES>-stable >>, and the release tags were named
641 C<< OpenSSL_I<VERSION> >> for regular releases, or
642 C<< OpenSSL_I<VERSION>-preI<n> >> for pre-releases.
644 From OpenSSL 3.0 ongoing, the release branches are named
645 C<< openssl-I<SERIES>.x >>, and the release tags are named
646 C<< openssl-I<VERSION> >> for regular releases, or
647 C<< openssl-I<VERSION>-alphaI<n> >> for alpha releases
648 and C<< openssl-I<VERSION>-betaI<n> >> for beta releases.
650 B<release.sh> recognises both forms.
652 =head1 VERSION AND STATE
654 With OpenSSL 3.0, all the version and state information is in the file
655 F<VERSION>, where the following variables are used and changed:
659 =item B<MAJOR>, B<MINOR>, B<PATCH>
661 The three part of the version number.
663 =item B<PRE_RELEASE_TAG>
665 The indicator of the current state of the branch. The value may be one pf:
671 This branch is "in development". This is typical for the C<master> branch
672 unless there are ongoing alpha or beta releases.
674 =item C<< alphaI<n> >> or C<< alphaI<n>-dev >>
676 This branch has alpha releases going on. C<< alphaI<n>-dev >> is what
677 should normally be seen in the git workspace, indicating that
678 C<< alphaI<n> >> is in development. C<< alphaI<n> >> is what should be
679 found in the alpha release tar file.
681 =item C<< alphaI<n> >> or C<< alphaI<n>-dev >>
683 This branch has beta releases going on. The details are otherwise exactly
688 This is normally not seen in the git workspace, but should always be what's
689 found in the tar file of a regular release.
693 =item B<RELEASE_DATE>
695 This is normally empty in the git workspace, but should always have the
696 release date in the tar file of any release.
702 Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
704 Licensed under the Apache License 2.0 (the "License"). You may not use
705 this file except in compliance with the License. You can obtain a copy
706 in the file LICENSE in the source distribution or at
707 L<https://www.openssl.org/source/license.html>.