Git Monitor

When you want to monitor a github repo, you can setup travis-ci, hudson or bamboo continous integration (CI) server. A problem arrises though. What if you want to run scripts on a server that is behind a firewall? The CI server may not be able to access this private server behind your protected network.

This is where gitmon is used. We can monitor the git repository for changes and then when things do change we can run a changed script. The changed script is placed within the repository itself so developers can work with it. This changed script can email people, run bash commands, whatever you want it to do.

You can see the gitmon script on github. Pull requests are welcome.

Usage

You’ll need a file that has things gitmon should do whenever the repo is updated.

vi path/to/git/repo/.gitmon/changed

1
2
3
4
#!/bin/bash

composer install
mail bob@gmail.com "it updated"

Next setup a crontab job

crontab -e

1
*/2 * * * * gitmon path/to/git/repo

Bash code

Here is the script in it’s entirety.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#!/bin/bash
#
# @author kelt@lbm.co
#
# first you will need to setup a file that tells
# gitmon what to do anytime this git repository
# is updated
#
# your/path/to/git/repo/.gitmon/changed
#
# next, to run script
#
# ./gitmon path/to/git/repo
#
# lastly you'll likely want to add this to crontab
# to run gitmon every 2 minutes to check for updates
#
# crontab -e
# */2 * * * * gitmon path/to/git/repo



########################################################
# variables that we need for this script to work
########################################################
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
MONITOR_DIR="$1"
MONITOR_BRANCH="HEAD"
GITMON_DIR=".gitmon"
HISTORY_FILE="$GITMON_DIR/local.commit";
LOCK_FILE="$GITMON_DIR/running.lock";
ONCHANGED_FILE="$GITMON_DIR/changed";



#######################################################
# show usage if there aren't any arguments from user
#######################################################
if [ -z "$MONITOR_DIR" ]; then
echo "usage:"
echo "$0 path/to/git/repository"
exit;
fi



########################################################
# ensure that this directory has .git repo in it
########################################################
if [ ! -d "$MONITOR_DIR/.git" ]; then
echo "Could not find .git in: '$MONITOR_DIR'"
exit
fi



#######################################################
# no point in running if we don't have onchanged file
#######################################################
if [ ! -f "$MONITOR_DIR/$ONCHANGED_FILE" ]; then
echo "You need to create on changed script: $MONITOR_DIR/$ONCHANGED_FILE"
exit
fi


########################################################
# only run this script when lock file doesn't exist
########################################################
cd $MONITOR_DIR

if [ -f $LOCK_FILE ]; then exit; fi;
touch $LOCK_FILE



########################################################
# find the last local and remote commit so we can
# compare them and see if they are different
########################################################
HISTORY=($(git ls-remote --quiet))

LOCAL_BRANCH=$(git symbolic-ref -q HEAD)
LOCAL_BRANCH=${LOCAL_BRANCH##refs/heads/}
LOCAL_BRANCH=${LOCAL_BRANCH:-HEAD}
LOCAL_COMMIT=$(git log -n 1 $LOCAL_BRANCH --pretty=format:"%H")

REMOTE_BRANCH=$(git symbolic-ref -q HEAD)
for ((i=0; i < ${#HISTORY[*]}; i+=2)) do
if [[ "${HISTORY[i+1]}" == "$REMOTE_BRANCH" ]]; then
REMOTE_COMMIT="${HISTORY[i]}"
fi
done



########################################################
# if no remote commit is set then we need to bail
########################################################
if [ -z "$REMOTE_COMMIT" ]; then
echo "Could not find remote branch commit for $REMOTE_BRANCH"
rm $LOCK_FILE
cd $SCRIPT_DIR
exit
fi



########################################################
# compares the LOCAL_COMMIT with REMOTE_COMMIT and if
# things have changed then onChange function is called
########################################################
if [ "$LOCAL_COMMIT" != "$REMOTE_COMMIT" ]; then
. $ONCHANGED_FILE "$LOCAL_BRANCH" "$REMOTE_BRANCH" "$LOCAL_COMMIT" "$REMOTE_COMMIT"
fi



########################################################
# remove the lock file now that we are done with script
########################################################
rm $LOCK_FILE
cd $SCRIPT_DIR