f3b8e09ee09c4f2ad4b5e8e52a4aa56234881d73
[openssl.git] / dev / release.sh
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.
10 POSIXLY_CORRECT=1
11
12 usage () {
13     cat <<EOF
14 Usage: 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
27 --reviewer=<id> The reviewer of the commits.
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
42 If none of --alpha, --beta, or --final are given, this script tries to
43 figure out the next step.
44 EOF
45     exit 0
46 }
47
48 # Set to one of 'major', 'minor', 'alpha', 'beta' or 'final'
49 next_method=
50 next_method2=
51
52 do_branch=false
53 warn_branch=false
54
55 do_clean=true
56 do_upload=true
57 do_update=true
58 DEBUG=:
59 VERBOSE=:
60 git_quiet=-q
61
62 force=false
63
64 do_help=false
65 do_manual=false
66
67 tagkey=' -s'
68 gpgkey=
69 reviewers=
70
71 upload_address=upload@dev.openssl.org
72
73 TEMP=$(getopt -l 'alpha,next-beta,beta,final' \
74               -l 'branch' \
75               -l 'no-upload,no-update' \
76               -l 'verbose,debug' \
77               -l 'local-user:' \
78               -l 'reviewer:' \
79               -l 'force' \
80               -l 'help,manual' \
81               -n release.sh -- - "$@")
82 eval set -- "$TEMP"
83 while 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         tagkey=" -u $1"
125         gpgkey=" -u $1"
126         shift
127         ;;
128     --reviewer )
129         reviewers="$reviewers $1=$2"
130         shift
131         shift
132         ;;
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
159 done
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
172 case "$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         ;;
183 esac
184
185 # Verbosity feed for certain commands
186 VERBOSITY_FIFO=/tmp/openssl-$$.fifo
187 mkfifo -m 600 $VERBOSITY_FIFO
188 ( cat $VERBOSITY_FIFO | while read L; do $VERBOSE "> $L"; done ) &
189 exec 42>$VERBOSITY_FIFO
190 trap "exec 42>&-; rm $VERBOSITY_FIFO" 0 2
191
192 # Setup ##############################################################
193
194 # Make sure we're in the work directory
195 cd $(dirname $0)/..
196 HERE=$(pwd)
197
198 # Check that we have the scripts that define functions we use
199 found=true
200 for 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
206 done
207 if ! $found; then
208     exit 1
209 fi
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
216 orig_branch=$(git rev-parse --abbrev-ref HEAD)
217 if (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     :
223 elif $force; then
224     :
225 else
226     echo >&2 "Not in master or any recognised release branch"
227     echo >&2 "Please 'git checkout' an approprite branch"
228     exit 1
229 fi
230 orig_HEAD=$(git rev-parse HEAD)
231
232 # Initialize #########################################################
233
234 echo "== Initializing work tree"
235
236 get_version
237
238 # Generate a cloned directory name
239 release_clone="$orig_branch-release-tmp"
240
241 echo "== Work tree will be in $release_clone"
242
243 # Make a clone in a subdirectory and move there
244 if ! [ -d "$release_clone" ]; then
245     $VERBOSE "== Cloning to $release_clone"
246     git clone $git_quiet -b "$orig_branch" -o parent . "$release_clone"
247 fi
248 cd "$release_clone"
249
250 get_version
251
252 # Branches we will work with.  The release branch is where we make the
253 # changes for the release, the update branch is where we make the post-
254 # release changes
255 update_branch="$orig_branch"
256 release_branch="openssl-$SERIES.x"
257
258 # among others, we only create a release branch if the patch number is zero
259 if [ "$update_branch" = "$release_branch" ] || [ $PATCH -ne 0 ]; then
260     if $do_branch && $warn_branch; then
261         echo >&2 "Warning! We're already in a release branch; --branch ignored"
262     fi
263     do_branch=false
264 fi
265
266 if ! $do_branch; then
267     release_branch="$update_branch"
268 fi
269
270 # Branches we create for PRs
271 branch_version="$VERSION${PRE_LABEL:+-$PRE_LABEL$PRE_NUM}"
272 tmp_update_branch="OSSL--$update_branch--$branch_version"
273 tmp_release_branch="OSSL--$release_branch--$branch_version"
274
275 # Check that we're still on the same branch as our parent repo, or on a
276 # release branch
277 current_branch=$(git rev-parse --abbrev-ref HEAD)
278 if [ "$current_branch" = "$update_branch" ]; then
279     :
280 elif [ "$current_branch" = "$release_branch" ]; then
281     :
282 else
283     echo >&2 "The cloned sub-directory '$release_clone' is on a branch"
284     if [ "$update_branch" = "$release_branch" ]; then
285         echo >&2 "other than '$update_branch'."
286     else
287         echo >&2 "other than '$update_branch' or '$release_branch'."
288     fi
289     echo >&2 "Please 'cd \"$(pwd)\"; git checkout $update_branch'"
290     exit 1
291 fi
292
293 SOURCEDIR=$(pwd)
294 $DEBUG >&2 "DEBUG: Source directory is $SOURCEDIR"
295
296 # Release ############################################################
297
298 # We always expect to start from a state of development
299 if [ "$TYPE" != 'dev' ]; then
300     echo >&2 "Not in a development branch"
301     echo >&2 "Have a look at the git log in $release_clone, it may be that"
302     echo >&2 "a previous crash left it in an intermediate state and that"
303     echo >&2 "need to drop the top commit:"
304     echo >&2 ""
305     echo >&2 "(cd $release_clone; git reset --hard HEAD^)"
306     echo >&2 "# WARNING! LOOK BEFORE YOU ACT"
307     exit 1
308 fi
309
310 # Update the version information.  This won't save anything anywhere, yet,
311 # but does check for possible next_method errors before we do bigger work.
312 next_release_state "$next_method"
313
314 # Create our temporary release branch
315 $VERBOSE "== Creating a local release branch: $tmp_release_branch"
316 git checkout $git_quiet -b "$tmp_release_branch"
317
318 echo "== Configuring OpenSSL for update and release.  This may take a bit of time"
319
320 ./Configure cc >&42
321
322 $VERBOSE "== Checking source file updates"
323
324 make update >&42
325
326 if [ -n "$(git status --porcelain)" ]; then
327     $VERBOSE "== Committing updates"
328     git add -u
329     git commit $git_quiet -m 'make update'
330     if [ -n "$reviewers" ]; then
331         addrev --nopr $reviewers
332     fi
333 fi
334
335 # Create our temporary update branch, if it's not the release branch.
336 # This is used in post-release below
337 if $do_branch; then
338     $VERBOSE "== Creating a local update branch: $tmp_update_branch"
339     git branch $git_quiet "$tmp_update_branch"
340 fi    
341
342 # Write the version information we updated
343 set_version
344
345 if [ -n "$PRE_LABEL" ]; then
346     release="$VERSION-$PRE_RELEASE_TAG$BUILD_METADATA"
347     release_text="$SERIES$BUILD_METADATA $PRE_LABEL $PRE_NUM"
348     announce_template=openssl-announce-pre-release.tmpl
349 else
350     release="$VERSION$BUILD_METADATA"
351     release_text="$release"
352     announce_template=openssl-announce-release.tmpl
353 fi
354 tag="openssl-$release"
355 $VERBOSE "== Updated version information to $release"
356
357 $VERBOSE "== Updating files with release date for $release : $RELEASE_DATE"
358 for fixup in "$HERE/dev/release-aux"/fixup-*-release.pl; do
359     file="$(basename "$fixup" | sed -e 's|^fixup-||' -e 's|-release\.pl$||')"
360     $VERBOSE "> $file"
361     RELEASE="$release" RELEASE_TEXT="$release_text" RELEASE_DATE="$RELEASE_DATE" \
362         perl -pi $fixup $file
363 done
364
365 $VERBOSE "== Comitting updates and tagging"
366 git add -u
367 git commit $git_quiet -m "Prepare for release of $release_text"
368 if [ -n "$reviewers" ]; then
369     addrev --nopr $reviewers
370 fi
371 echo "Tagging release with tag $tag.  You may need to enter a pass phrase"
372 git tag$tagkey "$tag" -m "OpenSSL $release release tag"
373
374 tarfile=openssl-$release.tar
375 tgzfile=$tarfile.gz
376 announce=openssl-$release.txt
377
378 echo "== Generating tar, hash and announcement files.  This make take a bit of time"
379
380 $VERBOSE "== Making tarfile: $tgzfile"
381 # Unfortunately, util/mktar.sh does verbose output on STDERR...  for good
382 # reason, but it means we don't display errors unless --verbose
383 ./util/mktar.sh --tarfile="../$tarfile" 2>&1 \
384     | while read L; do $VERBOSE "> $L"; done
385
386 if ! [ -f "../$tgzfile" ]; then
387     echo >&2 "Where did the tarball end up? (../$tgzfile)"
388     exit 1
389 fi
390
391 $VERBOSE "== Generating checksums: $tgzfile.sha1 $tgzfile.sha256"
392 openssl sha1 < "../$tgzfile" | \
393     (IFS='='; while read X H; do echo $H; done) > "../$tgzfile.sha1"
394 openssl sha256 < "../$tgzfile" | \
395     (IFS='='; while read X H; do echo $H; done) > "../$tgzfile.sha256"
396 length=$(wc -c < "../$tgzfile")
397 sha1hash=$(cat "../$tgzfile.sha1")
398 sha256hash=$(cat "../$tgzfile.sha256")
399
400 $VERBOSE "== Generating announcement text: $announce"
401 # Hack the announcement template
402 cat "$HERE/dev/release-aux/$announce_template" \
403     | sed -e "s|\\\$release_text|$release_text|g" \
404           -e "s|\\\$release|$release|g" \
405           -e "s|\\\$series|$SERIES|g" \
406           -e "s|\\\$label|$PRE_LABEL|g" \
407           -e "s|\\\$tarfile|$tgzfile|" \
408           -e "s|\\\$length|$length|" \
409           -e "s|\\\$sha1hash|$sha1hash|" \
410           -e "s|\\\$sha256hash|$sha256hash|" \
411     | perl -p "$HERE/dev/release-aux/fix-title.pl" \
412     > "../$announce"
413               
414 $VERBOSE "== Generating signatures: $tgzfile.asc $announce.asc"
415 rm -f "../$tgzfile.asc" "../$announce.asc"
416 echo "Signing the release files.  You may need to enter a pass phrase"
417 gpg$gpgkey --use-agent -sba "../$tgzfile"
418 gpg$gpgkey --use-agent -sta --clearsign "../$announce"
419
420 # Push everything to the parent repo
421 $VERBOSE "== Push what we have to the parent repository"
422 git push --follow-tags parent HEAD
423
424 if $do_upload; then
425     (
426         if [ "$VERBOSE" != ':' ]; then
427             echo "progress"
428         fi
429         echo "put ../$tgzfile"
430         echo "put ../$tgzfile.sha1"
431         echo "put ../$tgzfile.sha256"
432         echo "put ../$tgzfile.asc"
433         echo "put ../$announce.asc"
434     ) \
435     | sftp "$upload_address"
436 fi
437
438 # Post-release #######################################################
439
440 $VERBOSE "== Reset all files to their pre-release contents"
441 git reset $git_quiet HEAD^ -- .
442 git checkout -- .
443
444 prev_release_text="$release_text"
445 prev_release_date="$RELEASE_DATE"
446
447 next_release_state "$next_method2"
448 set_version
449
450 release="$VERSION-$PRE_RELEASE_TAG$BUILD_METADATA"
451 release_text="$VERSION$BUILD_METADATA"
452 if [ -n "$PRE_LABEL" ]; then
453     release_text="$SERIES$BUILD_METADATA $PRE_LABEL $PRE_NUM"
454 fi
455 $VERBOSE "== Updated version information to $release"
456
457 $VERBOSE "== Updating files for $release :"
458 for fixup in "$HERE/dev/release-aux"/fixup-*-postrelease.pl; do
459     file="$(basename "$fixup" | sed -e 's|^fixup-||' -e 's|-postrelease\.pl$||')"
460     $VERBOSE "> $file"
461     RELEASE="$release" RELEASE_TEXT="$release_text" \
462         PREV_RELEASE_TEXT="$prev_release_text" \
463         PREV_RELEASE_DATE="$prev_release_date" \
464         perl -pi $fixup $file
465 done
466
467 $VERBOSE "== Comitting updates"
468 git add -u
469 git commit $git_quiet -m "Prepare for $release_text"
470 if [ -n "$reviewers" ]; then
471     addrev --nopr $reviewers
472 fi
473
474 # Push everything to the parent repo
475 $VERBOSE "== Push what we have to the parent repository"
476 git push parent HEAD
477
478 if $do_branch; then
479     $VERBOSE "== Going back to the update branch $tmp_update_branch"
480     git checkout $git_quiet "$tmp_update_branch"
481
482     get_version
483     next_release_state "minor"
484     set_version
485
486     release="$VERSION-$PRE_RELEASE_TAG$BUILD_METADATA"
487     release_text="$SERIES$BUILD_METADATA"
488     $VERBOSE "== Updated version information to $release"
489
490     $VERBOSE "== Updating files for $release :"
491     for fixup in "$HERE/dev/release-aux"/fixup-*-postrelease.pl; do
492         file="$(basename "$fixup" | sed -e 's|^fixup-||' -e 's|-postrelease\.pl$||')"
493         $VERBOSE "> $file"
494         RELEASE="$release" RELEASE_TEXT="$release_text" \
495             perl -pi $fixup $file
496     done
497
498     $VERBOSE "== Comitting updates"
499     git add -u
500     git commit $git_quiet -m "Prepare for $release_text"
501     if [ -n "$reviewers" ]; then
502         addrev --nopr $reviewers
503     fi
504 fi
505
506 # Push everything to the parent repo
507 $VERBOSE "== Push what we have to the parent repository"
508 git push parent HEAD
509
510 # Done ###############################################################
511     
512 $VERBOSE "== Done"
513
514 cd $HERE
515 cat <<EOF
516
517 ======================================================================
518 The release is done, and involves a few files and commits for you to
519 deal with.  Everything you need has been pushed to your repository,
520 please see instructions that follow.
521 ======================================================================
522
523 EOF
524
525 if $do_release; then
526     cat <<EOF
527
528 The following files were uploaded to $upload_address, please ensure they
529 are dealt with appropriately:
530
531     $tgzfile
532     $tgzfile.sha1
533     $tgzfile.sha256
534     $tgzfile.asc
535     $announce.asc
536 EOF
537 fi
538
539 cat <<EOF
540
541 ----------------------------------------------------------------------
542 EOF
543
544 if $do_branch; then
545     cat <<EOF
546 You need to prepare the main repository with a new branch, '$release_branch'.
547 That is done directly in the server's bare repository like this:
548
549     git branch $release_branch $orig_HEAD
550
551 Two additional release branches have been added to your repository.
552 Push them to github, make PRs from them and have them approved:
553
554     $tmp_update_branch
555     $tmp_release_branch
556
557 When merging them into the main repository, do it like this:
558
559     git push openssl-git@git.openssl.org:openssl.git \\
560         $tmp_release_branch:$release_branch
561     git push openssl-git@git.openssl.org:openssl.git \\
562         $tmp_update_branch:$update_branch
563     git push openssl-git@git.openssl.org:openssl.git \\
564         $tag
565 EOF
566 else
567 cat <<EOF
568 One additional release branch has been added to your repository.
569 Push it to github, make a PR from it and have it approved:
570
571     $tmp_release_branch
572
573 When merging it into the main repository, do it like this:
574
575     git push openssl-git@git.openssl.org:openssl.git \\
576         $tmp_release_branch:$release_branch
577     git push openssl-git@git.openssl.org:openssl.git \\
578         $tag
579 EOF
580 fi
581
582 cat <<EOF
583
584 ----------------------------------------------------------------------
585 EOF
586
587 cat <<EOF
588
589 When everything is done, or if something went wrong and you want to start
590 over, simply clean away temporary things left behind:
591
592 The release worktree:
593
594     rm -rf $release_clone
595 EOF
596
597 if $do_branch; then
598     cat <<EOF
599
600 The additional release branches:
601
602     git branch -D $tmp_release_branch
603     git branch -D $tmp_update_branch
604 EOF
605 else
606     cat <<EOF
607
608 The temporary release branch:
609
610     git branch -D $tmp_release_branch
611 EOF
612 fi
613
614 exit 0
615
616 # cat is inconsequential, it's only there to fend off zealous shell parsers
617 # that parse all the way here.
618 cat <<EOF
619 ### BEGIN MANUAL
620 =pod
621
622 =head1 NAME
623
624 release.sh - OpenSSL release script
625
626 =head1 SYNOPSIS
627
628 B<release.sh>
629 [
630 B<--alpha> |
631 B<--next-beta> |
632 B<--beta> |
633 B<--final> |
634 B<--branch> |
635 B<--local-user>=I<keyid> |
636 B<--reviewer>=I<id> |
637 B<--no-upload> |
638 B<--no-update> |
639 B<--verbose> |
640 B<--debug> |
641 B<--help> |
642 B<--manual>
643 ]
644
645 =head1 DESCRIPTION
646
647 B<release.sh> creates an OpenSSL release, given current worktree conditions.
648 It will refuse to work unless the current branch is C<master> or a release
649 branch (see L</RELEASE BRANCHES AND TAGS> below for a discussion on those).
650
651 B<release.sh> tries to be smart and figure out the next release if no hints
652 are given through options, and will exit with an error in ambiguous cases.
653
654 B<release.sh> finishes off with instructions on what to do next.  When
655 finishing commands are given, they must be followed exactly.
656
657 B<release.sh> leaves behind a clone of the local workspace, as well as one
658 or two branches in the local repository.  These will be mentioned and can
659 safely be removed after all instructions have been successfully followed.
660
661 =head1 OPTIONS
662
663 =over 4
664
665 =item B<--alpha>, B<--beta>
666
667 Set the state of this branch to indicate that alpha or beta releases are
668 to be done.
669
670 B<--alpha> is only acceptable if the I<PATCH> version number is zero and
671 the current state is "in development" or that alpha releases are ongoing.
672
673 B<--beta> is only acceptable if the I<PATCH> version number is zero and
674 that alpha or beta releases are ongoing.
675
676 =item B<--next-beta>
677
678 Use together with B<--alpha> to switch to beta releases after the current
679 release is done.
680
681 =item B<--final>
682
683 Set the state of this branch to indicate that regular releases are to be
684 done.  This is only valid if alpha or beta releases are currently ongoing.
685
686 This implies B<--branch>.
687
688 =item B<--branch>
689
690 Create a branch specific for the I<SERIES>.x release series, if it doesn't
691 already exist, and switch to it.  The exact branch name will be
692 C<< openssl-I<SERIES>.x >>.
693
694 =item B<--no-upload>
695
696 Don't upload the produced files.
697
698 =item B<--no-update>
699
700 Don't run C<make update>.
701
702 =item B<--verbose>
703
704 Verbose output.
705
706 =item B<--debug>
707
708 Display extra debug output.  Implies B<--no-upload>
709
710 =item B<--local-user>=I<keyid>
711
712 Use I<keyid> as the local user for C<git tag> and for signing with C<gpg>.
713
714 If not given, then the default e-mail address' key is used.
715
716 =item B<--reviewer>=I<id>
717
718 Add I<id> to the set of reviewers for the commits performed by this script.
719 Multiple reviewers are allowed.
720
721 If no reviewer is given, you will have to run C<addrev> manually, which
722 means retagging a release commit manually as well.
723
724 =item B<--force>
725
726 Force execution.  Precisely, the check that the current branch is C<master>
727 or a release branch is not done.
728
729 =item B<--help>
730
731 Display a quick help text and exit.
732
733 =item B<--manual>
734
735 Display this manual and exit.
736
737 =back
738
739 =head1 RELEASE BRANCHES AND TAGS
740
741 Prior to OpenSSL 3.0, the release branches were named
742 C<< OpenSSL_I<SERIES>-stable >>, and the release tags were named
743 C<< OpenSSL_I<VERSION> >> for regular releases, or
744 C<< OpenSSL_I<VERSION>-preI<n> >> for pre-releases.
745
746 From OpenSSL 3.0 ongoing, the release branches are named
747 C<< openssl-I<SERIES>.x >>, and the release tags are named
748 C<< openssl-I<VERSION> >> for regular releases, or
749 C<< openssl-I<VERSION>-alphaI<n> >> for alpha releases
750 and C<< openssl-I<VERSION>-betaI<n> >> for beta releases.
751
752 B<release.sh> recognises both forms.
753
754 =head1 VERSION AND STATE
755
756 With OpenSSL 3.0, all the version and state information is in the file
757 F<VERSION.dat>, where the following variables are used and changed:
758
759 =over 4
760
761 =item B<MAJOR>, B<MINOR>, B<PATCH>
762
763 The three part of the version number.
764
765 =item B<PRE_RELEASE_TAG>
766
767 The indicator of the current state of the branch.  The value may be one pf:
768
769 =over 4
770
771 =item C<dev>
772
773 This branch is "in development".  This is typical for the C<master> branch
774 unless there are ongoing alpha or beta releases.
775
776 =item C<< alphaI<n> >> or C<< alphaI<n>-dev >>
777
778 This branch has alpha releases going on.  C<< alphaI<n>-dev >> is what
779 should normally be seen in the git workspace, indicating that
780 C<< alphaI<n> >> is in development.  C<< alphaI<n> >> is what should be
781 found in the alpha release tar file.
782
783 =item C<< alphaI<n> >> or C<< alphaI<n>-dev >>
784
785 This branch has beta releases going on.  The details are otherwise exactly
786 as for alpha.
787
788 =item I<no value>
789
790 This is normally not seen in the git workspace, but should always be what's
791 found in the tar file of a regular release.
792
793 =back
794
795 =item B<RELEASE_DATE>
796
797 This is normally empty in the git workspace, but should always have the
798 release date in the tar file of any release.
799
800 =back
801
802 =head1 COPYRIGHT
803
804 Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
805
806 Licensed under the Apache License 2.0 (the "License").  You may not use
807 this file except in compliance with the License.  You can obtain a copy
808 in the file LICENSE in the source distribution or at
809 L<https://www.openssl.org/source/license.html>.
810
811 =cut
812 ### END MANUAL
813 EOF