March 24, 2010

Simple Capistrano email notifier for rails

I needed to send out emails every time I deployed a rails app, and wanted to use the libraries that were already included with rails – e.g. ActionMailer.

My solution was based on some ideas from capistrano-mailer and Mislav Marohnić example, but I felt both were overkill for what I need, so here is my very simple, very customizable solution.

Create a file config/deploy/notifier.rb with the following contents:

$:.unshift File.dirname(__FILE__) + '/../../vendor/rails/actionmailer/lib'
require File.dirname(__FILE__) + '/../../vendor/rails/actionmailer/lib/actionmailer.rb'

ActionMailer::Base.delivery_method = :smtp
ActionMailer::Base.raise_delivery_errors = true
ActionMailer::Base.default_charset = "utf-8"
ActionMailer::Base.smtp_settings = {
  :address        => "",
  :port           => 25,
  :domain         => '',
  :perform_deliveries => true,
  :user_name      => 'user',
  :password       => 'secret',
  :authentication => :login }

class Notifier < ActionMailer::Base
  def deploy_notification(cap_vars)
    now =
    recipients cap_vars.notify_emails
    from     "App Deployments <>"
    subject  "Deployed to #{}"

    body <<-MSG
      Performed a deploy operation on #{now.strftime("%m/%d/%Y")} at #{now.strftime("%I:%M %p")} to #{}

      Deployed to: https://#{}

Which is stupid easy to customize, if you’d like to include the multistage info in the email body just edit the MSG and add #{cap_vars.stage} or any other variable that was set in the cap file.

Now to get it hooked into your cap file. Simply edit config/deploy.rb and add the following

require 'config/deploy/notifier.rb'

# Setup the emails, and after deploy hook

set :notify_emails, ["", "]
after "deploy", "deploy:notify"

# Create the task to send the notification

namespace :deploy do
  desc "Email notifier"
  task :notify

This is not really rails specific, but if I were using Sinatra I would probably not use ActionMailer – something like Pony would be a little prettier – but the Capistrano configuration would work just fine.