Continuous integration with Jenkins

On Tuesday morning, Joshua Jensen presented a introduction to continuous integration (CI) with Jenkins. Although CI is generally considered a part of the development process, it it has relevance to system administration. I can think of several occasions where a simple build that checked CFEngine syntax before deploying the change across clusters would have saved several hours of effort.

Jensen opened with some basic CI concepts. Perhaps the most basic question is "why do we need this?" There's a lot of value in detecting changes that break a build, and in being able to identify who broke it. In addition, it improves test coverage to avoid the "but it works on my machine!" problem. CI provides code integration, compilation, artifact archival, testing, and deployment.

A good CI strategy has regular builds, preferably after every commit. There should be a single source repository. Builds and tests should be automated. Fast builds are preferable, since long builds don't let you know quickly if a build is broken. High visibility and involvement for the team is key, too.

Jenkins began as a Sun Microsystems project called "Hudson" in 2004. It was build from the beginning to be flexible and support plugins. By 2007, Hudson was fairly mature and started seeing wider adoption. However, when Oracle purchased Sun, they began changing how the project was managed. As a result, original developer Kohsuke Kawaguchi forked the project in 2011. The name changed, but the goals remained the same. Jenkins is an active project, with 3 new plugins created and 400 new installs each week. It has a stable branch with longer release cycles and back ported bug fixes.

Once attendees were familiarized with Jenkins concepts, Jensen demonstrated installing Jenkins. It ships as a WAR file that can be run in an application server like Tomcat, or with its own lightweight server. Once Jenkins is installed, it's easy to set up a project. Projects are defined by a source code repository, build timing or triggers, and "what happens next".

Jenkins can track metadata about builds, including the most recent failed and successful builds. It keeps build history and can provide console output. The console output of the build can be helpful in determining if a failure is due to the code or a mis-configured build server. In his demonstration, Jensen had a build initially fail because git wasn't installed. It was instructive because the build occurred not on the server where Jenkins was installed, but on a separate build node. The ability to add multiple, independently-configurable build nodes is a powerful feature of Jenkins.

The other powerful feature of Jenkins is the plugin architecture. Over 800 plugins exist in the Jenkins ecosystem, providing a variety of features. Support for various version control systems, authentication methods, notification, workflow building, and many more features can be added. There are Jenkins-based CI-as-a-Service websites, too.

It would have been nice to see more real-world examples in how Jenkins could be used on the operations side, and to have more depth in how Jenkins is configured and maintained. There's no way that would fit in a half-day session, though. If you're looking for a good introduction to CI and Jenkins, this new course is for you.