From 3a6d0e89e8265aa748af1ce8ccaf0fc5f3bc8c78 Mon Sep 17 00:00:00 2001
From: aschwinn <al.schwinn@gsi.de>
Date: Thu, 2 Nov 2017 14:05:13 +0100
Subject: [PATCH] #21 Automatically create a GIT-tag on installation

---
 silecs-communication-cpp/releaseSilecs.sh | 165 ++++++++++++++++++----
 1 file changed, 134 insertions(+), 31 deletions(-)

diff --git a/silecs-communication-cpp/releaseSilecs.sh b/silecs-communication-cpp/releaseSilecs.sh
index 15ea071..8dd595f 100755
--- a/silecs-communication-cpp/releaseSilecs.sh
+++ b/silecs-communication-cpp/releaseSilecs.sh
@@ -1,16 +1,32 @@
+#!/bin/bash
+
+####################################################################################################################################
 # Usage examples:
 # first you need to source this script, so that you can use it's methods:
 # $ source releaseSilecs.sh
 #
-# release a new version v1.0.0
-# $ release 1.0.0 /home/bel/schwinn/lnx/git /common/usr/cscofe/silecs
+### release ####
+# release a new version v1.0.0 using the default pathes. A git branch and tag will be created and pushed
+# $ release_global 1.0.0 /home/bel/schwinn/lnx/git
+#
+# A local release will not create any branches and/or tags
+# $ release_local 1.0.0 /home/bel/schwinn/lnx/git
+# 
+### patch ###
+# patch two packages of an existing version 1.2.3, resulting of a installation of 1.2.4 using the default pathes. A git branch and tag will be created and pushed
+# $ patch_global silecs-codegen 1.2.3 /home/bel/schwinn/lnx/git
+# $ patch_global silecs-model 1.2.3 /home/bel/schwinn/lnx/git
 #
-# patch two packages of an existing version 1.2.3, resulting of a installation of 1.2.4
-# $ patch silecs-codegen 1.2.3 /home/bel/schwinn/lnx/git /common/usr/cscofe/silecs
-# $ patch silecs-model 1.2.3 /home/bel/schwinn/lnx/git /common/usr/cscofe/silecs
+# A local patch will not create any branches and/or tags
+# $ patch_local silecs-model 1.2.3 /home/bel/schwinn/lnx/git
 #
+
+### release plugin ###
 # release a new version of the silecs-eclipse plugin
 # $ plugin_release /home/bel/schwinn/lnx/git-silecs-plugin /common/usr/cscofe/silecs
+#
+####################################################################################################################################
+
 
 # List of silecs packages which can be released or patched
 PACKAGES="silecs-codegen silecs-model silecs-communication-cpp silecs-diagnostic-cpp silecs-cli-client snap7"
@@ -18,59 +34,76 @@ PACKAGES="silecs-codegen silecs-model silecs-communication-cpp silecs-diagnostic
 # branch to release
 RELEASE_BRANCH=gsi
 
-UPSTREAM=${1:-'@{u}'}
-LOCAL=$(git rev-parse @)
-REMOTE=$(git rev-parse "$UPSTREAM")
-BASE=$(git merge-base @ "$UPSTREAM")
+# name of git remote repo
+UPSTREAM=origin
+
+# release locations
+GLOBAL_RELEASE_DIR=${HOME}/tmp/silecs
+#GLOBAL_RELEASE_DIR=/common/usr/cscofe/silecs
+LOCAL_RELEASE_DIR=${HOME}/tmp/silecs
+
+
 
 validateBranch()
 {
     REQUIRED_BRANCH=$1
 
-    CURRENT_BRANCH = $(git branch | grep \* | cut -d ' ' -f2)
+    CURRENT_BRANCH=`git symbolic-ref --short -q HEAD`
+    echo "current: $CURRENT_BRANCH"
     if [ "$CURRENT_BRANCH" != "$REQUIRED_BRANCH" ]; then
         echo "Error: Release only can be done if branch '${REQUIRED_BRANCH}' is checked out."
-        echo "Installation cancelled."
         return 1
     fi
     
     git fetch
+    REMOTE_SHA=`git rev-parse origin/${REQUIRED_BRANCH}`
+    LOCAL_SHA=`git rev-parse origin/${REQUIRED_BRANCH}`
     
-    if [ $LOCAL = $REMOTE ]; then
-        echo "branch is identical with remote"
-        return 0
-    elif [ $LOCAL = $BASE ]; then
-        echo "Error: Pull required on branch '${RELEASE_BRANCH}'"
-        echo "Installation cancelled."
-        return 1
-    elif [ $REMOTE = $BASE ]; then
-        echo "Error: Push required on branch '${RELEASE_BRANCH}'"
-        echo "Installation cancelled."
-        return 1
+    if [[ -z $(git status -s) ]]
+    then
+      echo "workspace is in sync with local repo"
     else
-        echo "Error: branch '${RELEASE_BRANCH}' is diverged"
-        echo "Installation cancelled."
+      echo "workspace is dirty, please commit changes before running this"
+      return 1
+    fi
+    
+    
+
+    if [ $REMOTE_SHA != $LOCAL_SHA ]; then
+        echo "remote repo differs from local repo"
         return 1
     fi
 }
 
-createAndPushReleaseBranch()
+createAndPushBranch()
 {
     BRANCH_NAME=$1
     
-    # TODO: check if already exists
-    git ls-remote --heads <remote-name> ${BRANCH_NAME} | wc -l
+    # check if already exists
+    git ls-remote --heads ${UPSTREAM} ${BRANCH_NAME} | wc -l
+    if [ "$?" -eq "0" ]; then
+        echo "Error: The branch '${BRANCH_NAME}' already exists on ${UPSTREAM}."
+        echo "Creating branch cancelled."
+        return 1
+    fi
+    # create new and push
     git checkout -b ${BRANCH_NAME}
-    git push ${BRANCH_NAME}
+    git push ${UPSTREAM} ${BRANCH_NAME}
 }
 
 createAndPushTag()
 {
     TAG_NAME=$1
-    # TODO: check if already exists
-    git ls-remote <remote-name> refs/tags/<TAG_NAME>
+    # check if already exists
+    git ls-remote ${UPSTREAM} refs/tags/${TAG_NAME} | wc -l
+    if [ "$?" -eq "0" ]; then
+        echo "Error: The tag '${TAG_NAME}' already exists on ${UPSTREAM}."
+        echo "Creating branch cancelled."
+        return 1
+    fi
+    # create new and push
     git tag ${TAG_NAME}
-    git push origin ${TAG_NAME}
+    git push ${UPSTREAM} ${TAG_NAME}
 }
 
 # Check that folder exists, print proper error if not
@@ -85,6 +118,17 @@ checkFolderExists()
 }
 
 # releases all silecs-packages to release-dir
+
+release_local()
+{
+    release $1 $2 ${LOCAL_RELEASE_DIR}
+}
+
+release_global()
+{
+    release $1 $2 ${GLOBAL_RELEASE_DIR}
+}
+
 release()
 {
     VERSION=$1
@@ -93,6 +137,14 @@ release()
     
     checkFolderExists ${WORKSPACE}
     
+    if [ $RELEASE_DIR_BASE = $GLOBAL_RELEASE_DIR ]; then
+       validateBranch ${RELEASE_BRANCH}
+       if [ "$?" -eq "1" ]; then
+          echo "Installation cancelled."
+          return 1
+       fi
+    fi
+    
     for PACKAGE in $PACKAGES; do
         INSTALL_DIR=${RELEASE_DIR_BASE}/${PACKAGE}/${VERSION}
         if [ -d ${INSTALL_DIR} ]; then 
@@ -104,9 +156,25 @@ release()
             ${WORKSPACE}/${PACKAGE}/install.sh ${INSTALL_DIR}
         fi
     done
+    
+    if [ $RELEASE_DIR_BASE = $GLOBAL_RELEASE_DIR ]; then
+       RELEASE_BRANCH_VERSION=$(replace_tiny_version_with_x) VERSION
+       RELEASE_BRANCH=$(gsi-$RELEASE_BRANCH_VERSION)
+       createAndPushBranch ${RELEASE_BRANCH}
+    fi
     return 0
 }
 
+patch_local()
+{
+    patch $1 $2 $3 ${LOCAL_RELEASE_DIR}
+}
+
+patch_global()
+{
+    patch $1 $2 $3 ${GLOBAL_RELEASE_DIR}
+}
+
 plugin_release()
 {
     (
@@ -137,8 +205,23 @@ increment_version ()
   done
   new="${part[*]}"
   echo -e "${new// /.}"
+}
+
+replace_tiny_version_with_x ()
+{
+    echo -e "${1%.*}.x"
 } 
 
+patch_local()
+{
+    patch $1 $2 $3 ${LOCAL_RELEASE_DIR}
+}
+
+patch_global()
+{
+    patch $1 $2 $3 ${GLOBAL_RELEASE_DIR}
+}
+
 # releases a specific package to release-dir. For all other packages symlinks to the base-version are generated
 patch()
 {
@@ -151,6 +234,17 @@ patch()
     NEW_VERSION=$(increment_version $BASE_VERSION)
     echo "New version will be: '$NEW_VERSION'"
     
+    BASE_BRANCH_VERSION=$(replace_tiny_version_with_x) BASE_VERSION
+    BASE_BRANCH=$(gsi-$BASE_BRANCH_VERSION)
+       
+    if [ $RELEASE_DIR_BASE = $GLOBAL_RELEASE_DIR ]; then
+       validateBranch ${BASE_BRANCH}
+       if [ "$?" -eq "1" ]; then
+          echo "Installation cancelled."
+          return 1
+       fi
+    fi
+    
     for PACKAGE in $PACKAGES; do
         INSTALL_DIR=${RELEASE_DIR_BASE}/${PACKAGE}/${NEW_VERSION}
         BASE_DIR=${RELEASE_DIR_BASE}/${PACKAGE}/${BASE_VERSION}
@@ -181,5 +275,14 @@ patch()
             fi
         fi
     done
+    
+    echo "All packages patched successfully"
+     
+    if [ $RELEASE_DIR_BASE = $GLOBAL_RELEASE_DIR ]; then
+       echo "Attempt to create and push git tag"
+       TAG_NAME=$(gsi-$VERSION)
+       createAndPushTag ${TAG_NAME}
+    fi
+    
     return 0
 }
-- 
GitLab