Created
March 8, 2019 16:01
-
-
Save miraculixx/f70e5f91e96f8ceba98a85dd75530663 to your computer and use it in GitHub Desktop.
gitdeploy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# adopted from https://raw.githubusercontent.com/X1011/git-directory-deploy/master/deploy.sh | |
# | |
# changes | |
# * deploy from current directory is possible | |
# * set options from either .deploy file or parameters | |
set -o errexit #abort if any command fails | |
PREFIX=. | |
CONFIG=.deploy | |
# getting the last argument as the appname | |
appname=${@: -1} | |
appname=${appname:=default} | |
function show_help { | |
echo " $0 [options] [DEPLOYDIRECTORY] [APPNAME]" | |
echo "" | |
echo " APPNAME the application name as in $CONFIG" | |
echo " -v, --verbose print details" | |
echo " -s, --setup setup and deploy" | |
echo " -r, --repo the remote repository" | |
echo " -M, --remote-branch the remote branch" | |
echo " -B, --branch the local branch" | |
echo " -D, --directory the directory, from git root" | |
echo " -C, --config use a different config file (default $CONFIG)" | |
echo " -R, --reset BRANCH reset a failed deployment to BRANCH" | |
echo " -X, --resetup delete git setup and reset" | |
echo " -h this help" | |
echo " " | |
echo " All options can be specified in the .deploy file in the" | |
echo " respective deploy directory." | |
echo " " | |
} | |
function config_init { | |
cat << EOF > $CONFIG | |
[default] | |
# path to deploy from gitroot | |
deploy_directory=path/to/deploy; | |
# local git branch to deploy from (make this different from any other branch) | |
# convention is hk-deploy-appname | |
deploy_branch=deploy-branch; | |
# remote git branch to deploy to | |
deploy_branch_remote=master; | |
# git remote to deploy to, must be readable and writable. | |
repo=deploy; | |
# url of remote repo. | |
repourl=git@heroku.com:hkpcpsbbstage.git; | |
# Site environment to be used, this is what the packages are built for | |
# using fab build:siteenv | |
siteenv=default; | |
# Deploy environment | |
deploy_env=EnvSettings_site; | |
# if no user identity is already set in the current git environment, use this | |
# username to be used to login to deployment servers | |
default_username=ubuntu; | |
# heroku app instance type examples are ( matser, ipython, schedule, collector, etc) | |
apptype=master; | |
# app whose services are to be used in this app | |
master=default; | |
EOF | |
echo "Created $CONFIG" | |
} | |
# function to parse the ini style configuration file | |
function config_parser () { | |
local iniFile="$1"; | |
local tmpFile=$( mktemp /tmp/`basename $iniFile`.XXXXXX ); | |
local intLines; | |
local binSED=$( which sed ); | |
# copy the ini file to the temporary location | |
cp $iniFile $tmpFile; | |
# remove tabs or spaces around the = | |
$binSED -i -e 's/[ \t]*=[ \t]*/=/g' $tmpFile; | |
# transform section labels into function declaration | |
$binSED -i -e 's/\[\([A-Za-z0-9_-]*\)\]/config.section.\1() \{/g' $tmpFile; | |
$binSED -i -e 's/config\.section\./\}\'$'\nconfig\.section\./g' $tmpFile; | |
# remove first line | |
$binSED -i -e '1d' $tmpFile; | |
# add the last brace | |
echo -e "\n}" >> $tmpFile; | |
# now load the file | |
source $tmpFile; | |
# clean up | |
rm -f $tmpFile; | |
} | |
function reset_branch() { | |
RESET_BRANCH=$1 | |
echo resetting to $RESET_BRANCH | |
git symbolic-ref HEAD refs/heads/$RESET_BRANCH && git reset --mixed >&2 | |
} | |
if [[ "$1" == "-R" || "$1" == "--reset" ]]; then | |
reset_branch $2 | |
exit 0 | |
fi | |
# Parse arg flags | |
while : ; do | |
if [[ $1 == "-v" || $1 == "--verbose" ]]; then | |
verbose=true | |
shift | |
elif [[ $1 == "-s" || $1 == "--setup" ]]; then | |
setup=true | |
shift | |
elif [[ $1 == "-r" || $1 == "--repo" ]]; then | |
repo=$2 | |
shift 2 | |
elif [[ $1 == "-M" || $1 == "--remote-branch" ]]; then | |
deploy_branch_remote=master=$2 | |
shift 2 | |
elif [[ $1 == "-B" || $1 == "--branch" ]]; then | |
deploy_branch=$2 | |
shift 2 | |
elif [[ $1 == "-D" || $1 == "--directory" ]]; then | |
deploy_directory=$2 | |
shift 2 | |
elif [[ $1 == "-C" || $1 == "--config" ]]; then | |
CONFIG=$2 | |
shift 2 | |
elif [[ $1 == "-h" ]]; then | |
show_help | |
exit 0 | |
elif [[ $1 == "-X" || $1 == "--resetup" ]]; then | |
resetup=true | |
shift | |
else | |
break | |
fi | |
done | |
if [[ ! -f "$CONFIG" ]]; then | |
echo "$CONFIG not found. Create?" | |
select result in Yes No; do | |
if [[ "$result" == "Yes" ]]; then | |
config_init | |
fi | |
exit 0 | |
done | |
fi | |
# load config | |
config_parser "$CONFIG" | |
function go_gitroot { | |
GIT_TOPLEVEL="$(git rev-parse --show-toplevel)" | |
PREFIX=${PWD#"$GIT_TOPLEVEL/"} | |
pushd $GIT_TOPLEVEL | |
} | |
#echo expanded commands as they are executed (for debugging) | |
function enable_expanded_output { | |
if [ $verbose ]; then | |
set -o xtrace | |
set +o verbose | |
fi | |
} | |
#this is used to avoid outputting the repo URL, which may contain a secret token | |
function disable_expanded_output { | |
if [ $verbose ]; then | |
set +o xtrace | |
set -o verbose | |
fi | |
} | |
enable_expanded_output | |
function set_user_id { | |
if [[ -z `git config user.name` ]]; then | |
git config user.name "$default_username" | |
fi | |
if [[ -z `git config user.email` ]]; then | |
git config user.email "$default_email" | |
fi | |
} | |
function restore_head { | |
if [[ $previous_branch = "HEAD" ]]; then | |
#we weren't on any branch before, so just set HEAD back to the commit it was on | |
git update-ref --no-deref HEAD $commit_hash $deploy_branch | |
else | |
git symbolic-ref HEAD refs/heads/$previous_branch | |
fi | |
git reset --mixed | |
popd | |
} | |
if [[ `type -t config.section.$appname` == 'function' ]]; then | |
config.section.$appname | |
else | |
echo "FATAL!! No config for the app $appname in $CONFIG" | |
exit 0 | |
fi | |
commit_title=`git log -n 1 --format="%s" HEAD` | |
commit_hash=`git log -n 1 --format="%H" HEAD` | |
previous_branch=`git rev-parse --abbrev-ref HEAD` | |
go_gitroot | |
if [ $resetup ]; then | |
echo Deleting setup | |
git remote remove $repo | |
git branch -D $deploy_branch | |
setup=true | |
fi | |
if [ $setup ]; then | |
echo Setting up | |
mkdir -p $deploy_directory | |
git remote add $repo $repourl | |
git --work-tree $deploy_directory checkout --orphan $deploy_branch | |
git --work-tree $deploy_directory rm --cached "*" | |
git --work-tree $deploy_directory add --all | |
git --work-tree $deploy_directory commit -m "initial publish"$'\n\n'"generated from commit $commit_hash" | |
git push --force $repo $deploy_branch:$deploy_branch_remote | |
restore_head | |
exit | |
fi | |
if ! git diff --exit-code --quiet --cached; then | |
echo Aborting due to uncommitted changes in the index >&2 | |
exit 1 | |
fi | |
disable_expanded_output | |
git fetch --force $repo $deploy_branch_remote:$deploy_branch | |
enable_expanded_output | |
#make deploy_branch the current branch | |
git symbolic-ref HEAD refs/heads/$deploy_branch | |
#put the previously committed contents of deploy_branch branch into the index | |
git --work-tree "$deploy_directory" reset --mixed --quiet | |
git --work-tree "$deploy_directory" add --all | |
set +o errexit | |
diff=$(git --work-tree "$deploy_directory" diff --exit-code --quiet HEAD)$? | |
set -o errexit | |
case $diff in | |
0) echo No changes to files in $deploy_directory. Skipping commit.;; | |
1) | |
set_user_id | |
git --work-tree "$deploy_directory" commit -m \ | |
"publish: $commit_title"$'\n\n'"generated from commit $commit_hash" | |
disable_expanded_output | |
#--quiet is important here to avoid outputting the repo URL, which may contain a secret token | |
git push --force $repo $deploy_branch:$deploy_branch_remote | |
enable_expanded_output | |
;; | |
*) | |
echo git diff exited with code $diff. Aborting. Staying on branch $deploy_branch so you can debug. To switch back to master, use: git symbolic-ref HEAD refs/heads/master && git reset --mixed >&2 | |
exit $diff | |
;; | |
esac | |
restore_head |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment