ruby! rails! kids! oh my! … and other fun from terry heath
RSS icon Email icon Home icon
  • Cap Release Notes

    Posted on May 24th, 2010 terry No comments

    One of the really good things I learned from some guy, we’ll call Donkey, is to have everyone write down deployment dependencies in a file, so if someone goes on vacation or whatever during a deploy, you at least have an idea of what you should do.

    I put it in /README, and separate everything by sprints. It looks something like this:

    Even though everyone tries to remember to put things in there, there’s still a single point of failure, when the idiot who deploys it forgets to check the readme.

    So, to prevent future self-indictments, I put a task that runs at the end of our cap script that prints the current release notes.

    Ideally all of these are handled with a comprehensive deploy script, but that’s not always feasible/doable. Here’s the cap task, and if you make it the last thing that runs, you’ll get a friendly reminder at the end of every deploy for things you need to do.

  • Twitter::Deploy

    Posted on July 18th, 2009 terry No comments

    There are a lot of plugins and libraries that I consider must-haves for a Rails project. Capistrano is one of them.

    At work, we use cap to build to all of our different environments. It’s a pretty big script, since some of our instances span several boxes, some don’t, they all require special restart orders, etc. We use the same script to build to our staging environments, and push out to different staging environments several times a day for QE.

    This started to become a bit of a problem, because we couldn’t be sure when someone had deployed (we have timestamps, but who keeps up with the timestamps of when they check things in?). So, while taking one of my pretzel breaks, I added this to our cap script:

    task :tweet_build_started, :roles => :db do
      users = {
        'theath' => "@terrbear",
        'mroeder' => "@donkeyhighway",
        'rdejuana' => "@rdejuana"
      }
    
      env_user = ENV['USER'] || ENV['USERNAME']
      user = users[env_user] || env_user
    
      username = "FILTERED"
      password = "FILTERED"
      message = "building #{application} from revision #{revision} by #{user}!"
      `curl -u #{username}:#{password} -d status="#{message}" http://twitter.com/statuses/update.json`
    end
    
    task :tweet_build, :roles => :db do
      users = {
        'theath' => "@terrbear",
        'mroeder' => "@donkeyhighway",
        'rdejuana' => "@rdejuana"
      }
    
      env_user = ENV['USER'] || ENV['USERNAME']
      user = users[env_user] || env_user
    
      username = "FILTERED"
      password = "FILTERED"
      message = "new build pushed to #{application} from revision #{revision} by #{user}!"
      `curl -u #{username}:#{password} -d status="#{message}" http://twitter.com/statuses/update.json`
    end
    

    This worked out pretty nicely, so if anyone builds, I see the tweet, and know that any issues I’ve marked resolved, I can drop to QE (part of our workflow).

    So that was kind of cool. But then, talking with the QE guys, we realized that there’s lots of times where QE needs a fresh build to test things, and they have to get a hold of one of us for that to happen. I don’t want the QE guys knowing how to use our cap script, or even trying to, because that could be horrible (cap deploy production -> everybody fired).

    So I wrote a bot that runs on our CI server that polls our builder account for direct messages. If it receives one (using Twitter security, where it can only receive a DM from someone it’s following), it checks the environment to see if it’s a staging one, and then builds to the appropriate environment. It even tweets its progress. Here’s the script:

    # Sample loop to show process
    twitter = Twitter::Client.new(:login => "FILTERED", :password => "FILTERED")
    
    ACCEPTABLE_BUILD_ENVS = /staging1|staging2|staging3/
    
    loop do
      begin
      messages = twitter.messages(:received)
      messages.each do |m|
        env = m.text[ACCEPTABLE_BUILD_ENVS]
        unless(env.nil? || env.empty?)
          `cd ~/builder && cap deploy env=#{env} twitter=#{m.sender.screen_name}`
        end
        twitter.message(:delete, m)
      end
      rescue Twitter::RESTError
        puts "rest problem, continuing as normal"
      rescue
        puts "problem: #{$!}"
      end
      sleep 90
    end
    

    I just run that with nohup, and it’s been going strong for several days now. QE doesn’t even have to ask us for a build, and they’re notified when their build is done automatically, instead of asking for a build, then waiting for us to get around to it, then waiting for us to tell them when it’s ready to go.