diff --git a/.gitattributes b/.gitattributes index 96e40b6cd4..e2558331ac 100644 --- a/.gitattributes +++ b/.gitattributes @@ -10,3 +10,4 @@ util/mktar.sh export-ignore boringssl export-ignore krb5 export-ignore pyca-cryptography export-ignore +dev export-ignore diff --git a/dev/README b/dev/README new file mode 100644 index 0000000000..aee3fcd6af --- /dev/null +++ b/dev/README @@ -0,0 +1,6 @@ +Developer files +=============== + +Here are all kinds of things that an OpenSSL developer might need or +might choose to use. Some of them demand access to OpenSSL's +infrastructure, others are simply practical. diff --git a/dev/release-aux/README.md b/dev/release-aux/README.md new file mode 100644 index 0000000000..9d05ae5f98 --- /dev/null +++ b/dev/release-aux/README.md @@ -0,0 +1,30 @@ +Auxilliary files for dev/release.sh +=================================== + +- release-state-fn.sh + + This is the main version and state update logic... you could say + that it's the innermost engine for the release mechanism. It + tries to be agnostic of versioning schemes, and relies on + release-version-fn.sh to supply necessary functions that are + specific for versioning schemes. + +- release-version-fn.sh + + Supplies functions that are specific to versioning schemes: + + get_version() gets the version data from appropriate files. + + set_version() writes the version data to appropriate files. + + fixup_version() updates the version data, given a first argument + that instructs it what update to do. + +- openssl-announce-pre-release.tmpl and openssl-announce-release.tmpl + + Templates for announcements + +- fixup-*-release.pl and fixup-*-postrelease.pl + + Fixup scripts for specific files, to be done for the release + commit and for the post-release commit. diff --git a/dev/release-aux/fix-title.pl b/dev/release-aux/fix-title.pl new file mode 100644 index 0000000000..d3f00b984b --- /dev/null +++ b/dev/release-aux/fix-title.pl @@ -0,0 +1,6 @@ +#! /usr/bin/perl + +BEGIN { my $prev } +($_ = $prev) =~ s|^( *)(.*)$|"$1" . '=' x length($2)|e + if m|==========|; +$prev = $_; diff --git a/dev/release-aux/fixup-CHANGES.md-postrelease.pl b/dev/release-aux/fixup-CHANGES.md-postrelease.pl new file mode 100644 index 0000000000..6592635dc3 --- /dev/null +++ b/dev/release-aux/fixup-CHANGES.md-postrelease.pl @@ -0,0 +1,28 @@ +#! /usr/bin/env perl -pi + +BEGIN { + our $count = 1; # Only the first one + our $RELEASE = $ENV{RELEASE}; + our $RELEASE_TEXT = $ENV{RELEASE_TEXT}; + our $PREV_RELEASE_DATE = $ENV{PREV_RELEASE_DATE} || 'xx XXX xxxx'; + our $PREV_RELEASE_TEXT = $ENV{PREV_RELEASE_TEXT}; + + $RELEASE =~ s/-dev//; +} + +if (/^### Changes between (\S+) and (\S+) \[xx XXX xxxx\]/ + && $count-- > 0) { + my $v1 = $1; + my $v2 = $PREV_RELEASE_TEXT || $2; + + # If this is a pre-release, we do nothing + if ($RELEASE !~ /^\d+\.\d+\.\d+-(?:alpha|beta)/) { + $_ = <<_____ +### Changes between $v2 and $RELEASE_TEXT [xx XXX xxxx] ### + + * + +### Changes between $v1 and $v2 [$PREV_RELEASE_DATE] ### +_____ + } +} diff --git a/dev/release-aux/fixup-CHANGES.md-release.pl b/dev/release-aux/fixup-CHANGES.md-release.pl new file mode 100644 index 0000000000..7e5ba7e8ce --- /dev/null +++ b/dev/release-aux/fixup-CHANGES.md-release.pl @@ -0,0 +1,13 @@ +#! /usr/bin/env perl -p + +BEGIN { + our $count = 1; # Only the first one + our $RELEASE = $ENV{RELEASE}; + our $RELEASE_TEXT = $ENV{RELEASE_TEXT}; + our $RELEASE_DATE = $ENV{RELEASE_DATE}; +} + +if (/^### Changes between (\S+) and (\S+) \[xx XXX xxxx\]/ + && $count-- > 0) { + $_ = "### Changes between $1 and $RELEASE_TEXT [$RELEASE_DATE]$'"; +} diff --git a/dev/release-aux/fixup-NEWS.md-postrelease.pl b/dev/release-aux/fixup-NEWS.md-postrelease.pl new file mode 100644 index 0000000000..b1d47264b0 --- /dev/null +++ b/dev/release-aux/fixup-NEWS.md-postrelease.pl @@ -0,0 +1,28 @@ +#! /usr/bin/env perl -pi + +BEGIN { + our $count = 1; # Only the first one + our $RELEASE = $ENV{RELEASE}; + our $RELEASE_TEXT = $ENV{RELEASE_TEXT}; + our $PREV_RELEASE_DATE = $ENV{PREV_RELEASE_DATE} || 'under development'; + our $PREV_RELEASE_TEXT = $ENV{PREV_RELEASE_TEXT}; + + $RELEASE =~ s/-dev//; +} + +if (/^### Major changes between OpenSSL (\S+) and OpenSSL (\S+) \[under development\]/ + && $count-- > 0) { + my $v1 = $1; + my $v2 = $PREV_RELEASE_TEXT || $2; + + # If this is a pre-release, we do nothing + if ($RELEASE !~ /^\d+\.\d+\.\d+-(?:alpha|beta)/) { + $_ = <<_____ +### Major changes between OpenSSL $v2 and OpenSSL $RELEASE_TEXT [under development] ### + + * + +### Major changes between OpenSSL $v1 and OpenSSL $v2 [$PREV_RELEASE_DATE] ### +_____ + } +} diff --git a/dev/release-aux/fixup-NEWS.md-release.pl b/dev/release-aux/fixup-NEWS.md-release.pl new file mode 100644 index 0000000000..212e10e869 --- /dev/null +++ b/dev/release-aux/fixup-NEWS.md-release.pl @@ -0,0 +1,16 @@ +#! /usr/bin/env perl -p + +BEGIN { + our $count = 1; # Only the first one + our $RELEASE = $ENV{RELEASE}; + our $RELEASE_TEXT = $ENV{RELEASE_TEXT}; + our $RELEASE_DATE = $ENV{RELEASE_DATE}; + + $RELEASE_DATE = 'in pre-release' + if ($RELEASE =~ /\d+\.\d+\.\d+-(?:alpha|beta)/) +} + +if (/^### Major changes between OpenSSL (\S+) and OpenSSL (\S+) \[under development\]/ + && $count-- > 0) { + $_ = "### Major changes between OpenSSL $1 and OpenSSL $RELEASE_TEXT [$RELEASE_DATE]$'"; +} diff --git a/dev/release-aux/openssl-announce-pre-release.tmpl b/dev/release-aux/openssl-announce-pre-release.tmpl new file mode 100644 index 0000000000..2f3b5d36f4 --- /dev/null +++ b/dev/release-aux/openssl-announce-pre-release.tmpl @@ -0,0 +1,49 @@ + + OpenSSL version $release_text released + ====================================== + + OpenSSL - The Open Source toolkit for SSL/TLS + https://www.openssl.org/ + + OpenSSL $series is currently in $label. + + OpenSSL $release_text has now been made available. For details of + changes and known issues see the release notes at: + + https://www.openssl.org/news/openssl-$series-notes.html + + Note: This OpenSSL pre-release has been provided for testing ONLY. + It should NOT be used for security critical purposes. + + The $label release is available for download via HTTPS and FTP from the + following master locations (you can find the various FTP mirrors under + https://www.openssl.org/source/mirror.html): + + * https://www.openssl.org/source/ + * ftp://ftp.openssl.org/source/ + + The distribution file name is: + + o $tarfile + Size: $length + SHA1 checksum: $sha1hash + SHA256 checksum: $sha256hash + + The checksums were calculated using the following commands: + + openssl sha1 $tarfile + openssl sha256 $tarfile + + Please download and check this $LABEL release as soon as possible. + To report a bug, open an issue on GitHub: + + https://github.com/openssl/openssl/issues + + Please check the release notes and mailing lists to avoid duplicate + reports of known issues. (Of course, the source is also available + on GitHub.) + + Yours, + + The OpenSSL Project Team. + diff --git a/dev/release-aux/openssl-announce-release.tmpl b/dev/release-aux/openssl-announce-release.tmpl new file mode 100644 index 0000000000..8e708c2253 --- /dev/null +++ b/dev/release-aux/openssl-announce-release.tmpl @@ -0,0 +1,36 @@ + + OpenSSL version $release released + ================================= + + OpenSSL - The Open Source toolkit for SSL/TLS + https://www.openssl.org/ + + The OpenSSL project team is pleased to announce the release of + version $release of our open source toolkit for SSL/TLS. + For details of changes and known issues see the release notes at: + + https://www.openssl.org/news/openssl-$series-notes.html + + OpenSSL $release is available for download via HTTPS and FTP from the + following master locations (you can find the various FTP mirrors under + https://www.openssl.org/source/mirror.html): + + * https://www.openssl.org/source/ + * ftp://ftp.openssl.org/source/ + + The distribution file name is: + + o $tarfile + Size: $length + SHA1 checksum: $sha1hash + SHA256 checksum: $sha256hash + + The checksums were calculated using the following commands: + + openssl sha1 $tarfile + openssl sha256 $tarfile + + Yours, + + The OpenSSL Project Team. + diff --git a/dev/release-aux/release-state-fn.sh b/dev/release-aux/release-state-fn.sh new file mode 100644 index 0000000000..f495cb8536 --- /dev/null +++ b/dev/release-aux/release-state-fn.sh @@ -0,0 +1,202 @@ +#! /bin/sh +# Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +# This will increase the version number and pre-release tag, according to the +# current state of the source tree, and the function's first argument (called +# |next| internally), which is how the caller tells what the next step should +# be. +# +# The possible current source tree states are: +# '' The source is in a released state. +# 'dev' The source is in development. This is the normal state. +# 'alpha', 'alphadev' +# The source is undergoing a series of alpha releases. +# 'beta', 'betadev' +# The source is undergoing a series of beta releases. +# These states are computed from $PRE_LABEL and $TYPE +# +# The possible |next| values are: +# 'alpha' The source tree should move to an alpha release state, or +# stay there. This trips the alpha / pre-release counter. +# 'beta' The source tree should move to a beta release state, or +# stay there. This trips the beta / pre-release counter. +# 'final' The source tree should move to a final release (assuming it's +# currently in one of the alpha or beta states). This turns +# off the alpha or beta states. +# '' The source tree should move to the next release. The exact +# meaning depends on the current source state. It may mean +# tripping the alpha / beta / pre-release counter, or increasing +# the PATCH number. +# +# 'minor' The source tree should move to the next minor version. This +# should only be used in the master branch when a release branch +# has been created. +# +# This function expects there to be a function called fixup_version(), which +# SHOULD take the |next| as first argument, and SHOULD increase the label +# counter or the PATCH number accordingly, but only when the current +# state is "in development". + +next_release_state () { + local next="$1" + local today="$(date '+%-d %b %Y')" + local retry=true + + local before="$PRE_LABEL$TYPE" + + while $retry; do + retry=false + + $DEBUG >&2 "DEBUG[next_release_state]: BEGIN: \$before=$before" + $DEBUG >&2 "DEBUG[next_release_state]: BEGIN: \$next=$next" + $DEBUG >&2 "DEBUG[next_release_state]: BEGIN: \$MAJOR=$MAJOR" + $DEBUG >&2 "DEBUG[next_release_state]: BEGIN: \$MINOR=$MINOR" + $DEBUG >&2 "DEBUG[next_release_state]: BEGIN: \$PATCH=$PATCH" + $DEBUG >&2 "DEBUG[next_release_state]: BEGIN: \$TYPE=$TYPE" + $DEBUG >&2 "DEBUG[next_release_state]: BEGIN: \$PRE_LABEL=$PRE_LABEL" + $DEBUG >&2 "DEBUG[next_release_state]: BEGIN: \$PRE_NUM=$PRE_NUM" + $DEBUG >&2 "DEBUG[next_release_state]: BEGIN: \$RELEASE_DATE=$RELEASE_DATE" + + case "$before+$next" in + # MAKING ALPHA RELEASES ################################## + + # Alpha releases can't be made from beta versions or real versions + beta*+alpha | +alpha ) + echo >&2 "Invalid state for an alpha release" + echo >&2 "Try --beta or --final, or perhaps nothing" + exit 1 + ;; + # For alpha releases, the tag update is dev => alpha or + # alpha dev => alpha for the release itself, and + # alpha => alpha dev for post release. + dev+alpha | alphadev+alpha ) + TYPE= + RELEASE_DATE="$today" + fixup_version "alpha" + ;; + alpha+alpha ) + TYPE=dev + RELEASE_DATE= + fixup_version "alpha" + ;; + + # MAKING BETA RELEASES ################################### + + # Beta releases can't be made from real versions + +beta ) + echo >&2 "Invalid state for beta release" + echo >&2 "Try --final, or perhaps nothing" + exit 1 + ;; + # For beta releases, the tag update is dev => beta1, or + # alpha{n}-dev => beta1 when transitioning from alpha to + # beta, or beta{n}-dev => beta{n} for the release itself, + # or beta{n} => beta{n+1}-dev for post release. + dev+beta | alphadev+beta | betadev+beta ) + TYPE= + RELEASE_DATE="$today" + fixup_version "beta" + ;; + beta+beta ) + TYPE=dev + RELEASE_DATE= + fixup_version "beta" + ;; + # It's possible to switch from alpha to beta in the + # post release. That's what --next-beta does. + alpha+beta ) + TYPE=dev + RELEASE_DATE= + fixup_version "beta" + ;; + + # MAKING FINAL RELEASES ################################## + + # Final releases can't be made from the main development branch + dev+final) + echo >&2 "Invalid state for final release" + echo >&2 "This should have been preceded by an alpha or a beta release" + exit 1 + ;; + # For final releases, the starting point must be a dev state + alphadev+final | betadev+final ) + TYPE= + RELEASE_DATE="$today" + fixup_version "final" + ;; + # The final step of a final release is to switch back to + # development + +final ) + TYPE=dev + RELEASE_DATE= + fixup_version "final" + ;; + + # SWITCHING TO THE NEXT MINOR RELEASE #################### + + *+minor ) + TYPE=dev + RELEASE_DATE= + fixup_version "minor" + ;; + + # MAKING DEFAULT RELEASES ################################ + + # If we're coming from a non-dev, simply switch to dev. + # fixup_version() should trip up the PATCH number. + + ) + TYPE=dev + fixup_version "" + ;; + + # If we're coming from development, switch to non-dev, unless + # the PATCH number is zero. If it is, we force the caller to + # go through the alpha and beta release process. + dev+ ) + if [ "$PATCH" = "0" ]; then + echo >&2 "Can't update PATCH version number from 0" + echo >&2 "Please use --alpha or --beta" + exit 1 + fi + TYPE= + RELEASE_DATE="$today" + fixup_version "" + ;; + + # If we're currently in alpha, we continue with alpha, as if + # the user had specified --alpha + alpha*+ ) + next=alpha + retry=true + ;; + + # If we're currently in beta, we continue with beta, as if + # the user had specified --beta + beta*+ ) + next=beta + retry=true + ;; + + *) + echo >&2 "Invalid combination of options" + exit 1 + ;; + esac + + $DEBUG >&2 "DEBUG[next_release_state]: END: \$before=$before" + $DEBUG >&2 "DEBUG[next_release_state]: END: \$next=$next" + $DEBUG >&2 "DEBUG[next_release_state]: END: \$MAJOR=$MAJOR" + $DEBUG >&2 "DEBUG[next_release_state]: END: \$MINOR=$MINOR" + $DEBUG >&2 "DEBUG[next_release_state]: END: \$PATCH=$PATCH" + $DEBUG >&2 "DEBUG[next_release_state]: END: \$TYPE=$TYPE" + $DEBUG >&2 "DEBUG[next_release_state]: END: \$PRE_LABEL=$PRE_LABEL" + $DEBUG >&2 "DEBUG[next_release_state]: END: \$PRE_NUM=$PRE_NUM" + $DEBUG >&2 "DEBUG[next_release_state]: END: \$RELEASE_DATE=$RELEASE_DATE" + done +} + diff --git a/dev/release-aux/release-version-fn.sh b/dev/release-aux/release-version-fn.sh new file mode 100644 index 0000000000..f0ac69fa6e --- /dev/null +++ b/dev/release-aux/release-version-fn.sh @@ -0,0 +1,114 @@ +#! /bin/sh +# Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +# These functions load, manipulate and store the current version information +# for OpenSSL 3.0 and on. +# They are meant to be minimalistic for easy refactoring depending on OpenSSL +# version. +# +# Version information is stored in the following variables: +# +# |MAJOR|, |MINOR|, |PATCH| are the three parts of a version number. +# |MAJOR| is to be increased for new major releases, |MINOR| for new +# minor releases, and |PATCH| for update releases. +# +# |SERIES| tells what release series the current version belongs to, and +# is composed from |MAJOR| and |MINOR|. +# |VERSION| tells what the current version is, and is composed from |MAJOR|, +# |MINOR| and |PATCH|. +# |TYPE| tells what state the source is in. It may have an empty value +# for released source, or 'dev' for "in development". +# |PRE_LABEL| may be "alpha" or "beta" to signify an ongoing series of +# alpha or beta releases. |PRE_NUM| is a pre-release counter for the +# alpha and beta release series, but isn't necessarily strictly tied +# to the prerelease label. +# +# Scripts loading this file are not allowed to manipulate these +# variables directly. They must use functions such as fixup_version() +# below, or next_release_state(), found in release-state-fn.sh. + +# These functions depend on |SOURCEDIR|, which must have the intended +# OpenSSL source directory as value. + +get_version () { + eval $(git cat-file blob HEAD:VERSION) + VERSION="$MAJOR.$MINOR.$PATCH" + SERIES="$MAJOR.$MINOR" + TYPE=$( echo "$PRE_RELEASE_TAG" \ + | sed -E \ + -e 's|^dev$|dev|' \ + -e 's|^alpha([0-9]+)(-(dev))?$|\3|' \ + -e 's|^beta([0-9]+)(-(dev))?$|\3|' ) + PRE_LABEL=$( echo "$PRE_RELEASE_TAG" \ + | sed -E \ + -e 's|^dev$||' \ + -e 's|^alpha([0-9]+)(-(dev))?$|alpha|' \ + -e 's|^beta([0-9]+)(-(dev))?$|beta|' ) + PRE_NUM=$( echo "$PRE_RELEASE_TAG" \ + | sed -E \ + -e 's|^dev$|0|' \ + -e 's|^alpha([0-9]+)(-(dev))?$|\1|' \ + -e 's|^beta([0-9]+)(-(dev))?$|\1|' ) +} + +# $1 is one of "alpha", "beta", "final", "", or "minor" +fixup_version () { + local new_label="$1" + + case "$new_label" in + alpha | beta ) + if [ "$new_label" != "$PRE_LABEL" ]; then + PRE_LABEL="$new_label" + PRE_NUM=1 + elif [ "$TYPE" = 'dev' ]; then + PRE_NUM=$(expr $PRE_NUM + 1) + fi + ;; + final | '' ) + if [ "$TYPE" = 'dev' ]; then + PATCH=$(expr $PATCH + 1) + fi + PRE_LABEL= + PRE_NUM=0 + ;; + minor ) + if [ "$TYPE" = 'dev' ]; then + MINOR=$(expr $MINOR + 1) + PATCH=0 + fi + PRE_LABEL= + PRE_NUM=0 + ;; + esac + + VERSION="$MAJOR.$MINOR.$PATCH" + SERIES="$MAJOR.$MINOR" +} + +set_version () { + case "$TYPE+$PRE_LABEL+$PRE_NUM" in + *++* ) + PRE_RELEASE_TAG="$TYPE" + ;; + dev+* ) + PRE_RELEASE_TAG="$PRE_LABEL$PRE_NUM-dev" + ;; + +* ) + PRE_RELEASE_TAG="$PRE_LABEL$PRE_NUM" + ;; + esac + cat > "$SOURCEDIR/VERSION" < + For the purpose of signing tags and tar files, use this + key (default: use the default e-mail address’ key). + +--no-upload Don't upload to upload@dev.openssl.org. +--no-update Don't perform 'make update'. +--verbose Verbose output. +--debug Include debug output. Implies --no-upload. + +--force Force execution + +--help This text +--manual The manual + +If none of --alpha, --beta, or --final are given, this script tries to +figure out the next step. +EOF + exit 0 +} + +# Set to one of 'major', 'minor', 'alpha', 'beta' or 'final' +next_method= +next_method2= + +do_branch=false +warn_branch=false + +do_clean=true +do_upload=true +do_update=true +DEBUG=: +VERBOSE=: +git_quiet=-q + +force=false + +do_help=false +do_manual=false + +tagkey=' -s' +gpgkey= + +upload_address=upload@dev.openssl.org + +TEMP=$(getopt -l 'alpha,next-beta,beta,final' \ + -l 'branch' \ + -l 'no-upload,no-update' \ + -l 'verbose,debug' \ + -l 'local-user:' \ + -l 'force' \ + -l 'help,manual' \ + -n release.sh -- - "$@") +eval set -- "$TEMP" +while true; do + case $1 in + --alpha | --beta | --final ) + next_method=$(echo "x$1" | sed -e 's|^x--||') + if [ -z "$next_method2" ]; then + next_method2=$next_method + fi + shift + if [ "$next_method" = 'final' ]; then + do_branch=true + fi + ;; + --next-beta ) + next_method2=$(echo "x$1" | sed -e 's|^x--next-||') + shift + ;; + --branch ) + do_branch=true + warn_branch=true + shift + ;; + --no-upload ) + do_upload=false + shift + ;; + --no-update ) + do_update=false + shift + ;; + --verbose ) + VERBOSE=echo + git_quiet= + shift + ;; + --debug ) + DEBUG=echo + do_upload=false + shift + ;; + --local-user ) + shift + tagley=" -u $1" + gpgkey=" -u $1" + shift + ;; + --force ) + force=true + shift + ;; + --help ) + usage + exit 0 + ;; + --manual ) + sed -e '1,/^### BEGIN MANUAL/d' \ + -e '/^### END MANUAL/,$d' \ + < "$0" \ + | pod2man \ + | man -l - + exit 0 + ;; + -- ) + shift + break + ;; + * ) + echo >&2 "Unknown option $1" + shift + exit 1 + ;; + esac +done + +$DEBUG >&2 "DEBUG: \$next_method=$next_method" +$DEBUG >&2 "DEBUG: \$next_method2=$next_method2" + +$DEBUG >&2 "DEBUG: \$do_branch=$do_branch" + +$DEBUG >&2 "DEBUG: \$do_upload=$do_upload" +$DEBUG >&2 "DEBUG: \$do_update=$do_update" +$DEBUG >&2 "DEBUG: \$DEBUG=$DEBUG" +$DEBUG >&2 "DEBUG: \$VERBOSE=$VERBOSE" +$DEBUG >&2 "DEBUG: \$git_quiet=$git_quiet" + +case "$next_method+$next_method2" in + major+major | minor+minor ) + # These are expected + ;; + alpha+alpha | alpha+beta | beta+beta | final+final | + | +beta ) + # These are expected + ;; + * ) + echo >&2 "Internal option error ($next_method, $next_method2)" + exit 1 + ;; +esac + +# Verbosity feed for certain commands +VERBOSITY_FIFO=/tmp/openssl-$$.fifo +mkfifo -m 600 $VERBOSITY_FIFO +( cat $VERBOSITY_FIFO | while read L; do $VERBOSE "> $L"; done ) & +exec 42>$VERBOSITY_FIFO +trap "exec 42>&-; rm $VERBOSITY_FIFO" 0 2 + +# Setup ############################################################## + +# Make sure we're in the work directory +cd $(dirname $0)/.. +HERE=$(pwd) + +# Check that we have the scripts that define functions we use +found=true +for fn in "$HERE/dev/release-aux/release-version-fn.sh" \ + "$HERE/dev/release-aux/release-state-fn.sh"; do + if ! [ -f "$fn" ]; then + echo >&2 "'$fn' is missing" + found=false + fi +done +if ! $found; then + exit 1 +fi + +# Load version functions +. $HERE/dev/release-aux/release-version-fn.sh +. $HERE/dev/release-aux/release-state-fn.sh + +# Make sure it's a branch we recognise +orig_branch=$(git rev-parse --abbrev-ref HEAD) +if (echo "$orig_branch" \ + | grep -E -q \ + -e '^master$' \ + -e '^OpenSSL_[0-9]+_[0-9]+_[0-9]+[a-z]*-stable$' \ + -e '^openssl-[0-9]+\.[0-9]+\.x$'); then + : +elif $force; then + : +else + echo >&2 "Not in master or any recognised release branch" + echo >&2 "Please 'git checkout' an approprite branch" + exit 1 +fi + +# Initialize ######################################################### + +echo "== Initializing work tree" + +get_version + +# Generate a cloned directory name +clone_branch="openssl-$SERIES.x" +release_clone="$clone_branch-release-tmp" + +echo "== Work tree will be in $release_clone" + +# Make a clone in a subdirectory and move there +if ! [ -d "$release_clone" ]; then + $VERBOSE "== Cloning to $release_clone" + git clone $git_quiet -b "$orig_branch" . "$release_clone" +fi +cd "$release_clone" + +get_version + +current_branch="$(git rev-parse --abbrev-ref HEAD)" +new_branch="openssl-$SERIES.x" + +# Check that we're still on the same branch, or on a release branch +if [ "$current_branch" = "$orig_branch" ]; then + : +elif [ "$current_branch" = "$new_branch" ]; then + : +else + echo >&2 "The cloned sub-directory '$release_clone' is on a branch" + echo >&2 "other than '$current_branch' or '$new_branch'" + echo >&2 "Please 'cd \"$(pwd)\"; git checkout $current_branch'" + exit 1 +fi + +if $do_branch; then + if [ "$current_branch" = "$new_branch" ]; then + do_branch=false + fi + if ! $do_branch && $warn_branch; then + echo >&2 "Warning: --branch ignored, we're already in a release branch" + fi +fi + +SOURCEDIR=$(pwd) +$DEBUG >&2 "DEBUG: Source directory is $SOURCEDIR" + +# Release ############################################################ + +# We always expect to start from a state of development +if [ "$TYPE" != 'dev' ]; then + echo >&2 "Not in a development branch" + echo >&2 "Have a look at the git log in $release_clone, it may be that" + echo >&2 "a previous crash left it in an intermediate state and that" + echo >&2 "need to drop the top commit:" + echo >&2 "" + echo >&2 "(cd $release_clone; git reset --hard HEAD^)" + echo >&2 "# WARNING! LOOK BEFORE YOU ACT" + exit 1 +fi + +# We only create a release branch if the patch number is zero +if [ $PATCH -ne 0 ]; then + if $do_branch; then + echo >&2 "Warning! We're already in a release branch; --branch ignored" + fi + do_branch=false +fi + +# Update the version information. This won't save anything anywhere, yet, +# but does check for possible next_method errors before we do bigger work. +next_release_state "$next_method" + +if $do_branch; then + $VERBOSE "== Creating a release branch: $new_branch" + git checkout $git_quiet -b "$new_branch" +fi + +echo "== Configuring OpenSSL for update and release. This may take a bit of time" + +./Configure cc >&42 + +$VERBOSE "== Checking source file updates" + +make update >&42 + +if [ -n "$(git status --porcelain)" ]; then + $VERBOSE "== Committing updates" + git add -u + git commit $git_quiet -m 'make update' +fi + +# Write the version information we updated +set_version + +if [ -n "$PRE_LABEL" ]; then + release="$VERSION-$PRE_RELEASE_TAG$BUILD_METADATA" + release_text="$SERIES$BUILD_METADATA $PRE_LABEL $PRE_NUM" + announce_template=openssl-announce-pre-release.tmpl +else + release="$VERSION$BUILD_METADATA" + release_text="$release" + announce_template=openssl-announce-release.tmpl +fi +tag="openssl-$release" +$VERBOSE "== Updated version information to $release" + +$VERBOSE "== Updating files with release date for $release : $RELEASE_DATE" +for fixup in "$HERE/dev/release-aux"/fixup-*-release.pl; do + file="$(basename "$fixup" | sed -e 's|^fixup-||' -e 's|-release\.pl$||')" + $VERBOSE "> $file" + RELEASE="$release" RELEASE_TEXT="$release_text" RELEASE_DATE="$RELEASE_DATE" \ + perl -pi $fixup $file +done + +$VERBOSE "== Comitting updates and tagging" +git add -u +git commit $git_quiet -m "Prepare for release of $release_text" +echo "Tagging release with tag $tag. You may need to enter a pass phrase" +git tag$tagkey "$tag" -m "OpenSSL $release release tag" + +tarfile=openssl-$release.tar +tgzfile=$tarfile.gz +announce=openssl-$release.txt + +echo "== Generating tar, hash and announcement files. This make take a bit of time" + +$VERBOSE "== Making tarfile: $tgzfile" +# Unfortunately, util/mktar.sh does verbose output on STDERR... for good +# reason, but it means we don't display errors unless --verbose +./util/mktar.sh --tarfile="../$tarfile" 2>&1 \ + | while read L; do $VERBOSE "> $L"; done + +if ! [ -f "../$tgzfile" ]; then + echo >&2 "Where did the tarball end up? (../$tgzfile)" + exit 1 +fi + +$VERBOSE "== Generating checksums: $tgzfile.sha1 $tgzfile.sha256" +openssl sha1 < "../$tgzfile" | \ + (IFS='='; while read X H; do echo $H; done) > "../$tgzfile.sha1" +openssl sha256 < "../$tgzfile" | \ + (IFS='='; while read X H; do echo $H; done) > "../$tgzfile.sha256" +length=$(wc -c < "../$tgzfile") +sha1hash=$(cat "../$tgzfile.sha1") +sha256hash=$(cat "../$tgzfile.sha256") + +$VERBOSE "== Generating announcement text: $announce" +# Hack the announcement template +cat "$HERE/dev/release-aux/$announce_template" \ + | sed -e "s|\\\$release_text|$release_text|g" \ + -e "s|\\\$release|$release|g" \ + -e "s|\\\$series|$SERIES|g" \ + -e "s|\\\$label|$PRE_LABEL|g" \ + -e "s|\\\$tarfile|$tgzfile|" \ + -e "s|\\\$length|$length|" \ + -e "s|\\\$sha1hash|$sha1hash|" \ + -e "s|\\\$sha256hash|$sha256hash|" \ + | perl -p "$HERE/dev/release-aux/fix-title.pl" \ + > "../$announce" + +$VERBOSE "== Generating signatures: $tgzfile.asc $announce.asc" +rm -f "../$tgzfile.asc" "../$announce.asc" +echo "Signing the release files. You may need to enter a pass phrase" +gpg$gpgkey --use-agent -sba "../$tgzfile" +gpg$gpgkey --use-agent -sta --clearsign "../$announce" + +# We finish off by resetting all files, so we don't have to update +# files with release dates again +$VERBOSE "== Reset all files to their pre-commit contents" +git reset $git_quiet HEAD^ -- . +git checkout -- . + +if $do_upload; then + ( + if [ "$VERBOSE" != ':' ]; then + echo "progress" + fi + echo "put ../$tgzfile" + echo "put ../$tgzfile.sha1" + echo "put ../$tgzfile.sha256" + echo "put ../$tgzfile.asc" + echo "put ../$announce.asc" + ) \ + | sftp "$upload_address" +fi + +# Post-release ####################################################### + +prev_release_text="$release_text" +prev_release_date="$RELEASE_DATE" + +next_release_state "$next_method2" +set_version + +release="$VERSION-$PRE_RELEASE_TAG$BUILD_METADATA" +release_text="$VERSION$BUILD_METADATA" +if [ -n "$PRE_LABEL" ]; then + release_text="$SERIES$BUILD_METADATA $PRE_LABEL $PRE_NUM" +fi +$VERBOSE "== Updated version information to $release" + +$VERBOSE "== Updating files for $release :" +for fixup in "$HERE/dev/release-aux"/fixup-*-postrelease.pl; do + file="$(basename "$fixup" | sed -e 's|^fixup-||' -e 's|-postrelease\.pl$||')" + $VERBOSE "> $file" + RELEASE="$release" RELEASE_TEXT="$release_text" \ + PREV_RELEASE_TEXT="$prev_release_text" \ + PREV_RELEASE_DATE="$prev_release_date" \ + perl -pi $fixup $file +done + +$VERBOSE "== Comitting updates" +git add -u +git commit $git_quiet -m "Prepare for $release_text" + +if $do_branch; then + $VERBOSE "== Going back to the main branch $current_branch" + git checkout $git_quiet "$current_branch" + + get_version + next_release_state "minor" + set_version + + release="$VERSION-$PRE_RELEASE_TAG$BUILD_METADATA" + release_text="$SERIES$BUILD_METADATA" + $VERBOSE "== Updated version information to $release" + + $VERBOSE "== Updating files for $release :" + for fixup in "$HERE/dev/release-aux"/fixup-*-postrelease.pl; do + file="$(basename "$fixup" | sed -e 's|^fixup-||' -e 's|-postrelease\.pl$||')" + $VERBOSE "> $file" + RELEASE="$release" RELEASE_TEXT="$release_text" \ + perl -pi $fixup $file + done + + $VERBOSE "== Comitting updates" + git add -u + git commit $git_quiet -m "Prepare for $release_text" +fi + +# Done ############################################################### + +$VERBOSE "== Done" + +cat < +[ +B<--alpha> | +B<--next-beta> | +B<--beta> | +B<--final> | +B<--branch> | +B<--local-user>=I | +B<--no-upload> | +B<--no-update> | +B<--verbose> | +B<--debug> | +B<--help> | +B<--manual> +] + +=head1 DESCRIPTION + +B creates an OpenSSL release, given current worktree conditions. +It will refuse to work unless the current branch is C or a release +branch (see L below for a discussion on those). + +B tries to be smart and figure out the next release if no hints +are given through options, and will exit with an error in ambiguous cases. + +B always clones the current workspace into a sub-directory +named C<< openssl-I-tmp >>, where C<< I >> is taken from +the available version information in the source. + +=head1 OPTIONS + +=over 4 + +=item B<--alpha>, B<--beta> + +Set the state of this branch to indicate that alpha or beta releases are +to be done. + +B<--alpha> is only acceptable if the I version number is zero and +the current state is "in development" or that alpha releases are ongoing. + +B<--beta> is only acceptable if the I version number is zero and +that alpha or beta releases are ongoing. + +=item B<--next-beta> + +Use together with B<--alpha> to switch to beta releases after the current +release is done. + +=item B<--final> + +Set the state of this branch to indicate that regular releases are to be +done. This is only valid if alpha or beta releases are currently ongoing. + +This implies B<--branch>. + +=item B<--branch> + +Create a branch specific for the I.x release series, if it doesn't +already exist, and switch to it. The exact branch name will be +C<< openssl-I.x >>. + +=item B<--no-upload> + +Don't upload the produced files. + +=item B<--no-update> + +Don't run C. + +=item B<--verbose> + +Verbose output. + +=item B<--debug> + +Display extra debug output. Implies B<--no-upload> + +=item B<--local-user>=I + +Use I as the local user for C and for signing with C. + +If not given, then the default e-mail address' key is used. + +=item B<--force> + +Force execution. Precisely, the check that the current branch is C +or a release branch is not done. + +=item B<--help> + +Display a quick help text and exit. + +=item B<--manual> + +Display this manual and exit. + +=back + +=head1 RELEASE BRANCHES AND TAGS + +Prior to OpenSSL 3.0, the release branches were named +C<< OpenSSL_I-stable >>, and the release tags were named +C<< OpenSSL_I >> for regular releases, or +C<< OpenSSL_I-preI >> for pre-releases. + +From OpenSSL 3.0 ongoing, the release branches are named +C<< openssl-I.x >>, and the release tags are named +C<< openssl-I >> for regular releases, or +C<< openssl-I-alphaI >> for alpha releases +and C<< openssl-I-betaI >> for beta releases. + +B recognises both forms. + +=head1 VERSION AND STATE + +With OpenSSL 3.0, all the version and state information is in the file +F, where the following variables are used and changed: + +=over 4 + +=item B, B, B + +The three part of the version number. + +=item B + +The indicator of the current state of the branch. The value may be one pf: + +=over 4 + +=item C + +This branch is "in development". This is typical for the C branch +unless there are ongoing alpha or beta releases. + +=item C<< alphaI >> or C<< alphaI-dev >> + +This branch has alpha releases going on. C<< alphaI-dev >> is what +should normally be seen in the git workspace, indicating that +C<< alphaI >> is in development. C<< alphaI >> is what should be +found in the alpha release tar file. + +=item C<< alphaI >> or C<< alphaI-dev >> + +This branch has beta releases going on. The details are otherwise exactly +as for alpha. + +=item I + +This is normally not seen in the git workspace, but should always be what's +found in the tar file of a regular release. + +=back + +=item B + +This is normally empty in the git workspace, but should always have the +release date in the tar file of any release. + +=back + +=head1 COPYRIGHT + +Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut +### END MANUAL +EOF