Skip to content
This repository has been archived by the owner on Jan 23, 2018. It is now read-only.

Commit

Permalink
Implement post_release against v3 release API.
Browse files Browse the repository at this point in the history
(which currently doesn't really exist yet, oops)
  • Loading branch information
technomancy committed Feb 14, 2013
1 parent 9d745e5 commit 0176f74
Showing 1 changed file with 81 additions and 13 deletions.
94 changes: 81 additions & 13 deletions lib/sokoban.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
require "json"
require "timeout"
require "uri"

module Sokoban
module_function
Expand All @@ -13,7 +15,8 @@ def receive(*urls)
Sokoban.start_server(Sokoban::Receiver.new(*urls), (ENV["PORT"] || 5001))
end

def pre_receive(buildpack_url, slug_url=nil, release_url=nil)
def pre_receive(user, app_id, buildpack_url,
slug_put_url=nil, slug_url=nil, repo_put_url=nil)
if STDIN.read.split("\n").grep(/\s+refs\/heads\/master$/).empty?
puts "Pushed to non-master branch, skipping build."
else
Expand All @@ -25,10 +28,17 @@ def pre_receive(buildpack_url, slug_url=nil, release_url=nil)
FileUtils.rm_rf(build_dir)

system("git", "clone", Dir.pwd, build_dir)
slug, process_types = SlugCompiler.run(build_dir, buildpack_url,
cache_dir, output_dir)
put_slug(slug, slug_url) if slug_url
post_release(release_url) if slug_url && release_url
slug, dyno_types = SlugCompiler.run(build_dir, buildpack_url,
cache_dir, output_dir)

if slug_put_url
print("-----> Launching...")
put_slug(slug, slug_put_url)
params = release_params(slug, dyno_types, user, slug_url)
app_url, release_name = post_release(app_id, params)
puts("...done, #{release_name}")
puts(" http://#{app_url} deployed to Heroku")
end
end
rescue
suicide_dyno
Expand All @@ -43,17 +53,75 @@ def post_receive
end

def put_slug(slug, slug_url)
Timeout.timeout((ENV["POST_SLUG_TIMEOUT"] || 120).to_i) do
url = URI.parse(slug_url)
request = Net::HTTP::Post.new(url.path)
request.body_stream = File.open(slug)
request["Content-Length"] = File.size(slug)
response = Net::HTTP.start(url.host, url.port) do |http|
http.request(request)
# TODO: the signature we get from push_meta doesn't check out:
# The request signature we calculated does not match the signature
# you provided. Check your key and signing method.
# Timeout.timeout((ENV["POST_SLUG_TIMEOUT"] || 120).to_i) do
# url = URI.parse(slug_url)
# request = Net::HTTP::Post.new(url.path)
# request.body_stream = File.open(slug)
# request["Content-Length"] = File.size(slug)
# response = Net::HTTP.start(url.host, url.port) do |http|
# http.request(request)
# end
# end
end

def post_release(app_id, params)
Timeout.timeout((ENV["POST_RELEASE_TIMEOUT"] || 30).to_i) do
start = Time.now
response = release_request(app_id, params)
if (response.code == "200")
log("post_release at=post_response elapsed=#{Time.now - start}")
else
log("measure=slugc.release.error code='#{response.code}' " \
"body='#{response.body.strip}' elapsed=#{Time.now - start}")
error_message = begin
response.body && JSON.parse(response.body)["error"] \
or "failure releasing code"
rescue Timeout::Error
"timed out releasing code"
rescue
"failure releasing code"
end
abort(error_message)
end
response.code == "200"
log("measure=slugc.release.time val=#{Time.now - start}")
# TODO: need app_url as well as release_name from this call
JSON.parse(response.body)
end
end

def release_params(slug, dyno_types, user, slug_url)
{ "addons" => [], # TODO
"config_vars" => [], # TODO
"slug_size" => File.size(slug),
"stack" => "cedar",
"user" => user,
"description" => "TODO: A Sokoban-built release!",
"dyno_types" => dyno_types,
"slug_url" => slug_url,
}
end

def release_request(app_id, params)
uri = release_uri(app_id)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true

request = Net::HTTP::Post.new(uri.request_uri)
request.basic_auth(uri.user, uri.password)
request["Content-Type"] = "application/json"
request["Accept"] = "application/vnd.heroku+json; version=3"
request.body = JSON.unparse(params)
http.request(request)
end

def release_uri(app_id)
URI.parse("https://#{ENV['HEROKU_HOST'] || 'api.heroku.com'}/"\
"apps/#{app_id}/releases")
end

def start_server(handler, port)
require "puma"
s = Puma::Server.new(handler)
Expand Down

0 comments on commit 0176f74

Please sign in to comment.