heroku-rails-saas 0.1.4 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile.lock +1 -1
- data/README.md +15 -4
- data/heroku-rails.gemspec +1 -1
- data/lib/generators/templates/heroku.yml +9 -0
- data/lib/heroku-rails-saas/config.rb +20 -0
- data/lib/heroku-rails-saas/runner.rb +16 -0
- data/lib/heroku/rails/tasks.rb +34 -10
- data/spec/fixtures/awesomeapp.yml +9 -1
- data/spec/fixtures/heroku-config.yml +1 -1
- data/spec/fixtures/mediocreapp.yml +1 -1
- data/spec/heroku/rails/saas/heroku_config_spec.rb +32 -0
- metadata +8 -8
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -3,9 +3,8 @@ Heroku Rails SaaS
|
|
3
3
|
|
4
4
|
Easier configuration and deployment of Rails apps on Heroku
|
5
5
|
|
6
|
-
Configure all your Heroku
|
7
|
-
Configure your app specific Heroku environment via a YML file (config/heroku/awesomeapp.yml) thats defines all your environments, addons, and
|
8
|
-
environment variables for awesomeapp.
|
6
|
+
Configure all your Heroku environments via a YML file (config/heroku.yml) that defines all your environments, addons, scaling settings and environment variables.
|
7
|
+
Configure your app specific Heroku environment via a YML file (config/heroku/awesomeapp.yml) thats defines all your environments, addons, scaling settings and environment variables for awesomeapp.
|
9
8
|
|
10
9
|
## Install
|
11
10
|
|
@@ -44,6 +43,10 @@ For all configuration settings
|
|
44
43
|
- scheduler:standard
|
45
44
|
# add any other addons here
|
46
45
|
|
46
|
+
scale:
|
47
|
+
web: 1
|
48
|
+
worker: 0
|
49
|
+
|
47
50
|
For an app specific settings awesomeapp
|
48
51
|
|
49
52
|
apps:
|
@@ -70,6 +73,13 @@ For an app specific settings awesomeapp
|
|
70
73
|
- cron:daily
|
71
74
|
- newrelic:bronze
|
72
75
|
|
76
|
+
scale:
|
77
|
+
production:
|
78
|
+
web: 3
|
79
|
+
worker: 2
|
80
|
+
staging:
|
81
|
+
web: 2
|
82
|
+
worker: 1
|
73
83
|
|
74
84
|
### Setting up Heroku
|
75
85
|
|
@@ -99,7 +109,7 @@ A special rake task 'all' is created that causes any further commands to
|
|
99
109
|
execute on all heroku apps (Note: Any environment labeled `production` will not
|
100
110
|
be included, you must explicitly state it).
|
101
111
|
|
102
|
-
|
112
|
+
Furthermore there are rake task 'environments' created from environments in configs
|
103
113
|
that causes any further commands to execute on all heroku apps.
|
104
114
|
|
105
115
|
rake all:production heroku:info
|
@@ -120,6 +130,7 @@ A full list of tasks provided:
|
|
120
130
|
rake heroku:remotes # Add git remotes for all apps in this project
|
121
131
|
rake heroku:migrate # Migrates and restarts remote servers
|
122
132
|
rake heroku:restart # Restarts remote servers
|
133
|
+
rake heroku:scale # Scales heroku processes
|
123
134
|
|
124
135
|
rake heroku:setup # runs all heroku setup scripts
|
125
136
|
rake heroku:setup:addons # sets up the heroku addons
|
data/heroku-rails.gemspec
CHANGED
@@ -33,6 +33,11 @@
|
|
33
33
|
# - cron:daily
|
34
34
|
# - newrelic:bronze
|
35
35
|
|
36
|
+
# scale:
|
37
|
+
# production:
|
38
|
+
# web: 2
|
39
|
+
# worker: 1
|
40
|
+
|
36
41
|
|
37
42
|
# The following are configuration settings formally under the :all key
|
38
43
|
# for all apps and thier environments
|
@@ -50,3 +55,7 @@ collaborators:
|
|
50
55
|
addons:
|
51
56
|
- scheduler:standard
|
52
57
|
# add any other addons here
|
58
|
+
|
59
|
+
scale:
|
60
|
+
web: 1
|
61
|
+
worker: 0
|
@@ -22,6 +22,12 @@ module HerokuRailsSaas
|
|
22
22
|
name, env = app_env.split(SEPERATOR)
|
23
23
|
env
|
24
24
|
end
|
25
|
+
|
26
|
+
def extract_name_from(app_env)
|
27
|
+
name, env = app_env.split(SEPERATOR)
|
28
|
+
name
|
29
|
+
end
|
30
|
+
|
25
31
|
end
|
26
32
|
|
27
33
|
attr_accessor :settings
|
@@ -89,6 +95,20 @@ module HerokuRailsSaas
|
|
89
95
|
all.merge(merged_environment_configs)
|
90
96
|
end
|
91
97
|
|
98
|
+
# pull out the scaling setting hash for a particular app environment
|
99
|
+
def scale(app_env)
|
100
|
+
name, env = app_env.split(SEPERATOR)
|
101
|
+
scaling = self.settings['scale'] || {}
|
102
|
+
all = scaling['all'] || {}
|
103
|
+
|
104
|
+
app_scaling = (scaling[name] && scaling[name].reject { |k,v| v.class == Hash }) || {}
|
105
|
+
# overwrite app scaling with the environment specific ones
|
106
|
+
merged_environment_scaling = app_scaling.merge((scaling[name] && scaling[name][env]) || {})
|
107
|
+
|
108
|
+
# overwrite all scaling with the environment specific ones
|
109
|
+
all.merge(merged_environment_scaling)
|
110
|
+
end
|
111
|
+
|
92
112
|
# return a list of domains for a particular app environment
|
93
113
|
def domains(app_env)
|
94
114
|
name, env = app_env.split(SEPERATOR)
|
@@ -204,6 +204,22 @@ module HerokuRailsSaas
|
|
204
204
|
end
|
205
205
|
end
|
206
206
|
|
207
|
+
def scale
|
208
|
+
authorize unless @heroku
|
209
|
+
each_heroku_app do |heroku_env, app_name, repo|
|
210
|
+
scaling = @config.scale(heroku_env)
|
211
|
+
scaling.each do |process_name, instance_count|
|
212
|
+
begin
|
213
|
+
puts "Scaling app #{app_name} process #{process_name} to #{instance_count}"
|
214
|
+
response = @heroku.ps_scale(app_name, {:type => process_name, :qty => instance_count })
|
215
|
+
puts "Response: #{response}"
|
216
|
+
rescue => e
|
217
|
+
puts "Failed to scale #{app_name}. Error: #{e.inspect}"
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
207
223
|
# cycles through each configured heroku app
|
208
224
|
# yields the environment name, the app name, and the repo url
|
209
225
|
def each_heroku_app
|
data/lib/heroku/rails/tasks.rb
CHANGED
@@ -141,13 +141,6 @@ namespace :heroku do
|
|
141
141
|
task :switch_environment do
|
142
142
|
end
|
143
143
|
|
144
|
-
desc "Force deploys, migrates and restarts latest code"
|
145
|
-
task :force_deploy do
|
146
|
-
@git_push_arguments ||= []
|
147
|
-
@git_push_arguments << '--force'
|
148
|
-
Rake::Task["heroku:deploy"].execute
|
149
|
-
end
|
150
|
-
|
151
144
|
desc "Captures a bundle on Heroku"
|
152
145
|
task :capture do
|
153
146
|
HEROKU_RUNNER.each_heroku_app do |heroku_env, app_name, repo|
|
@@ -177,6 +170,11 @@ namespace :heroku do
|
|
177
170
|
end
|
178
171
|
end
|
179
172
|
|
173
|
+
desc "Scales heroku processes"
|
174
|
+
task :scale do
|
175
|
+
HEROKU_RUNNER.scale
|
176
|
+
end
|
177
|
+
|
180
178
|
namespace :setup do
|
181
179
|
|
182
180
|
desc "Creates the apps on Heroku"
|
@@ -232,11 +230,11 @@ namespace :heroku do
|
|
232
230
|
desc "Pulls the database from heroku and stores it into db/dumps/"
|
233
231
|
task :pull do
|
234
232
|
HEROKU_RUNNER.each_heroku_app do |heroku_env, app_name, repo|
|
235
|
-
system_with_echo "heroku
|
236
|
-
dump = `heroku
|
233
|
+
system_with_echo "heroku pgbackups:capture --app #{app_name}"
|
234
|
+
dump = `heroku pgbackups --app #{app_name}`.split("\n").last.split(" ").first
|
237
235
|
system_with_echo "mkdir -p #{HerokuRailsSaas::Config.root}/db/dumps"
|
238
236
|
file = "#{HerokuRailsSaas::Config.root}/db/dumps/#{dump}.sql.gz"
|
239
|
-
url = `heroku
|
237
|
+
url = `heroku pgbackups:url --app #{app_name} #{dump}`.chomp
|
240
238
|
system_with_echo "wget", url, "-O", file
|
241
239
|
|
242
240
|
# TODO: these are a bit distructive...
|
@@ -245,5 +243,31 @@ namespace :heroku do
|
|
245
243
|
# system_with_echo "rake jobs:clear"
|
246
244
|
end
|
247
245
|
end
|
246
|
+
|
247
|
+
desc "Resets a Non Production database"
|
248
|
+
task :reset do
|
249
|
+
HEROKU_RUNNER.each_heroku_app do |heroku_env, app_name, repo|
|
250
|
+
unless heroku_env[HEROKU_RUNNER.regex_for(:production)]
|
251
|
+
system_with_echo "heroku pg:reset DATABASE_URL --app #{app_name} --confirm #{app_name}"
|
252
|
+
else
|
253
|
+
puts "Will not reset the Production database"
|
254
|
+
end
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
desc "Copies a database over a Non Production database"
|
259
|
+
task :copy,[ :source] => :reset do |t, args|
|
260
|
+
HEROKU_RUNNER.each_heroku_app do |heroku_env, app_name, repo|
|
261
|
+
raise "missing source" unless HEROKU_CONFIG.app_name_on_heroku(args.source)
|
262
|
+
|
263
|
+
unless heroku_env[HEROKU_RUNNER.regex_for(:production)]
|
264
|
+
source_app_name = HEROKU_CONFIG.app_name_on_heroku(args.source)
|
265
|
+
system_with_echo "heroku pgbackups:restore DATABASE_URL `heroku pgbackups:url --app #{source_app_name}` --app #{app_name} --confirm #{app_name}"
|
266
|
+
else
|
267
|
+
puts "Will not overwrite the Production database"
|
268
|
+
end
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
248
272
|
end
|
249
273
|
end
|
@@ -153,5 +153,37 @@ module HerokuRailsSaas
|
|
153
153
|
end
|
154
154
|
end
|
155
155
|
|
156
|
+
describe "#scale" do
|
157
|
+
context "mediocrapp" do
|
158
|
+
it "should include the scaling settings defined in 'all'" do
|
159
|
+
@scale = @config.scale('mediocreapp')
|
160
|
+
@scale['web'].should_not be_nil
|
161
|
+
@scale['worker'].should_not be_nil
|
162
|
+
@scale['web'].should eql 1
|
163
|
+
@scale['worker'].should eql 0
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
context "staging environment" do
|
168
|
+
it "should include the scaling settings defined in 'staging'" do
|
169
|
+
@scale = @config.scale('awesomeapp:staging')
|
170
|
+
@scale['web'].should_not be_nil
|
171
|
+
@scale['worker'].should_not be_nil
|
172
|
+
@scale['web'].should eql 2
|
173
|
+
@scale['worker'].should eql 1
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
context "production environment" do
|
178
|
+
it "should include the scaling settings defined in 'production'" do
|
179
|
+
@scale = @config.scale('awesomeapp:production')
|
180
|
+
@scale['web'].should_not be_nil
|
181
|
+
@scale['worker'].should_not be_nil
|
182
|
+
@scale['web'].should eql 3
|
183
|
+
@scale['worker'].should eql 2
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
156
188
|
end
|
157
189
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: heroku-rails-saas
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.5
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -12,11 +12,11 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date: 2012-05-
|
15
|
+
date: 2012-05-04 00:00:00.000000000Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: heroku
|
19
|
-
requirement: &
|
19
|
+
requirement: &2156355220 !ruby/object:Gem::Requirement
|
20
20
|
none: false
|
21
21
|
requirements:
|
22
22
|
- - ! '>='
|
@@ -24,10 +24,10 @@ dependencies:
|
|
24
24
|
version: 2.24.1
|
25
25
|
type: :runtime
|
26
26
|
prerelease: false
|
27
|
-
version_requirements: *
|
27
|
+
version_requirements: *2156355220
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
29
|
name: rspec
|
30
|
-
requirement: &
|
30
|
+
requirement: &2156354200 !ruby/object:Gem::Requirement
|
31
31
|
none: false
|
32
32
|
requirements:
|
33
33
|
- - ~>
|
@@ -35,7 +35,7 @@ dependencies:
|
|
35
35
|
version: '2.0'
|
36
36
|
type: :development
|
37
37
|
prerelease: false
|
38
|
-
version_requirements: *
|
38
|
+
version_requirements: *2156354200
|
39
39
|
description: Manage multiple Heroku instances/apps for a single Rails app using Rake.
|
40
40
|
email: lance.sanchez@gmail.com
|
41
41
|
executables: []
|
@@ -84,7 +84,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
84
84
|
version: '0'
|
85
85
|
segments:
|
86
86
|
- 0
|
87
|
-
hash:
|
87
|
+
hash: 3808687770431151887
|
88
88
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
89
89
|
none: false
|
90
90
|
requirements:
|
@@ -93,7 +93,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
93
93
|
version: '0'
|
94
94
|
segments:
|
95
95
|
- 0
|
96
|
-
hash:
|
96
|
+
hash: 3808687770431151887
|
97
97
|
requirements: []
|
98
98
|
rubyforge_project: none
|
99
99
|
rubygems_version: 1.8.6
|