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