]> git.ipfire.org Git - thirdparty/openssl.git/blame - dev/release.sh
Prepare for release of 3.0 alpha 3
[thirdparty/openssl.git] / dev / release.sh
CommitLineData
b0b0b6a4
RL
1#! /bin/bash -e
2# Copyright 2020 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.
10POSIXLY_CORRECT=1
11
12usage () {
13 cat <<EOF
14Usage: release.sh [ options ... ]
15
16--alpha Start or increase the "alpha" pre-release tag.
17--next-beta Switch to the "beta" pre-release tag after alpha release.
18 It can only be given with --alpha.
19--beta Start or increase the "beta" pre-release tag.
20--final Get out of "alpha" or "beta" and make a final release.
21 Implies --branch.
22
23--branch Create a release branch 'openssl-{major}.{minor}.x',
24 where '{major}' and '{minor}' are the major and minor
25 version numbers.
26
64af3aec 27--reviewer=<id> The reviewer of the commits.
b0b0b6a4
RL
28--local-user=<keyid>
29 For the purpose of signing tags and tar files, use this
30 key (default: use the default e-mail address’ key).
31
32--no-upload Don't upload to upload@dev.openssl.org.
33--no-update Don't perform 'make update'.
34--verbose Verbose output.
35--debug Include debug output. Implies --no-upload.
36
37--force Force execution
38
39--help This text
40--manual The manual
41
42If none of --alpha, --beta, or --final are given, this script tries to
43figure out the next step.
44EOF
45 exit 0
46}
47
48# Set to one of 'major', 'minor', 'alpha', 'beta' or 'final'
49next_method=
50next_method2=
51
52do_branch=false
53warn_branch=false
54
55do_clean=true
56do_upload=true
57do_update=true
58DEBUG=:
59VERBOSE=:
60git_quiet=-q
61
62force=false
63
64do_help=false
65do_manual=false
66
67tagkey=' -s'
68gpgkey=
64af3aec 69reviewers=
b0b0b6a4
RL
70
71upload_address=upload@dev.openssl.org
72
73TEMP=$(getopt -l 'alpha,next-beta,beta,final' \
74 -l 'branch' \
75 -l 'no-upload,no-update' \
76 -l 'verbose,debug' \
77 -l 'local-user:' \
64af3aec 78 -l 'reviewer:' \
b0b0b6a4
RL
79 -l 'force' \
80 -l 'help,manual' \
81 -n release.sh -- - "$@")
82eval set -- "$TEMP"
83while true; do
84 case $1 in
85 --alpha | --beta | --final )
86 next_method=$(echo "x$1" | sed -e 's|^x--||')
87 if [ -z "$next_method2" ]; then
88 next_method2=$next_method
89 fi
90 shift
91 if [ "$next_method" = 'final' ]; then
92 do_branch=true
93 fi
94 ;;
95 --next-beta )
96 next_method2=$(echo "x$1" | sed -e 's|^x--next-||')
97 shift
98 ;;
99 --branch )
100 do_branch=true
101 warn_branch=true
102 shift
103 ;;
104 --no-upload )
105 do_upload=false
106 shift
107 ;;
108 --no-update )
109 do_update=false
110 shift
111 ;;
112 --verbose )
113 VERBOSE=echo
114 git_quiet=
115 shift
116 ;;
117 --debug )
118 DEBUG=echo
119 do_upload=false
120 shift
121 ;;
122 --local-user )
123 shift
124 tagley=" -u $1"
125 gpgkey=" -u $1"
126 shift
127 ;;
64af3aec
RL
128 --reviewer )
129 reviewers="$reviewers $1=$2"
130 shift
131 shift
132 ;;
b0b0b6a4
RL
133 --force )
134 force=true
135 shift
136 ;;
137 --help )
138 usage
139 exit 0
140 ;;
141 --manual )
142 sed -e '1,/^### BEGIN MANUAL/d' \
143 -e '/^### END MANUAL/,$d' \
144 < "$0" \
145 | pod2man \
146 | man -l -
147 exit 0
148 ;;
149 -- )
150 shift
151 break
152 ;;
153 * )
154 echo >&2 "Unknown option $1"
155 shift
156 exit 1
157 ;;
158 esac
159done
160
161$DEBUG >&2 "DEBUG: \$next_method=$next_method"
162$DEBUG >&2 "DEBUG: \$next_method2=$next_method2"
163
164$DEBUG >&2 "DEBUG: \$do_branch=$do_branch"
165
166$DEBUG >&2 "DEBUG: \$do_upload=$do_upload"
167$DEBUG >&2 "DEBUG: \$do_update=$do_update"
168$DEBUG >&2 "DEBUG: \$DEBUG=$DEBUG"
169$DEBUG >&2 "DEBUG: \$VERBOSE=$VERBOSE"
170$DEBUG >&2 "DEBUG: \$git_quiet=$git_quiet"
171
172case "$next_method+$next_method2" in
173 major+major | minor+minor )
174 # These are expected
175 ;;
176 alpha+alpha | alpha+beta | beta+beta | final+final | + | +beta )
177 # These are expected
178 ;;
179 * )
180 echo >&2 "Internal option error ($next_method, $next_method2)"
181 exit 1
182 ;;
183esac
184
185# Verbosity feed for certain commands
186VERBOSITY_FIFO=/tmp/openssl-$$.fifo
187mkfifo -m 600 $VERBOSITY_FIFO
188( cat $VERBOSITY_FIFO | while read L; do $VERBOSE "> $L"; done ) &
189exec 42>$VERBOSITY_FIFO
190trap "exec 42>&-; rm $VERBOSITY_FIFO" 0 2
191
192# Setup ##############################################################
193
194# Make sure we're in the work directory
195cd $(dirname $0)/..
196HERE=$(pwd)
197
198# Check that we have the scripts that define functions we use
199found=true
200for fn in "$HERE/dev/release-aux/release-version-fn.sh" \
201 "$HERE/dev/release-aux/release-state-fn.sh"; do
202 if ! [ -f "$fn" ]; then
203 echo >&2 "'$fn' is missing"
204 found=false
205 fi
206done
207if ! $found; then
208 exit 1
209fi
210
211# Load version functions
212. $HERE/dev/release-aux/release-version-fn.sh
213. $HERE/dev/release-aux/release-state-fn.sh
214
215# Make sure it's a branch we recognise
216orig_branch=$(git rev-parse --abbrev-ref HEAD)
217if (echo "$orig_branch" \
218 | grep -E -q \
219 -e '^master$' \
220 -e '^OpenSSL_[0-9]+_[0-9]+_[0-9]+[a-z]*-stable$' \
221 -e '^openssl-[0-9]+\.[0-9]+\.x$'); then
222 :
223elif $force; then
224 :
225else
226 echo >&2 "Not in master or any recognised release branch"
227 echo >&2 "Please 'git checkout' an approprite branch"
228 exit 1
229fi
230
231# Initialize #########################################################
232
233echo "== Initializing work tree"
234
235get_version
236
237# Generate a cloned directory name
238clone_branch="openssl-$SERIES.x"
239release_clone="$clone_branch-release-tmp"
240
241echo "== Work tree will be in $release_clone"
242
243# Make a clone in a subdirectory and move there
244if ! [ -d "$release_clone" ]; then
245 $VERBOSE "== Cloning to $release_clone"
246 git clone $git_quiet -b "$orig_branch" . "$release_clone"
247fi
248cd "$release_clone"
249
250get_version
251
252current_branch="$(git rev-parse --abbrev-ref HEAD)"
253new_branch="openssl-$SERIES.x"
254
255# Check that we're still on the same branch, or on a release branch
256if [ "$current_branch" = "$orig_branch" ]; then
257 :
258elif [ "$current_branch" = "$new_branch" ]; then
259 :
260else
261 echo >&2 "The cloned sub-directory '$release_clone' is on a branch"
262 echo >&2 "other than '$current_branch' or '$new_branch'"
263 echo >&2 "Please 'cd \"$(pwd)\"; git checkout $current_branch'"
264 exit 1
265fi
266
267if $do_branch; then
268 if [ "$current_branch" = "$new_branch" ]; then
269 do_branch=false
270 fi
271 if ! $do_branch && $warn_branch; then
272 echo >&2 "Warning: --branch ignored, we're already in a release branch"
273 fi
274fi
275
276SOURCEDIR=$(pwd)
277$DEBUG >&2 "DEBUG: Source directory is $SOURCEDIR"
278
279# Release ############################################################
280
281# We always expect to start from a state of development
282if [ "$TYPE" != 'dev' ]; then
283 echo >&2 "Not in a development branch"
284 echo >&2 "Have a look at the git log in $release_clone, it may be that"
285 echo >&2 "a previous crash left it in an intermediate state and that"
286 echo >&2 "need to drop the top commit:"
287 echo >&2 ""
288 echo >&2 "(cd $release_clone; git reset --hard HEAD^)"
289 echo >&2 "# WARNING! LOOK BEFORE YOU ACT"
290 exit 1
291fi
292
293# We only create a release branch if the patch number is zero
294if [ $PATCH -ne 0 ]; then
295 if $do_branch; then
296 echo >&2 "Warning! We're already in a release branch; --branch ignored"
297 fi
298 do_branch=false
299fi
300
301# Update the version information. This won't save anything anywhere, yet,
302# but does check for possible next_method errors before we do bigger work.
303next_release_state "$next_method"
304
305if $do_branch; then
306 $VERBOSE "== Creating a release branch: $new_branch"
307 git checkout $git_quiet -b "$new_branch"
308fi
309
310echo "== Configuring OpenSSL for update and release. This may take a bit of time"
311
312./Configure cc >&42
313
314$VERBOSE "== Checking source file updates"
315
316make update >&42
317
318if [ -n "$(git status --porcelain)" ]; then
319 $VERBOSE "== Committing updates"
320 git add -u
321 git commit $git_quiet -m 'make update'
64af3aec
RL
322 if [ -n "$reviewers" ]; then
323 addrev --nopr $reviewers
324 fi
b0b0b6a4
RL
325fi
326
327# Write the version information we updated
328set_version
329
330if [ -n "$PRE_LABEL" ]; then
331 release="$VERSION-$PRE_RELEASE_TAG$BUILD_METADATA"
332 release_text="$SERIES$BUILD_METADATA $PRE_LABEL $PRE_NUM"
333 announce_template=openssl-announce-pre-release.tmpl
334else
335 release="$VERSION$BUILD_METADATA"
336 release_text="$release"
337 announce_template=openssl-announce-release.tmpl
338fi
339tag="openssl-$release"
340$VERBOSE "== Updated version information to $release"
341
342$VERBOSE "== Updating files with release date for $release : $RELEASE_DATE"
343for fixup in "$HERE/dev/release-aux"/fixup-*-release.pl; do
344 file="$(basename "$fixup" | sed -e 's|^fixup-||' -e 's|-release\.pl$||')"
345 $VERBOSE "> $file"
346 RELEASE="$release" RELEASE_TEXT="$release_text" RELEASE_DATE="$RELEASE_DATE" \
347 perl -pi $fixup $file
348done
349
350$VERBOSE "== Comitting updates and tagging"
351git add -u
352git commit $git_quiet -m "Prepare for release of $release_text"
64af3aec
RL
353if [ -n "$reviewers" ]; then
354 addrev --nopr $reviewers
355fi
b0b0b6a4
RL
356echo "Tagging release with tag $tag. You may need to enter a pass phrase"
357git tag$tagkey "$tag" -m "OpenSSL $release release tag"
358
359tarfile=openssl-$release.tar
360tgzfile=$tarfile.gz
361announce=openssl-$release.txt
362
363echo "== Generating tar, hash and announcement files. This make take a bit of time"
364
365$VERBOSE "== Making tarfile: $tgzfile"
366# Unfortunately, util/mktar.sh does verbose output on STDERR... for good
367# reason, but it means we don't display errors unless --verbose
368./util/mktar.sh --tarfile="../$tarfile" 2>&1 \
369 | while read L; do $VERBOSE "> $L"; done
370
371if ! [ -f "../$tgzfile" ]; then
372 echo >&2 "Where did the tarball end up? (../$tgzfile)"
373 exit 1
374fi
375
376$VERBOSE "== Generating checksums: $tgzfile.sha1 $tgzfile.sha256"
377openssl sha1 < "../$tgzfile" | \
378 (IFS='='; while read X H; do echo $H; done) > "../$tgzfile.sha1"
379openssl sha256 < "../$tgzfile" | \
380 (IFS='='; while read X H; do echo $H; done) > "../$tgzfile.sha256"
381length=$(wc -c < "../$tgzfile")
382sha1hash=$(cat "../$tgzfile.sha1")
383sha256hash=$(cat "../$tgzfile.sha256")
384
385$VERBOSE "== Generating announcement text: $announce"
386# Hack the announcement template
387cat "$HERE/dev/release-aux/$announce_template" \
388 | sed -e "s|\\\$release_text|$release_text|g" \
389 -e "s|\\\$release|$release|g" \
390 -e "s|\\\$series|$SERIES|g" \
391 -e "s|\\\$label|$PRE_LABEL|g" \
392 -e "s|\\\$tarfile|$tgzfile|" \
393 -e "s|\\\$length|$length|" \
394 -e "s|\\\$sha1hash|$sha1hash|" \
395 -e "s|\\\$sha256hash|$sha256hash|" \
396 | perl -p "$HERE/dev/release-aux/fix-title.pl" \
397 > "../$announce"
398
399$VERBOSE "== Generating signatures: $tgzfile.asc $announce.asc"
400rm -f "../$tgzfile.asc" "../$announce.asc"
401echo "Signing the release files. You may need to enter a pass phrase"
402gpg$gpgkey --use-agent -sba "../$tgzfile"
403gpg$gpgkey --use-agent -sta --clearsign "../$announce"
404
405# We finish off by resetting all files, so we don't have to update
406# files with release dates again
407$VERBOSE "== Reset all files to their pre-commit contents"
408git reset $git_quiet HEAD^ -- .
409git checkout -- .
410
411if $do_upload; then
412 (
413 if [ "$VERBOSE" != ':' ]; then
414 echo "progress"
415 fi
416 echo "put ../$tgzfile"
417 echo "put ../$tgzfile.sha1"
418 echo "put ../$tgzfile.sha256"
419 echo "put ../$tgzfile.asc"
420 echo "put ../$announce.asc"
421 ) \
422 | sftp "$upload_address"
423fi
424
425# Post-release #######################################################
426
427prev_release_text="$release_text"
428prev_release_date="$RELEASE_DATE"
429
430next_release_state "$next_method2"
431set_version
432
433release="$VERSION-$PRE_RELEASE_TAG$BUILD_METADATA"
434release_text="$VERSION$BUILD_METADATA"
435if [ -n "$PRE_LABEL" ]; then
436 release_text="$SERIES$BUILD_METADATA $PRE_LABEL $PRE_NUM"
437fi
438$VERBOSE "== Updated version information to $release"
439
440$VERBOSE "== Updating files for $release :"
441for fixup in "$HERE/dev/release-aux"/fixup-*-postrelease.pl; do
442 file="$(basename "$fixup" | sed -e 's|^fixup-||' -e 's|-postrelease\.pl$||')"
443 $VERBOSE "> $file"
444 RELEASE="$release" RELEASE_TEXT="$release_text" \
445 PREV_RELEASE_TEXT="$prev_release_text" \
446 PREV_RELEASE_DATE="$prev_release_date" \
447 perl -pi $fixup $file
448done
449
450$VERBOSE "== Comitting updates"
451git add -u
452git commit $git_quiet -m "Prepare for $release_text"
64af3aec
RL
453if [ -n "$reviewers" ]; then
454 addrev --nopr $reviewers
455fi
b0b0b6a4
RL
456
457if $do_branch; then
458 $VERBOSE "== Going back to the main branch $current_branch"
459 git checkout $git_quiet "$current_branch"
460
461 get_version
462 next_release_state "minor"
463 set_version
464
465 release="$VERSION-$PRE_RELEASE_TAG$BUILD_METADATA"
466 release_text="$SERIES$BUILD_METADATA"
467 $VERBOSE "== Updated version information to $release"
468
469 $VERBOSE "== Updating files for $release :"
470 for fixup in "$HERE/dev/release-aux"/fixup-*-postrelease.pl; do
471 file="$(basename "$fixup" | sed -e 's|^fixup-||' -e 's|-postrelease\.pl$||')"
472 $VERBOSE "> $file"
473 RELEASE="$release" RELEASE_TEXT="$release_text" \
474 perl -pi $fixup $file
475 done
476
477 $VERBOSE "== Comitting updates"
478 git add -u
479 git commit $git_quiet -m "Prepare for $release_text"
64af3aec
RL
480 if [ -n "$reviewers" ]; then
481 addrev --nopr $reviewers
482 fi
b0b0b6a4
RL
483fi
484
485# Done ###############################################################
486
487$VERBOSE "== Done"
488
489cat <<EOF
490
491======================================================================
492The release is done, and involves a few commits for you to deal with.
493It has all been done in a clone of this workspace, see details below.
494EOF
495if $do_branch; then
496 cat <<EOF
497Additionally, a release branch has been created for you, so you need
498to look for new commits in two places.
499EOF
500fi
501
502if $do_release; then
503 cat <<EOF
504
505These files were uploaded to $upload_address:
506
507 ../$tgzfile
508 ../$tgzfile.sha1
509 ../$tgzfile.sha256
510 ../$tgzfile.asc
511 ../$announce.asc
512EOF
513fi
514
515cat <<EOF
516
517Release worktree: $release_clone
518EOF
519if [ "$current_branch" != "$new_branch" ]; then
520 cat <<EOF
521Current branch: $current_branch
522EOF
523fi
524if $do_branch; then
525 cat <<EOF
526New release branch: $new_branch
527EOF
528fi
529
530cat <<EOF
531======================================================================
532EOF
533
534cat <<EOF
535If something went wrong and you want to start over, all you need is to
536remove the release worktree:
537
538 rm -rf $release_clone
539
540If a tarball was uploaded, you must also clean that away, or ask you
541kind OpenSSL sysadmin to do so.
542EOF
543
544exit 0
545
546# cat is inconsequential, it's only there to fend off zealous shell parsers
547# that parse all the way here.
548cat <<EOF
549### BEGIN MANUAL
550=pod
551
552=head1 NAME
553
554release.sh - OpenSSL release script
555
556=head1 SYNOPSIS
557
558B<release.sh>
559[
560B<--alpha> |
561B<--next-beta> |
562B<--beta> |
563B<--final> |
564B<--branch> |
565B<--local-user>=I<keyid> |
64af3aec 566B<--reviewer>=I<id> |
b0b0b6a4
RL
567B<--no-upload> |
568B<--no-update> |
569B<--verbose> |
570B<--debug> |
571B<--help> |
572B<--manual>
573]
574
575=head1 DESCRIPTION
576
577B<release.sh> creates an OpenSSL release, given current worktree conditions.
578It will refuse to work unless the current branch is C<master> or a release
579branch (see L</RELEASE BRANCHES AND TAGS> below for a discussion on those).
580
581B<release.sh> tries to be smart and figure out the next release if no hints
582are given through options, and will exit with an error in ambiguous cases.
583
584B<release.sh> always clones the current workspace into a sub-directory
585named C<< openssl-I<SERIES>-tmp >>, where C<< I<SERIES> >> is taken from
586the available version information in the source.
587
588=head1 OPTIONS
589
590=over 4
591
592=item B<--alpha>, B<--beta>
593
594Set the state of this branch to indicate that alpha or beta releases are
595to be done.
596
597B<--alpha> is only acceptable if the I<PATCH> version number is zero and
598the current state is "in development" or that alpha releases are ongoing.
599
600B<--beta> is only acceptable if the I<PATCH> version number is zero and
601that alpha or beta releases are ongoing.
602
603=item B<--next-beta>
604
605Use together with B<--alpha> to switch to beta releases after the current
606release is done.
607
608=item B<--final>
609
610Set the state of this branch to indicate that regular releases are to be
611done. This is only valid if alpha or beta releases are currently ongoing.
612
613This implies B<--branch>.
614
615=item B<--branch>
616
617Create a branch specific for the I<SERIES>.x release series, if it doesn't
618already exist, and switch to it. The exact branch name will be
619C<< openssl-I<SERIES>.x >>.
620
621=item B<--no-upload>
622
623Don't upload the produced files.
624
625=item B<--no-update>
626
627Don't run C<make update>.
628
629=item B<--verbose>
630
631Verbose output.
632
633=item B<--debug>
634
635Display extra debug output. Implies B<--no-upload>
636
637=item B<--local-user>=I<keyid>
638
639Use I<keyid> as the local user for C<git tag> and for signing with C<gpg>.
640
641If not given, then the default e-mail address' key is used.
642
64af3aec
RL
643=item B<--reviewer>=I<id>
644
645Add I<id> to the set of reviewers for the commits performed by this script.
646Multiple reviewers are allowed.
647
648If no reviewer is given, you will have to run C<addrev> manually, which
649means retagging a release commit manually as well.
650
b0b0b6a4
RL
651=item B<--force>
652
653Force execution. Precisely, the check that the current branch is C<master>
654or a release branch is not done.
655
656=item B<--help>
657
658Display a quick help text and exit.
659
660=item B<--manual>
661
662Display this manual and exit.
663
664=back
665
666=head1 RELEASE BRANCHES AND TAGS
667
668Prior to OpenSSL 3.0, the release branches were named
669C<< OpenSSL_I<SERIES>-stable >>, and the release tags were named
670C<< OpenSSL_I<VERSION> >> for regular releases, or
671C<< OpenSSL_I<VERSION>-preI<n> >> for pre-releases.
672
673From OpenSSL 3.0 ongoing, the release branches are named
674C<< openssl-I<SERIES>.x >>, and the release tags are named
675C<< openssl-I<VERSION> >> for regular releases, or
676C<< openssl-I<VERSION>-alphaI<n> >> for alpha releases
677and C<< openssl-I<VERSION>-betaI<n> >> for beta releases.
678
679B<release.sh> recognises both forms.
680
681=head1 VERSION AND STATE
682
683With OpenSSL 3.0, all the version and state information is in the file
684F<VERSION>, where the following variables are used and changed:
685
686=over 4
687
688=item B<MAJOR>, B<MINOR>, B<PATCH>
689
690The three part of the version number.
691
692=item B<PRE_RELEASE_TAG>
693
694The indicator of the current state of the branch. The value may be one pf:
695
696=over 4
697
698=item C<dev>
699
700This branch is "in development". This is typical for the C<master> branch
701unless there are ongoing alpha or beta releases.
702
703=item C<< alphaI<n> >> or C<< alphaI<n>-dev >>
704
705This branch has alpha releases going on. C<< alphaI<n>-dev >> is what
706should normally be seen in the git workspace, indicating that
707C<< alphaI<n> >> is in development. C<< alphaI<n> >> is what should be
708found in the alpha release tar file.
709
710=item C<< alphaI<n> >> or C<< alphaI<n>-dev >>
711
712This branch has beta releases going on. The details are otherwise exactly
713as for alpha.
714
715=item I<no value>
716
717This is normally not seen in the git workspace, but should always be what's
718found in the tar file of a regular release.
719
720=back
721
722=item B<RELEASE_DATE>
723
724This is normally empty in the git workspace, but should always have the
725release date in the tar file of any release.
726
727=back
728
729=head1 COPYRIGHT
730
731Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
732
733Licensed under the Apache License 2.0 (the "License"). You may not use
734this file except in compliance with the License. You can obtain a copy
735in the file LICENSE in the source distribution or at
736L<https://www.openssl.org/source/license.html>.
737
738=cut
739### END MANUAL
740EOF