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.
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:
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.
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).
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 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.
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.
$ 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
Configure the Gerrit Trigger (from Manage Jenkins) to reflect the following values:
Field | Value |
---|---|
Hostname | Your gerrit server hostname |
Frontend URL | Full URL to your gerrit server |
SSH Port | Gerrit's ssh port (default is 29418) |
Username | username 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 Only | Checked |
Verify | Started: 0, Successful: 1, Failed: -1, Unstable: -1, Not built: 0 |
Code Review | All 0's |
All other values can be left as is, click Save then Start
Required configuration:
Field | Value |
---|---|
Source Code Management |
|
Branches to build | $GERRIT_BRANCH |
Choosing Strategy | Gerrit Trigger (found in Branches to build advanced tab) |
Build Triggers - Gerrit Event | Checked |
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) |
*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".
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: