Add an option to specify the upload address
[tools.git] / release-tools / release.sh
1 #! /bin/bash -e
2 # Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved.
3 #
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
8
9 # This is the most shell agnostic way to specify that POSIX rules.
10 POSIXLY_CORRECT=1
11
12 # Force C locale because some commands (like date +%b) relies
13 # on the current locale.
14 export LC_ALL=C
15
16 usage () {
17     cat <<EOF
18 Usage: release.sh [ options ... ]
19
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.
25                 Implies --branch.
26
27 --branch        Create a release branch 'openssl-{major}.{minor}',
28                 where '{major}' and '{minor}' are the major and minor
29                 version numbers.
30
31 --reviewer=<id> The reviewer of the commits.
32 --local-user=<keyid>
33                 For the purpose of signing tags and tar files, use this
34                 key (default: use the default e-mail address’ key).
35
36 --upload-address=<address>
37                 The location to upload release files to (default:
38                 upload@dev.openssl.org)
39 --no-upload     Don't upload the release files.
40 --no-update     Don't perform 'make update' and 'make update-fips-checksums'.
41 --verbose       Verbose output.
42 --debug         Include debug output.  Implies --no-upload.
43
44 --force         Force execution
45
46 --help          This text
47 --manual        The manual
48
49 If none of --alpha, --beta, or --final are given, this script tries to
50 figure out the next step.
51 EOF
52     exit 0
53 }
54
55 # Set to one of 'major', 'minor', 'alpha', 'beta' or 'final'
56 next_method=
57 next_method2=
58
59 do_branch=false
60 warn_branch=false
61
62 do_clean=true
63 do_upload=true
64 do_update=true
65 DEBUG=:
66 VERBOSE=:
67 git_quiet=-q
68
69 force=false
70
71 do_help=false
72 do_manual=false
73
74 tagkey=' -s'
75 gpgkey=
76 reviewers=
77
78 upload_address=upload@dev.openssl.org
79
80 TEMP=$(getopt -l 'alpha,next-beta,beta,final' \
81               -l 'branch' \
82               -l 'upload-address:' \
83               -l 'no-upload,no-update' \
84               -l 'verbose,debug' \
85               -l 'local-user:' \
86               -l 'reviewer:' \
87               -l 'force' \
88               -l 'help,manual' \
89               -n release.sh -- - "$@")
90 eval set -- "$TEMP"
91 while true; do
92     case $1 in
93     --alpha | --beta | --final )
94         next_method=$(echo "x$1" | sed -e 's|^x--||')
95         if [ -z "$next_method2" ]; then
96             next_method2=$next_method
97         fi
98         shift
99         if [ "$next_method" = 'final' ]; then
100             do_branch=true
101         fi
102         ;;
103     --next-beta )
104         next_method2=$(echo "x$1" | sed -e 's|^x--next-||')
105         shift
106         ;;
107     --branch )
108         do_branch=true
109         warn_branch=true
110         shift
111         ;;
112     --upload-address )
113         shift
114         upload_address="$1"
115         shift
116         ;;
117     --no-upload )
118         do_upload=false
119         shift
120         ;;
121     --no-update )
122         do_update=false
123         shift
124         ;;
125     --verbose )
126         VERBOSE=echo
127         git_quiet=
128         shift
129         ;;
130     --debug )
131         DEBUG=echo
132         do_upload=false
133         shift
134         ;;
135     --local-user )
136         shift
137         tagkey=" -u $1"
138         gpgkey=" -u $1"
139         shift
140         ;;
141     --reviewer )
142         reviewers="$reviewers $1=$2"
143         shift
144         shift
145         ;;
146     --force )
147         force=true
148         shift
149         ;;
150     --help )
151         usage
152         exit 0
153         ;;
154     --manual )
155         sed -e '1,/^### BEGIN MANUAL/d' \
156             -e '/^### END MANUAL/,$d' \
157             < "$0" \
158             | pod2man \
159             | man -l -
160         exit 0
161         ;;
162     -- )
163         shift
164         break
165         ;;
166     * )
167         echo >&2 "Unknown option $1"
168         shift
169         exit 1
170         ;;
171     esac
172 done
173
174 $DEBUG >&2 "DEBUG: \$next_method=$next_method"
175 $DEBUG >&2 "DEBUG: \$next_method2=$next_method2"
176
177 $DEBUG >&2 "DEBUG: \$do_branch=$do_branch"
178
179 $DEBUG >&2 "DEBUG: \$do_upload=$do_upload"
180 $DEBUG >&2 "DEBUG: \$do_update=$do_update"
181 $DEBUG >&2 "DEBUG: \$DEBUG=$DEBUG"
182 $DEBUG >&2 "DEBUG: \$VERBOSE=$VERBOSE"
183 $DEBUG >&2 "DEBUG: \$git_quiet=$git_quiet"
184
185 case "$next_method+$next_method2" in
186     major+major | minor+minor )
187         # These are expected
188         ;;
189     alpha+alpha | alpha+beta | beta+beta | final+final | + | +beta )
190         # These are expected
191         ;;
192     * )
193         echo >&2 "Internal option error ($next_method, $next_method2)"
194         exit 1
195         ;;
196 esac
197
198 # Verbosity feed for certain commands
199 VERBOSITY_FIFO=/tmp/openssl-$$.fifo
200 mkfifo -m 600 $VERBOSITY_FIFO
201 ( cat $VERBOSITY_FIFO | while read L; do $VERBOSE "> $L"; done ) &
202 exec 42>$VERBOSITY_FIFO
203 trap "exec 42>&-; rm $VERBOSITY_FIFO" 0 2
204
205 # Setup ##############################################################
206
207 # Check that we have the scripts that define functions we use
208 RELEASE_AUX=$(cd $(dirname $0)/release-aux; pwd)
209 found=true
210 for fn in "$RELEASE_AUX/release-version-fn.sh" \
211           "$RELEASE_AUX/release-state-fn.sh" \
212           "$RELEASE_AUX/upload-fn.sh"; do
213     if ! [ -f "$fn" ]; then
214         echo >&2 "'$fn' is missing"
215         found=false
216     fi
217 done
218 if ! $found; then
219     exit 1
220 fi
221
222 # Load version functions
223 . $RELEASE_AUX/release-version-fn.sh
224 . $RELEASE_AUX/release-state-fn.sh
225 # Load upload backend functions
226 . $RELEASE_AUX/upload-fn.sh
227
228 # Make sure we're in the work directory, and remember it
229 if HERE=$(git rev-parse --show-toplevel); then
230     :
231 else
232     echo >&2 "Not in a git worktree"
233     exit 1
234 fi
235
236 # Make sure that it's a plausible OpenSSL work tree, by checking
237 # that a version file is found
238 get_version
239
240 if [ -z "$VERSION_FILE" ]; then
241     echo >&2 "Couldn't find OpenSSL version data"
242     exit 1
243 fi
244
245 # Make sure it's a branch we recognise
246 orig_branch=$(git rev-parse --abbrev-ref HEAD)
247 if (echo "$orig_branch" \
248         | grep -E -q \
249                -e '^master$' \
250                -e '^OpenSSL_[0-9]+_[0-9]+_[0-9]+[a-z]*-stable$' \
251                -e '^openssl-[0-9]+\.[0-9]+$'); then
252     :
253 elif $force; then
254     :
255 else
256     echo >&2 "Not in master or any recognised release branch"
257     echo >&2 "Please 'git checkout' an appropriate branch"
258     exit 1
259 fi
260 orig_HEAD=$(git rev-parse HEAD)
261
262 # Make sure that we have fixup scripts for all the files that need
263 # to be modified for a release.  We trust this, because we're not
264 # going to change versioning scheme in the middle of a release.
265 save_IFS=$IFS
266 IFS=';'
267 found=true
268 for fn in $RELEASE_FILES; do
269     for file in "$RELEASE_AUX/fixup-$fn-release.pl" \
270                 "$RELEASE_AUX/fixup-$fn-postrelease.pl"; do
271         if ! [ -f "$file" ]; then
272             echo >&2 "'$file' is missing"
273             found=false
274         fi
275     done
276 done
277 IFS=$save_IFS
278 if ! $found; then
279     exit 1
280 fi
281
282 # We turn upload_address into a few variables, which can be used
283 # by backends that must understand a subset of the SFTP commands
284 upload_directory=
285 upload_backend=
286 case "$upload_address" in
287     *:* )
288         # Something with a colon is interpreted as the typical SCP
289         # location.  We reinterpret that in our terms
290         upload_directory="${upload_address#*:}"
291         upload_address="${upload_address%%:*}"
292         upload_backend=sftp
293         ;;
294     *@* )
295         upload_backend=sftp
296         ;;
297     sftp://?*/* | sftp://?* )
298         # First, remove the URI scheme
299         upload_address="${upload_address#sftp://}"
300         # Now we know that we have a host, followed by a slash, followed by
301         # a directory spec.  If there is no slash, there's no directory.
302         upload_directory="${upload_address#*/}"
303         if [ "$upload_directory" = "$upload_address" ]; then
304             # There was nothing with a slash to remove, so no directory.
305             upload_directory=
306         fi
307         upload_address="${upload_address%%/*}"
308         upload_backend=sftp
309         ;;
310     sftp:* )
311         echo >&2 "Invalid upload address $upload_address"
312         exit 1
313         ;;
314     * )
315         if $do_upload && ! [ -d "$upload_address" ]; then
316            echo >&2 "Not an existing directory: $upload_address"
317            exit 1
318         fi
319         upload_backend=file
320         ;;
321 esac
322
323 # Initialize #########################################################
324
325 echo "== Initializing work tree"
326
327 # Generate a cloned directory name
328 release_clone="$orig_branch-release-tmp"
329
330 echo "== Work tree will be in $release_clone"
331
332 # Make a clone in a subdirectory and move there
333 if ! [ -d "$release_clone" ]; then
334     $VERBOSE "== Cloning to $release_clone"
335     git clone $git_quiet -b "$orig_branch" -o parent . "$release_clone"
336 fi
337 cd "$release_clone"
338
339 get_version
340
341 # Branches we will work with.  The release branch is where we make the
342 # changes for the release, the update branch is where we make the post-
343 # release changes
344 update_branch="$orig_branch"
345 release_branch="$(std_branch_name)"
346
347 # among others, we only create a release branch if the patch number is zero
348 if [ "$update_branch" = "$release_branch" ] || [ $PATCH -ne 0 ]; then
349     if $do_branch && $warn_branch; then
350         echo >&2 "Warning! We're already in a release branch; --branch ignored"
351     fi
352     do_branch=false
353 fi
354
355 if ! $do_branch; then
356     release_branch="$update_branch"
357 fi
358
359 # Branches we create for PRs
360 branch_version="$VERSION${PRE_LABEL:+-$PRE_LABEL$PRE_NUM}"
361 tmp_update_branch="OSSL--$update_branch--$branch_version"
362 tmp_release_branch="OSSL--$release_branch--$branch_version"
363
364 # Check that we're still on the same branch as our parent repo, or on a
365 # release branch
366 current_branch=$(git rev-parse --abbrev-ref HEAD)
367 if [ "$current_branch" = "$update_branch" ]; then
368     :
369 elif [ "$current_branch" = "$release_branch" ]; then
370     :
371 else
372     echo >&2 "The cloned sub-directory '$release_clone' is on a branch"
373     if [ "$update_branch" = "$release_branch" ]; then
374         echo >&2 "other than '$update_branch'."
375     else
376         echo >&2 "other than '$update_branch' or '$release_branch'."
377     fi
378     echo >&2 "Please 'cd \"$(pwd)\"; git checkout $update_branch'"
379     exit 1
380 fi
381
382 SOURCEDIR=$(pwd)
383 $DEBUG >&2 "DEBUG: Source directory is $SOURCEDIR"
384
385 # Release ############################################################
386
387 # We always expect to start from a state of development
388 if [ "$TYPE" != 'dev' ]; then
389     echo >&2 "Not in a development branch"
390     echo >&2 "Have a look at the git log in $release_clone, it may be that"
391     echo >&2 "a previous crash left it in an intermediate state and that"
392     echo >&2 "need to drop the top commit:"
393     echo >&2 ""
394     echo >&2 "(cd $release_clone; git reset --hard HEAD^)"
395     echo >&2 "# WARNING! LOOK BEFORE YOU ACT"
396     exit 1
397 fi
398
399 # Update the version information.  This won't save anything anywhere, yet,
400 # but does check for possible next_method errors before we do bigger work.
401 next_release_state "$next_method"
402
403 # Create our temporary release branch
404 $VERBOSE "== Creating a local release branch: $tmp_release_branch"
405 git checkout $git_quiet -b "$tmp_release_branch"
406
407 echo "== Configuring OpenSSL for update and release.  This may take a bit of time"
408
409 ./Configure cc >&42
410
411 $VERBOSE "== Checking source file updates and fips checksums"
412
413 make update >&42
414 # As long as we're doing an alpha release, we can have symbols without specific
415 # numbers assigned. In a beta or final release, all symbols MUST have an
416 # assigned number.
417 if [ "$next_method" != 'alpha' ]; then
418     make renumber >&42
419 fi
420 make update-fips-checksums >&42
421
422 if [ -n "$(git status --porcelain)" ]; then
423     $VERBOSE "== Committing updates"
424     git add -u
425     git commit $git_quiet -m $'make update\n\nRelease: yes'
426     if [ -n "$reviewers" ]; then
427         addrev --release --nopr $reviewers
428     fi
429 fi
430
431 # Create our temporary update branch, if it's not the release branch.
432 # This is used in post-release below
433 if $do_branch; then
434     $VERBOSE "== Creating a local update branch: $tmp_update_branch"
435     git branch $git_quiet "$tmp_update_branch"
436 fi
437
438 # Write the version information we updated
439 set_version
440
441 release="$FULL_VERSION"
442 if [ -n "$PRE_LABEL" ]; then
443     release_text="$SERIES$_BUILD_METADATA $PRE_LABEL $PRE_NUM"
444     announce_template=openssl-announce-pre-release.tmpl
445 else
446     release_text="$release"
447     announce_template=openssl-announce-release.tmpl
448 fi
449 tag="$(std_tag_name)"
450 $VERBOSE "== Updated version information to $release"
451
452 $VERBOSE "== Updating files with release date for $release : $RELEASE_DATE"
453 (
454     IFS=';'
455     for file in $RELEASE_FILES; do
456         fixup="$RELEASE_AUX/fixup-$(basename "$file")-release.pl"
457         $VERBOSE "> $file"
458         RELEASE="$release" RELEASE_TEXT="$release_text" RELEASE_DATE="$RELEASE_DATE" \
459                perl -pi $fixup $file
460     done
461 )
462
463 $VERBOSE "== Committing updates and tagging"
464 git add -u
465 git commit $git_quiet -m "Prepare for release of $release_text"$'\n\nRelease: yes'
466 if [ -n "$reviewers" ]; then
467     addrev --release --nopr $reviewers
468 fi
469 echo "Tagging release with tag $tag.  You may need to enter a pass phrase"
470 git tag$tagkey "$tag" -m "OpenSSL $release release tag"
471
472 tarfile=openssl-$release.tar
473 tgzfile=$tarfile.gz
474 announce=openssl-$release.txt
475
476 echo "== Generating tar, hash and announcement files.  This make take a bit of time"
477
478 $VERBOSE "== Making tarfile: $tgzfile"
479 # Unfortunately, util/mktar.sh does verbose output on STDERR...  for good
480 # reason, but it means we don't display errors unless --verbose
481 ./util/mktar.sh --tarfile="../$tarfile" 2>&1 \
482     | while read L; do $VERBOSE "> $L"; done
483
484 if ! [ -f "../$tgzfile" ]; then
485     echo >&2 "Where did the tarball end up? (../$tgzfile)"
486     exit 1
487 fi
488
489 $VERBOSE "== Generating checksums: $tgzfile.sha1 $tgzfile.sha256"
490 openssl sha1 < "../$tgzfile" | \
491     (IFS='='; while read X H; do echo $H; done) > "../$tgzfile.sha1"
492 openssl sha256 < "../$tgzfile" | \
493     (IFS='='; while read X H; do echo $H; done) > "../$tgzfile.sha256"
494 length=$(wc -c < "../$tgzfile")
495 sha1hash=$(cat "../$tgzfile.sha1")
496 sha256hash=$(cat "../$tgzfile.sha256")
497
498 $VERBOSE "== Generating announcement text: $announce"
499 # Hack the announcement template
500 cat "$RELEASE_AUX/$announce_template" \
501     | sed -e "s|\\\$release_text|$release_text|g" \
502           -e "s|\\\$release|$release|g" \
503           -e "s|\\\$series|$SERIES|g" \
504           -e "s|\\\$label|$PRE_LABEL|g" \
505           -e "s|\\\$tarfile|$tgzfile|" \
506           -e "s|\\\$length|$length|" \
507           -e "s|\\\$sha1hash|$sha1hash|" \
508           -e "s|\\\$sha256hash|$sha256hash|" \
509     | perl -p "$RELEASE_AUX/fix-title.pl" \
510     > "../$announce"
511
512 $VERBOSE "== Generating signatures: $tgzfile.asc $announce.asc"
513 rm -f "../$tgzfile.asc" "../$announce.asc"
514 echo "Signing the release files.  You may need to enter a pass phrase"
515 gpg$gpgkey --use-agent -sba "../$tgzfile"
516 gpg$gpgkey --use-agent -sta --clearsign "../$announce"
517
518 # Push everything to the parent repo
519 $VERBOSE "== Push what we have to the parent repository"
520 git push --follow-tags parent HEAD
521
522 if $do_upload; then
523     echo "== Upload tar, hash and announcement files"
524 fi
525
526 (
527     # With sftp, the progress meter is enabled by default,
528     # so we turn it off unless --verbose was given
529     if [ "$VERBOSE" == ':' ]; then
530         echo "progress"
531     fi
532     if [ -n "$upload_directory" ]; then
533         echo "cd $upload_directory"
534     fi
535     echo "put ../$tgzfile"
536     echo "put ../$tgzfile.sha1"
537     echo "put ../$tgzfile.sha256"
538     echo "put ../$tgzfile.asc"
539     echo "put ../$announce.asc"
540 ) | upload_backend_$upload_backend "$upload_address" $do_upload
541
542 # Post-release #######################################################
543
544 $VERBOSE "== Reset all files to their pre-release contents"
545 git reset $git_quiet HEAD^ -- .
546 git checkout -- .
547
548 prev_release_text="$release_text"
549 prev_release_date="$RELEASE_DATE"
550
551 next_release_state "$next_method2"
552 set_version
553
554 release="$FULL_VERSION"
555 release_text="$VERSION$_BUILD_METADATA"
556 if [ -n "$PRE_LABEL" ]; then
557     release_text="$SERIES$_BUILD_METADATA $PRE_LABEL $PRE_NUM"
558 fi
559 $VERBOSE "== Updated version information to $release"
560
561 $VERBOSE "== Updating files for $release :"
562 (
563     IFS=';'
564     for file in $RELEASE_FILES; do
565         fixup="$RELEASE_AUX/fixup-$(basename "$file")-postrelease.pl"
566         $VERBOSE "> $file"
567         RELEASE="$release" RELEASE_TEXT="$release_text" \
568                PREV_RELEASE_TEXT="$prev_release_text" \
569                PREV_RELEASE_DATE="$prev_release_date" \
570                perl -pi $fixup $file
571     done
572 )
573
574 $VERBOSE "== Committing updates"
575 git add -u
576 git commit $git_quiet -m "Prepare for $release_text"$'\n\nRelease: yes'
577 if [ -n "$reviewers" ]; then
578     addrev --release --nopr $reviewers
579 fi
580
581 # Push everything to the parent repo
582 $VERBOSE "== Push what we have to the parent repository"
583 git push parent HEAD
584
585 if $do_branch; then
586     $VERBOSE "== Going back to the update branch $tmp_update_branch"
587     git checkout $git_quiet "$tmp_update_branch"
588
589     get_version
590     next_release_state "minor"
591     set_version
592
593     release="$FULL_VERSION"
594     release_text="$SERIES$_BUILD_METADATA"
595     $VERBOSE "== Updated version information to $release"
596
597     $VERBOSE "== Updating files for $release :"
598     (
599         IFS=';'
600         for file in $RELEASE_FILES; do
601             fixup="$RELEASE_AUX/fixup-$(basename "$file")-postrelease.pl"
602             $VERBOSE "> $file"
603             RELEASE="$release" RELEASE_TEXT="$release_text" \
604                    perl -pi $fixup $file
605         done
606     )
607
608     $VERBOSE "== Committing updates"
609     git add -u
610     git commit $git_quiet -m "Prepare for $release_text"$'\n\nRelease: yes'
611     if [ -n "$reviewers" ]; then
612         addrev --release --nopr $reviewers
613     fi
614 fi
615
616 # Push everything to the parent repo
617 $VERBOSE "== Push what we have to the parent repository"
618 git push parent HEAD
619
620 # Done ###############################################################
621
622 $VERBOSE "== Done"
623
624 cd $HERE
625 cat <<EOF
626
627 ======================================================================
628 The release is done, and involves a few files and commits for you to
629 deal with.  Everything you need has been pushed to your repository,
630 please see instructions that follow.
631 ======================================================================
632
633 EOF
634
635 if $do_release; then
636     cat <<EOF
637
638 The following files were uploaded to $upload_address, please ensure they
639 are dealt with appropriately:
640
641     $tgzfile
642     $tgzfile.sha1
643     $tgzfile.sha256
644     $tgzfile.asc
645     $announce.asc
646 EOF
647 fi
648
649 cat <<EOF
650
651 ----------------------------------------------------------------------
652 EOF
653
654 if $do_branch; then
655     cat <<EOF
656 You need to prepare the main repository with a new branch, '$release_branch'.
657 That is done directly in the server's bare repository like this:
658
659     git branch $release_branch $orig_HEAD
660
661 Two additional release branches have been added to your repository.
662 Push them to github, make PRs from them and have them approved:
663
664     $tmp_update_branch
665     $tmp_release_branch
666
667 When merging them into the main repository, do it like this:
668
669     git push git@github.openssl.org:openssl/openssl.git \\
670         $tmp_release_branch:$release_branch
671     git push git@github.openssl.org:openssl/openssl.git \\
672         $tmp_update_branch:$update_branch
673     git push git@github.openssl.org:openssl/openssl.git \\
674         $tag
675 EOF
676 else
677 cat <<EOF
678 One additional release branch has been added to your repository.
679 Push it to github, make a PR from it and have it approved:
680
681     $tmp_release_branch
682
683 When merging it into the main repository, do it like this:
684
685     git push git@github.openssl.org:openssl/openssl.git \\
686         $tmp_release_branch:$release_branch
687     git push git@github.openssl.org:openssl/openssl.git \\
688         $tag
689 EOF
690 fi
691
692 cat <<EOF
693
694 ----------------------------------------------------------------------
695 EOF
696
697 cat <<EOF
698
699 When everything is done, or if something went wrong and you want to start
700 over, simply clean away temporary things left behind:
701
702 The release worktree:
703
704     rm -rf $release_clone
705 EOF
706
707 if $do_branch; then
708     cat <<EOF
709
710 The additional release branches:
711
712     git branch -D $tmp_release_branch
713     git branch -D $tmp_update_branch
714 EOF
715 else
716     cat <<EOF
717
718 The temporary release branch:
719
720     git branch -D $tmp_release_branch
721 EOF
722 fi
723
724 exit 0
725
726 # cat is inconsequential, it's only there to fend off zealous shell parsers
727 # that parse all the way here.
728 cat <<EOF
729 ### BEGIN MANUAL
730 =pod
731
732 =head1 NAME
733
734 release.sh - OpenSSL release script
735
736 =head1 SYNOPSIS
737
738 B<release.sh>
739 [
740 B<--alpha> |
741 B<--next-beta> |
742 B<--beta> |
743 B<--final> |
744 B<--branch> |
745 B<--local-user>=I<keyid> |
746 B<--reviewer>=I<id> |
747 B<--upload-address>=I<address> |
748 B<--no-upload> |
749 B<--no-update> |
750 B<--verbose> |
751 B<--debug> |
752 B<--help> |
753 B<--manual>
754 ]
755
756 =head1 DESCRIPTION
757
758 B<release.sh> creates an OpenSSL release, given current worktree conditions.
759 It will refuse to work unless the current branch is C<master> or a release
760 branch (see L</RELEASE BRANCHES AND TAGS> below for a discussion on those).
761
762 B<release.sh> tries to be smart and figure out the next release if no hints
763 are given through options, and will exit with an error in ambiguous cases.
764
765 B<release.sh> finishes off with instructions on what to do next.  When
766 finishing commands are given, they must be followed exactly.
767
768 B<release.sh> leaves behind a clone of the local workspace, as well as one
769 or two branches in the local repository.  These will be mentioned and can
770 safely be removed after all instructions have been successfully followed.
771
772 =head1 OPTIONS
773
774 =over 4
775
776 =item B<--alpha>, B<--beta>
777
778 Set the state of this branch to indicate that alpha or beta releases are
779 to be done.
780
781 B<--alpha> is only acceptable if the I<PATCH> version number is zero and
782 the current state is "in development" or that alpha releases are ongoing.
783
784 B<--beta> is only acceptable if the I<PATCH> version number is zero and
785 that alpha or beta releases are ongoing.
786
787 =item B<--next-beta>
788
789 Use together with B<--alpha> to switch to beta releases after the current
790 release is done.
791
792 =item B<--final>
793
794 Set the state of this branch to indicate that regular releases are to be
795 done.  This is only valid if alpha or beta releases are currently ongoing.
796
797 This implies B<--branch>.
798
799 =item B<--branch>
800
801 Create a branch specific for the I<SERIES> release series, if it doesn't
802 already exist, and switch to it.  The exact branch name will be
803 C<< openssl-I<SERIES> >>.
804
805 =item B<--upload-address>=I<address>
806
807 The location that the release files are to be uploaded to.  Supported values
808 are:
809
810 =over 4
811
812 =item -
813
814 an existing local directory
815
816 =item -
817
818 something that can be interpreted as an SCP/SFTP address.  In this case,
819 SFTP will always be used.  Typical SCP remote file specs will be translated
820 into something that makes sense for SFTP.
821
822 =back
823
824 The default upload address is C<upload@dev.openssl.org>.
825
826 =item B<--no-upload>
827
828 Don't upload the release files.
829
830 =item B<--no-update>
831
832 Don't run C<make update> and C<make update-fips-checksums>.
833
834 =item B<--verbose>
835
836 Verbose output.
837
838 =item B<--debug>
839
840 Display extra debug output.  Implies B<--no-upload>
841
842 =item B<--local-user>=I<keyid>
843
844 Use I<keyid> as the local user for C<git tag> and for signing with C<gpg>.
845
846 If not given, then the default e-mail address' key is used.
847
848 =item B<--reviewer>=I<id>
849
850 Add I<id> to the set of reviewers for the commits performed by this script.
851 Multiple reviewers are allowed.
852
853 If no reviewer is given, you will have to run C<addrev> manually, which
854 means retagging a release commit manually as well.
855
856 =item B<--force>
857
858 Force execution.  Precisely, the check that the current branch is C<master>
859 or a release branch is not done.
860
861 =item B<--help>
862
863 Display a quick help text and exit.
864
865 =item B<--manual>
866
867 Display this manual and exit.
868
869 =back
870
871 =head1 RELEASE BRANCHES AND TAGS
872
873 Prior to OpenSSL 3.0, the release branches were named
874 C<< OpenSSL_I<SERIES>-stable >>, and the release tags were named
875 C<< OpenSSL_I<VERSION> >> for regular releases, or
876 C<< OpenSSL_I<VERSION>-preI<n> >> for pre-releases.
877
878 From OpenSSL 3.0 ongoing, the release branches are named
879 C<< openssl-I<SERIES> >>, and the release tags are named
880 C<< openssl-I<VERSION> >> for regular releases, or
881 C<< openssl-I<VERSION>-alphaI<n> >> for alpha releases
882 and C<< openssl-I<VERSION>-betaI<n> >> for beta releases.
883
884 B<release.sh> recognises both forms.
885
886 =head1 VERSION AND STATE
887
888 With OpenSSL 3.0, all the version and state information is in the file
889 F<VERSION.dat>, where the following variables are used and changed:
890
891 =over 4
892
893 =item B<MAJOR>, B<MINOR>, B<PATCH>
894
895 The three part of the version number.
896
897 =item B<PRE_RELEASE_TAG>
898
899 The indicator of the current state of the branch.  The value may be one pf:
900
901 =over 4
902
903 =item C<dev>
904
905 This branch is "in development".  This is typical for the C<master> branch
906 unless there are ongoing alpha or beta releases.
907
908 =item C<< alphaI<n> >> or C<< alphaI<n>-dev >>
909
910 This branch has alpha releases going on.  C<< alphaI<n>-dev >> is what
911 should normally be seen in the git workspace, indicating that
912 C<< alphaI<n> >> is in development.  C<< alphaI<n> >> is what should be
913 found in the alpha release tar file.
914
915 =item C<< alphaI<n> >> or C<< alphaI<n>-dev >>
916
917 This branch has beta releases going on.  The details are otherwise exactly
918 as for alpha.
919
920 =item I<no value>
921
922 This is normally not seen in the git workspace, but should always be what's
923 found in the tar file of a regular release.
924
925 =back
926
927 =item B<BUILD_METADATA>
928
929 Extra build metadata to be used by anyone for their own purposes.
930
931 =item B<RELEASE_DATE>
932
933 This is normally empty in the git workspace, but should always have the
934 release date in the tar file of any release.
935
936 =back
937
938 =head1 COPYRIGHT
939
940 Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved.
941
942 Licensed under the Apache License 2.0 (the "License").  You may not use
943 this file except in compliance with the License.  You can obtain a copy
944 in the file LICENSE in the source distribution or at
945 L<https://www.openssl.org/source/license.html>.
946
947 =cut
948 ### END MANUAL
949 EOF