2 # Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved.
4 # Licensed under the Apache License 2.0 (the "License"). You may not use
5 # this file except in compliance with the License. You can obtain a copy
6 # in the file LICENSE in the source distribution or at
7 # https://www.openssl.org/source/license.html
9 # This is the most shell agnostic way to specify that POSIX rules.
12 # Force C locale because some commands (like date +%b) relies
13 # on the current locale.
18 Usage: release.sh [ options ... ]
20 --alpha Start or increase the "alpha" pre-release tag.
21 --next-beta Switch to the "beta" pre-release tag after alpha release.
22 It can only be given with --alpha.
23 --beta Start or increase the "beta" pre-release tag.
24 --final Get out of "alpha" or "beta" and make a final release.
27 --branch Create a release branch 'openssl-{major}.{minor}',
28 where '{major}' and '{minor}' are the major and minor
31 --reviewer=<id> The reviewer of the commits.
33 For the purpose of signing tags and tar files, use this
34 key (default: use the default e-mail address’ key).
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.
46 --force Force execution
51 If none of --alpha, --beta, or --final are given, this script tries to
52 figure out the next step.
57 # Set to one of 'major', 'minor', 'alpha', 'beta' or 'final'
82 upload_address=upload@dev.openssl.org
84 TEMP=$(getopt -l 'alpha,next-beta,beta,final' \
86 -l 'upload-address:' \
87 -l 'no-upload,no-update' \
88 -l 'quiet,verbose,debug' \
94 -n release.sh -- - "$@")
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
104 if [ "$next_method" = 'final' ]; then
109 next_method2=$(echo "x$1" | sed -e 's|^x--next-||')
153 reviewers="$reviewers $1=$2"
170 sed -e '1,/^### BEGIN MANUAL/d' \
171 -e '/^### END MANUAL/,$d' \
182 echo >&2 "Unknown option $1"
189 $DEBUG >&2 "DEBUG: \$next_method=$next_method"
190 $DEBUG >&2 "DEBUG: \$next_method2=$next_method2"
192 $DEBUG >&2 "DEBUG: \$do_branch=$do_branch"
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"
200 case "$next_method+$next_method2" in
201 major+major | minor+minor )
204 alpha+alpha | alpha+beta | beta+beta | final+final | + | +beta )
208 echo >&2 "Internal option error ($next_method, $next_method2)"
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
220 # Setup ##############################################################
222 # Check that we have the scripts that define functions we use
223 RELEASE_AUX=$(cd $(dirname $0)/release-aux; pwd)
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"
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
243 # Make sure we're in the work directory, and remember it
244 if HERE=$(git rev-parse --show-toplevel); then
247 echo >&2 "Not in a git worktree"
251 # Make sure that it's a plausible OpenSSL work tree, by checking
252 # that a version file is found
255 if [ -z "$VERSION_FILE" ]; then
256 echo >&2 "Couldn't find OpenSSL version data"
260 # Make sure it's a branch we recognise
261 orig_branch=$(git rev-parse --abbrev-ref HEAD)
262 if (echo "$orig_branch" \
265 -e '^OpenSSL_[0-9]+_[0-9]+_[0-9]+[a-z]*-stable$' \
266 -e '^openssl-[0-9]+\.[0-9]+$'); then
271 echo >&2 "Not in master or any recognised release branch"
272 echo >&2 "Please 'git checkout' an appropriate branch"
275 orig_HEAD=$(git rev-parse HEAD)
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.
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"
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
301 case "$upload_address" in
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%%:*}"
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.
322 upload_address="${upload_address%%/*}"
326 echo >&2 "Invalid upload address $upload_address"
330 if $do_upload && ! [ -d "$upload_address" ]; then
331 echo >&2 "Not an existing directory: $upload_address"
338 # Initialize #########################################################
340 $ECHO "== Initializing work tree"
342 # Generate a cloned directory name
343 release_clone="$orig_branch-release-tmp"
345 $ECHO "== Work tree will be in $release_clone"
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"
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-
359 update_branch="$orig_branch"
360 release_branch="$(std_branch_name)"
362 # among others, we only create a release branch if the patch number is zero
363 if [ "$update_branch" = "$release_branch" ] \
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"
372 if ! $do_branch; then
373 release_branch="$update_branch"
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"
381 # Check that we're still on the same branch as our parent repo, or on a
383 current_branch=$(git rev-parse --abbrev-ref HEAD)
384 if [ "$current_branch" = "$update_branch" ]; then
386 elif [ "$current_branch" = "$release_branch" ]; then
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'."
393 echo >&2 "other than '$update_branch' or '$release_branch'."
395 echo >&2 "Please 'cd \"$(pwd)\"; git checkout $update_branch'"
400 $DEBUG >&2 "DEBUG: Source directory is $SOURCEDIR"
402 # Release ############################################################
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:"
411 echo >&2 "(cd $release_clone; git reset --hard HEAD^)"
412 echo >&2 "# WARNING! LOOK BEFORE YOU ACT"
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"
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"
424 $ECHO "== Configuring OpenSSL for update and release. This may take a bit of time"
428 $VERBOSE "== Checking source file updates and fips checksums"
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
434 if [ "$next_method" != 'alpha' ] && grep -q '^renumber *:' Makefile; then
437 if grep -q '^update-fips-checksums *:' Makefile; then
438 make update-fips-checksums >&42
441 if [ -n "$(git status --porcelain --untracked-files=no --ignore-submodules=all)" ]; then
442 $VERBOSE "== Committing updates"
444 git commit $git_quiet -m $'make update\n\nRelease: yes'
445 if [ -n "$reviewers" ]; then
446 addrev --release --nopr $reviewers
450 # Create our temporary update branch, if it's not the release branch.
451 # This is used in post-release below
453 $VERBOSE "== Creating a local update branch: $tmp_update_branch"
454 git branch $git_quiet "$tmp_update_branch"
457 # Write the version information we updated
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
465 release_text="$release"
466 announce_template=openssl-announce-release.tmpl
468 tag="$(std_tag_name)"
469 $VERBOSE "== Updated version information to $release"
471 $VERBOSE "== Updating files with release date for $release : $RELEASE_DATE"
474 for file in $RELEASE_FILES; do
475 fixup="$RELEASE_AUX/fixup-$(basename "$file")-release.pl"
477 RELEASE="$release" RELEASE_TEXT="$release_text" RELEASE_DATE="$RELEASE_DATE" \
478 perl -pi $fixup $file
482 $VERBOSE "== Committing updates and tagging"
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
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"
491 tarfile=openssl-$release.tar
493 announce=openssl-$release.txt
495 $ECHO "== Generating tar, hash and announcement files. This make take a bit of time"
497 $VERBOSE "== Making tarfile: $tgzfile"
499 # Unfortunately, some tarball generators do verbose output on STDERR... for
500 # good reason, but it means we don't display errors unless --verbose
502 if [ -f ./util/mktar.sh ]; then
503 ./util/mktar.sh --tarfile="../$tarfile" 2>&1
505 make DISTTARVARS=TARFILE="../$tarfile" dist 2>&1
507 ) | while read L; do $VERBOSE "> $L"; done
509 if ! [ -f "../$tgzfile" ]; then
510 echo >&2 "Where did the tarball end up? (../$tgzfile)"
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")
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" \
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"
543 # Push everything to the parent repo
544 $VERBOSE "== Push what we have to the parent repository"
545 git push --follow-tags parent HEAD
548 $ECHO "== Upload tar, hash and announcement files"
552 # With sftp, the progress meter is enabled by default,
553 # so we turn it off unless --verbose was given
554 if [ "$VERBOSE" == ':' ]; then
557 if [ -n "$upload_directory" ]; then
558 echo "cd $upload_directory"
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
567 # Post-release #######################################################
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.
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^ -- .
583 prev_release_text="$release_text"
584 prev_release_date="$RELEASE_DATE"
586 next_release_state "$next_method2"
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"
594 $VERBOSE "== Updated version information to $release"
596 $VERBOSE "== Updating files for $release :"
599 for file in $RELEASE_FILES; do
600 fixup="$RELEASE_AUX/fixup-$(basename "$file")-postrelease.pl"
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
609 $VERBOSE "== Committing updates"
611 git commit $git_quiet -m "Prepare for $release_text"$'\n\nRelease: yes'
612 if [ -n "$reviewers" ]; then
613 addrev --release --nopr $reviewers
616 # Push everything to the parent repo
617 $VERBOSE "== Push what we have to the parent repository"
621 $VERBOSE "== Going back to the update branch $tmp_update_branch"
622 git checkout $git_quiet "$tmp_update_branch"
625 next_release_state "minor"
628 release="$FULL_VERSION"
629 release_text="$SERIES$_BUILD_METADATA"
630 $VERBOSE "== Updated version information to $release"
632 $VERBOSE "== Updating files for $release :"
635 for file in $RELEASE_FILES; do
636 fixup="$RELEASE_AUX/fixup-$(basename "$file")-postrelease.pl"
638 RELEASE="$release" RELEASE_TEXT="$release_text" \
639 perl -pi $fixup $file
643 $VERBOSE "== Committing updates"
645 git commit $git_quiet -m "Prepare for $release_text"$'\n\nRelease: yes'
646 if [ -n "$reviewers" ]; then
647 addrev --release --nopr $reviewers
651 if ! $clean_worktree; then
652 # Push everything to the parent repo
653 $VERBOSE "== Push what we have to the parent repository"
657 # Done ###############################################################
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'"
670 echo "release_tag='$tag'"
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 ======================================================================
685 The following files were uploaded to $upload_address, please ensure they
686 are dealt with appropriately:
698 ----------------------------------------------------------------------
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:
706 git branch $release_branch $orig_HEAD
708 Two additional release branches have been added to your repository.
709 Push them to github, make PRs from them and have them approved:
714 When merging them into the main repository, do it like this:
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 \\
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:
730 When merging it into the main repository, do it like this:
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 \\
741 ----------------------------------------------------------------------
746 When everything is done, or if something went wrong and you want to start
747 over, simply clean away temporary things left behind:
749 The release worktree:
751 rm -rf $release_clone
757 The additional release branches:
759 git branch -D $tmp_release_branch
760 git branch -D $tmp_update_branch
765 The temporary release branch:
767 git branch -D $tmp_release_branch
774 # cat is inconsequential, it's only there to fend off zealous shell parsers
775 # that parse all the way here.
782 release.sh - OpenSSL release script
793 B<--local-user>=I<keyid> |
794 B<--reviewer>=I<id> |
795 B<--upload-address>=I<address> |
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).
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.
815 B<release.sh> finishes off with instructions on what to do next. When
816 finishing commands are given, they must be followed exactly.
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.
826 =item B<--alpha>, B<--beta>
828 Set the state of this branch to indicate that alpha or beta releases are
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.
834 B<--beta> is only acceptable if the I<PATCH> version number is zero and
835 that alpha or beta releases are ongoing.
839 Use together with B<--alpha> to switch to beta releases after the current
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.
847 This implies B<--branch>.
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> >>.
855 =item B<--upload-address>=I<address>
857 The location that the release files are to be uploaded to. Supported values
864 an existing local directory
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.
874 The default upload address is C<upload@dev.openssl.org>.
878 Don't upload the release files.
882 Don't run C<make update> and C<make update-fips-checksums>.
886 Really quiet, only bare necessity output, which is the final instructions,
887 or should the B<--porcelain> option be used, only that output.
889 messages appearing on standard error will still be shown, but should be
898 Display extra debug output. Implies B<--no-upload>
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:
907 =item B<clone_directory>=I<dir>
909 The directory for the clone that this script creates.
911 =item B<update_branch>=I<branch>
913 The temporary update branch
915 =item B<final_update_branch>=I<branch>
917 The final update branch that the temporary update branch should end up being
920 =item B<release_branch>=I<branch>
922 The temporary release branch, only given if it differs from the update branch
923 (i.e. B<--branch> was given or implied).
925 =item B<final_release_branch>=I<branch>
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).
931 =item B<release_tag>=I<tag>
937 =item B<--local-user>=I<keyid>
939 Use I<keyid> as the local user for C<git tag> and for signing with C<gpg>.
941 If not given, then the default e-mail address' key is used.
943 =item B<--reviewer>=I<id>
945 Add I<id> to the set of reviewers for the commits performed by this script.
946 Multiple reviewers are allowed.
948 If no reviewer is given, you will have to run C<addrev> manually, which
949 means retagging a release commit manually as well.
953 Force execution. Precisely, the check that the current branch is C<master>
954 or a release branch is not done.
958 Display a quick help text and exit.
962 Display this manual and exit.
966 =head1 RELEASE BRANCHES AND TAGS
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.
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.
979 B<release.sh> recognises both forms.
981 =head1 VERSION AND STATE
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:
988 =item B<MAJOR>, B<MINOR>, B<PATCH>
990 The three part of the version number.
992 =item B<PRE_RELEASE_TAG>
994 The indicator of the current state of the branch. The value may be one pf:
1000 This branch is "in development". This is typical for the C<master> branch
1001 unless there are ongoing alpha or beta releases.
1003 =item C<< alphaI<n> >> or C<< alphaI<n>-dev >>
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.
1010 =item C<< alphaI<n> >> or C<< alphaI<n>-dev >>
1012 This branch has beta releases going on. The details are otherwise exactly
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.
1022 =item B<BUILD_METADATA>
1024 Extra build metadata to be used by anyone for their own purposes.
1026 =item B<RELEASE_DATE>
1028 This is normally empty in the git workspace, but should always have the
1029 release date in the tar file of any release.
1035 Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved.
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>.