2 # Copyright 2020-2022 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.
12 # Force C locale because some commands (like date +%b) relies
13 # on the current locale.
18 Usage: release.sh [ options ... ]
20 --alpha Start or increase the "alpha" pre-release tag.
21 --next-beta Switch to the "beta" pre-release tag after alpha release.
22 It can only be given with --alpha.
23 --beta Start or increase the "beta" pre-release tag.
24 --final Get out of "alpha" or "beta" and make a final release.
27 --branch Create a release branch 'openssl-{major}.{minor}',
28 where '{major}' and '{minor}' are the major and minor
31 --reviewer=<id> The reviewer of the commits.
33 For the purpose of signing tags and tar files, use this
34 key (default: use the default e-mail address’ key).
36 --no-upload Don't upload to upload@dev.openssl.org.
37 --no-update Don't perform 'make update' and 'make update-fips-checksums'.
38 --verbose Verbose output.
39 --debug Include debug output. Implies --no-upload.
41 --force Force execution
46 If none of --alpha, --beta, or --final are given, this script tries to
47 figure out the next step.
52 # Set to one of 'major', 'minor', 'alpha', 'beta' or 'final'
75 upload_address
=upload@dev.openssl.org
77 TEMP
=$
(getopt
-l 'alpha,next-beta,beta,final' \
79 -l 'no-upload,no-update' \
85 -n release.sh
-- - "$@")
89 --alpha |
--beta |
--final )
90 next_method
=$
(echo "x$1" |
sed -e 's|^x--||')
91 if [ -z "$next_method2" ]; then
92 next_method2
=$next_method
95 if [ "$next_method" = 'final' ]; then
100 next_method2
=$
(echo "x$1" |
sed -e 's|^x--next-||')
133 reviewers
="$reviewers $1=$2"
146 sed -e '1,/^### BEGIN MANUAL/d' \
147 -e '/^### END MANUAL/,$d' \
158 echo >&2 "Unknown option $1"
165 $DEBUG >&2 "DEBUG: \$next_method=$next_method"
166 $DEBUG >&2 "DEBUG: \$next_method2=$next_method2"
168 $DEBUG >&2 "DEBUG: \$do_branch=$do_branch"
170 $DEBUG >&2 "DEBUG: \$do_upload=$do_upload"
171 $DEBUG >&2 "DEBUG: \$do_update=$do_update"
172 $DEBUG >&2 "DEBUG: \$DEBUG=$DEBUG"
173 $DEBUG >&2 "DEBUG: \$VERBOSE=$VERBOSE"
174 $DEBUG >&2 "DEBUG: \$git_quiet=$git_quiet"
176 case "$next_method+$next_method2" in
177 major
+major | minor
+minor
)
180 alpha
+alpha | alpha
+beta | beta
+beta | final
+final |
+ |
+beta
)
184 echo >&2 "Internal option error ($next_method, $next_method2)"
189 # Verbosity feed for certain commands
190 VERBOSITY_FIFO
=/tmp
/openssl-$$.fifo
191 mkfifo -m 600 $VERBOSITY_FIFO
192 ( cat $VERBOSITY_FIFO |
while read L
; do $VERBOSE "> $L"; done ) &
193 exec 42>$VERBOSITY_FIFO
194 trap "exec 42>&-; rm $VERBOSITY_FIFO" 0 2
196 # Setup ##############################################################
198 # Make sure we're in the work directory
202 # Check that we have the scripts that define functions we use
204 for fn
in "$HERE/dev/release-aux/release-version-fn.sh" \
205 "$HERE/dev/release-aux/release-state-fn.sh"; do
206 if ! [ -f "$fn" ]; then
207 echo >&2 "'$fn' is missing"
215 # Load version functions
216 .
$HERE/dev
/release-aux
/release-version-fn.sh
217 .
$HERE/dev
/release-aux
/release-state-fn.sh
219 # Make sure it's a branch we recognise
220 orig_branch
=$
(git rev-parse
--abbrev-ref HEAD
)
221 if (echo "$orig_branch" \
224 -e '^OpenSSL_[0-9]+_[0-9]+_[0-9]+[a-z]*-stable$' \
225 -e '^openssl-[0-9]+\.[0-9]+$'); then
230 echo >&2 "Not in master or any recognised release branch"
231 echo >&2 "Please 'git checkout' an appropriate branch"
234 orig_HEAD
=$
(git rev-parse HEAD
)
236 # Initialize #########################################################
238 echo "== Initializing work tree"
242 # Generate a cloned directory name
243 release_clone
="$orig_branch-release-tmp"
245 echo "== Work tree will be in $release_clone"
247 # Make a clone in a subdirectory and move there
248 if ! [ -d "$release_clone" ]; then
249 $VERBOSE "== Cloning to $release_clone"
250 git clone
$git_quiet -b "$orig_branch" -o parent .
"$release_clone"
256 # Branches we will work with. The release branch is where we make the
257 # changes for the release, the update branch is where we make the post-
259 update_branch
="$orig_branch"
260 release_branch
="openssl-$SERIES"
262 # among others, we only create a release branch if the patch number is zero
263 if [ "$update_branch" = "$release_branch" ] ||
[ $PATCH -ne 0 ]; then
264 if $do_branch && $warn_branch; then
265 echo >&2 "Warning! We're already in a release branch; --branch ignored"
270 if ! $do_branch; then
271 release_branch
="$update_branch"
274 # Branches we create for PRs
275 branch_version
="$VERSION${PRE_LABEL:+-$PRE_LABEL$PRE_NUM}"
276 tmp_update_branch
="OSSL--$update_branch--$branch_version"
277 tmp_release_branch
="OSSL--$release_branch--$branch_version"
279 # Check that we're still on the same branch as our parent repo, or on a
281 current_branch
=$
(git rev-parse
--abbrev-ref HEAD
)
282 if [ "$current_branch" = "$update_branch" ]; then
284 elif [ "$current_branch" = "$release_branch" ]; then
287 echo >&2 "The cloned sub-directory '$release_clone' is on a branch"
288 if [ "$update_branch" = "$release_branch" ]; then
289 echo >&2 "other than '$update_branch'."
291 echo >&2 "other than '$update_branch' or '$release_branch'."
293 echo >&2 "Please 'cd \"$(pwd)\"; git checkout $update_branch'"
298 $DEBUG >&2 "DEBUG: Source directory is $SOURCEDIR"
300 # Release ############################################################
302 # We always expect to start from a state of development
303 if [ "$TYPE" != 'dev' ]; then
304 echo >&2 "Not in a development branch"
305 echo >&2 "Have a look at the git log in $release_clone, it may be that"
306 echo >&2 "a previous crash left it in an intermediate state and that"
307 echo >&2 "need to drop the top commit:"
309 echo >&2 "(cd $release_clone; git reset --hard HEAD^)"
310 echo >&2 "# WARNING! LOOK BEFORE YOU ACT"
314 # Update the version information. This won't save anything anywhere, yet,
315 # but does check for possible next_method errors before we do bigger work.
316 next_release_state
"$next_method"
318 # Create our temporary release branch
319 $VERBOSE "== Creating a local release branch: $tmp_release_branch"
320 git checkout
$git_quiet -b "$tmp_release_branch"
322 echo "== Configuring OpenSSL for update and release. This may take a bit of time"
326 $VERBOSE "== Checking source file updates and fips checksums"
329 # As long as we're doing an alpha release, we can have symbols without specific
330 # numbers assigned. In a beta or final release, all symbols MUST have an
332 if [ "$next_method" != 'alpha' ]; then
335 make update-fips-checksums
>&42
337 if [ -n "$(git status --porcelain)" ]; then
338 $VERBOSE "== Committing updates"
340 git commit
$git_quiet -m $
'make update\n\nRelease: yes'
341 if [ -n "$reviewers" ]; then
342 addrev
--release --nopr $reviewers
346 # Create our temporary update branch, if it's not the release branch.
347 # This is used in post-release below
349 $VERBOSE "== Creating a local update branch: $tmp_update_branch"
350 git branch
$git_quiet "$tmp_update_branch"
353 # Write the version information we updated
356 if [ -n "$PRE_LABEL" ]; then
357 release
="$VERSION-$PRE_RELEASE_TAG$BUILD_METADATA"
358 release_text
="$SERIES$BUILD_METADATA $PRE_LABEL $PRE_NUM"
359 announce_template
=openssl-announce-pre-release.tmpl
361 release
="$VERSION$BUILD_METADATA"
362 release_text
="$release"
363 announce_template
=openssl-announce-release.tmpl
365 tag
="openssl-$release"
366 $VERBOSE "== Updated version information to $release"
368 $VERBOSE "== Updating files with release date for $release : $RELEASE_DATE"
369 for fixup
in "$HERE/dev/release-aux"/fixup-
*-release.pl
; do
370 file="$(basename "$fixup" | sed -e 's|^fixup-||' -e 's|-release\.pl$||')"
372 RELEASE
="$release" RELEASE_TEXT
="$release_text" RELEASE_DATE
="$RELEASE_DATE" \
373 perl
-pi $fixup $file
376 $VERBOSE "== Committing updates and tagging"
378 git commit
$git_quiet -m "Prepare for release of $release_text"$
'\n\nRelease: yes'
379 if [ -n "$reviewers" ]; then
380 addrev
--release --nopr $reviewers
382 echo "Tagging release with tag $tag. You may need to enter a pass phrase"
383 git tag
$tagkey "$tag" -m "OpenSSL $release release tag"
385 tarfile
=openssl-
$release.
tar
387 announce
=openssl-
$release.txt
389 echo "== Generating tar, hash and announcement files. This make take a bit of time"
391 $VERBOSE "== Making tarfile: $tgzfile"
392 # Unfortunately, util/mktar.sh does verbose output on STDERR... for good
393 # reason, but it means we don't display errors unless --verbose
394 .
/util
/mktar.sh
--tarfile="../$tarfile" 2>&1 \
395 |
while read L
; do $VERBOSE "> $L"; done
397 if ! [ -f "../$tgzfile" ]; then
398 echo >&2 "Where did the tarball end up? (../$tgzfile)"
402 $VERBOSE "== Generating checksums: $tgzfile.sha1 $tgzfile.sha256"
403 openssl sha1
< "../$tgzfile" | \
404 (IFS
='='; while read X H
; do echo $H; done) > "../$tgzfile.sha1"
405 openssl sha256
< "../$tgzfile" | \
406 (IFS
='='; while read X H
; do echo $H; done) > "../$tgzfile.sha256"
407 length
=$
(wc -c < "../$tgzfile")
408 sha1hash
=$
(cat "../$tgzfile.sha1")
409 sha256hash
=$
(cat "../$tgzfile.sha256")
411 $VERBOSE "== Generating announcement text: $announce"
412 # Hack the announcement template
413 cat "$HERE/dev/release-aux/$announce_template" \
414 |
sed -e "s|\\\$release_text|$release_text|g" \
415 -e "s|\\\$release|$release|g" \
416 -e "s|\\\$series|$SERIES|g" \
417 -e "s|\\\$label|$PRE_LABEL|g" \
418 -e "s|\\\$tarfile|$tgzfile|" \
419 -e "s|\\\$length|$length|" \
420 -e "s|\\\$sha1hash|$sha1hash|" \
421 -e "s|\\\$sha256hash|$sha256hash|" \
422 | perl
-p "$HERE/dev/release-aux/fix-title.pl" \
425 $VERBOSE "== Generating signatures: $tgzfile.asc $announce.asc"
426 rm -f "../$tgzfile.asc" "../$announce.asc"
427 echo "Signing the release files. You may need to enter a pass phrase"
428 gpg
$gpgkey --use-agent -sba "../$tgzfile"
429 gpg
$gpgkey --use-agent -sta --clearsign "../$announce"
431 # Push everything to the parent repo
432 $VERBOSE "== Push what we have to the parent repository"
433 git push
--follow-tags parent HEAD
437 if [ "$VERBOSE" != ':' ]; then
440 echo "put ../$tgzfile"
441 echo "put ../$tgzfile.sha1"
442 echo "put ../$tgzfile.sha256"
443 echo "put ../$tgzfile.asc"
444 echo "put ../$announce.asc"
446 | sftp
"$upload_address"
449 # Post-release #######################################################
451 $VERBOSE "== Reset all files to their pre-release contents"
452 git
reset $git_quiet HEAD^
-- .
455 prev_release_text
="$release_text"
456 prev_release_date
="$RELEASE_DATE"
458 next_release_state
"$next_method2"
461 release
="$VERSION-$PRE_RELEASE_TAG$BUILD_METADATA"
462 release_text
="$VERSION$BUILD_METADATA"
463 if [ -n "$PRE_LABEL" ]; then
464 release_text
="$SERIES$BUILD_METADATA $PRE_LABEL $PRE_NUM"
466 $VERBOSE "== Updated version information to $release"
468 $VERBOSE "== Updating files for $release :"
469 for fixup
in "$HERE/dev/release-aux"/fixup-
*-postrelease.pl
; do
470 file="$(basename "$fixup" | sed -e 's|^fixup-||' -e 's|-postrelease\.pl$||')"
472 RELEASE
="$release" RELEASE_TEXT
="$release_text" \
473 PREV_RELEASE_TEXT
="$prev_release_text" \
474 PREV_RELEASE_DATE
="$prev_release_date" \
475 perl
-pi $fixup $file
478 $VERBOSE "== Committing updates"
480 git commit
$git_quiet -m "Prepare for $release_text"$
'\n\nRelease: yes'
481 if [ -n "$reviewers" ]; then
482 addrev
--release --nopr $reviewers
485 # Push everything to the parent repo
486 $VERBOSE "== Push what we have to the parent repository"
490 $VERBOSE "== Going back to the update branch $tmp_update_branch"
491 git checkout
$git_quiet "$tmp_update_branch"
494 next_release_state
"minor"
497 release
="$VERSION-$PRE_RELEASE_TAG$BUILD_METADATA"
498 release_text
="$SERIES$BUILD_METADATA"
499 $VERBOSE "== Updated version information to $release"
501 $VERBOSE "== Updating files for $release :"
502 for fixup
in "$HERE/dev/release-aux"/fixup-
*-postrelease.pl
; do
503 file="$(basename "$fixup" | sed -e 's|^fixup-||' -e 's|-postrelease\.pl$||')"
505 RELEASE
="$release" RELEASE_TEXT
="$release_text" \
506 perl
-pi $fixup $file
509 $VERBOSE "== Committing updates"
511 git commit
$git_quiet -m "Prepare for $release_text"$
'\n\nRelease: yes'
512 if [ -n "$reviewers" ]; then
513 addrev
--release --nopr $reviewers
517 # Push everything to the parent repo
518 $VERBOSE "== Push what we have to the parent repository"
521 # Done ###############################################################
528 ======================================================================
529 The release is done, and involves a few files and commits for you to
530 deal with. Everything you need has been pushed to your repository,
531 please see instructions that follow.
532 ======================================================================
539 The following files were uploaded to $upload_address, please ensure they
540 are dealt with appropriately:
552 ----------------------------------------------------------------------
557 You need to prepare the main repository with a new branch, '$release_branch'.
558 That is done directly in the server's bare repository like this:
560 git branch $release_branch $orig_HEAD
562 Two additional release branches have been added to your repository.
563 Push them to github, make PRs from them and have them approved:
568 When merging them into the main repository, do it like this:
570 git push git@github.openssl.org:openssl/openssl.git \\
571 $tmp_release_branch:$release_branch
572 git push git@github.openssl.org:openssl/openssl.git \\
573 $tmp_update_branch:$update_branch
574 git push git@github.openssl.org:openssl/openssl.git \\
579 One additional release branch has been added to your repository.
580 Push it to github, make a PR from it and have it approved:
584 When merging it into the main repository, do it like this:
586 git push git@github.openssl.org:openssl/openssl.git \\
587 $tmp_release_branch:$release_branch
588 git push git@github.openssl.org:openssl/openssl.git \\
595 ----------------------------------------------------------------------
600 When everything is done, or if something went wrong and you want to start
601 over, simply clean away temporary things left behind:
603 The release worktree:
605 rm -rf $release_clone
611 The additional release branches:
613 git branch -D $tmp_release_branch
614 git branch -D $tmp_update_branch
619 The temporary release branch:
621 git branch -D $tmp_release_branch
627 # cat is inconsequential, it's only there to fend off zealous shell parsers
628 # that parse all the way here.
635 release.sh - OpenSSL release script
646 B<--local-user>=I<keyid> |
647 B<--reviewer>=I<id> |
658 B<release.sh> creates an OpenSSL release, given current worktree conditions.
659 It will refuse to work unless the current branch is C<master> or a release
660 branch (see L</RELEASE BRANCHES AND TAGS> below for a discussion on those).
662 B<release.sh> tries to be smart and figure out the next release if no hints
663 are given through options, and will exit with an error in ambiguous cases.
665 B<release.sh> finishes off with instructions on what to do next. When
666 finishing commands are given, they must be followed exactly.
668 B<release.sh> leaves behind a clone of the local workspace, as well as one
669 or two branches in the local repository. These will be mentioned and can
670 safely be removed after all instructions have been successfully followed.
676 =item B<--alpha>, B<--beta>
678 Set the state of this branch to indicate that alpha or beta releases are
681 B<--alpha> is only acceptable if the I<PATCH> version number is zero and
682 the current state is "in development" or that alpha releases are ongoing.
684 B<--beta> is only acceptable if the I<PATCH> version number is zero and
685 that alpha or beta releases are ongoing.
689 Use together with B<--alpha> to switch to beta releases after the current
694 Set the state of this branch to indicate that regular releases are to be
695 done. This is only valid if alpha or beta releases are currently ongoing.
697 This implies B<--branch>.
701 Create a branch specific for the I<SERIES> release series, if it doesn't
702 already exist, and switch to it. The exact branch name will be
703 C<< openssl-I<SERIES> >>.
707 Don't upload the produced files.
711 Don't run C<make update> and C<make update-fips-checksums>.
719 Display extra debug output. Implies B<--no-upload>
721 =item B<--local-user>=I<keyid>
723 Use I<keyid> as the local user for C<git tag> and for signing with C<gpg>.
725 If not given, then the default e-mail address' key is used.
727 =item B<--reviewer>=I<id>
729 Add I<id> to the set of reviewers for the commits performed by this script.
730 Multiple reviewers are allowed.
732 If no reviewer is given, you will have to run C<addrev> manually, which
733 means retagging a release commit manually as well.
737 Force execution. Precisely, the check that the current branch is C<master>
738 or a release branch is not done.
742 Display a quick help text and exit.
746 Display this manual and exit.
750 =head1 RELEASE BRANCHES AND TAGS
752 Prior to OpenSSL 3.0, the release branches were named
753 C<< OpenSSL_I<SERIES>-stable >>, and the release tags were named
754 C<< OpenSSL_I<VERSION> >> for regular releases, or
755 C<< OpenSSL_I<VERSION>-preI<n> >> for pre-releases.
757 From OpenSSL 3.0 ongoing, the release branches are named
758 C<< openssl-I<SERIES> >>, and the release tags are named
759 C<< openssl-I<VERSION> >> for regular releases, or
760 C<< openssl-I<VERSION>-alphaI<n> >> for alpha releases
761 and C<< openssl-I<VERSION>-betaI<n> >> for beta releases.
763 B<release.sh> recognises both forms.
765 =head1 VERSION AND STATE
767 With OpenSSL 3.0, all the version and state information is in the file
768 F<VERSION.dat>, where the following variables are used and changed:
772 =item B<MAJOR>, B<MINOR>, B<PATCH>
774 The three part of the version number.
776 =item B<PRE_RELEASE_TAG>
778 The indicator of the current state of the branch. The value may be one pf:
784 This branch is "in development". This is typical for the C<master> branch
785 unless there are ongoing alpha or beta releases.
787 =item C<< alphaI<n> >> or C<< alphaI<n>-dev >>
789 This branch has alpha releases going on. C<< alphaI<n>-dev >> is what
790 should normally be seen in the git workspace, indicating that
791 C<< alphaI<n> >> is in development. C<< alphaI<n> >> is what should be
792 found in the alpha release tar file.
794 =item C<< alphaI<n> >> or C<< alphaI<n>-dev >>
796 This branch has beta releases going on. The details are otherwise exactly
801 This is normally not seen in the git workspace, but should always be what's
802 found in the tar file of a regular release.
806 =item B<RELEASE_DATE>
808 This is normally empty in the git workspace, but should always have the
809 release date in the tar file of any release.
815 Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved.
817 Licensed under the Apache License 2.0 (the "License"). You may not use
818 this file except in compliance with the License. You can obtain a copy
819 in the file LICENSE in the source distribution or at
820 L<https://www.openssl.org/source/license.html>.