Jira <-> Gerrit integration experience

Jira <-> Gerrit integration experience

Jira and Gerrit integrate with several tools. It took us a while to find a balance we like – so I decided to share our experience.

Jira -> Gerrit

MeemMe developed a very nice way to point from issues in Jira to Changes in Gerrit. Their plugin, called “Gerrit Code Review for JIRA” keeps querying Gerrit whenever you look at a specific issue, in order to locate Changes with this issue’s code. At first we tried out a scheme where we were setting the Change’s Topic in Gerrit to match the Jira ID. It didn’t work out well, probably because learning how to deal with topics in Gerrit takes an extra effort. However – adding the Jira ID to the summary of the commit message turned out to be a great success, and people started using it right away.

Gerrit -> Jira – Part 1

This one took a while to find. Apparently, Gerrit has a feature which is a bit obscure: commentlinks. Once you set it up, Issue IDs in Gerrit that appear in commit message on the review page – turn into links to the respective Jira page. Our etc/gerrit.config commentlink section looks something like this now:

[commentlink "jira"]
  match = ([A-Z]+-[0-9]+)
  link = http://jira.example.com:8080/browse/$1

Gerrit -> Jira – Part 2

A hassle we had, was that whenever a developer integrated a gerrit change into the master – it took an annoying manual step in order to update some details back in Jira. Having the links back and forth between Jira and Gerrit helped, but specifically updating the issue in jira with our version numbering scheme was a hassle. In order to do that – we’ve used the change-merged hook, and wrote some python code that leverages both pygerrit and the jira library for python.

import argparse
import os
import re
import sys
import jira
from pygerrit.rest import GerritRestAPI

parser = argparse.ArgumentParser(description = 'Gerrit\'s change-merged')

parser.add_argument('--change')
parser.add_argument('--change-url')
parser.add_argument('--change-owner')
parser.add_argument('--project')
parser.add_argument('--branch')
parser.add_argument('--topic')
parser.add_argument('--submitter')
parser.add_argument('--commit')
parser.add_argument('--newrev')

args = parser.parse_args()

commitCount = os.popen('git rev-list %s --count' % args.commit).read().strip()

# Requires that ~/.netrc will contain:
# machine localhost login gerrit password XXXXXXXXXXXXX
rest = GerritRestAPI(url = 'http://localhost:8080')

rest.put("/a/changes/%s/topic" % args.change, json = {'topic': 'C' + str(commitCount)})

commitMessage = os.popen('git log -n 1 %s' % args.commit).read().strip()
regex = re.compile(r'\w+-\d+')
if regex.search(commitMessage):
  # ~/.netrc should contain the credentials for the user "gerrit"
  options = {'server': 'http://jira.example.com:8080', 'basic_auth': 'gerrit'}
  jiraInstance = jira.JIRA(options)

  for match in regex.findall(commitMessage):
    issue = jiraInstance.issue(match)
    if issue.fields.customfield_10505 != "" and issue.fields.customfield_10505 is not None:
      specificVersionString = "%s; %s" % (issue.fields.customfield_10505, commitCount)
    else:
      specificVersionString = commitCount
    issue.update(fields={ "customfield_10505": specificVersionString })

 

Leave a Reply

Your email address will not be published.