heroku_san_gt 1.0.8
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +113 -0
- data/Rakefile +2 -0
- data/lib/heroku_san/railtie.rb +10 -0
- data/lib/heroku_san/tasks.rb +288 -0
- data/lib/heroku_san.rb +4 -0
- data/lib/tasks/heroku.rake +1 -0
- data/lib/templates/heroku.example.yml +22 -0
- metadata +83 -0
data/README.rdoc
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
= Heroku San
|
2
|
+
|
3
|
+
Helpful rake tasks for Heroku.
|
4
|
+
|
5
|
+
== Install
|
6
|
+
|
7
|
+
=== Rails 3
|
8
|
+
|
9
|
+
Add this to your Gemfile:
|
10
|
+
|
11
|
+
group :development do
|
12
|
+
gem 'heroku_san'
|
13
|
+
end
|
14
|
+
|
15
|
+
=== Rails 2
|
16
|
+
|
17
|
+
To install add the following to config/environment.rb:
|
18
|
+
|
19
|
+
config.gem 'heroku_san'
|
20
|
+
|
21
|
+
Rake tasks are not automatically loaded from gems, so you’ll need to add the following to your Rakefile:
|
22
|
+
|
23
|
+
begin
|
24
|
+
require 'heroku_san/tasks'
|
25
|
+
rescue LoadError
|
26
|
+
STDERR.puts "Run `rake gems:install` to install heroku_san"
|
27
|
+
end
|
28
|
+
|
29
|
+
== Configure
|
30
|
+
|
31
|
+
In config/heroku.yml you will need add the Heroku apps that you would like to attach to this project. You can generate this file and edit it by running:
|
32
|
+
|
33
|
+
rake heroku:create_config
|
34
|
+
|
35
|
+
If this is a fresh project, heroku_san can create all the applications for
|
36
|
+
you, and set the RACK_ENV.
|
37
|
+
|
38
|
+
rake all heroku:create heroku:rack_env
|
39
|
+
|
40
|
+
== Usage
|
41
|
+
|
42
|
+
After configuring your Heroku apps you can use rake tasks to control the
|
43
|
+
apps.
|
44
|
+
|
45
|
+
rake production deploy
|
46
|
+
|
47
|
+
A rake task with the shorthand name of each app is now available and adds that
|
48
|
+
server to the list that subsequent commands will execute on. Because this list
|
49
|
+
is additive, you can easily select which servers to run a command on.
|
50
|
+
|
51
|
+
rake demo staging restart
|
52
|
+
|
53
|
+
A special rake task 'all' is created that causes any further commands to
|
54
|
+
execute on all heroku apps.
|
55
|
+
|
56
|
+
Manipulate collaborators on all this project's apps (prompts for email
|
57
|
+
address):
|
58
|
+
|
59
|
+
rake all heroku:share
|
60
|
+
rake all heroku:unshare
|
61
|
+
|
62
|
+
Need to add remotes for each app?
|
63
|
+
|
64
|
+
rake all heroku:remotes
|
65
|
+
|
66
|
+
A full list of tasks provided:
|
67
|
+
|
68
|
+
rake all # Select all Heroku apps for later command
|
69
|
+
rake console # Opens a remote console
|
70
|
+
rake deploy[commit] # Pushes the given commit, migrates and restarts (default: HEAD)
|
71
|
+
rake deploy:force[commit] # Force-pushes the given commit, migrates and restarts (default: HEAD)
|
72
|
+
rake after_deploy # Callback after deploys
|
73
|
+
rake before_deploy # Callback before deploys
|
74
|
+
rake capture # Captures a bundle on Heroku
|
75
|
+
rake heroku:apps # Lists configured apps
|
76
|
+
rake heroku:create # Creates the Heroku app
|
77
|
+
rake heroku:create_config # Creates an example configuration file
|
78
|
+
rake heroku:gems # Generate the Heroku gems manifest from gem dependencies
|
79
|
+
rake heroku:maintenance # Enable maintenance mode
|
80
|
+
rake heroku:maintenance_off# Disable maintenance mode
|
81
|
+
rake heroku:push # Pushes the given commit (default: HEAD)
|
82
|
+
rake heroku:push:force # Force-pushes the given commit (default: HEAD)
|
83
|
+
rake heroku:remotes # Add git remotes for all apps in this project
|
84
|
+
rake heroku:rack_env # Add proper RACK_ENV to each application
|
85
|
+
rake heroku:rake[task] # Runs a rake task remotely
|
86
|
+
rake heroku:share # Adds a collaborator
|
87
|
+
rake heroku:unshare # Removes a collaborator
|
88
|
+
rake logs # Shows the Heroku logs
|
89
|
+
rake migrate # Migrates and restarts remote servers
|
90
|
+
rake restart # Restarts remote servers
|
91
|
+
|
92
|
+
Frequently used tasks are not namespaced, everything else lives under heroku.
|
93
|
+
|
94
|
+
== Links
|
95
|
+
|
96
|
+
Homepage:: http://github.com/fastestforward/heroku_san
|
97
|
+
Issue Tracker:: http://github.com/fastestforward/heroku_san/issues
|
98
|
+
|
99
|
+
== Contributors
|
100
|
+
|
101
|
+
* Elijah Miller (elijah.miller@gmail.com)
|
102
|
+
* Glenn Roberts (glenn.roberts@siyelo.com)
|
103
|
+
* Damien Mathieu (42@dmathieu.com)
|
104
|
+
* Matthew Hassfurder (matthew.hassfurder@gmail.com)
|
105
|
+
* Peter Jaros
|
106
|
+
* Lee Semel
|
107
|
+
* Michael Haddad (michael@ludditetechnology.com)
|
108
|
+
* Les Hill (leshill@gmail.com)
|
109
|
+
* Bryan Ash
|
110
|
+
|
111
|
+
== License
|
112
|
+
|
113
|
+
License:: Copyright (c) 2009 Elijah Miller <mailto:elijah.miller@gmail.com>, released under the MIT license.
|
data/Rakefile
ADDED
@@ -0,0 +1,288 @@
|
|
1
|
+
HEROKU_CONFIG_FILE = Rails.root.join('config', 'heroku.yml')
|
2
|
+
|
3
|
+
@app_settings =
|
4
|
+
if File.exists?(HEROKU_CONFIG_FILE)
|
5
|
+
YAML.load_file(HEROKU_CONFIG_FILE)
|
6
|
+
else
|
7
|
+
{}
|
8
|
+
end
|
9
|
+
|
10
|
+
if @app_settings.has_key? 'apps'
|
11
|
+
@app_settings = @app_settings['apps']
|
12
|
+
@app_settings.each_pair do |shorthand, app_name|
|
13
|
+
@app_settings[shorthand] = {'app' => app_name}
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
(@app_settings.keys || []).each do |name|
|
18
|
+
desc "Select #{name} Heroku app for later commands"
|
19
|
+
task name do
|
20
|
+
@heroku_apps ||= []
|
21
|
+
@heroku_apps << name
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
desc 'Select all Heroku apps for later command'
|
26
|
+
task :all do
|
27
|
+
@heroku_apps = @app_settings.keys
|
28
|
+
end
|
29
|
+
|
30
|
+
namespace :heroku do
|
31
|
+
desc "Creates the Heroku app"
|
32
|
+
task :create do
|
33
|
+
each_heroku_app do |name, app, repo|
|
34
|
+
sh "heroku create #{app} --stack bamboo-mri-1.9.2"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
desc "Generate the Heroku gems manifest from gem dependencies"
|
39
|
+
task :gems => 'gems:base' do
|
40
|
+
RAILS_ENV='production'
|
41
|
+
Rake::Task[:environment].invoke
|
42
|
+
gems = Rails.configuration.gems.reject { |g| g.frozen? && !g.framework_gem? }
|
43
|
+
list = gems.collect do |g|
|
44
|
+
command, *options = g.send(:install_command)
|
45
|
+
options.join(" ")
|
46
|
+
end
|
47
|
+
|
48
|
+
list.unshift(%Q{rails --version "= #{Rails.version}"})
|
49
|
+
|
50
|
+
File.open(Rails.root.join('.gems'), 'w') do |f|
|
51
|
+
f.write(list.join("\n"))
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
desc 'Add git remotes for all apps in this project'
|
56
|
+
task :remotes do
|
57
|
+
each_heroku_app do |name, app, repo|
|
58
|
+
system("git remote add #{name} #{repo}")
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
desc 'Adds a collaborator'
|
63
|
+
task :share do
|
64
|
+
print "Email address of collaborator to add: "
|
65
|
+
$stdout.flush
|
66
|
+
email = $stdin.gets
|
67
|
+
each_heroku_app do |name, app, repo|
|
68
|
+
sh "heroku sharing:add --app #{app} #{email}"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
desc 'Removes a collaborator'
|
73
|
+
task :unshare do
|
74
|
+
print "Email address of collaborator to remove: "
|
75
|
+
$stdout.flush
|
76
|
+
email = $stdin.gets
|
77
|
+
each_heroku_app do |name, app, repo|
|
78
|
+
sh "heroku sharing:remove --app #{app} #{email}"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
desc 'Lists configured apps'
|
83
|
+
task :apps => :all do
|
84
|
+
each_heroku_app do |name, app, repo|
|
85
|
+
puts "#{name} is shorthand for the Heroku app #{app} located at:"
|
86
|
+
puts " #{repo}"
|
87
|
+
puts
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
desc 'Add proper RACK_ENV to each application'
|
92
|
+
task :rack_env => :all do
|
93
|
+
each_heroku_app do |name, app, repo|
|
94
|
+
command = "heroku config --app #{app}"
|
95
|
+
puts command
|
96
|
+
config = Hash[`#{command}`.scan(/^(.+?)\s*=>\s*(.+)$/)]
|
97
|
+
if config['RACK_ENV'] != name
|
98
|
+
sh "heroku config:add --app #{app} RACK_ENV=#{name}"
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
desc 'Creates an example configuration file'
|
104
|
+
task :create_config do
|
105
|
+
example = File.join(File.dirname(__FILE__), '..', 'templates', 'heroku.example.yml')
|
106
|
+
if File.exists?(HEROKU_CONFIG_FILE)
|
107
|
+
puts "config/heroku.yml already exists"
|
108
|
+
else
|
109
|
+
puts "Copied example config to config/heroku.yml"
|
110
|
+
FileUtils.cp(example, HEROKU_CONFIG_FILE)
|
111
|
+
sh("#{ENV['EDITOR']} #{HEROKU_CONFIG_FILE}")
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
desc 'Add config:vars to each application.'
|
116
|
+
task :config do
|
117
|
+
each_heroku_app do |name, app, repo, config|
|
118
|
+
(config).each do |var, value|
|
119
|
+
sh "heroku config:add --app #{app} #{var}=#{value}"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
desc 'Runs a rake task remotely'
|
125
|
+
task :rake, :task do |t, args|
|
126
|
+
each_heroku_app do |name, app, repo|
|
127
|
+
sh "heroku rake --app #{app} #{args[:task]}"
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
desc "Pushes the given commit (default: HEAD)"
|
132
|
+
task :push, :commit do |t, args|
|
133
|
+
each_heroku_app do |name, app, repo|
|
134
|
+
push(args[:commit], repo)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
namespace :push do
|
139
|
+
desc "Force-pushes the given commit (default: HEAD)"
|
140
|
+
task :force, :commit do |t, args|
|
141
|
+
@git_push_arguments ||= []
|
142
|
+
@git_push_arguments << '--force'
|
143
|
+
Rake::Task[:'heroku:push'].execute(args)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
desc "Enable maintenance mode"
|
148
|
+
task :maintenance do
|
149
|
+
each_heroku_app do |name, app, repo|
|
150
|
+
maintenance(app, 'on')
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
desc "Disable maintenance mode"
|
155
|
+
task :maintenance_off do
|
156
|
+
each_heroku_app do |name, app, repo|
|
157
|
+
maintenance(app, 'off')
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
desc "Pushes the given commit, migrates and restarts (default: HEAD)"
|
163
|
+
task :deploy, :commit, :needs => :before_deploy do |t, args|
|
164
|
+
each_heroku_app do |name, app, repo|
|
165
|
+
push(args[:commit], repo)
|
166
|
+
migrate(app)
|
167
|
+
end
|
168
|
+
Rake::Task[:after_deploy].execute
|
169
|
+
end
|
170
|
+
|
171
|
+
namespace :deploy do
|
172
|
+
desc "Force-pushes the given commit, migrates and restarts (default: HEAD)"
|
173
|
+
task :force, :commit do |t, args|
|
174
|
+
@git_push_arguments ||= []
|
175
|
+
@git_push_arguments << '--force'
|
176
|
+
Rake::Task[:deploy].invoke(args)
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
# Deprecated.
|
181
|
+
task :force_deploy do
|
182
|
+
Rake::Task[:'deploy:force'].invoke
|
183
|
+
end
|
184
|
+
|
185
|
+
desc "Callback before deploys"
|
186
|
+
task :before_deploy do
|
187
|
+
end
|
188
|
+
|
189
|
+
desc "Callback after deploys"
|
190
|
+
task :after_deploy do
|
191
|
+
end
|
192
|
+
|
193
|
+
desc "Captures a bundle on Heroku"
|
194
|
+
task :capture do
|
195
|
+
each_heroku_app do |name, app, repo|
|
196
|
+
sh "heroku bundles:capture --app #{app}"
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
desc "Opens a remote console"
|
201
|
+
task :console do
|
202
|
+
each_heroku_app do |name, app, repo|
|
203
|
+
sh "heroku console --app #{app}"
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
desc "Restarts remote servers"
|
208
|
+
task :restart do
|
209
|
+
each_heroku_app do |name, app, repo|
|
210
|
+
sh "heroku restart --app #{app}"
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
desc "Migrates and restarts remote servers"
|
215
|
+
task :migrate do
|
216
|
+
each_heroku_app do |name, app, repo|
|
217
|
+
migrate(app)
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
desc "Shows the Heroku logs"
|
222
|
+
task :logs do
|
223
|
+
each_heroku_app do |name, app, repo|
|
224
|
+
sh "heroku logs --app #{app}"
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
namespace :db do
|
229
|
+
task :pull do
|
230
|
+
each_heroku_app do |name, app, repo|
|
231
|
+
sh "heroku pgdumps:capture --app #{app}"
|
232
|
+
dump = `heroku pgdumps --app #{app}`.split("\n").last.split(" ").first
|
233
|
+
sh "mkdir -p #{Rails.root}/db/dumps"
|
234
|
+
file = "#{Rails.root}/db/dumps/#{dump}.sql.gz"
|
235
|
+
url = `heroku pgdumps:url --app #{app} #{dump}`.chomp
|
236
|
+
sh "wget", url, "-O", file
|
237
|
+
sh "rake db:drop db:create"
|
238
|
+
sh "gunzip -c #{file} | #{Rails.root}/script/dbconsole"
|
239
|
+
sh "rake jobs:clear"
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
def each_heroku_app
|
245
|
+
if @heroku_apps.blank? && @app_settings.keys.size == 1
|
246
|
+
app = @app_settings.keys.first
|
247
|
+
puts "Defaulting to #{app} app since only one app is defined"
|
248
|
+
@heroku_apps = [app]
|
249
|
+
end
|
250
|
+
if @heroku_apps.present?
|
251
|
+
@heroku_apps.each do |name|
|
252
|
+
app = @app_settings[name]['app']
|
253
|
+
config = @app_settings[name]['config'] || []
|
254
|
+
yield(name, app, "git@heroku.com:#{app}.git", config)
|
255
|
+
end
|
256
|
+
puts
|
257
|
+
else
|
258
|
+
puts "You must first specify at least one Heroku app:
|
259
|
+
rake <app> [<app>] <command>
|
260
|
+
rake production restart
|
261
|
+
rake demo staging deploy"
|
262
|
+
|
263
|
+
puts "\nYou can use also command all Heroku apps for this project:
|
264
|
+
rake all heroku:share"
|
265
|
+
|
266
|
+
exit(1)
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
def push(commit, repo)
|
271
|
+
commit ||= "HEAD"
|
272
|
+
@git_push_arguments ||= []
|
273
|
+
begin
|
274
|
+
sh "git update-ref refs/heroku_san/deploy #{commit}"
|
275
|
+
sh "git push #{repo} #{@git_push_arguments.join(' ')} refs/heroku_san/deploy:refs/heads/master"
|
276
|
+
ensure
|
277
|
+
sh "git update-ref -d refs/heroku_san/deploy"
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
def migrate(app)
|
282
|
+
sh "heroku rake --app #{app} db:migrate"
|
283
|
+
sh "heroku restart --app #{app}"
|
284
|
+
end
|
285
|
+
|
286
|
+
def maintenance(app, action)
|
287
|
+
sh "heroku maintenance:#{action} --app #{app}"
|
288
|
+
end
|
data/lib/heroku_san.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'heroku_san', 'tasks'))
|
@@ -0,0 +1,22 @@
|
|
1
|
+
#
|
2
|
+
# Format:
|
3
|
+
#
|
4
|
+
# <heroku_san shorthand name>:
|
5
|
+
# app: <Heroku app name>
|
6
|
+
# config:
|
7
|
+
# - <Heroku config:var name>: <Heroku config:var value>
|
8
|
+
#
|
9
|
+
production:
|
10
|
+
app: awesomeapp
|
11
|
+
config:
|
12
|
+
- BUNDLE_WITHOUT: "development:test"
|
13
|
+
- GOOGLE_ANALYTICS: "UA-12345678-1"
|
14
|
+
|
15
|
+
staging:
|
16
|
+
app: awesomeapp-staging
|
17
|
+
config: &default
|
18
|
+
- BUNDLE_WITHOUT: "development:test"
|
19
|
+
|
20
|
+
demo:
|
21
|
+
app: awesomeapp-demo
|
22
|
+
config: *default
|
metadata
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: heroku_san_gt
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 1
|
7
|
+
- 0
|
8
|
+
- 8
|
9
|
+
version: 1.0.8
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Elijah Miller
|
13
|
+
- Glenn Roberts
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-01-06 00:00:00 -08:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: heroku
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
segments:
|
30
|
+
- 0
|
31
|
+
version: "0"
|
32
|
+
type: :runtime
|
33
|
+
version_requirements: *id001
|
34
|
+
description: Manage multiple Heroku instances/apps for a single Rails app using Rake
|
35
|
+
email: elijah.miller@gmail.com
|
36
|
+
executables: []
|
37
|
+
|
38
|
+
extensions: []
|
39
|
+
|
40
|
+
extra_rdoc_files: []
|
41
|
+
|
42
|
+
files:
|
43
|
+
- README.rdoc
|
44
|
+
- Rakefile
|
45
|
+
- lib/heroku_san.rb
|
46
|
+
- lib/heroku_san/railtie.rb
|
47
|
+
- lib/heroku_san/tasks.rb
|
48
|
+
- lib/tasks/heroku.rake
|
49
|
+
- lib/templates/heroku.example.yml
|
50
|
+
has_rdoc: true
|
51
|
+
homepage: http://github.com/glennr/heroku_san
|
52
|
+
licenses: []
|
53
|
+
|
54
|
+
post_install_message:
|
55
|
+
rdoc_options:
|
56
|
+
- --charset=UTF-8
|
57
|
+
require_paths:
|
58
|
+
- lib
|
59
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
60
|
+
none: false
|
61
|
+
requirements:
|
62
|
+
- - ">="
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
segments:
|
65
|
+
- 0
|
66
|
+
version: "0"
|
67
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
68
|
+
none: false
|
69
|
+
requirements:
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
segments:
|
73
|
+
- 0
|
74
|
+
version: "0"
|
75
|
+
requirements: []
|
76
|
+
|
77
|
+
rubyforge_project:
|
78
|
+
rubygems_version: 1.3.7
|
79
|
+
signing_key:
|
80
|
+
specification_version: 3
|
81
|
+
summary: A bunch of useful Rake tasks for managing your Heroku apps
|
82
|
+
test_files: []
|
83
|
+
|