How to build a git polling build bot?

2019-03-13 23:09发布

问题:

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

回答1:

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


回答2:

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:

  1. update the stored sha1
  2. 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


回答3:

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.



回答4:

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