Skip to content

Instantly share code, notes, and snippets.

@mfaust35
Last active September 4, 2019 20:51
Show Gist options
  • Save mfaust35/128416840c25a93a29d0ecda8d780baf to your computer and use it in GitHub Desktop.
Save mfaust35/128416840c25a93a29d0ecda8d780baf to your computer and use it in GitHub Desktop.
pre-push hook - run android project unit tests
#!/bin/sh
#
# Custom pre-push hook: ensure we can run tests with current git status that
# will correspond to the branch we are trying to push, then run unit tests
# and android instrument tests before pushing
#
# To use, name this file pre-push in a .git/hooks directory and make it
# executable
#
###### Variable declaration
# Git no-branch
z40=0000000000000000000000000000000000000000
# Branch to push, will be known later
branch_to_push="unknown"
# Current branch name in git
current_branch=$(git symbolic-ref --short HEAD)
# Android emulator name to use for instrumentation tests
emulator_name="Tests"
###### Helper function
# Indent some text
indent() {
echo "$1" | awk '{print " "$0}'
}
# Kill android emulator
kill_emulator() {
echo "+ Killing android emulator"
adb devices | while read -r emulator device; do
avd_name=$(adb -s $emulator emu avd name)
if [[ $avd_name =~ "Tests" ]]; then
indent "Found emulator @Tests"
adb -s $emulator emu kill &> /dev/null
indent "Killed emulator"
fi
done
}
###### Ensure files under current git status correspond to the branch we want
###### to push
# Parse commits to be pushed
while read local_ref local_sha remote_ref remote_sha
do
# Check if we are trying to delete a branch on distant repository,
# in which case do not run tests
if [ "$local_sha" = $z40 ]; then
# Trying to delete a branch on distant repository,
# let git handle it
exit 0
fi
# If we are here it means there are commits
has_commit=true
# Assign value to branch_to_push
# local_ref looks like /refs/heads/{my_branch_name}
# branch_to_push = the part after the last "/"
branch_to_push=${local_ref##*/}
# Check if we are on correct branch to launch the tests
echo "+ Assert current branch is branch to be pushed"
if [[ ! $local_ref =~ $current_branch ]]; then
indent "You want to push the branch "$branch_to_push", and I want to run some test before."
indent "It appears that you are not on this particular branch, so please help me and checkout the branch you want to push."
indent "Hint: your could run 'git checkout "$branch_to_push"'"
exit 1
else
indent "Current branch is the same as branch to push"
fi
done
# Verify $has_commit has been initialized when parsing commits to be pushed,
# which means there is at least 1 commit to push
echo "+ Assert there are commits to push"
if [ ! $has_commit ]; then
indent "No commit found"
exit 0
else
indent "Commit found"
fi
# Then check if the work tree is clean
echo "+ Assert work tree is clean"
if ! git diff --quiet HEAD; then
indent "You want to push the branch "$branch_to_push", and I want to run some test before."
indent "It appears that your work tree isn't clean, so please help me and commit or stash your current work"
indent "Hint: you could run 'git stash'"
exit 1
else
indent "Work tree is clean"
fi
# Run jUnit tests
echo "+ Run jUnit tests"
if ./gradlew clean test ;then
indent "jUnit tests passed"
else
indent "jUnit tests not passed. You are not allowed to push this branch"
exit 1
fi
# Start android emulator to be able to run instrumentation tests
echo "+ Start android emulator -no-window"
emulator @"$emulator_name" -no-window -wipe-data &
indent "Waiting for emulator to start"
WAIT_CMD="adb wait-for-device shell getprop init.svc.bootanim"
until $WAIT_CMD | grep -m 1 stopped; do
indent "wait ..."
sleep 1
done
indent "Emulator started"
# Run android instrumented tests
echo "+ Run Android instrumented tests"
./gradlew connectedAndroidTest test
status=$?
if [ $status -eq 0 ]; then
indent "Android instrumented tests passed"
else
indent "Android instrumented tests not passed. You are not allowed to push this branch"
fi
# Kill emulator whatever the result of test is
kill_emulator
if [ ! $status -eq 0 ]; then
exit 1
fi
@mfaust35
Copy link
Author

mfaust35 commented Aug 31, 2019

To use this pre-push hook:

  1. Create pre-push file under directory .git/hook:
# Assuming you are at the base of a git repository
# EITHER
# create file
vim .git/hooks/pre-push
# and copy past this gist content

# OR
# curl this raw gist url directly into file
curl "https://gist.githubusercontent.com/mfaust35/128416840c25a93a29d0ecda8d780baf/raw" >> .git/hooks/pre-push
  1. Ensure file is executable:
chmod +x .git/hooks/pre-push
  1. Run git push and you should see your android unit tests being executed:
git push origin My-branch

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment