Table of Contents

Introduction

Experienced developers realize there is much more to writing good software than hacking out code behind the keyboard. Creating quality software requires good software engineering principles like architecture, design, testing, and more. Performing all of these tasks properly takes diligence, and inadequate tools can hinder the process. These hindering effects can encumber the software development process to a point where critically important steps like code review get neglected entirely in favour of fighting with unproductive and unstable development practices. Here I discuss how to set up the tools we use on our team in order to achieve a fast and delightful software engineering loop. The information here is mostly targeted towards developers, build masters, and product managers.

This guide walks you through the steps on how to install and configure a basic Git, Gerrit, and Jenkins configuration. All tools presented here are free and open source.

Prerequisites

It is strongly recommended to use Linux (or a relative) for these tools, though they can be used most any popular platform.

You will need the following pieces of software:

Postgres

Installation of Postgres can be a bit tricky and varies from platform to platform. Their wiki outlines installation guides for these different platforms. After installing Postgres, we will need to add a user and database for Gerrit to use as outlined here.

Git

By far the simplest of these three tools to install is Git. Installation details can be found here. Git makes a strongly committed effort to remain backwards compatible, though new repositories may not be readable by older versions lacking the newer features. After installing git, each user should configure their git environment's user name and email and other preferences such as terminal colors and merge and diff tools (vimdiff, meld, p4merge, etc).

Gerrit

The Gerrit code review system is rather unusual in it's approach to installation and configuration. Here are a few more of it's esoteric features to be aware of:

It is recommended to run Gerrit as a dedicated user on your system so that system resources are restricted to only code review responsibilities. Any username may be used, however to get default ident authentication working with Postgres you may wish to use the Linux account name gerrit2 (ident authentication sidesteps the need for a password and authenticates via the current logged in Linux user). Switch to your gerrit user and follow the installation guide on Gerrit's website. You will be asked a series of configuration questions during installation. If you are going to use the same machine for both Gerrit and Jenkins, choose a port other than 8080 for Gerrit to avoid a conflict (or use some other mechanism such as virtual hosting if running Gerrit and Jenkins as part of a larger server installation like Tomcat or Jetty). When Gerrit asks for the authentication method keep the following in mind:

Unfortunately the details on all of these different authentication methods vary widely so they are not discussed here. If you are just checking Gerrit out yourself, get started with OpenID, the configuration can always be changed later. Once installed, gerrit can be started, stopped, and restarted with bin/gerrit.sh (start | stop | restart)

When creating projects in Gerrit, you may wish to change some options depending on your teams preferred git work flow. I highly recommend the "fast forward only" submit type because it forces the history of the project to be clean and linear at the cost of minor inconvenience up front (due to required and frequent rebasing) - Everyone will will be glad they did when they have to go back and find regressions or blame commits with git bisect! Regardless of your submit type, conflicts will have to be resolved at some point - might as well get it out of the way sooner than later! The fast forward submit type disallows merge commits from being pushed up for review and forces people to resolve conflicts up front; with it people on the project should add the --rebase flag whenever they perform git pull (consider making it an alias).

Jenkins

Jenkins has much wider adoption than Gerrit and is distributed by package managers in many Linux distributions. However if you wish to always be on latest builds, Jenkins may be installed manually. As usual, if you do install Jenkins manually, it is recommended to run Jenkins as a dedicated user on your system so that system resources are restricted to only Jenkins build responsibilities. Any user account name may be used. Jenkins can be run standalone with java -jar jenkins.war or the war file may be part of a larger installation and run in a Java container like Jetty or Tomcat. Installation instructions may be found Here.

A blank Jenkins installation allows anonymous access and configuration. To remedy this issue, open Jenkins in your browser (defaults to port 8080), navigate to Manage Jenkins > Configure System, check Enable Security, and configure the settings to your needs. Jenkins has a large and excellent plugin system that provides an easy to use interface for customization. For larger enterprise Jenkins deployments you may wish to install the Role-Based Authorization Strategy plugin to allow several teams to manage their own project configurations.

Integrating Jenkins and Gerrit

In order for Jenkins and Gerrit to integrate we need to give our Jenkins user ssh access; Allow Jenkins to log in to Gerrit with this ssh key; Add a new review type "verified" that Jenkins can use to mark a code review as having passed the build phase; And finally configure the GerritTrigger plugin so builds get kicked off whenever new code is pushed up for review.

  1. Switch to your jenkins user and use ssh-keygen to generate an rsa key pair (e.g. ssh-keygen -t rsa -C "jenkins@localhost")
  2. Set the global git configuration user.email and user.name properties for the jenkins user (from the command line)
  3. Create an ssh key pair for the account that logged into gerrit first (the admin)
  4. In the browser, navigate to gerrit and access your account settings (top right) > SSH Public Keys and upload your id_rsa.pub for the admin account. All gerrit users should do this for their public keys.
  5. Notify Gerrit of a new "non-interactive" user account: $cat /path/for/jenkins/id_rsa.pub | ssh -p 29418 admin@localhost gerrit create-account --ssh-key - --full-name "jenkins" --email "jenkins@localhost" jenkins You may have to copy out jenkins id_rsa.pub to a readable location like tmp instead of their ~/.ssh folder
  6. In the browser, navigate to gerrit and access People > List Groups > Non-Interactive Users > Members > add jenkins to the Members section
  7. Add the verified label to gerrit reviews using the steps below* as the admin user:
    
    $ mkdir tmp
    $ cd tmp
    $ git init
    $ git remote add origin ssh://admin@remote.site.com:29418/All-Projects
    $ git fetch origin refs/meta/config:refs/remotes/origin/meta/config
    $ git checkout meta/config
    

    Add the following to the end of project.config

    
    [label "Verified"]
           function = MaxWithBlock
           value = -1 Fails
           value =  0 No score
           value = +1 Verified
    

    Push the code back to gerrit

    
    $ git commit -a
    $ git push origin meta/config:meta/config
    
  8. Now that we have the verified label, we must add permissions to Non-Interactive users to use it. In the Gerrit web interface navigate to Projects > All-Projects > Access > Add Permission for "Label Verified" (drop down at the bottom of the refs/heads/* section) > add Non-Interactive Users. > Save Changes
  9. Install the Gerrit Trigger plugin on Jenkins
  10. Configure the Gerrit Trigger (from Manage Jenkins) to reflect the following values:

    FieldValue
    HostnameYour gerrit server hostname
    Frontend URLFull URL to your gerrit server
    SSH PortGerrit's ssh port (default is 29418)
    Usernameusername you configured for jenkins
    SSH Keyfile/path/to/jenkins/.ssh/id_rsa (the private key, probably at /var/lib/jenkins/.ssh/id_rsa)
    Build Current Patches OnlyChecked
    VerifyStarted: 0, Successful: 1, Failed: -1, Unstable: -1, Not built: 0
    Code ReviewAll 0's

    All other values can be left as is, click Save then Start

  11. Create a new project on Gerrit called test (don't forget to set fast forward only!)
  12. Create a "free-style" Jenkins job for the test project. Since this is your first project you will need to set up all the configuration from scratch. Later you can simply clone an existing job.
  13. Required configuration:

    FieldValue
    Source Code Management
    • Git, get the ssh url for your project from gerrit
    • Advanced - Name: origin
    • Advanced - Refspec: $GERRIT_REFSPEC
    Branches to build$GERRIT_BRANCH
    Choosing StrategyGerrit Trigger (found in Branches to build advanced tab)
    Build Triggers - Gerrit EventChecked
    Gerrit Project (below Dynaimc Trigger Configuration, it is separate)Pattern: your project name (test), Branch Pattern: list a branch you wish to monitor (e.g. master)
  14. Add tasks to execute for your job (make, ant gradle, etc)
  15. Save and push up some code for review with git push origin HEAD:refs/for/master, this should now trigger a build!

*Special thanks to Peter for these instructions copied here to avoid potential link rot. With any luck Gerrit will add control for this feature to their web interface in a later release. Older versions came with the valid label by default, but they removed it deeming it too "confusing".

Conclusion

After following this guide, you should now have a Git/Gerrit/Jenkins installation that creates a tight loop between developers writing, reviewing, and building code. Much of it now automated! As git commits are pushed up to Gerrit, the code review is not allowed to pass until both a user has given it a +2 review and Jenkins has given it a +1 verified. There are many features of Jenkins that were left out of this guide, it is under active development and integrates well with all the popular build systems.

While not essential, it is a good idea to ensure all developers on a team have a common base of software accessible on their path. Allow engineers to customize their environment, but keep the "officially supported" versions centralized and well known so everyone is on the same page. However beware of the urge to "lock in" to old versions of tools. It is strongly recommended to not only version control the code, but also find a way to version the build system itself! The build system can then be easily read, modified, reviewed, and improved.

Here are the versions of software used at the time of this writing: