10
\$\begingroup\$

In my company I follow the following workflow. (I think it can be defined a kind of 'Continuous Integration'.)

Workflow:

  • We have 3 fixed branches (staging/master/production)
  • Every push to staging or production automatically deploy to staging/production server.

We use git in the following way:
(suppose I'm working on the new functionality 'A')

  1. I create a new branch from Master (ex. branch 'A')
  2. If I want to show my changes to the client I merge A to staging and push it.
  3. once finish my work on A I merge back A on Master and push master
  4. to send changes live I merge Master in Production branch and push production

I find quite boring/time consuming to git checkout ... git pull .. bla bla every time I have to deploy live/staging my work.

So I have produced the following bash script, the aim is to simplify the process of deploying branch A into a single command deploy.sh live A

#!/bin/bash
function merge() { 
 SOURCE=1ドル
 DEST=2ドル
 echo ''
 echo "--- Merging $SOURCE with $DEST ---" 
 echo "--> Checkout $DEST ..." 
 git checkout $DEST
 echo "--> Pull $DEST ..."
 git pull --ff-only origin $DEST
 if [ $? -ne 0 ]
 then
 echo "ERROR: Could not PULL" 
 return 1
 fi
 echo "--> Merging $SOURCE with $DEST ..." 
 git merge --ff-only $SOURCE --no-edit # --ff-only trigger errors if merge/pull is not possible
 if [ $? -ne 0 ]
 then
 echo "ERROR: Could not MERGE"
 return 1
 fi
 echo "--> Push $DEST ..."
 git push origin $DEST
 return 0
}
function deploy() {
 MODE=1ドル
 SOURCE_BRANCH=2ドル
 echo ''
 echo "### START ###"
 echo ''
 echo "--- Pull changes from Master ---"
 git checkout $SOURCE_BRANCH
 git pull --progress --no-edit --no-stat -v --progress origin master
 merge $SOURCE_BRANCH 'staging'
 status=$?
 if [ $status -ne 0 ]
 then
 echo "ERROR: STEP 1" >&2
 exit 1
 fi
 if [ $MODE = "live" ]
 then
 merge $SOURCE_BRANCH 'master'
 status=$?
 if [ $status -ne 0 ]
 then
 echo "ERROR: STEP 2"
 return 1
 fi
 merge 'master' 'production'
 status=$?
 if [ $status -ne 0 ]
 then
 echo "ERROR: STEP 3"
 return 1
 fi
 fi
 echo ''
 echo "### END ###"
 echo ''
}
MODE=1ドル;
SOURCE_BRANCH=2ドル;
if [ -z "$MODE" -o -z "$SOURCE_BRANCH" ]
 then
 echo "Usage:"
 echo ""
 echo "MODE BRANCH_NAME (MODE: live|staging)"
 else
 if git show-ref --verify --quiet "refs/heads/$SOURCE_BRANCH";
 # if [ `git branch --list $SOURCE_BRANCH ` ]
 then
 deploy $MODE $SOURCE_BRANCH
 else
 echo ''
 echo "Error: Branch $SOURCE_BRANCH not found"
 fi
fi

The question:

I'm quite newby both on GIT and BASH scripting. So I would like to know if the above workflow/script is ok ? Any recommendation is welcome. (I'm happy to share this as resource.)

200_success
145k22 gold badges190 silver badges478 bronze badges
asked Jun 7, 2016 at 4:20
\$\endgroup\$

1 Answer 1

13
\$\begingroup\$

Use exit codes directly

Instead of this:

merge $SOURCE_BRANCH 'staging'
status=$?
if [ $status -ne 0 ]
then
 echo "ERROR: STEP 1" >&2
 exit 1
fi

You can use exit codes directly in conditions, like this:

if ! merge $SOURCE_BRANCH 'staging'
then
 echo "ERROR: STEP 1" >&2
 exit 1
fi

Use it this way everywhere.

Handle errors consistently

The error handling is inconsistent throughout the script:

  • Sometimes you exit 1, sometimes you return 1 in functions. It would be better to do consistently
  • Sometimes you print the error message on stdout, sometimes on stderr. It would be better to print it consistently on stderr

Style

To print a blank line you can simply echo without a parameter.

You can drop return 0 as the last statement of a function. The exit code of the last statement will be used as the exit code of the function.

A semicolon is unnecessary at the end of the line.

Long comments at the end of a line are generally hard to read. Move these to the previous line.

The indentation is not consistent. The code inside the functions looks nice, do the same way for the code outside.

Ex. ( edited by @WonderLand)

#!/bin/bash
function merge() { 
 SOURCE=1ドル
 DEST=2ドル
 echo
 echo "---> Merging $SOURCE with $DEST" 
 echo
 echo "---> ---> Checkout $DEST ..." 
 git checkout $DEST
 echo
 echo "---> ---> Pull $DEST ..."
 if ! git pull --ff-only origin $DEST
 then
 exit 1
 fi
 echo
 echo "---> ---> Merging $SOURCE with $DEST ..." 
 # --ff-only trigger errors if merge/pull is not possible
 if ! git merge --ff-only $SOURCE --no-edit
 then
 exit 1
 fi
 echo
 echo "---> ---> Push $DEST ..."
 git push origin $DEST
}
function deploy() {
 MODE=1ドル
 SOURCE_BRANCH=2ドル
 echo 
 echo "---> Pull changes from Master ..."
 if ! git checkout $SOURCE_BRANCH
 then 
 exit 1
 fi
 git pull --progress --no-edit --no-stat -v --progress origin master
 if ! merge $SOURCE_BRANCH 'staging'
 then 
 exit 1
 fi
 if [ $MODE = "live" ]
 then
 if ! merge $SOURCE_BRANCH 'master'
 then 
 exit 1
 fi
 if ! merge 'master' 'production'
 then 
 exit 1
 fi
 fi
}
MODE=1ドル
SOURCE_BRANCH=2ドル
if [ -z "$MODE" -o -z "$SOURCE_BRANCH" ]
then
 echo "Usage:"
 echo ""
 echo "MODE BRANCH_NAME (MODE: live|staging)"
else
 if git show-ref --verify --quiet "refs/heads/$SOURCE_BRANCH"
 then
 echo
 echo "### START ###"
 echo
 deploy $MODE $SOURCE_BRANCH
 echo
 echo "### END ###"
 echo
 else
 echo
 echo "Error: Branch $SOURCE_BRANCH not found"
 fi
fi
answered Jun 7, 2016 at 5:33
\$\endgroup\$
0

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.