×

Hubot Deploy

Hubot

Published: February 16, 2012

Hubot is super badass. So is Capistrano. Getting them working together is like syrup and bacon. So good.

I won't cover getting Hubot setup as there are plenty of posts available and it's not too terribly difficult. Just pick what service you want to hook into and fire it up. (We use hipchat)

I'm also not going to cover creating deploy scripts with Capistrano as again there are plenty of other posts that can help.

We're going to jump in and assume you have Hubot running on a local machine and have at least one app setup to deploy. (Make sure the Hubot machine has access to run deploys)

To get Hubot to talk to the repos and deploy them we are using a simple Sinatra app as a middle layer.

Before that though, let's start with a quick overview of how the whole thing is going to work.

User tells Hubot "deploy application" -> Hubot passes the application to a Sinatra API endpoint -> Sinatra runs the deploy script for the repo -> Hubot tells the user the app is deployed

So let's start with the Hubot script.

# Deploy with capistrano
#

Usage:

deploy <repo>

what can you deploy?

# hackers = [ "http://hubot-assets.s3.amazonaws.com/hackers/1.gif", "http://hubot-assets.s3.amazonaws.com/hackers/2.gif", "http://hubot-assets.s3.amazonaws.com/hackers/3.gif", "http://hubot-assets.s3.amazonaws.com/hackers/4.gif", "http://hubot-assets.s3.amazonaws.com/hackers/5.gif", "http://hubot-assets.s3.amazonaws.com/hackers/6.gif", "http://hubot-assets.s3.amazonaws.com/hackers/7.gif", ]

array of the repo names to match and deploy

repos = [ "example_app_1", "example_app_2", "example_app_3" ]

module.exports = (robot) -> robot.respond /deploy (.+)/i, (msg) -> if msg.match[1] in repos #send waiting messages msg.send 'Attempting deploy. Please hold.' msg.send msg.random hackers

  #hit the sinatra app to do the deploy
  msg.http(&quot;http://localhost:9393/deploy/#{msg.match[1]}&quot;)
  .get() (err, res, body) -&gt;
    if res.statusCode == 404
      msg.send &#39;Something went horribly wrong&#39;
    else
      msg.send &#39;Deployed like a boss&#39;
      msg.send &#39;http://hubot-assets.s3.amazonaws.com/fuck-yeah/3.gif&#39;
else
  msg.send &#39;Nope. I dont know what that is. Try deploying one of these: &#39; + repos.join(&quot;, &quot;)

robot.respond /(what can you deploy?)/i, (msg) -> msg.send 'I can deploy the shit out of ' + repos.join(", ")

This is a pretty simple Hubot script. Hubot checks if the application is one he knows and if so, hit the Sinatra API. There's also some fluff in there that tells the user something is happening and to be patient and a few gifs for added fun.

Add your applications to the repos array. One thing to note is the Sinatra URL, depending on your setup, this url may change for you.

Now that Hubot is listening for deploys, we can create the simple Sinatra app.

require 'rubygems'
require 'sinatra'

get '/' do "Leave this place" end

pass in the repo name and deploy that shit

get '/deploy/:name' do bb = IO.popen("cd ~/Desktop/deploy_repos/"+params[:name]+"; git pull origin master; cap deploy") b = bb.readlines puts b.join end

Again, really really simple.

All the app does it take the name of the application as a URL parameter and deploys that app. This is also where a little hackery comes in.

The key to this working correctly is the names in the Hubot script need to be exactly the same as the repo folder names. You must also keep a copy of the repos on the same machine that is running the Sinatra app and Hubot.

This allows the Sinatra app to cd into the repo, update the repo, then run Capistrano deploy. This example uses a deploy_repo folder on the Desktop to store all the repos. Change this as needed.

If everything is setup correctly you should now be able to tell Hubot "deploy application" and watch as Hubot does all the work.

There's a lot a room for expansion here too. Follow the same basic setup and you can add the ability to have Hubot rollback code incase of a problem.