Integrate Jenkins builds into GitHub Pull Requests

As we bootstrap our projects, we want to go lean and keep the over cost as low as possible. I have used other CI tools in the past (SemaphoreCI, Circle, etc…) and integrate their builds with GitHub PRs; it would cost us at least $30/month per project / with limited users. I have recently deployed a private server for Jenkins builds and for other ‘sandbox’ scripts for $10/month. I can use it for unlimited projects and users!

Meet Jenkins, an open source automation software which you can set up on your server for automating, building and deploying all kinds of projects. Don’t you just love open source especially open source + automation? I do.

Ready?

I will skip the boring steps of installing Jenkins from scratch and save the setting up Jenkins projects for another post.

Install GitHub Pull Request Builder plugin

You will need to install “GitHub Pull Request Builder” plugin for this to work.

Go to Manage Jenkins > Manage Plugins
On the Available tab, search for “GitHub pull request builder” (source) This plugin will require other git and GitHub related plugins to be installed, so make sure you install them all.

Set up Jenkins server to authenticate GitHub

Go to Manage Jenkins > Configure System
Under GitHub Pull Request Builder, fill in authentication info for your GitHub repo.
GitHub Server API URL: https://api.github.com
Credentials: Click Add

If it says “connected to GitHub.” Yay! Let’s move on.

Configure your build project to receive web-hook from GitHub

I will assume that you already have a Jenkins build project set up. Mine is named “RSpec Prod” — it runs a set of RSpec tests for our API Ruby on Rails application. I want these tests to run whenever a Pull Request is created on GitHub in our app repo. Take a look at the workflow below:

Let’s configure your project to receive and handle these web-hooks from GitHub! Click on the project name, click Configure. Enter:

Under Advanced, set Name to origin
If you just want to build PRs, set refspec to +refs/pull/$/*:refs/remotes/origin/pr/$/*

If you want to build PRs and branches, set refspec to +refs/heads/*:refs/remotes/origin/* +refs/pull/*:refs/remotes/origin/pr/* (see note below about parameterized builds)
In Branch Specifier , enter $ instead of the default */master .
If you want to use the actual commit in the pull request, use $ instead of $

More detailed instructions can be found here

Optional: (re)start the builds by leaving a special text in the PR comment

Under Build Triggers, I have a Regex “.*(re)?run tests.*” for the Trigger phrase so that when I purposely comment “run tests” or “rerun tests…” on a PR, I can force the build to re-run!

For better presentation purposes: Under Trigger Setup, enter the info as follow (I’ll explain why below)

Test

Now when you create a Pull Request in your GitHub repo, if everything has been set up correctly, you will immediately see this:

By default, you will see your avatar and the text “Default” next to it. As you see here, the text you entered in the Commit Status Context as “Jenkins” in the last step will appear instead.

And when the build finishes, voila!

Similarly, the text “RSpec tests passed” was also set by you in the last step in Commit Status Build Result for Success. You would have seen something ‘default’ here instead.

“User Interface” Improvement

You might notice that instead of the Jenkins logo next to “Jenkins” in the build status, it displays your GitHub avatar and ‘Default’ in your case. Why?

I actually created another GitHub account called “.*-jenkins-bot” with a fox logo, and then added this account as a collaborator to my repo. I don’t feel comfortable using our GitHub admin account for this. Using a jenkins-bot account adds another security layer — also, the bonus is that you will have the Jenkins logo next to your custom build status! Cool, right?

Remember to update Jenkins to authenticate your GitHub repo using this “bot” account.

GitHub Pull Request Builder announced that there was a security hole (SECURITY-261 / CVE-2018–1000142) in versions before 1.40.0.

GitHub Pull Request Builder Plugin stored serialized objects in build.xml files that contained the credential used to poll Jenkins. This can be used by users with master file system access to obtain GitHub credentials.