#!/bin/bash #################################################################################################################################### # Usage examples: # first you need to source this script, so that you can use it's methods: # $ source releaseSilecs.sh # ### 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 # # 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" # branch to release RELEASE_BRANCH=gsi # name of git remote repo UPSTREAM=origin # release locations #GLOBAL_RELEASE_DIR=${HOME}/tmp/silecs-global GLOBAL_RELEASE_DIR=/common/usr/cscofe/silecs LOCAL_RELEASE_DIR=${HOME}/tmp/silecs validateBranch() { REQUIRED_BRANCH=$1 CURRENT_BRANCH=`git symbolic-ref --short -q HEAD` if [ "$CURRENT_BRANCH" != "$REQUIRED_BRANCH" ]; then echo "Error: Release only can be done if branch '${REQUIRED_BRANCH}' is checked out." return 1 fi git fetch REMOTE_SHA=`git rev-parse origin/${REQUIRED_BRANCH}` LOCAL_SHA=`git rev-parse HEAD` if [[ -z $(git status -s) ]] then echo "workspace is in sync with local repo" else echo "workspace is dirty, please commit changes before running this" return 1 fi if [ $REMOTE_SHA != $LOCAL_SHA ]; then echo "Error: local repo differs from remote repo ! Please first push/pull to get a consistant state!" return 1 fi } createAndPushBranch() { BRANCH_NAME=$1 git rev-parse --verify ${BRANCH_NAME} if [ "$?" = "0" ]; then echo "Error: The branch '${BRANCH_NAME}' already exists locally." echo "Creating branch cancelled." return 1 fi # check if already exists EXISTS=`git ls-remote --heads ${UPSTREAM} ${BRANCH_NAME} | wc -l` if [ "$EXISTS" != "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 ${UPSTREAM} ${BRANCH_NAME} } createAndPushTag() { TAG_NAME=$1 if [ $(git tag -l "${TAG_NAME}") ]; then echo "Error: The tag '${TAG_NAME}' already exists locally." echo "Creating tag cancelled." return 1 fi EXISTS=`git ls-remote ${UPSTREAM} refs/tags/${TAG_NAME} | wc -l` echo $EXISTS if [ "$EXISTS" != "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 ${UPSTREAM} ${TAG_NAME} } # Check that folder exists, print proper error if not checkFolderExists() { FOLDER=$1 if [ ! -d ${FOLDER} ]; then echo "Error: The folder '${FOLDER}' is needed in order to finish the installation." echo "Installation cancelled." return 1 fi } # 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 WORKSPACE=$2 RELEASE_DIR_BASE=$3 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 echo "Error: Silecs version ${VERSION} is already installed in ${INSTALL_DIR}. Exiting now." return 1 else checkFolderExists ${WORKSPACE}/${PACKAGE} echo "installing ${INSTALL_DIR} from ${WORKSPACE}/${PACKAGE}" ${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_NAME="gsi-$RELEASE_BRANCH_VERSION" createAndPushBranch ${RELEASE_BRANCH_NAME} if [ "$?" -eq "1" ]; then echo "Creation of branch cancelled." return 1 fi RELEASE_TAG="gsi-$VERSION" createAndPushTag ${RELEASE_TAG} fi return 0 } patch_local() { patch $1 $2 $3 ${LOCAL_RELEASE_DIR} } patch_global() { patch $1 $2 $3 ${GLOBAL_RELEASE_DIR} } plugin_release() { ( set -e WORKSPACE=$1 RELEASE_DIR_BASE=$2 PACKAGE=silecs-eclipse-plugin-update-site INSTALL_DIR=${RELEASE_DIR_BASE}/${PACKAGE} checkFolderExists ${WORKSPACE}/${PACKAGE} echo "installing ${INSTALL_DIR} from ${WORKSPACE}/${PACKAGE}" ${WORKSPACE}/${PACKAGE}/install.sh ${INSTALL_DIR} return 0 ) } increment_version () { declare -a part=( ${1//\./ } ) declare new declare -i carry=1 for (( CNTR=${#part[@]}-1; CNTR>=0; CNTR-=1 )); do len=${#part[CNTR]} new=$((part[CNTR]+carry)) [ ${#new} -gt $len ] && carry=1 || carry=0 [ $CNTR -gt 0 ] && part[CNTR]=${new: -len} || part[CNTR]=${new} 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() { PACKAGE_TO_PATCH=$1 BASE_VERSION=$2 WORKSPACE=$3 RELEASE_DIR_BASE=$4 checkFolderExists ${WORKSPACE} 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} checkFolderExists ${BASE_DIR} checkFolderExists ${INSTALL_DIR} if [ "$PACKAGE" == "$PACKAGE_TO_PATCH" ]; then if [ -d ${INSTALL_DIR} ]; then if [ -L ${INSTALL_DIR} ]; then checkFolderExists ${WORKSPACE}/${PACKAGE} # Replace Sym-Link with patch-version ... needed if more than one package is patched for the same version unlink ${INSTALL_DIR} checkFolderExists ${WORKSPACE}/${PACKAGE} ${WORKSPACE}/${PACKAGE}/install.sh ${INSTALL_DIR} else echo "Error: Silecs version ${NEW_VERSION} of package ${PACKAGE} is already installed in ${INSTALL_DIR}. Exiting now." return 1 fi else checkFolderExists ${WORKSPACE}/${PACKAGE} echo "installing ${INSTALL_DIR} from ${WORKSPACE}/${PACKAGE}" ${WORKSPACE}/${PACKAGE}/install.sh ${INSTALL_DIR} fi else if [ ! -d ${INSTALL_DIR} ]; then # no patched version for this package available --> link to base-version echo "Symbolic link to base version '${BASE_VERSION}' created for package '${PACKAGE}' of version '${NEW_VERSION}'" ln -s ${BASE_VERSION} ${INSTALL_DIR} 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-$NEW_VERSION" createAndPushTag ${TAG_NAME} fi return 0 }