Skip to content

Instantly share code, notes, and snippets.

@lski
Last active December 11, 2020 12:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lski/a0c9229d515d8616b381c813744918d9 to your computer and use it in GitHub Desktop.
Save lski/a0c9229d515d8616b381c813744918d9 to your computer and use it in GitHub Desktop.
Replace an entire branch with new code, commit all and push it. Useful for generated github pages.
#!/bin/bash
# Echo usage to console
usage() {
cat << EOF
usage: replace-branch.sh [options] repo-url
options:
-s
The source folder (default: './build')
-b
The branch to deploy too (default: main)
-o
The temp output directory (default: '../deploy-{currenttime}')
-y
Continue without promoting for confirmation
EOF
exit 1;
}
# Generic echo of a message as first param, second
function msg() {
if [[ ! -z "$2" ]]
then
echo "$1" 1>&2; exit 1
else
echo $1
fi
}
# the colon denotes that there has to be a value following the -flag, e.g. `-s ./dist, not that the flag is optional
# spacing is NOT important
# A case statement wont run if the option wasnt passed
while getopts s:b:o:yh option
do
case "${option}" in
s) SOURCEDIR=${OPTARG};;
b) BRANCH=${OPTARG};;
o) OUTPUTDIR=${OPTARG};;
y) AUTOCONFIRM=1 && echo "hello";;
h) usage;;
:)
msg "ERROR: Option -$OPTARG requires an argument" 1
;;
\?)
msg "ERROR: Invalid option -$OPTARG" 1
;;
esac
done
shift $((OPTIND -1)) # This removes the params available so we can use positional params for the git repo "$1"
GITREPO=$1
[[ -z "$GITREPO" ]] && usage;
if [ -z "$BRANCH" ]; then BRANCH="main"; fi
# First ensure there is a value for outputdir, if not create generate one with a timestamp to avoid clashes
if [ -z "$OUTPUTDIR" ]; then OUTPUTDIR="$(readlink -f ../deploy-$(date +%s%N))"; else OUTPUTDIR="$(readlink -f $OUTPUTDIR)"; fi
# Check there isnt already an output directory as it will cause clashes
[ -d "$OUTPUTDIR" ] && msg "The '$OUTPUTDIR' already exists" 1;
# Ensure there is a source directory and it exists
if [ -z "$SOURCEDIR" ]; then SOURCEDIR="$(readlink -f './build')"; else SOURCEDIR="$(readlink -f $SOURCEDIR)"; fi
[ ! -d "$SOURCEDIR" ] && msg "The source directory '$SOURCEDIR' could not be found" 1;
ORIGINALDIR="$(pwd)"
## User message
echo "Git Repo: $GITREPO"
echo "Branch: $BRANCH"
echo "Source: $ORIGINALDIR"
echo "Temp Folder: $OUTPUTDIR"
# Get conformation from the user (a key press of 'y') to ensure they are happy to continue
[[ "$AUTOCONFIRM" -ne "1" ]] && read -p "Are you sure? " -n 1 -r
# Note as some have pointed out its better to 'not' negate this and exit as the code could still run if there is an error
if [[ "$AUTOCONFIRM" -eq "1" || $REPLY =~ ^[Yy]$ ]]
then
# Create the output directory
mkdir "$OUTPUTDIR"
# Clone the lightest version of the repo possible into the current directory
git clone --depth 1 $GITREPO "$OUTPUTDIR"
# Switch to that directory
cd "$OUTPUTDIR"
# Delete all files from target folder, making sure to ignore the .git files and folder at top level only
find . -maxdepth 1 ! -name '.git*' ! -name '.' -exec rm -rf {} \;
cp -R "$SOURCEDIR/." "$OUTPUTDIR"
git add .
git commit -m "Published"
git push
cd "$ORIGINALDIR"
rm -rf "$OUTPUTDIR"
echo "Finished..."
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment