Skip to content

Instantly share code, notes, and snippets.

@boppreh
Last active March 4, 2025 14:39
Show Gist options
  • Save boppreh/d0e5ac2bef22be07e305eee087cfd0c9 to your computer and use it in GitHub Desktop.
Save boppreh/d0e5ac2bef22be07e305eee087cfd0c9 to your computer and use it in GitHub Desktop.
Git update hook that builds and auto-deploys on push, with automatic rollback on failure
#!/usr/bin/env bash
# Script to deploy new releases on git push, automatically rolling back and rejecting pushes that fail to start.
# The repo must have a Makefile with `build`, `start` and `stop` targets.
# Each deployment starts from scratch, and ALL FILES UNDER THE REPO WORKTREE ARE DELETED.
# Use the parent dir if persistence is important.
# This script is meant to be executed as an `update` hook, which runs on every pushed ref, before it's accepted.
# Documentation: https://git-scm.com/docs/githooks
# - Exiting with an error rejects the push.
# - The output from this script is visible to the user pushing.
# - Force pushes, rebases, reverts, etc are accepted with no special handling.
# - It runs from the .git directory.
set -eu
alias make="make --always-make"
echo $1 $2 $3 > pushed_test
if [ "$1" != "refs/heads/master" ] && [ "$1" != "refs/heads/main" ]; then
exit 0
fi
oldrev="$2"
newrev="$3"
oldtree="../deployment-$(git rev-list --count $oldrev)-$oldrev"
newtree="../deployment-$(git rev-list --count $newrev)-$newrev"
mkdir "$newtree"
git --work-tree "$newtree" checkout -f "$newrev"
if [ -d "$oldtree" ]; then
make -C "$newtree" build
make -C "$oldtree" stop
make -C "$newtree" start || (make -C "$oldtree" start; exit 1)
rm -rf "$oldtree"
echo -e "\n\e[32mDeployed update $newtree\e[0m"
else
make -C "$newtree" build start
echo -e "\n\e[34mDeployed new $newtree\e[0m"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment