Skip to content

Instantly share code, notes, and snippets.

@purpleidea
Last active September 9, 2018 00:05
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save purpleidea/1b769e2cd1bd7b01a406 to your computer and use it in GitHub Desktop.
Save purpleidea/1b769e2cd1bd7b01a406 to your computer and use it in GitHub Desktop.
Safely pust to git master once CI passes: https://ttboj.wordpress.com/2016/02/16/introducing-git-tpush/
#!/bin/bash
# git-tpush: Safely push to git master once CI passes
# Copyright (C) 2016+ James Shubin, AGPLv3+
# Written by James Shubin <james@shubin.ca>
# Put in your $PATH such as ~/bin/ as "git-tpush" and make it executable
# README: https://ttboj.wordpress.com/2016/02/16/introducing-git-tpush/
ORIGIN='origin' # remote remote, most call this 'origin', some say 'upstream'
BRANCH='master' # remote branch, most everyone calls this master
POLL='5s' # how often do we sleep between polling the ci?
TPUSH='tpush' # branch prefix to use, eg: $TPUSH/test-N, iow: tpush/test-0
GIT=`which git`
if [ -z $GIT ]; then
echo "The \`git' utility can't be found." # lol
echo "Are you sure you're ready for this?"
exit 1
fi
HUB=`which hub`
if [ -z $HUB ]; then
echo "The \`hub' utility can't be found."
exit 1
fi
TPUT=`which tput`
UPSTREAM="$ORIGIN/$BRANCH"
HEAD=`git describe --contains --all HEAD` # current branch
upstream_sha1=`git show -s --format='format:%H' $UPSTREAM`
head_sha1=`git show -s --format='format:%H' $HEAD`
# TODO: compare the individual sequences of commits, to check if they overlap
if [ "$upstream_sha1" = "$head_sha1" ]; then
echo "Your branch is up-to-date with '$UPSTREAM'."
exit 0
fi
# find an unused local and remote branch
count=0
while branch="$TPUSH/test-$count" && ((git branch --list "$branch" | grep -qF "$branch") || (git ls-remote --exit-code $ORIGIN "$branch" >/dev/null)); do
count=`expr $count + 1`
done
echo "tpush branch is: $branch"
git checkout -b "$branch"
git push $ORIGIN "$branch"
git checkout $HEAD # return to previous branch, or: git checkout -
echo "- CI is starting..."
i=1; spinner='\|/-'
sleep 5s # let it startup
# wait for ci status
while status="`hub ci-status $head_sha1`" ; [ "$status" = "pending" ]; do
([ ! -z $TPUT ] && [ "$once" = "1" ] && $TPUT cuu 1 && $TPUT el) ; once="1"
echo "${spinner:i++%${#spinner}:1} Waiting for CI..."
sleep $POLL
done
git branch -d $branch && git push $ORIGIN ":${branch}" # cleanup
# check result
if [ "$status" = "success" ]; then
git push $ORIGIN $BRANCH # w00t!
echo 'Done!'
exit 0
fi
# we failed!
# TODO: add some red text here
echo 'Upstream CI failed with:'
echo "`hub ci-status -v $head_sha1`"
echo "Fix branch '$HEAD' with:"
echo 'git commit --amend'
echo 'or:'
echo 'git reset --soft HEAD^'
echo 'Happy hacking!'
exit 1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment