Retainability

Life's lessons expressed in UTF-8

Triggering Jenkins Builds From GitHub, Made Easy

Recently, I had to connect a private Jenkins-CI instance to a number of private repositories stored on GitHub. The process of connecting GitHub to Jenkins, at first, proved to be a bit tricky. But now, I have it all figured all out.
Before getting into details on my setup, let me briefly discuss my first two attempts at connecting GitHub to a private Jenkins instance. First, I started off by connecting GitHub to Jenkins by following the steps outlined in Mark Theunissen’s blog post Triggering Jenkins build by Pushing to Github, which worked, but was a bit limited given my SSH private key setup on the Jenkins master/slave nodes–I am using a SSH config file, with pseudo GitHub URLs, for identifying the SSH key associated with a particular GitHub repository.

# git@github.com:nywilken/blogapp.git
Host blogapp.github.com
Hostname github.com
IdentityFile ~/.ssh/id_rsa.blogapp

# git@github.com:nywilken/chef-repo.git
Host chefrepo.github.com
Hostname github.com
IdentityFile ~/.ssh/id_rsa.chefrepo

While not explicitly documented, the GitHub plugin validates the GitHub URL configured for a Jenkins job against the GitHub URL provided in the payload data that is posted to the configured GitHub web-hook URL. So seeing as I am using a pseudo URLs and Github is posting posting the valid url (git@github.com:nywilken/blogapp.git) in the payload to the Github plugin, Jenkins ignores the POST request because it can not find a matching URL.

After figuring out how the GitHub plugin works with the configured GitHub URLs I decided to move on and find another solution. This lead me to the triggering builds remotely feature for Jenkins, which allows a user to configure a random authentication token that can be used to trigger builds via a RESTful api.

To setup the remote build feature I assigned an authentication token to each Jenkins jobs (Job Configuration Screen) and then configured a GitHub web-hook for each of the repositories with a URL like the following:

## Using the gituser and gitpassword above
http://GITUSER:GITPASSWORD@myjenkinsurl.com/job/blogapp/build?token=LONG_RANDOM_TOKEN
Using this setup a new build would be triggered upon a successful push to the GitHub repository for the job URL configured in the web-hook URL. This setup worked fine up until today, when I noticed that a build is triggered any time a push is made to any branch under the GitHub repository–regardless of the branch configuration specified in the job’s Git configuration properties.

While looking into the Git plugin documentation for restricting when GitHub web-hook POSTs are triggered I found a simple, but informative, post by Kohsuke Kawaguchi Polling must die. Where he explains how to setup a simple Git push notification system that works in conjunction with SCM polling for triggering builds upon a new commit.

Given the new found facts I updated the Jenkins job configuration by enabling the Poll SCM feature with no schedule–we don’t actually want Jenkins to poll automatically -only when it receives a push notification from GitHub. Then I went over to the GitHub repositories and updated the web-hook URLs so that they look like the following:

http://myjenkinsurl.com/git/notifyCommit?url=git@blogapp.github.com:nywilken/blogapp.git&branches=master
Now, using the notifyCommit URL I am able to pass along my psuedo URLs as the GitHub repository URL and specify exactly which branch to watch for new push commits.  Thus allowing my Jenkins instance to trigger builds anytime there is a new commit to the master branch for anyone of the configured GitHub repositories.