2 # Copyright 2020-2023 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: stage-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
32 Expect the current worktree to be clean, and uses it directly.
33 This implies the current branch of the worktree will be updated.
36 Format for branch names.
37 Default is "%b" for the release branch.
38 --tag-fmt=<fmt> Format for tag names.
39 Default is "%t" for the release tag.
41 --reviewer=<id> The reviewer of the commits.
43 For the purpose of signing tags and tar files, use this
44 key (default: use the default e-mail address’ key).
46 --staging-address=<address>
47 The staging location to upload release files to (default:
48 upload@dev.openssl.org)
49 --no-upload Don't upload the staging release files.
50 --no-update Don't perform 'make update' and 'make update-fips-checksums'.
51 --quiet Really quiet, only the final output will still be output.
52 --verbose Verbose output.
53 --debug Include debug output. Implies --no-upload.
54 --porcelain Give the output in an easy-to-parse format for scripts.
56 --force Force execution
61 If none of --alpha, --beta, or --final are given, this script tries to
62 figure out the next step.
67 # Set to one of 'major', 'minor', 'alpha', 'beta' or 'final'
79 default_branch_fmt='OSSL--%b--%v'
97 staging_address=upload@dev.openssl.org
99 TEMP=$(getopt -l 'alpha,next-beta,beta,final' \
101 -l 'clean-worktree' \
102 -l 'branch-fmt:,tag-fmt:' \
105 -l 'staging-address:' \
106 -l 'no-upload,no-update' \
107 -l 'quiet,verbose,debug' \
111 -n stage-release.sh -- - "$@")
115 --alpha | --beta | --final )
116 next_method=$(echo "x$1" | sed -e 's|^x--||')
117 if [ -z "$next_method2" ]; then
118 next_method2=$next_method
121 if [ "$next_method" = 'final' ]; then
126 next_method2=$(echo "x$1" | sed -e 's|^x--next-||')
136 default_branch_fmt='%b'
151 reviewers="$reviewers $1=$2"
203 sed -e '1,/^### BEGIN MANUAL/d' \
204 -e '/^### END MANUAL/,$d' \
215 echo >&2 "Unknown option $1"
222 if [ -z "$branch_fmt" ]; then branch_fmt="$default_branch_fmt"; fi
223 if [ -z "$tag_fmt" ]; then tag_fmt="$default_tag_fmt"; fi
225 $DEBUG >&2 "DEBUG: \$next_method=$next_method"
226 $DEBUG >&2 "DEBUG: \$next_method2=$next_method2"
228 $DEBUG >&2 "DEBUG: \$do_branch=$do_branch"
230 $DEBUG >&2 "DEBUG: \$do_upload=$do_upload"
231 $DEBUG >&2 "DEBUG: \$do_update=$do_update"
232 $DEBUG >&2 "DEBUG: \$DEBUG=$DEBUG"
233 $DEBUG >&2 "DEBUG: \$VERBOSE=$VERBOSE"
234 $DEBUG >&2 "DEBUG: \$git_quiet=$git_quiet"
236 case "$next_method+$next_method2" in
237 major+major | minor+minor )
240 alpha+alpha | alpha+beta | beta+beta | final+final | + | +beta )
244 echo >&2 "Internal option error ($next_method, $next_method2)"
249 # Verbosity feed for certain commands
250 VERBOSITY_FIFO=/tmp/openssl-$$.fifo
251 mkfifo -m 600 $VERBOSITY_FIFO
252 ( cat $VERBOSITY_FIFO | while read L; do $VERBOSE "> $L"; done ) &
253 exec 42>$VERBOSITY_FIFO
254 trap "exec 42>&-; rm $VERBOSITY_FIFO" 0 2
256 # Setup ##############################################################
258 # Check that we have the scripts that define functions we use
259 RELEASE_AUX=$(cd $(dirname $0)/release-aux; pwd)
261 for fn in "$RELEASE_AUX/release-version-fn.sh" \
262 "$RELEASE_AUX/release-state-fn.sh" \
263 "$RELEASE_AUX/string-fn.sh" \
264 "$RELEASE_AUX/upload-fn.sh"; do
265 if ! [ -f "$fn" ]; then
266 echo >&2 "'$fn' is missing"
274 # Load version functions
275 . $RELEASE_AUX/release-version-fn.sh
276 . $RELEASE_AUX/release-state-fn.sh
277 # Load string manipulation functions
278 . $RELEASE_AUX/string-fn.sh
279 # Load upload backend functions
280 . $RELEASE_AUX/upload-fn.sh
282 # Make sure we're in the work directory, and remember it
283 if HERE=$(git rev-parse --show-toplevel); then
286 echo >&2 "Not in a git worktree"
290 # Make sure that it's a plausible OpenSSL work tree, by checking
291 # that a version file is found
294 if [ -z "$VERSION_FILE" ]; then
295 echo >&2 "Couldn't find OpenSSL version data"
299 # Make sure it's a branch we recognise
300 orig_branch=$(git rev-parse --abbrev-ref HEAD)
301 if (echo "$orig_branch" \
304 -e '^OpenSSL_[0-9]+_[0-9]+_[0-9]+[a-z]*-stable$' \
305 -e '^openssl-[0-9]+\.[0-9]+$'); then
310 echo >&2 "Not in master or any recognised release branch"
311 echo >&2 "Please 'git checkout' an appropriate branch"
314 orig_HEAD=$(git rev-parse HEAD)
316 # Make sure that we have fixup scripts for all the files that need
317 # to be modified for a release. We trust this, because we're not
318 # going to change versioning scheme in the middle of a release.
322 for fn in $RELEASE_FILES; do
323 for file in "$RELEASE_AUX/fixup-$fn-release.pl" \
324 "$RELEASE_AUX/fixup-$fn-postrelease.pl"; do
325 if ! [ -f "$file" ]; then
326 echo >&2 "'$file' is missing"
336 # We turn staging_address into a few variables, which can be used
337 # by backends that must understand a subset of the SFTP commands
340 case "$staging_address" in
342 # Something with a colon is interpreted as the typical SCP
343 # location. We reinterpret that in our terms
344 staging_directory="${staging_address#*:}"
345 staging_address="${staging_address%%:*}"
351 sftp://?*/* | sftp://?* )
352 # First, remove the URI scheme
353 staging_address="${staging_address#sftp://}"
354 # Now we know that we have a host, followed by a slash, followed by
355 # a directory spec. If there is no slash, there's no directory.
356 staging_directory="${staging_address#*/}"
357 if [ "$staging_directory" = "$staging_address" ]; then
358 # There was nothing with a slash to remove, so no directory.
361 staging_address="${staging_address%%/*}"
365 echo >&2 "Invalid staging address $staging_address"
369 if $do_upload && ! [ -d "$staging_address" ]; then
370 echo >&2 "Not an existing directory: $staging_address"
377 # Initialize #########################################################
379 $ECHO "== Initializing work tree"
382 if $clean_worktree; then
383 if [ -n "$(git status -s)" ]; then
384 echo >&2 "You've specified --clean-worktree, but your worktree is unclean"
388 # Generate a cloned directory name
389 release_clone="$orig_branch-release-tmp"
391 $ECHO "== Work tree will be in $release_clone"
393 # Make a clone in a subdirectory and move there
394 if ! [ -d "$release_clone" ]; then
395 $VERBOSE "== Cloning to $release_clone"
396 git clone $git_quiet -b "$orig_branch" -o parent . "$release_clone"
403 # Branches to start from. The release branch is where the changes for the
404 # release are made, and the update branch is where the post-release changes are
405 # made. If --branch was given and is relevant, they should be different (and
406 # the update branch should be 'master'), otherwise they should be the same.
407 orig_update_branch="$orig_branch"
408 orig_release_branch="$(std_branch_name)"
410 # among others, we only create a release branch if the patch number is zero
411 if [ "$orig_update_branch" = "$orig_release_branch" ] \
412 || [ -n "$PATCH" -a "$PATCH" != 0 ]; then
413 if $do_branch && $warn_branch; then
414 echo >&2 "Warning! We're already in a release branch; --branch ignored"
420 if [ "$orig_update_branch" != "master" ]; then
421 echo >&2 "--branch is invalid unless the current branch is 'master'"
424 # No need to check if $orig_update_branch and $orig_release_branch differ,
425 # 'cause the code a few lines up guarantee that if they are the same,
426 # $do_branch becomes false
428 # In this case, the computed release branch may differ from the update branch,
429 # even if it shouldn't... this is the case when alpha or beta releases are
430 # made in the master branch, which is perfectly ok. Therefore, simply reset
431 # the release branch to be the same as the update branch and carry on.
432 orig_release_branch="$orig_update_branch"
435 # Check that the current branch is still on the same branch as our parent repo,
436 # or on a release branch
437 current_branch=$(git rev-parse --abbrev-ref HEAD)
438 if [ "$current_branch" = "$orig_update_branch" ]; then
440 elif [ "$current_branch" = "$orig_release_branch" ]; then
443 # It is an error to end up here. Let's try to figure out what went wrong
445 if $clean_worktree; then
446 # We should never get here. If we do, something is incorrect in
448 echo >&2 "Unexpected current branch: $current_branch"
450 echo >&2 "The cloned sub-directory '$release_clone' is on a branch"
451 if [ "$orig_update_branch" = "$orig_release_branch" ]; then
452 echo >&2 "other than '$orig_update_branch'."
454 echo >&2 "other than '$orig_update_branch' or '$orig_release_branch'."
456 echo >&2 "Please 'cd \"$(pwd)\"; git checkout $orig_update_branch'"
462 $DEBUG >&2 "DEBUG: Source directory is $SOURCEDIR"
464 # Release ############################################################
466 # We always expect to start from a state of development
467 if [ "$TYPE" != 'dev' ]; then
468 upstream=$(git rev-parse --abbrev-ref '@{u}' 2>/dev/null || echo 'HEAD^')
469 if $clean_worktree; then
471 Not in a development branch.
473 Have a look at the git log, it may be that a previous crash left it in
474 an intermediate state and that need to drop the top commit:
476 git reset --hard $upstream
477 # WARNING! LOOK BEFORE YOU ACT, KNOW WHAT YOU DO
481 Not in a development branch.
483 Have a look at the git log in $release_clone, it may be that
484 a previous crash left it in an intermediate state and that need to drop
487 (cd $release_clone; git reset --hard $upstream)
488 # WARNING! LOOK BEFORE YOU ACT, KNOW WHAT YOU DO
494 # Make the update branch name according to our current data
495 update_branch=$(format_string "$branch_fmt" \
496 "b=$orig_update_branch" \
500 # Update the version information. This won't save anything anywhere, yet,
501 # but does check for possible next_method errors before we do bigger work.
502 next_release_state "$next_method"
504 # Make the release tag and branch name according to our current data
505 tag=$(format_string "$tag_fmt" \
506 "b=$orig_release_branch" \
507 "t=$(std_tag_name)" \
509 release_branch=$(format_string "$branch_fmt" \
510 "b=$orig_release_branch" \
511 "t=$(std_tag_name)" \
514 # Create a update branch, unless it's the same as our current branch
515 if [ "$update_branch" != "$orig_update_branch" ]; then
516 $VERBOSE "== Creating a local update branch and switch to it: $update_branch"
517 git checkout $git_quiet -b "$update_branch"
520 $ECHO "== Configuring OpenSSL for update and release. This may take a bit of time"
524 $VERBOSE "== Checking source file updates and fips checksums"
527 # As long as we're doing an alpha release, we can have symbols without specific
528 # numbers assigned. In a beta or final release, all symbols MUST have an
530 if [ "$next_method" != 'alpha' ] && grep -q '^renumber *:' Makefile; then
533 if grep -q '^update-fips-checksums *:' Makefile; then
534 make update-fips-checksums >&42
537 if [ -n "$(git status --porcelain --untracked-files=no --ignore-submodules=all)" ]; then
538 $VERBOSE "== Committing updates"
540 git commit $git_quiet -m $'make update\n\nRelease: yes'
541 if [ -n "$reviewers" ]; then
542 addrev --release --nopr $reviewers
546 # Create a update branch, unless it's the same as the update branch
547 if [ "$release_branch" != "$update_branch" ]; then
548 $VERBOSE "== Creating a local release branch and switch to it: $release_branch"
549 git checkout $git_quiet -b "$release_branch"
552 # Write the version information we updated
555 release="$FULL_VERSION"
556 if [ -n "$PRE_LABEL" ]; then
557 release_text="$SERIES$_BUILD_METADATA $PRE_LABEL $PRE_NUM"
558 announce_template=openssl-announce-pre-release.tmpl
560 release_text="$release"
561 announce_template=openssl-announce-release.tmpl
563 $VERBOSE "== Updated version information to $release"
565 $VERBOSE "== Updating files with release date for $release : $RELEASE_DATE"
568 for file in $RELEASE_FILES; do
569 fixup="$RELEASE_AUX/fixup-$(basename "$file")-release.pl"
571 RELEASE="$release" RELEASE_TEXT="$release_text" RELEASE_DATE="$RELEASE_DATE" \
572 perl -pi $fixup $file
576 $VERBOSE "== Committing updates and tagging"
578 git commit $git_quiet -m "Prepare for release of $release_text"$'\n\nRelease: yes'
579 if [ -n "$reviewers" ]; then
580 addrev --release --nopr $reviewers
582 $ECHO "Tagging release with tag $tag. You may need to enter a pass phrase"
583 git tag$tagkey "$tag" -m "OpenSSL $release release tag"
585 tarfile=openssl-$release.tar
587 announce=openssl-$release.txt
589 $ECHO "== Generating tar, hash and announcement files. This make take a bit of time"
591 $VERBOSE "== Making tarfile: $tgzfile"
593 # Unfortunately, some tarball generators do verbose output on STDERR... for
594 # good reason, but it means we don't display errors unless --verbose
596 if [ -f ./util/mktar.sh ]; then
597 ./util/mktar.sh --tarfile="../$tarfile" 2>&1
599 make DISTTARVARS=TARFILE="../$tarfile" dist 2>&1
601 ) | while read L; do $VERBOSE "> $L"; done
603 if ! [ -f "../$tgzfile" ]; then
604 echo >&2 "Where did the tarball end up? (../$tgzfile)"
608 $VERBOSE "== Generating checksums: $tgzfile.sha1 $tgzfile.sha256"
609 openssl sha1 < "../$tgzfile" | \
610 (IFS='='; while read X H; do echo $H; done) > "../$tgzfile.sha1"
611 openssl sha256 < "../$tgzfile" | \
612 (IFS='='; while read X H; do echo $H; done) > "../$tgzfile.sha256"
613 length=$(wc -c < "../$tgzfile")
614 sha1hash=$(cat "../$tgzfile.sha1")
615 sha256hash=$(cat "../$tgzfile.sha256")
617 $VERBOSE "== Generating announcement text: $announce"
618 # Hack the announcement template
619 cat "$RELEASE_AUX/$announce_template" \
620 | sed -e "s|\\\$release_text|$release_text|g" \
621 -e "s|\\\$release|$release|g" \
622 -e "s|\\\$series|$SERIES|g" \
623 -e "s|\\\$label|$PRE_LABEL|g" \
624 -e "s|\\\$tarfile|$tgzfile|" \
625 -e "s|\\\$length|$length|" \
626 -e "s|\\\$sha1hash|$sha1hash|" \
627 -e "s|\\\$sha256hash|$sha256hash|" \
628 | perl -p "$RELEASE_AUX/fix-title.pl" \
631 $VERBOSE "== Generating signatures: $tgzfile.asc $announce.asc"
632 rm -f "../$tgzfile.asc" "../$announce.asc"
633 $ECHO "Signing the release files. You may need to enter a pass phrase"
634 gpg$gpgkey --use-agent -sba "../$tgzfile"
635 gpg$gpgkey --use-agent -sta --clearsign "../$announce"
637 if ! $clean_worktree; then
638 # Push everything to the parent repo
639 $VERBOSE "== Push what we have to the parent repository"
640 git push --follow-tags parent HEAD
643 staging_files=( "$tgzfile" "$tgzfile.sha1" "$tgzfile.sha256"
644 "$tgzfile.asc" "$announce.asc" )
647 $ECHO "== Upload tar, hash and announcement files to staging location"
651 # With sftp, the progress meter is enabled by default,
652 # so we turn it off unless --verbose was given
653 if [ "$VERBOSE" == ':' ]; then
656 if [ -n "$staging_directory" ]; then
657 echo "cd $staging_directory"
659 for uf in "${staging_files[@]}"; do
662 ) | upload_backend_$staging_backend "$staging_address" $do_upload
664 # Post-release #######################################################
666 # Reset the files to their pre-release contents. This doesn't affect
667 # HEAD, but simply set all the files in a state that 'git revert -n HEAD'
668 # would have given, but without the artifacts that 'git revert' adds.
670 # This allows all the post-release fixup scripts to perform from the
671 # same point as the release fixup scripts, hopefully making them easier
672 # to write. This also makes the same post-release fixup scripts easier
673 # to run when --branch has been used, as they will be run both on the
674 # release branch and on the update branch, essentially from the same
675 # state for affected files.
676 $VERBOSE "== Reset all files to their pre-release contents"
677 git reset $git_quiet HEAD^ -- .
680 prev_release_text="$release_text"
681 prev_release_date="$RELEASE_DATE"
683 next_release_state "$next_method2"
686 release="$FULL_VERSION"
687 release_text="$VERSION$_BUILD_METADATA"
688 if [ -n "$PRE_LABEL" ]; then
689 release_text="$SERIES$_BUILD_METADATA $PRE_LABEL $PRE_NUM"
691 $VERBOSE "== Updated version information to $release"
693 $VERBOSE "== Updating files for $release :"
696 for file in $RELEASE_FILES; do
697 fixup="$RELEASE_AUX/fixup-$(basename "$file")-postrelease.pl"
699 RELEASE="$release" RELEASE_TEXT="$release_text" \
700 PREV_RELEASE_TEXT="$prev_release_text" \
701 PREV_RELEASE_DATE="$prev_release_date" \
702 perl -pi $fixup $file
706 $VERBOSE "== Committing updates"
708 git commit $git_quiet -m "Prepare for $release_text"$'\n\nRelease: yes'
709 if [ -n "$reviewers" ]; then
710 addrev --release --nopr $reviewers
713 if ! $clean_worktree; then
714 # Push everything to the parent repo
715 $VERBOSE "== Push what we have to the parent repository"
719 if [ "$release_branch" != "$update_branch" ]; then
720 $VERBOSE "== Going back to the update branch $update_branch"
721 git checkout $git_quiet "$update_branch"
724 next_release_state "minor"
727 release="$FULL_VERSION"
728 release_text="$SERIES$_BUILD_METADATA"
729 $VERBOSE "== Updated version information to $release"
731 $VERBOSE "== Updating files for $release :"
734 for file in $RELEASE_FILES; do
735 fixup="$RELEASE_AUX/fixup-$(basename "$file")-postrelease.pl"
737 RELEASE="$release" RELEASE_TEXT="$release_text" \
738 perl -pi $fixup $file
742 $VERBOSE "== Committing updates"
744 git commit $git_quiet -m "Prepare for $release_text"$'\n\nRelease: yes'
745 if [ -n "$reviewers" ]; then
746 addrev --release --nopr $reviewers
750 if ! $clean_worktree; then
751 # Push everything to the parent repo
752 $VERBOSE "== Push what we have to the parent repository"
756 # Done ###############################################################
761 if $do_porcelain; then
762 if [ -n "$release_clone" ]; then
763 echo "clone_directory='$release_clone'"
765 echo "update_branch='$update_branch'"
766 if [ "$update_branch" != "$orig_update_branch" ]; then
767 echo "final_update_branch='$orig_update_branch'"
769 if [ "$release_branch" != "$update_branch" ]; then
770 echo "release_branch='$release_branch'"
771 if [ "$release_branch" != "$orig_release_branch" ]; then
772 echo "final_release_branch='$orig_release_branch'"
775 echo "release_tag='$tag'"
776 echo "upload_files='${staging_files[@]}'"
780 ======================================================================
781 The release is done, and involves a few files and commits for you to
782 deal with. Everything you need has been pushed to your repository,
783 please see instructions that follow.
784 ======================================================================
790 The following files were uploaded to $staging_address, please ensure they
791 are dealt with appropriately:
796 The following files were generated for upload, please deal with them
801 for uf in "${staging_files[@]}"; do
806 ----------------------------------------------------------------------
810 if [ "$release_branch" != "$update_branch" ]; then
812 You need to prepare the main repository with a new branch, '$release_branch'.
813 That is done directly in the server's bare repository like this:
815 git branch $release_branch $orig_HEAD
819 if [ "$update_branch" != "$orig_update_branch" ] \
820 && [ "$release_branch" != "$update_branch" ]; then
821 # "Normal" scenario with --branch
823 A release tag and two branches have been added to your local repository.
824 Push them to github, make PRs from them and have them approved.
826 Update branch: $update_branch
827 Release branch: $release_branch
830 When merging everything into the main repository, do it like this:
832 git push git@github.openssl.org:openssl/openssl.git \\
833 $release_branch:$orig_release_branch
834 git push git@github.openssl.org:openssl/openssl.git \\
835 $update_branch:$orig_update_branch
836 git push git@github.openssl.org:openssl/openssl.git \\
839 elif [ "$update_branch" != "$orig_update_branch" ]; then
840 # "Normal" scenario without --branch
842 A release tag and a release/update branch have been added to your local
843 repository. Push them to github, make PRs from them and have them
846 Release/update branch: $update_branch
849 When merging everything into the main repository, do it like this:
851 git push git@github.openssl.org:openssl/openssl.git \\
852 $update_branch:$orig_update_branch
853 git push git@github.openssl.org:openssl/openssl.git \\
856 elif [ "$release_branch" != "$update_branch" ]; then
857 # --clean-worktree and --branch scenario
859 A release tag and a release branch has been added to your repository,
860 and the current branch has been updated. Push them to github, make
861 PRs from them and have them approved:
863 Updated branch: $update_branch
864 Release branch: $release_branch
867 When merging everything into the main repository, do it like this:
869 git push git@github.openssl.org:openssl/openssl.git \\
870 $release_branch:$orig_release_branch
871 git push git@github.openssl.org:openssl/openssl.git \\
873 git push git@github.openssl.org:openssl/openssl.git \\
877 # --clean-worktree without --branch scenario
879 A release tag has been added to your local repository, and the current
880 branch has been updated. Push them to github, make PRs from them and
883 Release/update branch: $update_branch
886 When merging everything into the main repository, do it like this:
888 git push git@github.openssl.org:openssl/openssl.git \\
890 git push git@github.openssl.org:openssl/openssl.git \\
897 ----------------------------------------------------------------------
902 When everything is done, or if something went wrong and you want to start
903 over, simply clean away temporary things left behind:
905 if [ -n "$release_clone" ]; then
907 The release worktree:
909 rm -rf $release_clone
917 if [ "$release_branch" != "$update_branch" ]; then
919 git branch -D $release_branch
922 if [ "$update_branch" != "$orig_update_branch" ]; then
924 git branch -D $update_branch
931 # cat is inconsequential, it's only there to fend off zealous shell parsers
932 # that parse all the way here.
939 stage-release.sh - OpenSSL release staging script
950 B<--clean-worktree> |
951 B<--branch-fmt>=I<fmt> |
952 B<--tag-fmt>=I<fmt> |
953 B<--local-user>=I<keyid> |
954 B<--reviewer>=I<id> |
955 B<--staging-address>=I<address> |
968 B<stage-release.sh> creates an OpenSSL release, given current worktree
969 conditions. It will refuse to work unless the current branch is C<master>
970 or a release branch (see L</RELEASE BRANCHES AND TAGS> below for a
971 discussion on those).
973 B<stage-release.sh> tries to be smart and figure out the next release if no
974 hints are given through options, and will exit with an error in ambiguous
977 B<stage-release.sh> normally finishes off with instructions on what to do
978 next. When B<--porcelain> is given, it finishes off with script friendly
979 data instead, see the description of that option. When finishing commands
980 are given, they must be followed exactly.
982 B<stage-release.sh> normally leaves behind a clone of the local repository,
983 as a subdirectory in the current worktree, as well as an extra branch with
984 the results of running this script in the local repository. This extra
985 branch is useful to create a pull request from, which will also be mentioned
986 at the end of the run of B<stage-release.sh>. This local clone subdirectory
987 as well as this extra branch can safely be removed after all instructions
988 have been successfully followed.
990 When the option B<--clean-worktree> is given, B<stage-release.sh> has a
991 different behaviour. In this case, it doesn't create that clone or any
992 extra branch, and it will update the current branch of the worktree
993 directly. This is useful when it's desirable to push the changes directly
994 to a remote repository without having to go through a pull request and
1001 =item B<--alpha>, B<--beta>
1003 Set the state of this branch to indicate that alpha or beta releases are
1006 B<--alpha> is only acceptable if the I<PATCH> version number is zero and
1007 the current state is "in development" or that alpha releases are ongoing.
1009 B<--beta> is only acceptable if the I<PATCH> version number is zero and
1010 that alpha or beta releases are ongoing.
1012 =item B<--next-beta>
1014 Use together with B<--alpha> to switch to beta releases after the current
1019 Set the state of this branch to indicate that regular releases are to be
1020 done. This is only valid if alpha or beta releases are currently ongoing.
1022 This implies B<--branch>.
1026 Create a branch specific for the I<SERIES> release series, if it doesn't
1027 already exist, and switch to it when making the release files. The exact
1028 branch name will be C<< openssl-I<SERIES> >>.
1030 =item B<--clean-worktree>
1032 This indicates that the current worktree is clean and can be acted on
1033 directly, instead of creating a clone of the local repository or creating
1036 =item B<--branch-fmt>=I<fmt>
1038 =item B<--tag-fmt>=I<fmt>
1040 Format for branch and tag names. This can be used to tune the names of
1041 branches and tags that are updated or added by this script.
1043 I<fmt> can include printf-like formating directives:
1049 is replaced with a branch name. This branch name is usually the current
1050 branch of the current repository, but may also be the default release
1051 branch name that is generated when B<--branch> is given.
1055 is replaced with the generated release tag name.
1059 is replaced with the version number. The exact version number varies
1060 through the process of this script.
1064 This script uses the following defaults:
1068 =item * Without B<--clean-worktree>
1070 For branches: C<OSSL--%b--%v>
1074 =item * With B<--clean-worktree>
1082 =item B<--reviewer>=I<id>
1084 Add I<id> to the set of reviewers for the commits performed by this script.
1085 Multiple reviewers are allowed.
1087 If no reviewer is given, you will have to run C<addrev> manually, which
1088 means retagging a release commit manually as well.
1090 =item B<--local-user>=I<keyid>
1092 Use I<keyid> as the local user for C<git tag> and for signing with C<gpg>.
1094 If not given, then the default e-mail address' key is used.
1096 =item B<--staging-address>=I<address>
1098 The staging location that the release files are to be uploaded to.
1099 Supported values are:
1105 an existing local directory
1109 something that can be interpreted as an SCP/SFTP address. In this case,
1110 SFTP will always be used. Typical SCP remote file specs will be translated
1111 into something that makes sense for SFTP.
1115 The default staging address is C<upload@dev.openssl.org>.
1117 =item B<--no-upload>
1119 Don't upload the release files to the staging location.
1121 =item B<--no-update>
1123 Don't run C<make update> and C<make update-fips-checksums>.
1127 Really quiet, only bare necessity output, which is the final instructions,
1128 or should the B<--porcelain> option be used, only that output.
1130 messages appearing on standard error will still be shown, but should be
1139 Display extra debug output. Implies B<--no-upload>
1141 =item B<--porcelain>
1143 Give final output in an easy-to-parse format for scripts. The output comes
1144 in a form reminicent of shell variable assignments. Currently supported are:
1148 =item B<clone_directory>=I<dir>
1150 The directory for the clone that this script creates. This is not given when
1151 the option B<--clean-worktree> is used.
1153 =item B<update_branch>=I<branch>
1155 The temporary update branch. This is always given.
1157 =item B<final_update_branch>=I<branch>
1159 The final update branch that the temporary update branch should end up being
1160 merged into. This is not given when the option B<--clean-worktree> is used.
1162 =item B<release_branch>=I<branch>
1164 The temporary release branch, only given if it differs from the update branch
1165 (i.e. B<--branch> was given or implied).
1167 =item B<final_release_branch>=I<branch>
1169 The final release branch that the temporary release branch should end up being
1170 merged into. This is only given if it differs from the final update branch
1171 (i.e. B<--branch> was given or implied).
1173 =item B<release_tag>=I<tag>
1175 The release tag. This is always given.
1177 =item B<upload_files>='I<files>'
1179 The space separated list of files that were or would have been uploaded
1180 to the staging location (depending on the presence of B<--no-upload>).
1186 Force execution. Precisely, the check that the current branch is C<master>
1187 or a release branch is not done.
1191 Display a quick help text and exit.
1195 Display this manual and exit.
1199 =head1 RELEASE BRANCHES AND TAGS
1201 Prior to OpenSSL 3.0, the release branches were named
1202 C<< OpenSSL_I<SERIES>-stable >>, and the release tags were named
1203 C<< OpenSSL_I<VERSION> >> for regular releases, or
1204 C<< OpenSSL_I<VERSION>-preI<n> >> for pre-releases.
1206 From OpenSSL 3.0 ongoing, the release branches are named
1207 C<< openssl-I<SERIES> >>, and the release tags are named
1208 C<< openssl-I<VERSION> >> for regular releases, or
1209 C<< openssl-I<VERSION>-alphaI<n> >> for alpha releases
1210 and C<< openssl-I<VERSION>-betaI<n> >> for beta releases.
1212 B<stage-release.sh> recognises both forms.
1214 =head1 VERSION AND STATE
1216 With OpenSSL 3.0, all the version and state information is in the file
1217 F<VERSION.dat>, where the following variables are used and changed:
1221 =item B<MAJOR>, B<MINOR>, B<PATCH>
1223 The three part of the version number.
1225 =item B<PRE_RELEASE_TAG>
1227 The indicator of the current state of the branch. The value may be one pf:
1233 This branch is "in development". This is typical for the C<master> branch
1234 unless there are ongoing alpha or beta releases.
1236 =item C<< alphaI<n> >> or C<< alphaI<n>-dev >>
1238 This branch has alpha releases going on. C<< alphaI<n>-dev >> is what
1239 should normally be seen in the git workspace, indicating that
1240 C<< alphaI<n> >> is in development. C<< alphaI<n> >> is what should be
1241 found in the alpha release tar file.
1243 =item C<< alphaI<n> >> or C<< alphaI<n>-dev >>
1245 This branch has beta releases going on. The details are otherwise exactly
1250 This is normally not seen in the git workspace, but should always be what's
1251 found in the tar file of a regular release.
1255 =item B<BUILD_METADATA>
1257 Extra build metadata to be used by anyone for their own purposes.
1259 =item B<RELEASE_DATE>
1261 This is normally empty in the git workspace, but should always have the
1262 release date in the tar file of any release.
1268 Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved.
1270 Licensed under the Apache License 2.0 (the "License"). You may not use
1271 this file except in compliance with the License. You can obtain a copy
1272 in the file LICENSE in the source distribution or at
1273 L<https://www.openssl.org/source/license.html>.