Openismus running jenkins for continuous integration

Over the last couple of weeks, I’ve been playing with a Jenkins installation at jenkins.openismus.com, building some of the Openismus projects. Here are some notes about my experience.

Installation

This runs on an Amazon EC2 instance. Initial installation was surprisingly simple and well documented, though it took me a while to figure out how to use Jenkins properly. I initially used the official Ubuntu 12.10 packages for Jenkins, but they are a little old so I had to switch to using the Debian/Ubuntu packages from jenkins.org to fix a bug with the copyArtifacts plugin. The two packages seem to be structured very differently, so I had to remove all the Ubuntu Jenkins packages before installing the jenkins.org packages, to avoid a conflict.

See also the Jenkins standard security setup instructions, though I had to use the “Jenkins own user database -> Allow users to sign up” feature first, to create a user which I could then enter in to the matrix grid. I then disabled the “Allow users to sign up” checkbox.

Although Jenkins can use slave servers, and probably should, I’m doing everything on one server for now, because I’m afraid of the Amazon EC2 costs getting out of control. Luckily we don’t need to run each build more than once or twice per day to get some benefit. Later I will probably try running EC2 spot instances for the builds. Maybe that won’t be too expensive.

Git-based projects with Jenkins

You’ll need to use the pluginManager page to install the Git plugin, so that there is something other than “None” listed under “Source Code Control” when creating a job. Of course, we have to “apt-get install git” too. We must also specify a git username and email address for the “git plugin” on the configure page, to avoid “Please tell me who you are” errors in the job when Jenkins tries to locally tag the checked out git repository. Neither the configure page or the pluginManager admin pages seem to be linked from anywhere, so I had to discover them via google searches.

Be careful to specify the master branch rather than leaving that blank, or I think Jenkins will try building arbitrary branches, and maybe all of them.

You can specify a “git clean -dfx” via the “Clean after checkout” option under the “advanced” section, and you probably should so you get a truly clean build each time.

You can use the “Poll SCM” Build trigger, with the cronjob syntax, to regularly check the git repository for changes. This is not ideal, but to do it properly you’d need to add a git hook to the git repository to request a build from your jenkins server whenever there is a git commit.

Multiple branches

You can specify more than one git branch, to make Jenkins try building more than just one, but it’s hard see what branch was built when looking at the results.

Simple maven builds

For maven-based Java projects such as OnlineGlom, Jenkins is very straightforward, because maven typically downloads all the dependencies without expecting anything to be installed already, and “maven package” typically does the whole build.

Autotools builds, or similar

For autotools-based projects, you’ll need to make sure that you’ve “apt-get install”ed the project’s dependencies.

Then you must specify the configure and make (or qmake) steps in a build step.

Of course, many real-world projects will need newer versions of their dependencies. For instance, we build maliit-plugins, which depends on maliit-framework, which we develop in sync. For this, I:

  • Tell the maliit-framework job’s build to “make install” into a local directory, via the “–prefix=” configure option.
  • Use an “archive the artifacts” post-build action to store everything in that directory.
  • Use a “copy artifacts from another project” build step in the maliit-plugins job.
  • Export several variables so the build system has access to the dependency in the local prefix. For instance, (maliit uses hateful awful qtmake instead of autotools, but you’d need something similar for autotools):
    export MALIIT_FW_PREFIX=$WORKSPACE/build_install
    export C_INCLUDE_PATH=$MALIIT_FW_PREFIX/include:$C_INCLUDE_PATH
    export CPLUS_INCLUDE_PATH=$MALIIT_FW_PREFIX/include:$CPLUS_INCLUDE_PATH
    export PKG_CONFIG_PATH=$MALIIT_FW_PREFIX/lib/pkgconfig:$PKG_CONFIG_PATH
    export LD_LIBRARY_PATH=$MALIIT_FW_PREFIX/lib:$LD_LIBRARY_PATH
    export XDG_DATA_DIRS=$MALIIT_FW_PREFIX/share:$XDG_DATA_DIRS
    export XDG_CONFIG_DIRS=$MALIIT_FW_PREFIX/etc/xdg:$XDG_CONFIG_DIRS
    export QMAKEFEATURES=$MALIIT_FW_PREFIX/share/qt4/mkspecs/features/:$QMAKEFEATURES

You can use the “” build trigger to make Jenkins try a build whenever a dependency is built.

I have not tried this with multiple built dependencies. I imagine it could get awkard. It feels like Jenkins needs a plugin for autotools to make this simpler.

Multiple configurations

You can create “multiple configuration” jobs to try multiple ways of building your project. For instance, you might provide different sets of options to your configure script. But I couldn’t use this feature due to the spaces that it puts in the build paths. So I created separate top-level jobs for each configuration. Other people seem to do the same, maybe for the same reason.

Email notifcation

I’ve tried using Amazon’s Simple Email Service to send notification emails about build failures, but I don’t have that working yet. I’ll update this if I do.

5 thoughts on “Openismus running jenkins for continuous integration

  1. Have you tried plugins for unit testing and static code analysis (cppcheck for C/C++)? At work, it has saved our life in constant-change environments.

  2. Nice.
    At work, we have tried both jenkins and buildbot and we choose to use buildbot. it’s a programmable continuous integration system, making it configurable to every need we had.
    If it’s not too late, you should give it a look.

      1. My experience with maintaining the Maliit Buildbot instance (up to July):
        Initial config/setup for Buildbot was easy, but without any best-practice for configuration available (that I could find) it quickly grew ugly for even our fairly simple setup. Perhaps my way of doing config had too much abstraction, or too little, or in the wrong place. But in the end I think that the Buildbot approach to config is hurtful for most use-cases.
        Saying ‘there are no config tools, here is the API, go nuts’ places too much of the burden on the user.

        I set up Jenkins for MyPaint the other day (http://ci.mypaint.org/jenkins/). I don’t think I had to read a single page of documentation to do so. Setting up another instance for another project next week. Can’t really compare the two systems until I have a couple of months experience maintaining it though.

Comments are closed.