Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Add support for addons. #81

Merged
merged 1 commit into from

2 participants

@spraints

No description provided.

@kmayer
Collaborator

+1

@kmayer
Collaborator

I tested this on my laptop and everything worked, but I got a different default addon: 'shared-database:5mb' -- I'm wondering if that has something to do with the configured stack of the app?

@kmayer kmayer merged commit c077102 into fastestforward:master
@spraints

Yeah, buildpacks install addons, too. For example, the ruby buildpack installs the shared-database:5mb addon for rails apps on the first push (see here and here).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Apr 20, 2012
  1. @spraints

    Add support for addons.

    spraints authored
This page is out of date. Refresh to see the latest.
View
2  README.rdoc
@@ -69,6 +69,8 @@ Need to add remotes for each app?
A full list of tasks provided:
+ rake heroku:addons # Install addons for the application.
+ rake heroku:addons:local # List configured addons, without installing them
rake heroku:apps # Lists configured apps
rake heroku:apps:local # Lists configured apps without hitting heroku
rake heroku:config # Add config:vars to each application.
View
1  features/remote.feature
@@ -27,4 +27,5 @@ Feature: heroku_san can control a project on Heroku
And I turn maintenance off
And I restart my project
And I list all apps on Heroku
+ And I install an addon
Then heroku_san is green
View
19 features/step_definitions/remote_steps.rb
@@ -131,6 +131,25 @@
assert_partial_output "@ #{sha} master", output
end
+When /^I install an addon$/ do
+ # Install the campfire addon.
+ overwrite_file 'config/heroku.yml', <<END_CONFIG
+test_app:
+ app: #{@app}
+ addons:
+ - deployhooks:campfire
+END_CONFIG
+ run_simple 'rake test_app heroku:addons'
+ output = stdout_from 'rake test_app heroku:addons'
+ puts output
+ # The output should show the default addons...
+ assert_partial_output "logging:basic", output
+ # ... and the new one ...
+ assert_partial_output "deployhooks:campfire", output
+ # ... with a note about needing to configure it.
+ assert_partial_output "https://api.heroku.com/myapps/#{@app}/addons/deployhooks:campfire", output
+end
+
Then /^heroku_san is green$/ do
run_simple "heroku apps:destroy #{@app} --confirm #{@app}"
end
View
21 lib/heroku_san/stage.rb
@@ -37,6 +37,10 @@ def tag
def config
@options['config'] ||= {}
end
+
+ def addons
+ (@options['addons'] ||= []).flatten
+ end
def run(command, args = nil)
if stack =~ /cedar/
@@ -99,6 +103,23 @@ def push_config(options = nil)
heroku.put_config_vars(app, params).body
end
+ def get_installed_addons
+ heroku.get_addons(app).body
+ end
+
+ def install_addons
+ return if addons.empty?
+ installed_addons = get_installed_addons
+ addons_to_install = addons - installed_addons.map{|a|a['name']}
+ if addons_to_install.any?
+ (addons - installed_addons.map{|a|a['name']}).each do |addon|
+ sh_heroku "addons:add #{addon}" rescue nil
+ end
+ installed_addons = get_installed_addons
+ end
+ installed_addons
+ end
+
def restart
"restarted" if heroku.post_ps_restart(app).body == 'ok'
end
View
20 lib/tasks.rb
@@ -86,6 +86,26 @@
end
end
+ desc 'Install addons for the application.'
+ task :addons do
+ each_heroku_app do |stage|
+ addons = stage.install_addons
+ puts y("#{stage.name} addons" => addons.map { |addon| addon['configured'] ? addon['name'] : { addon['name'] => "Configure at https://api.heroku.com/myapps/#{stage.app}/addons/#{addon['name']}" } })
+ end
+ end
+
+ namespace :addons do
+ desc 'List configured addons, without installing them'
+ task :local do
+ each_heroku_app do |stage|
+ puts "Configured addons for #{stage.name}:"
+ stage.addons.each do |addon|
+ puts " - #{addon}"
+ end
+ end
+ end
+ end
+
desc 'Creates an example configuration file'
task :create_config do
filename = %Q{#{@heroku_san.config_file.to_s}}
View
59 spec/heroku_san/stage_spec.rb
@@ -3,7 +3,7 @@
describe HerokuSan::Stage do
include Git
- subject { HerokuSan::Stage.new('production', {"app" => "awesomeapp", "stack" => "bamboo-ree-1.8.7"})}
+ subject { HerokuSan::Stage.new('production', {"app" => "awesomeapp", "stack" => "bamboo-ree-1.8.7", "addons" => ["one", "two"]})}
STOCK_CONFIG = {"BUNDLE_WITHOUT"=>"development:test", "LANG"=>"en_US.UTF-8", "RACK_ENV"=>"production"}
before do
Heroku::Auth.stub(:api_key) { 'API_KEY' }
@@ -14,7 +14,8 @@
{"stack" => "cedar",
"app" => "awesomeapp-demo",
"tag" => "demo/*",
- "config"=> {"BUNDLE_WITHOUT"=>"development:test"}
+ "config"=> {"BUNDLE_WITHOUT"=>"development:test"},
+ "addons"=> ['one:addon', 'two:addons'],
})}
its(:name) { should == 'production' }
@@ -23,6 +24,7 @@
its(:tag) { should == "demo/*" }
its(:config) { should == {"BUNDLE_WITHOUT"=>"development:test"} }
its(:repo) { should == 'git@heroku.com:awesomeapp-demo.git' }
+ its(:addons) { should == ['one:addon', 'two:addons'] }
end
describe "#app" do
@@ -49,6 +51,26 @@
end
end
+ describe '#addons' do
+ subject { HerokuSan::Stage.new('production', {'addons' => addons}) }
+ context 'default' do
+ let(:addons) { nil }
+ its(:addons) { should == [] }
+ end
+ context 'nested' do
+ # This is for when you do:
+ # default_addons: &default_addons
+ # - a
+ # - b
+ # env:
+ # addons:
+ # - *default_addons
+ # - other
+ let(:addons) { [ ['a', 'b'], 'other' ] }
+ its(:addons) { should == [ 'a', 'b', 'other' ] }
+ end
+ end
+
describe "#run" do
it "runs commands using the pre-cedar format" do
subject.should_receive(:sh).with("heroku run:rake foo bar bleh --app awesomeapp")
@@ -223,4 +245,35 @@
subject.revision.should == ''
end
end
-end
+
+ describe '#install_addons' do
+ it "installs the addons" do
+ subject.stub(:get_installed_addons => [])
+ subject.should_receive(:sh_heroku).with("addons:add one")
+ subject.should_receive(:sh_heroku).with("addons:add two")
+ subject.install_addons
+ end
+ it "tries to install all addons" do
+ subject.stub(:get_installed_addons => [])
+ subject.should_receive(:sh_heroku).with("addons:add one").and_raise('boom 1')
+ subject.should_receive(:sh_heroku).with("addons:add two").and_raise('boom 2')
+ subject.install_addons
+ end
+ it "only installs missing addons" do
+ subject.stub(:get_installed_addons => [{'name' => 'one'}])
+ subject.should_receive(:sh_heroku).with("addons:add two")
+ subject.install_addons
+ end
+ it "returns a list of installed addons" do
+ addons = [{'name' => 'one'}, {'name' => 'two'}]
+ subject.stub(:get_installed_addons => addons)
+ subject.install_addons.should == addons
+ end
+ it "re-queries addons after installing them" do
+ subject.should_receive(:get_installed_addons).and_return([])
+ subject.stub(:sh_heroku => nil)
+ subject.should_receive(:get_installed_addons).and_return("FINAL RESULT")
+ subject.install_addons.should == "FINAL RESULT"
+ end
+ end
+end
Something went wrong with that request. Please try again.