Integrity is a lightweight Continuous Integration server written in Ruby. As any other continuous integration server, it can be configured so that as soon as you push your commits, it builds your project, runs your tests, and makes sure everything is still working fine.

Integrity comes with a simple but powerful notification system that reports the build status to all team members in (optionally) many different ways. Currently there are notifiers available for Email, Jabber, Campfire, IRC, Twitter, Basecamp and Yammer, and they are all easy to set up.

Setting up a notifier

For example, if you want Integrity to send you an email after each build, you can set up the email notifier in 3 simple steps:

1. Install the notifier gem

sudo gem install integrity-email

2. Require the notifier in your config.ru file

require "rubygems"
require "integrity"

# You need to add the following line:
require "integrity/notifier/email"

3. Restart Integrity

That’s it! Now you can configure the email notifier options for each project on your Integrity installation. The process is exactly the same for all the other notifiers.

Creating your own notifiers

As you can see, setting up a notifier is easy. But where Integrity’s notification system really shines is when you start writing your own notifiers.

Creating a new notifier is really simple. There are just a couple of rules to consider:

  • All notifiers are derived from Integrity::Notifier::Base
  • At a minimum, a notifier must implement two methods: to_haml and deliver!. The first one must return some markup in haml format that will be rendered on the projects page, and it is useful if your notifier requires some configuration (as most notifiers do). The deliver! method is where the real action takes place, as this is the method that gets called after Integrity builds a project.
  • Although you can have a notifier working by implementing just these two methods, I would suggest that you also implement the to_s method in your notifier so that its messages are easily identifiable on Integrity’s log file.

Following these rules, we can create a simple Integrity notifier with just a few lines of code:

require 'integrity'

module Integrity
  class Notifier
    class Dummy < Notifier::Base
      def self.to_haml
      end

      def deliver!
      end

      def to_s
        'Dummy'
      end
    end

    register Dummy # Don't forget to register your notifier!
  end
end

Of course, a notifier like this one does not do anything interesting. All it does is to register itself with the Integrity server and write a message on the log file each time it gets called.

A real-life example: the Tumblr notifier

Let’s complicate things a bit more by creating a notifier that will post a message to a tumblelog informing the result of each new build.

One of the first things we need to decide when we create a new notifier is the info that we want to include in the notifications. All Integrity notifiers get access to the following info by default:

Method Description
short_message A readable status message. E.g. “Built #{short_identifier} successfully”
full_message A long message containing all the info available for this commit (commit identifier, status, timestamp, author, output, etc.)
commit_url Integrity url corresponding to this commit
stripped_commit_output Build output

In most cases, that is all you will need. But if you have particular needs and/or prefer to have more control over the info included on your notifications, you could also access the commit object directly:

Method Description
commit.identifier Unique identifier for this commit
commit.short_identifier First 7 digits of the unique identifier
commit.message Commit message as entered by the author
commit.project.name Project’s name
commit.author.name Author’s name
commit.committed_at Timestamp of this commit
commit.status Build status. Could be :pending, :success, or :failed
commit.successful? True if commit.status == :success, false otherwise
commit.pending? True if commit.status == :pending, false otherwise
commit.failed? True if commit.status == :failed, false otherwise
commit.human_readable_status A readable status message. E.g. “Built #{short_identifier} successfully”
commit.output Build output. Use stripped_commit_output instead

For this notifier I will be using the short_message as the post’s title, and the full_message as the post’s body. Let’s see how the code looks like:

# tumblr.rb

require 'integrity'
require File.dirname(__FILE__) + '/tumblr_client.rb'

module Integrity
  class Notifier
    class Tumblr < Notifier::Base
      attr_reader :config

      def self.to_haml
        File.read(File.dirname(__FILE__) + "/config.haml")
      end

      def deliver!
        TumblrClient.post(config['email'], config['password'], short_message, full_message)
      end

      def to_s
        'Tumblr'
      end
    end

    register Tumblr
  end
end

I will also need to provide a configuration form that let us configure both the Tumblr account’s email address and password:

# config.haml

%p.normal
  %label{ :for => "tumblr_notifier_email" } Email
  %input.text#tumblr_notifier_email{ :name => "notifiers[Tumblr][email]",         |
                                     :value => config['email'], :type => 'text' } |

%p.normal
  %label{ :for => "tumblr_notifier_password" } Password
  %input.text#tumblr_notifier_password{ :name => "notifiers[Tumblr][password]",         |
                                        :value => config['password'], :type => 'text' } |

I have already created a gem with this code and published it on GitHub. Feel free to install it and play around with it if you want. Just remember the 3 steps:

1. Install the gem

sudo gem install matflores-integrity-tumblr

2. Require the notifier in your config.ru file

require "integrity/notifier/tumblr"

3. Restart Integrity and enable notifications via Tumblr for the projects you want

Recursive notification

Here is the integrity-tumblr notifier notifying me via Tumblr that Integrity has successfully built the integrity-tumblr project itself. Cool!

Resources:

blog comments powered by Disqus