lib/gantree/deploy.rb
require 'json'
require 'archive/zip'
require 'colorize'
require 'librato/metrics'
require_relative 'release_notes'
require_relative 'wiki'
require_relative 'notification'
module Gantree
class Deploy < Base
attr_reader :name
def initialize name, options
check_credentials
set_aws_keys
@name = name
@options = options
@ext = @options[:ext]
@dockerrun_file = "Dockerrun.aws.json"
print_options
end
def run
check_eb_bucket
if application?
DeployApplication.new(@name,@options).run
elsif environment?
puts "Found Environment: #{name}".green
deploy([name])
else
error_msg "You leave me with nothing to deploy".red
end
end
def environment_found?
@environments.length >=1 ? true : false
end
def deploy_to_one
env = @environments.first[:environment_name]
puts "Found Environment: #{env}".green
deploy([env])
end
def application?
results = eb.describe_applications({ application_names: ["#{@name}"]})
results[:applications].length == 1 ? true : false
end
def environment?
results = eb.describe_environments({ environment_names: ["#{@name}"]})[:environments]
if results.length == 0
puts "ERROR: Environment '#{name}' not found"
exit 1
else
@app = results[0][:application_name]
return true
end
end
def deploy(envs)
@envs = envs
check_dir_name(envs) unless @options[:force]
return if @options[:dry_run]
version = DeployVersion.new(@options, envs[0])
@packaged_version = version.run
puts "packaged_version: #{@packaged_version}"
upload_to_s3
create_eb_version
update_application(envs)
if @options[:slack]
msg = "#{ENV['USER']} is deploying #{@packaged_version} to #{@app} #{@envs.inspect} gantree version #{Gantree::VERSION} "
msg += "Tag: #{@options[:tag]}" if @options[:tag]
Notification.new(@options[:slack]).say(msg) unless @options[:silent]
end
if @options[:librato]
puts "Found Librato Key"
Librato::Metrics.authenticate @options[:librato]["email"], @options[:librato]["token"]
Librato::Metrics.annotate :deploys, "deploys",:source => "#{@app}", :start_time => Time.now.to_i
puts "Librato metric submitted"
end
env = @envs.find {|e| e =~ /-app/ }
if env && @options[:release_notes_wiki] && (prod_deploy? || @options[:release_notes_staging])
ReleaseNotes.new(@options[:release_notes_wiki], env, @packaged_version).create
`git tag #{tag}`
`git push --tags`
end
version.clean_up
end
def upload_to_s3
puts "uploading #{@packaged_version} to #{set_bucket}"
s3.buckets["#{set_bucket}"].objects["#{@app}-#{@packaged_version}"].write(:file => @packaged_version)
end
def create_eb_version
begin
eb.create_application_version({
:application_name => "#{@app}",
:version_label => "#{@packaged_version}",
:source_bundle => {
:s3_bucket => "#{set_bucket}",
:s3_key => "#{@app}-#{@packaged_version}"
}
})
rescue AWS::ElasticBeanstalk::Errors::InvalidParameterValue => e
puts "No Application named #{@app} found #{e}"
end
end
def update_application(envs)
envs.each do |env|
begin
eb.update_environment({
:environment_name => env,
:version_label => @packaged_version
})
puts "Deployed #{@packaged_version} to #{env} on #{@app}".green
rescue AWS::ElasticBeanstalk::Errors::InvalidParameterValue => e
puts "Error: Something went wrong during the deploy to #{env}".red
puts "#{e.message}"
end
end
end
def check_dir_name envs
dir_name = File.basename(Dir.getwd)
msg = "WARN: You are deploying from a repo that doesn't match #{@app}"
puts msg.yellow if envs.any? { |env| env.include?(dir_name) } == false
end
def check_eb_bucket
bucket = set_bucket
puts "S3 Bucket: #{bucket}".light_blue
s3.buckets.create(bucket) unless s3.buckets[bucket].exists?
end
def set_bucket
if @options[:eb_bucket]
bucket = @options[:eb_bucket]
else
bucket = generate_eb_bucket
end
end
def generate_eb_bucket
unique_hash = Digest::SHA1.hexdigest ENV['AWS_ACCESS_KEY_ID']
"eb-bucket-#{unique_hash}"
end
def prod_deploy?
@envs.first.split("-").first == "prod"
end
end
end