You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by fr...@apache.org on 2019/05/01 05:15:58 UTC

[calcite-avatica] 01/02: [CALCITE-XXXX] Improve release script

This is an automated email from the ASF dual-hosted git repository.

francischuang pushed a commit to branch improve-docker-release-script
in repository https://gitbox.apache.org/repos/asf/calcite-avatica.git

commit 99d126c8a5a93bf62352eb2f20854dce536b44d6
Author: Francis Chuang <fr...@apache.org>
AuthorDate: Wed May 1 14:05:38 2019 +1000

    [CALCITE-XXXX] Improve release script
---
 docker-compose.yml |  14 +++
 docker.sh          | 281 +++++++++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 286 insertions(+), 9 deletions(-)

diff --git a/docker-compose.yml b/docker-compose.yml
index 01021e2..aa3c9a4 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -39,6 +39,20 @@ services:
       - .:/src
       - maven-repo:/root/.m2
 
+  publish-release-for-voting:
+    image: maven
+    working_dir: /src
+    command: sh -c "./docker.sh publish-release-for-voting"
+    volumes:
+      - .:/source
+
+  promote-release:
+    image: alpine
+    working_dir: /src
+    command: sh -c "./docker.sh promote-release"
+    volumes:
+      - .:/source
+
   test:
     image: maven
     working_dir: /src
diff --git a/docker.sh b/docker.sh
index 1c5b180..2beb20e 100755
--- a/docker.sh
+++ b/docker.sh
@@ -15,6 +15,13 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+set -e
+
+GITBOX_URL=https://gitbox.apache.org/repos/asf/calcite-avatica.git
+RELEASE_REPO=https://dist.apache.org/repos/dist/release/calcite/
+DEV_REPO=https://dist.apache.org/repos/dist/dev/calcite/
+PRODUCT=apache-calcite-avatica
+
 function terminate() {
     printf "\n\nUser terminated build. Exiting...\n"
     exit 1
@@ -145,11 +152,12 @@ RELEASE_VERSION=""
 RC_NUMBER=""
 DEV_VERSION=""
 ASF_USERNAME=""
+ASF_PASSWORD=""
 NAME=""
 
-get_build_configuration(){
+get_dry_run_build_configuration(){
 
-    while $NOT_CONFIRMED; do
+    while $DRY_RUN_NOT_CONFIRMED; do
         read -p "Enter the version number to be released (example: 1.12.0): " RELEASE_VERSION
         read -p "Enter the release candidate number (example: if you are releasing rc0, enter 0): " RC_NUMBER
         read -p "Enter the development version number (example: if your release version is 1.12.0, enter 1.13.0): " DEV_VERSION
@@ -167,7 +175,7 @@ get_build_configuration(){
             read -p "Is this correct? (y/n) " CONFIRM
 
             if [[ ($CONFIRM == "Y") || ($CONFIRM == "y") ]]; then
-                NOT_CONFIRMED=false
+                DRY_RUN_NOT_CONFIRMED=false
                 INVALID_CONFIRMATION=false
             elif [[ ($CONFIRM == "N") || ($CONFIRM == "n") ]]; then
                 INVALID_CONFIRMATION=false
@@ -176,13 +184,56 @@ get_build_configuration(){
     done
 }
 
-ASF_PASSWORD=""
+get_build_configuration(){
 
-set_git_credentials(){
-    read -s -p "Enter your ASF password: " ASF_PASSWORD
+    while $BUILD_NOT_CONFIRMED; do
+        read -p "Enter the version number to be released (example: 1.12.0): " RELEASE_VERSION
+        read -p "Enter the release candidate number (example: if you are releasing rc0, enter 0): " RC_NUMBER
+        read -p "Enter the development version number (example: if your release version is 1.12.0, enter 1.13.0): " DEV_VERSION
+        read -p "Enter your name (this will be used for git commits): " NAME
+        echo "Build configured as follows:"
+        echo "Release: $RELEASE_VERSION-rc$RC_NUMBER"
+        echo "Next development version: $DEV_VERSION-SNAPSHOT"
+        echo "Name: $NAME"
 
-    printf "\n"
+        INVALID_CONFIRMATION=true
+
+        while $INVALID_CONFIRMATION; do
+            read -p "Is this correct? (y/n) " CONFIRM
+
+            if [[ ($CONFIRM == "Y") || ($CONFIRM == "y") ]]; then
+                BUILD_NOT_CONFIRMED=false
+                INVALID_CONFIRMATION=false
+            elif [[ ($CONFIRM == "N") || ($CONFIRM == "n") ]]; then
+                INVALID_CONFIRMATION=false
+            fi
+        done
+    done
+}
+
+get_asf_credentials(){
+    while $ASF_CREDS_NOT_CONFIRMED; do
+        read -p "Enter your ASF username: " ASF_USERNAME
+        read -s -p "Enter your ASF password: " ASF_PASSWORD
+        printf "\n"
+        echo "Your ASF Username is:" $ASF_USERNAME
+
+        INVALID_CONFIRMATION=true
+
+        while $INVALID_CONFIRMATION; do
+            read -p "Is this correct? (y/n) " CONFIRM
+
+            if [[ ($CONFIRM == "Y") || ($CONFIRM == "y") ]]; then
+                ASF_CREDS_NOT_CONFIRMED=false
+                INVALID_CONFIRMATION=false
+            elif [[ ($CONFIRM == "N") || ($CONFIRM == "n") ]]; then
+                INVALID_CONFIRMATION=false
+            fi
+        done
+    done
+}
 
+set_git_credentials(){
     echo https://$ASF_USERNAME:$ASF_PASSWORD@gitbox.apache.org >> /root/.git-credentials
     git config --global credential.helper 'store --file=/root/.git-credentials'
 
@@ -222,11 +273,214 @@ EOF
 EOF
 }
 
+publish_release_for_voting(){
+
+    LATEST_TAG=$(git describe --tags `git rev-list --tags --max-count=1`)
+
+    if [[ ! $LATEST_TAG =~ .+-rc[[:digit:]]+$ ]]; then
+        echo "The latest tag ($LATEST_TAG) is not a RC release and should not be published for voting."
+        exit 1
+    fi
+
+    TAG_WITHOUT_PRODUCT=$(echo $LATEST_TAG | sed -e 's/avatica-//')
+    TAG_WITHOUT_RC=$(echo $TAG_WITHOUT_PRODUCT | sed -e 's/-rc[0-9][0-9]*//')
+    SOURCE_RELEASE=$PRODUCT-$TAG_WITHOUT_RC-src.tar.gz
+    GPG_SIGNATURE=$PRODUCT-$TAG_WITHOUT_RC-src.tar.gz.asc
+    SHA512=$PRODUCT-$TAG_WITHOUT_RC-src.tar.gz.sha512
+    GPG_SHA512=$PRODUCT-$TAG_WITHOUT_RC-src.tar.gz.asc.sha512
+    COMMIT=$(git rev-list -n 1 $LATEST_TAG)
+
+    # Check to see a release is built
+    MISSING_FILES=false
+
+    if [ ! -f "target/$SOURCE_RELEASE" ]; then
+        echo "Did not find source release ($SOURCE_RELEASE) in target folder."
+        MISSING_FILES=true
+    fi
+
+    if [ ! -f "target/$GPG_SIGNATURE" ]; then
+        echo "Did not find GPG signature ($GPG_SIGNATURE) in target folder."
+        MISSING_FILES=true
+    fi
+
+    if [ ! -f "target/$SHA512" ]; then
+        echo "Did not find SHA512 ($SHA512) in target folder."
+        MISSING_FILES=true
+    fi
+
+    if [ ! -f "target/$GPG_SHA512" ]; then
+        echo "Did not find GPG SHA512 ($GPG_SHA512) in target folder."
+        MISSING_FILES=true
+    fi
+
+    if $MISSING_FILES == true; then
+        exit 1
+    fi
+
+    while $NOT_CONFIRMED; do
+        echo "Publish configured as follows:"
+        echo "Release: $LATEST_TAG"
+
+        INVALID_CONFIRMATION=true
+
+        while $INVALID_CONFIRMATION; do
+            read -p "Is this correct? (y/n) " CONFIRM
+
+            if [[ ($CONFIRM == "Y") || ($CONFIRM == "y") ]]; then
+                NOT_CONFIRMED=false
+                INVALID_CONFIRMATION=false
+            elif [[ ($CONFIRM == "N") || ($CONFIRM == "n") ]]; then
+                INVALID_CONFIRMATION=false
+            fi
+        done
+    done
+
+    HASH=$(cat "target/$SHA512" | tr -d '\n')
+
+    get_asf_credentials
+
+    svn checkout $DEV_REPO /tmp/calcite --depth empty
+    mkdir -p /tmp/calcite/$PRODUCT-$TAG_WITHOUT_PRODUCT
+    cp -R target/$PRODUCT /tmp/calcite/$PRODUCT-$TAG_WITHOUT_PRODUCT
+
+    cd /tmp/calcite
+    svn add $PRODUCT-$TAG_WITHOUT_PRODUCT
+    chmod -x $PRODUCT-$TAG_WITHOUT_PRODUCT/*
+
+    ls -la
+
+    #svn commit -m "$PRODUCT-$TAG_WITHOUT_PRODUCT" --force-log --username $ASF_USERNAME --password $ASF_PASSWORD
+
+    [[ $LATEST_TAG =~ -rc([[:digit:]]+)$ ]]
+    RC_NUMBER=${BASH_REMATCH[1]}
+
+    [[ $TAG_WITHOUT_RC =~ ([[:digit:]]+\.[[:digit:]]+)\.[[:digit:]]+$ ]]
+    BRANCH_VERSION=${BASH_REMATCH[1]}
+
+    read -p "Please enter your first name for the voting email: " FIRST_NAME
+    read -p "Enter the ID at the end of the staged repository (for orgapachecalcite-1000, enter 1000): " STAGED_REPO_ID
+
+    echo "The release $PRODUCT-$TAG_WITHOUT_PRODUCT has been uploaded to the development repository."
+    printf "\n"
+    printf "\n"
+    echo "Email the following message to dev@calcite.apache.org. Please check the message before sending."
+    printf "\n"
+    echo "To: dev@calcite.apache.org"
+    echo "Subject: [VOTE] Release $PRODUCT-$TAG_WITHOUT_RC (release candidate $RC_NUMBER)"
+    echo "Message:
+Hi all,
+
+I have created a build for Apache Calcite Avatica $TAG_WITHOUT_RC, release candidate $RC_NUMBER.
+
+Thanks to everyone who has contributed to this release.
+
+You can read the release notes here:
+https://github.com/apache/calcite-avatica/blob/branch-avatica-$BRANCH_VERSION/site/_docs/history.md
+
+The commit to be voted upon:
+https://gitbox.apache.org/repos/asf?p=calcite-avatica.git;a=commit;h=$COMMIT
+
+Its hash is $COMMIT
+
+The artifacts to be voted on are located here:
+$DEV_REPO$PRODUCT-$TAG_WITHOUT_PRODUCT/
+
+The hashes of the artifacts are as follows:
+src.tar.gz.sha512 $HASH
+
+A staged Maven repository is available for review at:
+https://repository.apache.org/content/repositories/orgapachecalcite-$STAGED_REPO_ID
+
+Release artifacts are signed with the following key:
+https://people.apache.org/keys/committer/$ASF_USERNAME.asc
+
+If you do not have a Java environment available, you can run the tests using docker. To do so, install docker and docker-compose, then run \"docker-compose run test\" from the root of the directory.
+
+Please vote on releasing this package as Apache Calcite Avatica $TAG_WITHOUT_RC.
+
+The vote is open for the next 72 hours and passes if a majority of at least three +1 PMC votes are cast.
+
+[ ] +1 Release this package as Apache Calcite 1.14.0
+[ ]  0 I don't feel strongly about it, but I'm okay with the release
+[ ] -1 Do not release this package because...
+
+
+Here is my vote:
+
++1 (binding)
+
+$NAME
+"
+}
+
+promote_release(){
+
+    LATEST_TAG=$(git describe --tags `git rev-list --tags --max-count=1`)
+
+    if [[ ! $LATEST_TAG =~ .+-rc[[:digit:]]+$ ]]; then
+        echo "The latest tag ($LATEST_TAG) is not a RC release and should not be re-released."
+        exit 1
+    fi
+
+    TAG_WITHOUT_PRODUCT=$(echo $LATEST_TAG | sed -e 's/avatica-//')
+    TAG_WITHOUT_RC=$(echo $TAG_WITHOUT_PRODUCT | sed -e 's/-rc[0-9][0-9]*//')
+
+    if ! svn ls $DEV_REPO/$PRODUCT-$TAG_WITHOUT_PRODUCT; then
+        echo "The release $PRODUCT-$TAG_WITHOUT_PRODUCT was not found in the dev repository. Was it uploaded for voting?"
+        exit 1
+    fi
+
+    get_asf_credentials
+
+    set_git_credentials
+
+    git tag rel/avatica-$TAG_WITHOUT_RC $LATEST_TAG
+
+    #git push $GITBOX_URL rel/avatica-$TAG_WITHOUT_RC
+
+    svn checkout $RELEASE_REPO /tmp/release
+    rm -rf /tmp/release/$PRODUCT-$TAG_WITHOUT_RC
+    mkdir -p /tmp/release/$PRODUCT-$TAG_WITHOUT_RC
+
+    svn checkout $DEV_REPO/$PRODUCT-$TAG_WITHOUT_PRODUCT /tmp/rc
+    cp -rp /tmp/rc/* /tmp/release/$PRODUCT-$TAG_WITHOUT_RC
+
+    cd /tmp/release
+
+    ls -la
+
+    svn add $PRODUCT-$TAG_WITHOUT_RC
+
+    # If there is more than 1 release, delete all of them, except for the newest one
+    # To do this, we do the following:
+    # 1. Get the list of releases with verbose information from svn
+    # 2. Sort by the first field (revision number) in descending order
+    # 3. Select apache-calcite-avatica-go releases
+    # 4. Exclude the release we're trying to promote, in case it was from a failed promotion.
+    # 5. Trim all whitespace down to 1 empty space.
+    # 6. Select field 7, which is each release's folder
+    CURRENT_RELEASES=$(svn ls -v $RELEASE_REPO | sort -k1 -r | grep $PRODUCT | grep -v $PRODUCT-$TAG_WITHOUT_RC | tr -s ' ' | cut -d ' ' -f 7)
+
+    RELEASE_COUNT=0
+    while read -r RELEASE; do
+        if [[ $RELEASE_COUNT -ne 0 ]]; then
+            svn rm $RELEASE
+            echo "Removing release $RELEASE"
+        fi
+
+        RELEASE_COUNT=$((RELEASE_COUNT+1))
+    done <<< "$CURRENT_RELEASES"
+
+    #svn commit -m "Release $PRODUCT-$TAG_WITHOUT_RC" --force-log --username $ASF_USERNAME --password $ASF_PASSWORD
+
+    echo "Release $PRODUCT-$LATEST_TAG successfully promoted to $PRODUCT-$TAG_WITHOUT_RC"
+}
+
 case $1 in
     dry-run)
         mount_gpg_keys
         select_gpg_key
-        get_build_configuration
+        get_dry_run_build_configuration
 
         mvn -Dmaven.artifact.threads=20 -DdryRun=true -DreleaseVersion=$RELEASE_VERSION -DdevelopmentVersion=$DEV_VERSION-SNAPSHOT -Dtag="avatica-$RELEASE_VERSION-rc$RC_NUMBER" -Papache-release -Duser.name=$ASF_USERNAME release:prepare -Darguments=-Dgpg.keyname=$SELECTED_GPG_KEY
         ;;
@@ -235,6 +489,7 @@ case $1 in
         mount_gpg_keys
         select_gpg_key
         get_build_configuration
+        get_asf_credentials
         set_git_credentials
         set_maven_credentials
 
@@ -246,12 +501,20 @@ case $1 in
         mvn release:clean
         ;;
 
+    publish-release-for-voting)
+        publish_release_for_voting
+        ;;
+
+    promote-release)
+        promote_release
+        ;;
+
     test)
         mvn clean verify -Dcheckstyle.skip
         ;;
 
     *)
-       echo $"Usage: $0 {dry-run|release|clean|test}"
+       echo $"Usage: $0 {dry-run|release|clean|publish-release-for-voting|promote-release|test}"
        ;;
 
 esac