Automatically deploying to Engine Yard Cloud

I’m working on a application which is deployed to Engine Yard’s Cloud infrastructure and I wanted to automatically redeploy the application whenever our tests passed on our continuous integration server.

Engine Yard will eventually allow us to push a branch to our cloud environment from git (ie “git push engineyard master”) but until that is available the best option seems to be to trigger a github post receive hook directly.

To that end I rewrote an existing script to trigger post receive hooks as a rake task; http://gist.github.com/271433

require 'rubygems'
require 'json'
begin
  require 'restclient'
rescue Exception
end

namespace :ey do

  # Based on http://gist.github.com/114954
  # Discussed at https://cloud-support.engineyard.com/discussions/questions/83-deploying-to-solo-instance-from-automated-build
  desc 'Trigger a GitHub Post Receive Hook to deploy the app'
  task :deploy do
    post_receive_hook 'preview'
  end

  desc 'Trigger a GitHub Post Receive Hook to deploy and migrate the app'
  task :deploy_and_migrate do
    post_receive_hook 'preview', true
  end

  def post_receive_hook(envname, migrate=false)
    token = `git config --get cloud.token`.chomp

    if token.empty?
      token = ENV['cloud.token']
      end

    if token.empty?
      puts <<-EOT
The cloud token is not set.
To store the token, use:
$ git config --add cloud.token SOMETOKEN
or set the cloud.token environment variable.
EOT
      exit 2
    end

    commit = `git rev-parse HEAD`.chomp
    payload = {
        "commits" => [{"id" => commit, "message"=>"[deploy #{envname}#{migrate ? ' migrate' : ''}]"}],
        "ref" => "refs/heads/master",
        }

    puts "Triggering a deploy for #{commit} on #{envname}"
    begin
      response = RestClient.post("https://cloud.engineyard.com/github/#{token}",
                                 :payload => payload.to_json)
      puts "Successfully triggered the deploy"
    rescue RestClient::RequestFailed => e
      puts "Could not deploy your changes"
      puts e.response.code
      puts e.response.body
      exit 1
    end
  end
end

In setting this up I discovered a couple of potential stumbling points:

  • The environment must have been deployed via the EY dashboard before you will be able to trigger a deploy using the post receive hook API.
  • The branch specified in the API call (and therefore the git branch you should be working in if running that rake task) must match the branch deployed using the EY dashboard.
  • If you make an API call to deploy the ‘master’ branch EY will attempt to deploy branch ‘HEAD’.
  • If the branch specified in the API call does not match the branch specified on the dashboard the API will report success but not redeploy the environment.

The folks at Engine Yard are working to correct some of those issues and now I’ve got a project which automatically pushes changes to the cloud every time our tests cycle.

Share:
  • Digg
  • del.icio.us
  • Facebook
  • Technorati
  • StumbleUpon
  • TwitThis
  • email

0 Response to “Automatically deploying to Engine Yard Cloud”


  • No Comments

Leave a Reply