Created
July 18, 2013 04:43
-
-
Save melcher/6026768 to your computer and use it in GitHub Desktop.
Some code that uses headless heroku and github to enable continuous delivery (e.g. a new server for each pull request and cleanup of servers once they're merged). This is BETA and (although it should work) it may have bugs. Also, it relies on using a forked headless heroku (https://github.com/healthio/heroku-headless) until https://github.com/mo…
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
require 'rubygems' | |
require 'bundler/setup' | |
require 'active_support/all' | |
require 'heroku-headless' | |
require 'heroku-api' | |
require 'github_api' | |
module ContinuousDelivery | |
class HerokuServers | |
# TODO: Make this more easily configurable. Get it from the ENV? | |
FEATURE_ADDONS = %w/mongohq:sandbox loggly:mole/ | |
attr_accessor :server_name, :options | |
def initialize(server_name, options = {}) | |
@server_name = server_name | |
@options = options | |
end | |
def heroku | |
@heroku ||= Heroku::API.new | |
end | |
# Implementation/Heroku specific | |
def find_server | |
begin | |
self.heroku.get_app(self.server_name) | |
rescue Heroku::API::Errors::NotFound | |
puts "No app found with name #{self.server_name}." | |
return false | |
end | |
end | |
def create_feature_server | |
puts "Creating new server #{self.server_name}" | |
self.heroku.post_app('name' => self.server_name) | |
FEATURE_ADDONS.each do |addon| | |
puts "Adding add-on #{addon}..." | |
self.heroku.post_addon(self.server_name, addon) | |
end | |
@new_feature_server = true | |
puts "Done!" | |
end | |
def destroy_server(server_name) | |
self.heroku.delete_app(server_name) | |
end | |
def deploy_self | |
HerokuHeadless.configure do | config | | |
config.post_deploy_commands = ['rake db:migrate'] | |
config.post_deploy_commands = ['rake db:seed'] if @new_feature_server | |
config.force_push = true | |
end | |
puts "Deploying to... #{server_name}" | |
HerokuHeadless::Deployer.deploy(server_name) | |
end | |
def all_servers | |
self.heroku.get_apps.body | |
end | |
# Generic methods | |
def find_or_create_feature_server | |
find_server || create_feature_server | |
end | |
def servers_to_clean | |
all_servers.select do |server| | |
options[:clean].include?(server[:name]) | |
end | |
end | |
def clean_up | |
servers_to_clean.each do |server_name| | |
destroy_server(server_name) | |
end | |
end | |
def deploy! | |
find_or_create_feature_server if options[:feature] | |
clean_up if options[:clean] | |
deploy_self | |
end | |
end | |
end | |
def server_name(suffix) | |
base_name = 'your-application-name' | |
[base_name, suffix.to_s].compact.join('-') | |
end | |
if ENV['TRAVIS_PULL_REQUEST'] && ENV['TRAVIS_PULL_REQUEST'] != 'false' | |
deployer = ContinuousDelivery::HerokuServers.new(server_name(ENV['TRAVIS_PULL_REQUEST']), feature: true) | |
elsif ENV['TRAVIS_BRANCH'] == 'master' | |
# The most recent 30 closed pull requests (30 is the default api limit) | |
inactive_servers = Github::PullRequests.new.all(*ENV['TRAVIS_REPO_SLUG'].split('/') << {state: 'closed'}).collect{|p| server_name(p.number) } | |
deployer = ContinuousDelivery::HerokuServers.new(server_name('production'), clean: inactive_servers) | |
end | |
if deployer | |
deployer.deploy! | |
else | |
puts "Nothing to deploy." | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Nice!