Monday, October 21, 2013

Subscribing to Behind-the-firewall Jenkins

You can use Just the Facts to subscribe to build results from Jenkins, including failed test counts, coverage levels and lint results.  The process is straight-forward if your Jenkins instance is publicly available or on a hosted service such as CloudBees:

  1. Navigate to your latest build results and activate the Just the Facts plugin:
  2. Select the facts you want to subscribe to and click "Subscribe".
  3. Enter your Jenkins account information, available from the configuration screens:

However, what if you are hosting Jenkins behind a firewall, so that public services like Just the Facts cannot access it?

In this case you can use the Just the Facts REST API to push the results of each build.

The API endpoint is and it takes the following arguments:

  • account - the email address you used to sign up for Just the Facts 
  • service - each supported service has a constant value, such as JENKINS.
  • metric - each supported service has a fixed set of available metric names.  For Jenkins, the available names are:  test, coverage, codenarc.
  • value - the current value for the specified metric.
  • url - optional, the url-encoded value for the dashboard containing the fact

Any additional URL arguments will be added as metadata for the fact.

For example, to set a value for number of tests failed for a project named justfacts-ci hosted at, you would use a URL of the form:

One approach to incorporating this call into your build results is to use the Groovy Postbuild plugin.  As the name suggests, it lets you execute an arbitrary Groovy script as a postbuild step.

To set this up, add the plugin to Jenkins, go to your build configuration, click "Add post-build action," select 'Groovy Postbuild," and enter the following script:

int failedTests = 0
def pattern = /Completed (\d+) (.*) tests, (\d+) failed(.*)/
def logger = manager.listener.logger { line ->
    def m = line =~ pattern

    if (m?.count > 0) {
        failedTests += m[0][3] as int

def account = ''
def jenkinsUrl = ''
def projectName = 'jenkins-ci'
def url = "${account}&service=JENKINS&metric=test&value=${failedTests}&project=${projectName}&url=${jenkinsUrl}"
def result = new URL(url).getText()

substituting your own values for the account, jenkinsUrl, and projectName variables.

This will scan the build results for test results, sum up any failures, and report that as the new count.

This configuration is ideal for daily builds, which report results once a day.  It can also be used for continuous integration builds; the most recent result for a given calendar day will be stored as that day's value.