Saturday, September 21, 2013

Supporting code review with Maven, Git, Jenkins and Atlassian Stash

I have to admit, the first time I used git it left a bad taste in my mouth. The commands seemed to promote using options in your default workflow and it felt overly complicated, like a tool designed by developers who love complexity. I chalked it up to the fact it was designed by Linux kernel hackers. I used the tool only when I had to, such as when contributing to projects hosted in GitHub, like Jenkins. It turned out, I was wrong. I was working with a different mental from the tool's designers and expecting the tool to feel natural to me

Recently, a colleague of mine sent a couple of videos that explain how git works. After watching them, the elegance and simplicity of the tool was obvious. Now, I am spending the weekend rushing to get a git repository manager, Atlassian Stash, integrated into our work flow in time to welcome a new team member with pre-integration code reviews; something that Git and Stash make extremely easy.

If you are interested in those videos, I can't recommend them more especially for Git skeptics:


Atlassian Stash and Code Review


I wanted to introduce code review into the core of my team's development loop. I have seen teams completely transformed by it. I have had success with patch-based review, but the exceptions like handling binary files and trying to update patches with conflicts for teams with reservations about review being too cumbersome is not recommended. It still has more benefits than drawbacks, but with negative stakeholders it can be like walking through a mine field. Distributed version control makes these exceptions a non-issue since a pull request can be integrated as-is, no patch-up intervention necessary.

When looking for a supporting tool, GitHub Enterprise was a natural choice, but the pricing was expensive especially for the size of my team. Alternatively, Atlassian Stash had extremely affordable pricing for the size of my team. The code viewer is admittedly more cumbersome than GitHub's, but is still better than the tools we were using before. More importantly, it handles the pull request work flow with reviewers and once you configure it, it integrates well with Jenkins and Jira.

Configuring Maven


Stash supports the SSH transport, and can simply add your SSH key to your user profile. Under Cygwin/Linux it's the normal SSH key authentication setup. Add your public (.pub) key under your user profile in Stash and clone an empty Stash repo. You can then setup Maven to use the repo by adding an SCM section in a project pom:

<scm>
  <developerConnection>
  scm:git:ssh://git@your.stash.host:7999/ex/example.git
  </developerConnection>
</scm>

By default, the Maven Git SCM provider will use this as both the fetch and push URL. You can optionally specify different push/fetch URLs.

Configuring Jenkins


Before you start, you will want to install the following:

  • Jenkins Maven Integration (included with recent Jenkins versions)
  • Jenkins Git Plugin
  • Stash Notifier Plugin

You'll need to configure key auth for Jenkins to clone the repo. You will also want to configure Stash settings for the notifier (Manage Jenkins->Configure System). Once you've done this, to set up a single branch build on 'master':

  • Source Code Managment: Git
  • Repository URL: ssh://git@your.stash.host:7999/ex/example.git
  • Name: origin
  • Refspec: +refs/heads/master:refs/remotes/origin/master
  • Branches to build: master
  • Checkout/merge to local branch (Advanced): master (required to use release plugin)
  • Repository browser: stash
  • Repository browser URL:  https://your.stash.host/projects/EX/repos/example
  • Build triggers: when snapshots dependencies are built, Poll SCM with long interval
  • Maven release build (if you are using it)
  • Post-build actions: Notify Stash Instance (reports build results back to Stash)

Pull-request Builds


There are multiple ways to configure this, including writing your own plugins. However, using another build you can publish build results to Stash pull requests. Create a new job and configure the following:

  • Source Code Managment: Git
  • Repository URL: ssh://git@your.stash.host:7999/ex/example.git
  • Name: origin
  • Refspec: +refs/pull-requests/*:refs/remotes/origin/pull-requests/*
  • Branches to build: origin/pull-requests/*/from
  • Repository browser: stash
  • Repository browser URL:  https://your.stash.host/projects/EX/repos/example
  • Build triggers: when snapshots dependencies are built, Poll SCM with long interval
  • Build: Goals and options = clean verify
  • Post-build actions: Notify Stash Instance (reports build results back to Stash)

Triggered Builds


This will work, but if you want to start the builds immediately upon pushed changes you need to configure a web hook in stash. In the repository settings, add the 'Stash Post-Receive Webhook to Jenkins'. Configure it with the following settings:

  • Jenkins URL: https://your.jenkins.host/
  • Git Repo URL: ssh://git@your.stash.host:7999/ex/example.git

The plugin tells your Jenkins server to poll immediately and a build will start if there are relevant changes to build. You could just trigger a build with a direct web hook to the job, but this will always trigger a build, regardless of whether the changes are for the branch(es) you are building.


How It Works


Using this setup, your master build publishes artifacts with approved changes to your repository. Your team integrates changes by merging submitted pull requests. When pull requests are submitted, Jenkins detects them and updates the pull request with the build status.This allows your reviewers to  review the code and allows them to see whether the pull request builds in advance.

No comments:

Post a Comment