Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Changeset 5222

Show
Ignore:
Timestamp:
10/03/06 00:14:36 (2 years ago)
Author:
david
Message:

Added Campfire notification support [DHH]

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • plugins/continuous_builder/lib/continuous_builder.rb

    r2770 r5222  
     1require File.dirname(__FILE__) + '/marshmallow' 
     2 
    13module ContinuousBuilder 
    24  class Build 
     
    57    def initialize(options = {}) 
    68      @options  = options 
    7  
    8       @status = Status.new(@options[:application_root] + "/log/last_build.log") 
    9  
     9      @status   = Status.new(log_file_path) 
    1010      @checkout = Checkout.new(options) 
    11       @checkout.update! 
    1211    end 
    1312  
    1413    def run 
    15       previous_status = @status.recall 
     14      under_lock do 
     15        checkout.update! 
     16        previous_status = @status.recall 
    1617       
    17       if checkout.has_changes? 
    18         if status = make 
    19           @status.keep(:succesful) 
    20           previous_status == :failed ? :revived : :succesful 
     18        if checkout.has_changes? 
     19          if status = make 
     20            @status.keep(:succesful) 
     21            previous_status == :failed ? :revived : :succesful 
     22          else 
     23            @status.keep(:failed) 
     24            previous_status == :failed ? :broken : :failed 
     25          end 
    2126        else 
    22           @status.keep(:failed) 
    23           previous_status == :failed ? :broken : :failed 
     27          :unchanged 
    2428        end 
    25       else 
    26         :unchanged 
    2729      end 
    2830    end 
    2931  
    3032    private 
     33      def log_file_path 
     34        @log_file_path ||= @options[:application_root] + "/log/last_build.log" 
     35      end 
     36     
     37      def lock_file_path 
     38        @lock_file ||= File.join(@options[:application_root], 'tmp', 'pids', 'continuous_builder.pid') 
     39      end 
     40     
    3141      def make 
    3242        @output = `cd #{@options[:application_root]} && #{@options[:bin_path]}rake #{@options[:task_name]} RAILS_ENV=test` 
     
    3646      def make_successful? 
    3747        $?.exitstatus == 0 
     48      end 
     49       
     50      def under_lock 
     51        wait_for_lock 
     52 
     53        begin 
     54          grab_lock 
     55          yield 
     56        ensure 
     57          File.delete(lock_file_path) 
     58        end 
     59      end 
     60       
     61      def wait_for_lock 
     62        begin 
     63          Timeout::timeout(600) do # timeout after 10 minutes 
     64            while File.exists?(lock_file_path) 
     65              sleep(10) # check back after 10 seconds 
     66            end 
     67          end 
     68        rescue Timeout::Error 
     69          exit(1) # abort build 
     70        end 
     71      end 
     72       
     73      def grab_lock 
     74        File.open(lock_file_path, 'w') { |f| f << $$ } 
     75      end 
     76       
     77      def release_lock 
     78        File.delete(lock_file_path) 
    3879      end 
    3980  end 
     
    65106  
    66107    def last_author 
    67       info['Last Changed Author'] 
     108      info['Last Changed Author'].capitalize 
    68109    end 
    69110 
     
    93134  end 
    94135 
    95   class Notifier < ActionMailer::Base 
     136  class MailNotifier < ActionMailer::Base 
    96137    def failure(build, options, sent_at = Time.now) 
    97138      @subject = "[#{options[:application_name]}] Build broken by #{build.checkout.last_author} (##{build.checkout.current_revision})" 
     
    115156    end 
    116157  end 
     158   
     159  module CampfireNotifier 
     160    extend self 
     161     
     162    def deliver_failure(build, options) 
     163      deliver(options[:campfire_url], "#{build.checkout.last_author} broke #{application(options)} with #{changeset(options, build)}", build.output) 
     164    end 
     165     
     166    def deliver_broken(build, options) 
     167      deliver(options[:campfire_url], "#{build.checkout.last_author} didn't fix #{application(options)} with #{changeset(options, build)}", build.output) 
     168    end 
     169     
     170    def deliver_revival(build, options) 
     171      deliver(options[:campfire_url], "#{build.checkout.last_author} fixed #{application(options)} with #{changeset(options, build)}") 
     172    end 
     173     
     174    private 
     175      def application(options) 
     176        options[:application_name].capitalize 
     177      end 
     178     
     179      def changeset(options, build) 
     180        options[:changeset_url] + build.checkout.current_revision.to_s 
     181      end 
     182     
     183      def deliver(to, subject, output = nil) 
     184        Marshmallow.say(to, subject) 
     185        Marshmallow.paste(to, output) unless output.nil? 
     186      end 
     187  end 
    117188end 
  • plugins/continuous_builder/README.txt

    r2736 r5222  
    44Continuous integration made trivial. 
    55 
    6 Subversion post-commit hook
     6Subversion post-commit hook for email
    77 
    88DEVELOPERS=david@loudthinking.com 
     
    1111cd /u/apps/your/app    && /usr/local/bin/rake -t test_latest_revision NAME=YourApp RECIPIENTS="$DEVELOPERS" SENDER="$BUILDER" & 
    1212cd /u/apps/another/app && /usr/local/bin/rake -t test_latest_revision NAME=AnotherApp RECIPIENTS="$DEVELOPERS" SENDER="$BUILDER" & 
     13 
     14 
     15Subversion post-commit hook for Campfire: 
     16 
     17CAMPFIRE_URL  = 'https://username:password@domain.campfirenow.com/rooms/1234' 
     18CHANGESET_URL = 'https://dev.example.com/trac/changeset/' 
     19 
     20cd /u/apps/your/app    && /usr/local/bin/rake -t test_latest_revision NAME=YourApp    CAMPFIRE_URL="$CAMPFIRE_URL" CHANGESET_URL="$CHANGESET_URL" & 
     21cd /u/apps/another/app && /usr/local/bin/rake -t test_latest_revision NAME=AnotherApp CAMPFIRE_URL="$CAMPFIRE_URL" CHANGESET_URL="$CHANGESET_URL" & 
  • plugins/continuous_builder/tasks/test_build.rake

    r2735 r5222  
    99  ) 
    1010 
    11   notice_options = { 
     11  mail_notice_options = { 
    1212    :application_name => ENV['NAME'],  
    1313    :recipients       => ENV['RECIPIENTS'],  
    1414    :sender           => ENV['SENDER'] || "'Continuous Builder' <cb@example.com>"  
    1515  } 
     16     
     17  campfire_notice_options = { 
     18    :application_name => ENV['NAME'], 
     19    :campfire_url     => ENV['CAMPFIRE_URL'], 
     20    :changeset_url    => ENV['CHANGESET_URL'] 
     21  } 
    1622 
    1723  case build.run 
    1824    when :failed 
    19       ContinuousBuilder::Notifier.deliver_failure(build, notice_options) 
     25      ContinuousBuilder::MailNotifier.deliver_failure(build, notice_options) if ENV['RECIPIENTS'] 
     26      ContinuousBuilder::CampfireNotifier.deliver_failure(build, campfire_notice_options) if ENV['CAMPFIRE_URL'] 
    2027    when :revived 
    21       ContinuousBuilder::Notifier.deliver_revival(build, notice_options) 
     28      ContinuousBuilder::MailNotifier.deliver_revival(build, notice_options) if ENV['RECIPIENTS'] 
     29      ContinuousBuilder::CampfireNotifier.deliver_revival(build, campfire_notice_options) if ENV['CAMPFIRE_URL'] 
    2230    when :broken 
    23       ContinuousBuilder::Notifier.deliver_broken(build, notice_options) 
     31      ContinuousBuilder::MailNotifier.deliver_broken(build, notice_options) if ENV['RECIPIENTS'] 
     32      ContinuousBuilder::CampfireNotifier.deliver_broken(build, campfire_notice_options) if ENV['CAMPFIRE_URL'] 
    2433    when :unchanged, :succesful 
    2534      # Smile, be happy, it's all good