Om man driftar sitt eget Git-repo (och därmed saknar det inbyggda stödet i t.ex. GitHub och BitBucket) är det enkelt att lägga in kopplingar (hooks) så att ett bygge automatiskt startas vid commit. På så sätt kan man undivka att byggservern kontinuerligt måste polla repot efter förändringar. Detta är framför allt till stor nytta om man vill ha en snabbare återkoppling mellan incheckning och automatiska tester m.m.

Nedan visar jag hur man automatiskt kan trigga två olika typer av Jenkins-byggen från Gits post-receive hook. När en git-tag pushas upp triggas ett parametriserat release-bygge och när ett gren-huvud uppdateras triggas ett vanligt dev-bygge.

I det första fallet triggas bygget direkt. I det andra fallet säger vi till Jenkins att det är dags att polla repot för ett visst jobb. Man kan ju naturligtvis tänka sig att även dev-byggen är parametriserade byggen, men detta var vad som behövdes när jag skrev hooken.

#!/bin/bash

## Git post-receive hook for triggering release builds and dev build in
## Jenkins for selfhosted Git servers. Dev builds are triggered using Jenkins
## polling mechanism when branches are commited to. The release builds are
## triggered when tags are pushed.

## Naming conventions
##
## Bare git repo: 			myproj.git
## Jenkins dev job:			myproj
## Jenkins release job:		myproj-release

JENKINS_URL="http://jenkins"
JENKINS_CREDENTIALS="someuser:apassword"
REPO_PATH="$(readlink -f "$(git rev-parse --git-dir)")"
JOB_NAME="$(basename $REPO_PATH .git)"
REL_JOB_NAME="$JOB_NAME-release"

############


#  Remove trailing slash if any
JENKINS_URL="${JENKINS_URL%/}"

while read oldval newval refname; do
	# Ignore if we are deleting something
	[ $newval = '0000000000000000000000000000000000000000' ] && break

	case $refname in
		refs/tags/*)
			# Adding or updating tag
			res="$(curl -sSf -u $JENKINS_CREDENTIALS "$JENKINS_URL/job/$REL_JOB_NAME/buildWithParameters" --data-urlencode "GIT_TAG=$refname" 2>&1)"
			status=$?
			case $status in
				22) echo "Couldn't trigger Jenkins job for: $REL_JOB_NAME" ;; 
				0) echo "Triggered Jenkins job $REL_JOB_NAME: $refname" ;;
				*) echo "Failed to trigger Jenkins job $REL_JOB_NAME: $res";;
			esac
			;;
		refs/heads/*)
			# Adding or updating a branch
			res="$(curl -sSf -u $JENKINS_CREDENTIALS -X POST "$JENKINS_URL/job/$JOB_NAME/polling" 2>&1)"
			status=$?
			case $status in
				22) echo "Couldn't trigger polling of Jenkins job for: $JOB_NAME" ;; 
				0) echo "Triggered polling of Jenkins job $JOB_NAME: $refname" ;;
				*) echo "Failed to trigger polling of Jenkins job $JOB_NAME: $res";;
			esac
			;;
	esac
done