Bonus Build – Setting up Jenkins to build and validate pull requests

In my last post about creating a local build environment, I showed how you can set up a local CI server to validate your local commits.

When working with Open-Source on GitHub, contributions usually come in the form of pull-requests. When such a request comes in, it is usually wise to validate the code. But hey, validating commits is hard work when you have to do it manually. You have to pull in the change, merge it locally, build it, run the tests, maybe even sniff test the final application to catch errors the unit-tests can’t catch (for example GUI errors). It’s hard and complex and so every now and then we skip these tests and accept the pull request blindly and deal with the fall out afterwards.

Why not automate those steps?

Technically, a pull request is a branch in your server side repository, created automatically by the GitHub systems. A valid branch should build and should run all tests without errors.

So now that we have a build infrastructure in place, lets use it to build and validate all pull requests for us.

Jenkins comes with an pull-request builder plugin for that job.  I was never able to make this work – as it requires some GitHub API magic to update the status of the request on GitHub, and does not seem to run without it.  But why use something complicated when pull requests are just branches.

A slight word of warning: Pentaho uses non-unique “TRUNK-SNAPSHOT” references for its internal libraries. When a project is built, it always pulls in the latest version of that library, and not the version that was current when that pull-request was made. Therefore it is highly unlikely that very old pull requests build correctly now.

Project set up

This set up requires that you have configured the system to run local builds already. If not, please read the previous posting in this series before you continue.

Begin by creating a new free-style project. Give it a name, and click continue to enter the configuration screen.

1. Configure the clean-up rules

jenkins-pr-01-discard

First, lets make sure we never run out of disk space. As every build can be quite large (between 600 MB and 1GB), we never want to have more than two builds around.

2. Define a parameter for the pull-request ID

jenkins-pr-02-parameter

The build will be parametrized, so that we can choose which pull request to build. Building will be a manual process (you don’t want random people submit code that then gets executed on your machine without your explicit consent.

Create a new string-parameter “PR_ID” and give it a nice description and maybe a default value of a known-good pull request (so that you can test this set up easily).

We will reference this PR_ID parameter in the next step.

3. Configure the Git Checkout rules

jenkins-pr-03-scm

Configure to checkout from GitHub as usual. However, this time we are not going to monitor or build the “master” branch. Instead we are checking against the pull-requests filed in GitHub.

Github stores all pull requests in a special section named “refs/pull”. For each pull request it creates a new sub-entry for the pull-request ID which contains two pointer for “head” (the actual code) and “merge” pointing to the merge commit for the pull request.

Change the “Refspec” parameter to “+refs/pull/*:refs/remotes/origin/pr/*”. This tells Jenkins to monitor the remote references under “pull/*” (which is where GitHub deposits pull request data) and to drop it into the local branch reference “remotes/origin/pr/*”.

Next, specify that we want to build the branch “origin/pr/${PR_ID}/head”. The ${PR_ID} is a reference to your job-parameter that you defined above.

And last but not least: Make sure you clean the working directory and yhat you check-out into the “code” sub-directory.

As the pull requests are triggered manually, you do not need to configure any of the build triggers.

4. Provide the Ant and Ivy configuration to point to our local artifactory.

jenkins-pr-04-config

Reference the same files as you did in the previous posting.

5. Invoke Ant to build the project

jenkins-pr-05-ant

Configure your ANT build step to use testing (to validate that the new code does not break anything) and to publish locally. The artefacts created by the pull request build should not be published to a shared repository. If you do, you start mixing artefacts from branches locations into the same category, which is a recipe for subtle bugs.

6. Archive your artefacts to make them available for manual testing

jenkins-pr-06-archive

Unlike in the previous builds, I prefer to let Jenkins archive the final assembly. This allows me to download and install the Report Designer for some quick manual testing (to see that nothing big is broken – or at least is not more broken than before).

 

That’s it. Hit “Save” and you will be able to build pull requests. Whenever you select “Build now” you will be asked for a pull-request ID and Jenkins will happily start building this particular pull request for you.

This entry was posted in Development, Report Designer & Engine on by .
Thomas

About Thomas

After working as all-hands guy and lead developer on Pentaho Reporting for over an decade, I have learned a thing or two about report generation, layouting and general BI practices. I have witnessed the remarkable growth of Pentaho Reporting from a small niche product to a enterprise class Business Intelligence product. This blog documents my own perspective on Pentaho Reporting's development process and our our steps towards upcoming releases.