How can a little cron, bash + make based script (e.g. much smaller and less robust than, for example, Hudson) build-bot poll a git repo and detect if it should build now - e.g. if in its periodic pull from the remote git repo, it has retrieved new code?
Currently, it looks like this:
git fetch > build_log.txt 2>&1
if [ $? -eq 0 ]
then
echo "Fetch from git done";
git merge FETCH_HEAD >> build_log.txt 2>&1 ;
if [ $? -eq 0 ]
then
echo "Merge via git done"; ...
# builds unconditionally at the moment
fi
fi
If nothing was fetched, then "get fetch" will output no lines, so just check for zero filesize on build_log.txt:
git fetch > build_log.txt 2>&1
if [ -s build_log.txt ]
then
# build
fi
You can record the tip of your branch to build between polls, and build whenever the the tip changes–that is, when the branch has been changed.
git rev-parse <branch_name>
Will retrieve the sha1 of the latest commit in the branch. Compare the output of the command with the stored output, and when it changes:
- update the stored sha1
- perform the build
This lets you target specific branches and only build when that branch changes. Otherwise, if you want to build whenever any branch changes you can just check that the output of git fetch
is empty (when there are no updates, git fetch
returns nothing).
Here's a version of your script that only builds when master changes (so that changes to experimental branches don't trigger new builds of master if it hasn't changed):
if [ ! -f prev_head ]; # initialize if this is the 1st poll
then
git rev-parse master > prev_head
fi
# fetch & merge, then inspect head
git fetch > build_log.txt 2>&1
if [ $? -eq 0 ]
then
echo "Fetch from git done";
git merge FETCH_HEAD >> build_log.txt 2>&1 ;
git rev-parse master > latest_head
if ! diff latest_head prev_head > /dev/null ;
then
echo "Merge via git done"; ...
cat latest_head > prev_head # update stored HEAD
# there has been a change, build
fi
fi
If you have control over the remote repo, you might consider doing it via hooks instead of polling. That way your script only gets called when there is something new to build.
You can also target a specific branch without maintaining the most recent head or using a temporary file:
if [[ $(git fetch 2>&1 | grep master) ]]; then
# build
fi