suspenders 1.44.0 → 1.45.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.ruby-version +1 -1
- data/.travis.yml +1 -1
- data/LICENSE +1 -1
- data/NEWS.md +27 -0
- data/README.md +7 -4
- data/lib/suspenders.rb +2 -0
- data/lib/suspenders/actions.rb +6 -1
- data/lib/suspenders/adapters/heroku.rb +18 -0
- data/lib/suspenders/app_builder.rb +24 -30
- data/lib/suspenders/generators/app_generator.rb +11 -14
- data/lib/suspenders/generators/enforce_ssl_generator.rb +12 -0
- data/lib/suspenders/generators/initialize_active_job_generator.rb +19 -0
- data/lib/suspenders/generators/stylesheet_base_generator.rb +6 -2
- data/lib/suspenders/version.rb +2 -2
- data/spec/adapters/heroku_spec.rb +15 -0
- data/spec/features/heroku_spec.rb +4 -8
- data/spec/features/new_project_spec.rb +38 -4
- data/spec/support/suspenders.rb +17 -1
- data/suspenders.gemspec +1 -1
- data/templates/Gemfile.erb +11 -7
- data/templates/Procfile +1 -1
- data/templates/_analytics.html.erb +4 -3
- data/templates/active_job.rb +13 -0
- data/templates/application.scss +1 -1
- data/templates/bin_deploy +1 -1
- data/templates/bin_setup +7 -3
- data/templates/bin_setup_review_app.erb +5 -2
- data/templates/bundler_audit.rake +2 -10
- data/templates/postgresql_database.yml.erb +0 -2
- data/templates/secrets.yml +1 -7
- data/templates/spec_helper.rb +4 -0
- data/templates/suspenders_gitignore +6 -1
- metadata +11 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 253fc6f3c173bce9e7858831161cf75924094222
|
4
|
+
data.tar.gz: 947de81dd1fc955c04f13ea1260e4391b505b0f2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 003c8627d76eaad3f8a51f404608dc1cd66ee35dbaba8b45cf6f5ef0e9a06fc4fe7f826f9f387a51118d2670df7499a46b83a7441541e21f5a0b691a08a0e063
|
7
|
+
data.tar.gz: 3a08ab29152033941e6a1b2baba20743d2992ab9872e590e7815007cadcbba37514700cc6f9deaed72f02408458a21d1ed020f15c1e060e16250bd7da01a5553
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.4.
|
1
|
+
2.4.1
|
data/.travis.yml
CHANGED
data/LICENSE
CHANGED
data/NEWS.md
CHANGED
@@ -1,3 +1,30 @@
|
|
1
|
+
1.45.0 (September 8, 2017)
|
2
|
+
|
3
|
+
* Bump Rails to 5.1.3 (#857)
|
4
|
+
* Configure HONEYBADGER_ENV for staging, production (#861)
|
5
|
+
* Remove vestigial `staging` references (#860)
|
6
|
+
* Prevent memory bloat in ActiveJob children (#856)
|
7
|
+
* .git/safe is opt-in (#837)
|
8
|
+
* Enforce SSL in production environment (#855)
|
9
|
+
* Configures action mailer asset host (#853)
|
10
|
+
* Install normalize.css via yarn (#851)
|
11
|
+
* Update Rails to 5.1 (#847)
|
12
|
+
* Update bourbon from 5.0.0.beta.7 to 5.0.0.beta.8 (#848)
|
13
|
+
* Update Neat to 2.1 (#849)
|
14
|
+
* Update Bitters to 1.7 (#850)
|
15
|
+
* Fix incorrect Timecop link (#845)
|
16
|
+
* Update Ruby to 2.4.1 (#841)
|
17
|
+
* Update rspec-rails to 3.6 (#842)
|
18
|
+
* Configure TimeCop safe mode (#840)
|
19
|
+
* Pull normalize.css through Rails Assets (#839)
|
20
|
+
* Fix fatal git failures in tests (#832)
|
21
|
+
* Schedule Heroku Backups and Capture backup of existing staging database for
|
22
|
+
Review Apps (#826)
|
23
|
+
* Use bundle-audit rake task from the gem (#831)
|
24
|
+
* Update thoughtbot logo (#829)
|
25
|
+
* Change terminal symbol in README's deploying section (#828)
|
26
|
+
* Update Segment snippet to 4.0.0 (#822)
|
27
|
+
|
1
28
|
1.44.0 (January 25, 2017)
|
2
29
|
|
3
30
|
* Improve readability of `bin/setup-review-app` (#819)
|
data/README.md
CHANGED
@@ -87,7 +87,7 @@ And testing gems like:
|
|
87
87
|
* [RSpec Mocks](https://github.com/rspec/rspec-mocks) for stubbing and spying
|
88
88
|
* [Shoulda Matchers](https://github.com/thoughtbot/shoulda-matchers) for common
|
89
89
|
RSpec matchers
|
90
|
-
* [Timecop](https://github.com/
|
90
|
+
* [Timecop](https://github.com/travisjeffery/timecop) for testing time
|
91
91
|
|
92
92
|
## Other goodies
|
93
93
|
|
@@ -127,9 +127,10 @@ This:
|
|
127
127
|
|
128
128
|
* Creates a staging and production Heroku app
|
129
129
|
* Sets them as `staging` and `production` Git remotes
|
130
|
-
* Configures staging with `
|
130
|
+
* Configures staging with `HONEYBADGER_ENV` environment variable set
|
131
131
|
to `staging`
|
132
132
|
* Creates a [Heroku Pipeline] for review apps
|
133
|
+
* Schedules automated backups for 10AM UTC for both `staging` and `production`
|
133
134
|
|
134
135
|
[Heroku Pipeline]: https://devcenter.heroku.com/articles/pipelines
|
135
136
|
|
@@ -205,7 +206,7 @@ Thank you, [contributors]!
|
|
205
206
|
|
206
207
|
## License
|
207
208
|
|
208
|
-
Suspenders is Copyright © 2008-
|
209
|
+
Suspenders is Copyright © 2008-2017 thoughtbot.
|
209
210
|
It is free software,
|
210
211
|
and may be redistributed under the terms specified in the [LICENSE] file.
|
211
212
|
|
@@ -213,7 +214,7 @@ and may be redistributed under the terms specified in the [LICENSE] file.
|
|
213
214
|
|
214
215
|
## About thoughtbot
|
215
216
|
|
216
|
-
![thoughtbot]
|
217
|
+
[![thoughtbot][thoughtbot-logo]][thoughtbot]
|
217
218
|
|
218
219
|
Suspenders is maintained and funded by thoughtbot, inc.
|
219
220
|
The names and logos for thoughtbot are trademarks of thoughtbot, inc.
|
@@ -222,5 +223,7 @@ We love open source software!
|
|
222
223
|
See [our other projects][community].
|
223
224
|
We are [available for hire][hire].
|
224
225
|
|
226
|
+
[thoughtbot]: https://thoughtbot.com?utm_source=github
|
227
|
+
[thoughtbot-logo]: http://presskit.thoughtbot.com/images/thoughtbot-logo-for-readmes.svg
|
225
228
|
[community]: https://thoughtbot.com/community?utm_source=github
|
226
229
|
[hire]: https://thoughtbot.com?utm_source=github
|
data/lib/suspenders.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
require 'suspenders/version'
|
2
2
|
require 'suspenders/generators/app_generator'
|
3
|
+
require "suspenders/generators/enforce_ssl_generator"
|
4
|
+
require "suspenders/generators/initialize_active_job_generator"
|
3
5
|
require 'suspenders/generators/static_generator'
|
4
6
|
require 'suspenders/generators/stylesheet_base_generator'
|
5
7
|
require 'suspenders/actions'
|
data/lib/suspenders/actions.rb
CHANGED
@@ -14,6 +14,11 @@ module Suspenders
|
|
14
14
|
configure_environment(rails_env, config)
|
15
15
|
end
|
16
16
|
|
17
|
+
def action_mailer_asset_host(rails_env, host)
|
18
|
+
config = "config.action_mailer.asset_host = { host: #{host} }"
|
19
|
+
configure_environment(rails_env, config)
|
20
|
+
end
|
21
|
+
|
17
22
|
def configure_application_file(config)
|
18
23
|
inject_into_file(
|
19
24
|
"config/application.rb",
|
@@ -25,7 +30,7 @@ module Suspenders
|
|
25
30
|
def configure_environment(rails_env, config)
|
26
31
|
inject_into_file(
|
27
32
|
"config/environments/#{rails_env}.rb",
|
28
|
-
"\n
|
33
|
+
"\n #{config}",
|
29
34
|
before: "\nend"
|
30
35
|
)
|
31
36
|
end
|
@@ -37,6 +37,24 @@ module Suspenders
|
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
40
|
+
def set_heroku_honeybadger_env
|
41
|
+
%w(staging production).each do |environment|
|
42
|
+
run_toolbelt_command(
|
43
|
+
"config:add HONEYBADGER_ENV=#{environment}",
|
44
|
+
environment,
|
45
|
+
)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def set_heroku_backup_schedule
|
50
|
+
%w(staging production).each do |environment|
|
51
|
+
run_toolbelt_command(
|
52
|
+
"pg:backups:schedule DATABASE_URL --at '10:00 UTC'",
|
53
|
+
environment,
|
54
|
+
)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
40
58
|
def create_review_apps_setup_script
|
41
59
|
app_builder.template(
|
42
60
|
"bin_setup_review_app.erb",
|
@@ -5,15 +5,19 @@ module Suspenders
|
|
5
5
|
include Suspenders::Actions
|
6
6
|
extend Forwardable
|
7
7
|
|
8
|
-
def_delegators
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
8
|
+
def_delegators(
|
9
|
+
:heroku_adapter,
|
10
|
+
:create_heroku_application_manifest_file,
|
11
|
+
:create_heroku_pipeline,
|
12
|
+
:create_production_heroku_app,
|
13
|
+
:create_review_apps_setup_script,
|
14
|
+
:create_staging_heroku_app,
|
15
|
+
:set_heroku_application_host,
|
16
|
+
:set_heroku_backup_schedule,
|
17
|
+
:set_heroku_honeybadger_env,
|
18
|
+
:set_heroku_rails_secrets,
|
19
|
+
:set_heroku_remotes,
|
20
|
+
)
|
17
21
|
|
18
22
|
def readme
|
19
23
|
template 'README.md.erb', 'README.md'
|
@@ -43,14 +47,6 @@ module Suspenders
|
|
43
47
|
'raise_delivery_errors = false', 'raise_delivery_errors = true'
|
44
48
|
end
|
45
49
|
|
46
|
-
def remove_turbolinks
|
47
|
-
replace_in_file(
|
48
|
-
"app/assets/javascripts/application.js",
|
49
|
-
"//= require turbolinks",
|
50
|
-
""
|
51
|
-
)
|
52
|
-
end
|
53
|
-
|
54
50
|
def set_test_delivery_method
|
55
51
|
inject_into_file(
|
56
52
|
"config/environments/development.rb",
|
@@ -157,11 +153,7 @@ module Suspenders
|
|
157
153
|
config.middleware.use Rack::CanonicalHost, ENV.fetch("APPLICATION_HOST")
|
158
154
|
RUBY
|
159
155
|
|
160
|
-
|
161
|
-
"config/environments/production.rb",
|
162
|
-
config,
|
163
|
-
after: "Rails.application.configure do",
|
164
|
-
)
|
156
|
+
configure_environment "production", config
|
165
157
|
end
|
166
158
|
|
167
159
|
def enable_rack_deflater
|
@@ -226,7 +218,7 @@ config.public_file_server.headers = {
|
|
226
218
|
end
|
227
219
|
|
228
220
|
def create_database
|
229
|
-
bundle_command
|
221
|
+
bundle_command "exec rails db:create db:migrate"
|
230
222
|
end
|
231
223
|
|
232
224
|
def replace_gemfile(path)
|
@@ -310,8 +302,14 @@ Rack::Timeout.timeout = (ENV["RACK_TIMEOUT"] || 10).to_i
|
|
310
302
|
|
311
303
|
def configure_action_mailer
|
312
304
|
action_mailer_host "development", %{"localhost:3000"}
|
305
|
+
action_mailer_asset_host "development", %{"localhost:3000"}
|
313
306
|
action_mailer_host "test", %{"www.example.com"}
|
307
|
+
action_mailer_asset_host "test", %{"www.example.com"}
|
314
308
|
action_mailer_host "production", %{ENV.fetch("APPLICATION_HOST")}
|
309
|
+
action_mailer_asset_host(
|
310
|
+
"production",
|
311
|
+
%{ENV.fetch("ASSET_HOST", ENV.fetch("APPLICATION_HOST"))},
|
312
|
+
)
|
315
313
|
end
|
316
314
|
|
317
315
|
def configure_active_job
|
@@ -351,10 +349,6 @@ Rack::Timeout.timeout = (ENV["RACK_TIMEOUT"] || 10).to_i
|
|
351
349
|
directory("dotfiles", ".")
|
352
350
|
end
|
353
351
|
|
354
|
-
def init_git
|
355
|
-
run 'git init'
|
356
|
-
end
|
357
|
-
|
358
352
|
def create_heroku_apps(flags)
|
359
353
|
create_staging_heroku_app(flags)
|
360
354
|
create_production_heroku_app(flags)
|
@@ -370,8 +364,8 @@ Rack::Timeout.timeout = (ENV["RACK_TIMEOUT"] || 10).to_i
|
|
370
364
|
If you have previously run the `./bin/setup` script,
|
371
365
|
you can deploy to staging and production with:
|
372
366
|
|
373
|
-
|
374
|
-
|
367
|
+
% ./bin/deploy staging
|
368
|
+
% ./bin/deploy production
|
375
369
|
MARKDOWN
|
376
370
|
|
377
371
|
append_file "README.md", instructions
|
@@ -401,7 +395,7 @@ you can deploy to staging and production with:
|
|
401
395
|
|
402
396
|
def setup_bundler_audit
|
403
397
|
copy_file "bundler_audit.rake", "lib/tasks/bundler_audit.rake"
|
404
|
-
append_file "Rakefile", %{\ntask default: "
|
398
|
+
append_file "Rakefile", %{\ntask default: "bundle:audit"\n}
|
405
399
|
end
|
406
400
|
|
407
401
|
def setup_spring
|
@@ -29,6 +29,12 @@ module Suspenders
|
|
29
29
|
class_option :skip_test, type: :boolean, default: true,
|
30
30
|
desc: "Skip Test Unit"
|
31
31
|
|
32
|
+
class_option :skip_system_test,
|
33
|
+
type: :boolean, default: true, desc: "Skip system test files"
|
34
|
+
|
35
|
+
class_option :skip_turbolinks,
|
36
|
+
type: :boolean, default: true, desc: "Skip turbolinks gem"
|
37
|
+
|
32
38
|
def finish_template
|
33
39
|
invoke :suspenders_customization
|
34
40
|
super
|
@@ -47,7 +53,6 @@ module Suspenders
|
|
47
53
|
invoke :remove_config_comment_lines
|
48
54
|
invoke :remove_routes_comment_lines
|
49
55
|
invoke :setup_dotfiles
|
50
|
-
invoke :setup_git
|
51
56
|
invoke :setup_database
|
52
57
|
invoke :create_local_heroku_setup
|
53
58
|
invoke :create_heroku_apps
|
@@ -56,6 +61,7 @@ module Suspenders
|
|
56
61
|
invoke :setup_bundler_audit
|
57
62
|
invoke :setup_spring
|
58
63
|
invoke :generate_default
|
64
|
+
invoke :setup_default_directories
|
59
65
|
invoke :outro
|
60
66
|
end
|
61
67
|
|
@@ -80,7 +86,6 @@ module Suspenders
|
|
80
86
|
say 'Setting up the development environment'
|
81
87
|
build :raise_on_missing_assets_in_test
|
82
88
|
build :raise_on_delivery_errors
|
83
|
-
build :remove_turbolinks
|
84
89
|
build :set_test_delivery_method
|
85
90
|
build :add_bullet_gem_configuration
|
86
91
|
build :raise_on_unpermitted_parameters
|
@@ -142,14 +147,6 @@ module Suspenders
|
|
142
147
|
build :setup_rack_mini_profiler
|
143
148
|
end
|
144
149
|
|
145
|
-
def setup_git
|
146
|
-
if !options[:skip_git]
|
147
|
-
say "Initializing git"
|
148
|
-
invoke :setup_default_directories
|
149
|
-
invoke :init_git
|
150
|
-
end
|
151
|
-
end
|
152
|
-
|
153
150
|
def create_local_heroku_setup
|
154
151
|
say "Creating local Heroku setup"
|
155
152
|
build :create_review_apps_setup_script
|
@@ -164,6 +161,8 @@ module Suspenders
|
|
164
161
|
build :set_heroku_remotes
|
165
162
|
build :set_heroku_rails_secrets
|
166
163
|
build :set_heroku_application_host
|
164
|
+
build :set_heroku_honeybadger_env
|
165
|
+
build :set_heroku_backup_schedule
|
167
166
|
build :create_heroku_pipeline
|
168
167
|
build :configure_automatic_deployment
|
169
168
|
end
|
@@ -199,10 +198,6 @@ module Suspenders
|
|
199
198
|
build :setup_spring
|
200
199
|
end
|
201
200
|
|
202
|
-
def init_git
|
203
|
-
build :init_git
|
204
|
-
end
|
205
|
-
|
206
201
|
def copy_miscellaneous_files
|
207
202
|
say 'Copying miscellaneous support files'
|
208
203
|
build :copy_miscellaneous_files
|
@@ -223,6 +218,8 @@ module Suspenders
|
|
223
218
|
|
224
219
|
def generate_default
|
225
220
|
run("spring stop")
|
221
|
+
generate("suspenders:initialize_active_job")
|
222
|
+
generate("suspenders:enforce_ssl")
|
226
223
|
generate("suspenders:static")
|
227
224
|
generate("suspenders:stylesheet_base")
|
228
225
|
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require "rails/generators"
|
2
|
+
require_relative "../actions"
|
3
|
+
|
4
|
+
module Suspenders
|
5
|
+
class EnforceSslGenerator < Rails::Generators::Base
|
6
|
+
include Suspenders::Actions
|
7
|
+
|
8
|
+
def enforce_ssl
|
9
|
+
configure_environment "production", "config.force_ssl = true"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require "rails/generators"
|
2
|
+
|
3
|
+
module Suspenders
|
4
|
+
class InitializeActiveJobGenerator < Rails::Generators::Base
|
5
|
+
source_root(
|
6
|
+
File.expand_path(
|
7
|
+
File.join("..", "..", "..", "templates"),
|
8
|
+
File.dirname(__FILE__),
|
9
|
+
),
|
10
|
+
)
|
11
|
+
|
12
|
+
def initialize_active_job
|
13
|
+
copy_file(
|
14
|
+
"active_job.rb",
|
15
|
+
"config/initializers/active_job.rb",
|
16
|
+
)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -7,8 +7,8 @@ module Suspenders
|
|
7
7
|
File.dirname(__FILE__))
|
8
8
|
|
9
9
|
def add_stylesheet_gems
|
10
|
-
gem "bourbon", "~> 5.0.0.beta.
|
11
|
-
gem "neat", "~> 2.
|
10
|
+
gem "bourbon", "~> 5.0.0.beta.8"
|
11
|
+
gem "neat", "~> 2.1"
|
12
12
|
gem "refills", group: [:development, :test]
|
13
13
|
Bundler.with_clean_env { run "bundle install" }
|
14
14
|
end
|
@@ -33,5 +33,9 @@ module Suspenders
|
|
33
33
|
def install_bitters
|
34
34
|
run "bitters install --path app/assets/stylesheets"
|
35
35
|
end
|
36
|
+
|
37
|
+
def install_normalize_css
|
38
|
+
run "bin/yarn add normalize.css"
|
39
|
+
end
|
36
40
|
end
|
37
41
|
end
|
data/lib/suspenders/version.rb
CHANGED
@@ -30,6 +30,16 @@ module Suspenders
|
|
30
30
|
)
|
31
31
|
end
|
32
32
|
|
33
|
+
it "sets the heroku backup schedule" do
|
34
|
+
app_builder = double(app_name: app_name)
|
35
|
+
allow(app_builder).to receive(:run)
|
36
|
+
|
37
|
+
Heroku.new(app_builder).set_heroku_backup_schedule
|
38
|
+
|
39
|
+
expect(app_builder).to have_backup_schedule("staging")
|
40
|
+
expect(app_builder).to have_backup_schedule("production")
|
41
|
+
end
|
42
|
+
|
33
43
|
it "sets the application host" do
|
34
44
|
app_builder = double(app_name: app_name)
|
35
45
|
allow(app_builder).to receive(:run)
|
@@ -49,6 +59,11 @@ module Suspenders
|
|
49
59
|
SuspendersTestHelpers::APP_NAME
|
50
60
|
end
|
51
61
|
|
62
|
+
def have_backup_schedule(remote_name)
|
63
|
+
have_received(:run).
|
64
|
+
with(/pg:backups:schedule DATABASE_URL --at '10:00 UTC' --remote #{remote_name}/)
|
65
|
+
end
|
66
|
+
|
52
67
|
def have_configured_var(remote_name, var)
|
53
68
|
have_received(:run).with(/config:add #{var}=.+ --remote #{remote_name}/)
|
54
69
|
end
|
@@ -18,14 +18,10 @@ RSpec.describe "Heroku" do
|
|
18
18
|
"production",
|
19
19
|
"SECRET_KEY_BASE",
|
20
20
|
)
|
21
|
-
|
22
|
-
"
|
23
|
-
"
|
24
|
-
|
25
|
-
expect(FakeHeroku).to have_configured_vars(
|
26
|
-
"production",
|
27
|
-
"APPLICATION_HOST",
|
28
|
-
)
|
21
|
+
%w(staging production).each do |env|
|
22
|
+
expect(FakeHeroku).to have_configured_vars(env, "APPLICATION_HOST")
|
23
|
+
expect(FakeHeroku).to have_configured_vars(env, "HONEYBADGER_ENV")
|
24
|
+
end
|
29
25
|
expect(FakeHeroku).to have_setup_pipeline_for(app_name)
|
30
26
|
|
31
27
|
bin_setup_path = "#{project_path}/bin/setup"
|
@@ -29,6 +29,14 @@ RSpec.describe "Suspend a new project with default configuration" do
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
+
it "includes the bundle:audit task" do
|
33
|
+
Dir.chdir(project_path) do
|
34
|
+
Bundler.with_clean_env do
|
35
|
+
expect(`rails -T`).to include("rails bundle:audit")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
32
40
|
it "creates .ruby-version from Suspenders .ruby-version" do
|
33
41
|
ruby_version_file = IO.read("#{project_path}/.ruby-version")
|
34
42
|
|
@@ -92,6 +100,11 @@ RSpec.describe "Suspend a new project with default configuration" do
|
|
92
100
|
expect(env).to include "RACK_MINI_PROFILER=0"
|
93
101
|
end
|
94
102
|
|
103
|
+
it "initializes ActiveJob to avoid memory bloat" do
|
104
|
+
expect(File).
|
105
|
+
to exist("#{project_path}/config/initializers/active_job.rb")
|
106
|
+
end
|
107
|
+
|
95
108
|
it "creates a rack-mini-profiler initializer" do
|
96
109
|
expect(File).
|
97
110
|
to exist("#{project_path}/config/initializers/rack_mini_profiler.rb")
|
@@ -101,7 +114,7 @@ RSpec.describe "Suspend a new project with default configuration" do
|
|
101
114
|
expect(analytics_partial).
|
102
115
|
to include(%{<% if ENV["SEGMENT_KEY"] %>})
|
103
116
|
expect(analytics_partial).
|
104
|
-
to include(%{
|
117
|
+
to include(%{analytics.load("<%= ENV["SEGMENT_KEY"] %>");})
|
105
118
|
end
|
106
119
|
|
107
120
|
it "raises on unpermitted parameters in all environments" do
|
@@ -124,6 +137,12 @@ RSpec.describe "Suspend a new project with default configuration" do
|
|
124
137
|
)
|
125
138
|
end
|
126
139
|
|
140
|
+
it "configures production environment to enforce SSL" do
|
141
|
+
expect(production_config).to match(
|
142
|
+
/^ +config.force_ssl = true/,
|
143
|
+
)
|
144
|
+
end
|
145
|
+
|
127
146
|
it "raises on missing translations in development and test" do
|
128
147
|
[development_config, test_config].each do |environment_file|
|
129
148
|
expect(environment_file).to match(
|
@@ -147,6 +166,13 @@ RSpec.describe "Suspend a new project with default configuration" do
|
|
147
166
|
to match(/^ +config.action_mailer.delivery_method = :file$/)
|
148
167
|
end
|
149
168
|
|
169
|
+
it "sets action mailer default host and asset host" do
|
170
|
+
config_key = 'config\.action_mailer\.asset_host'
|
171
|
+
config_value =
|
172
|
+
'{ host: ENV\.fetch\("ASSET_HOST", ENV\.fetch\("APPLICATION_HOST"\)\) }'
|
173
|
+
expect(production_config).to match(/#{config_key} = #{config_value}/)
|
174
|
+
end
|
175
|
+
|
150
176
|
it "uses APPLICATION_HOST, not HOST in the production config" do
|
151
177
|
expect(production_config).to match(/"APPLICATION_HOST"/)
|
152
178
|
expect(production_config).not_to match(/"HOST"/)
|
@@ -221,7 +247,8 @@ RSpec.describe "Suspend a new project with default configuration" do
|
|
221
247
|
|
222
248
|
expect(bin_setup).to include("PARENT_APP_NAME=#{app_name.dasherize}-staging")
|
223
249
|
expect(bin_setup).to include("APP_NAME=#{app_name.dasherize}-staging-pr-$1")
|
224
|
-
expect(bin_setup).
|
250
|
+
expect(bin_setup).
|
251
|
+
to include("heroku run rails db:migrate --exit-code --app $APP_NAME")
|
225
252
|
expect(bin_setup).to include("heroku ps:scale worker=1 --app $APP_NAME")
|
226
253
|
expect(bin_setup).to include("heroku restart --app $APP_NAME")
|
227
254
|
|
@@ -232,7 +259,7 @@ RSpec.describe "Suspend a new project with default configuration" do
|
|
232
259
|
bin_deploy_path = "#{project_path}/bin/deploy"
|
233
260
|
bin_deploy = IO.read(bin_deploy_path)
|
234
261
|
|
235
|
-
expect(bin_deploy).to include("heroku run
|
262
|
+
expect(bin_deploy).to include("heroku run rails db:migrate --exit-code")
|
236
263
|
expect(File.stat(bin_deploy_path)).to be_executable
|
237
264
|
end
|
238
265
|
|
@@ -264,7 +291,9 @@ RSpec.describe "Suspend a new project with default configuration" do
|
|
264
291
|
expect(read_project_file(flashes_path)).to match(/\$flashes/m)
|
265
292
|
|
266
293
|
app_css = read_project_file(%w(app assets stylesheets application.scss))
|
267
|
-
expect(app_css).to match(
|
294
|
+
expect(app_css).to match(
|
295
|
+
/normalize\.css\/normalize\.css.*bourbon.*neat.*base.*refills/m,
|
296
|
+
)
|
268
297
|
end
|
269
298
|
|
270
299
|
it "doesn't use turbolinks" do
|
@@ -272,6 +301,11 @@ RSpec.describe "Suspend a new project with default configuration" do
|
|
272
301
|
expect(app_js).not_to match(/turbolinks/)
|
273
302
|
end
|
274
303
|
|
304
|
+
it "configures Timecop safe mode" do
|
305
|
+
spec_helper = read_project_file(%w(spec spec_helper.rb))
|
306
|
+
expect(spec_helper).to match(/Timecop.safe_mode = true/)
|
307
|
+
end
|
308
|
+
|
275
309
|
def development_config
|
276
310
|
@_development_config ||=
|
277
311
|
read_project_file %w(config environments development.rb)
|
data/spec/support/suspenders.rb
CHANGED
@@ -17,6 +17,12 @@ module SuspendersTestHelpers
|
|
17
17
|
`
|
18
18
|
#{suspenders_bin} #{APP_NAME} #{arguments}
|
19
19
|
`
|
20
|
+
Dir.chdir(APP_NAME) do
|
21
|
+
with_env("HOME", tmp_path) do
|
22
|
+
`git add .`
|
23
|
+
`git commit -m 'Initial commit'`
|
24
|
+
end
|
25
|
+
end
|
20
26
|
end
|
21
27
|
end
|
22
28
|
end
|
@@ -45,7 +51,7 @@ module SuspendersTestHelpers
|
|
45
51
|
if File.exist?(project_path)
|
46
52
|
Dir.chdir(project_path) do
|
47
53
|
Bundler.with_clean_env do
|
48
|
-
`
|
54
|
+
`rails db:drop`
|
49
55
|
end
|
50
56
|
end
|
51
57
|
end
|
@@ -80,4 +86,14 @@ module SuspendersTestHelpers
|
|
80
86
|
def root_path
|
81
87
|
File.expand_path('../../../', __FILE__)
|
82
88
|
end
|
89
|
+
|
90
|
+
def with_env(name, new_value)
|
91
|
+
prior = ENV[name]
|
92
|
+
ENV[name] = new_value.to_s
|
93
|
+
|
94
|
+
yield
|
95
|
+
|
96
|
+
ensure
|
97
|
+
ENV[name] = prior
|
98
|
+
end
|
83
99
|
end
|
data/suspenders.gemspec
CHANGED
@@ -27,7 +27,7 @@ rush to build something amazing; don't use it if you like missing deadlines.
|
|
27
27
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
28
28
|
s.version = Suspenders::VERSION
|
29
29
|
|
30
|
-
s.add_dependency 'bitters', '~> 1.
|
30
|
+
s.add_dependency 'bitters', '~> 1.7'
|
31
31
|
s.add_dependency 'bundler', '~> 1.3'
|
32
32
|
s.add_dependency 'rails', Suspenders::RAILS_VERSION
|
33
33
|
|
data/templates/Gemfile.erb
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
source "https://rubygems.org"
|
2
2
|
|
3
|
+
git_source(:github) do |repo_name|
|
4
|
+
repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/")
|
5
|
+
"https://github.com/#{repo_name}.git"
|
6
|
+
end
|
7
|
+
|
3
8
|
ruby "<%= Suspenders::RUBY_VERSION %>"
|
4
9
|
|
5
10
|
gem "autoprefixer-rails"
|
@@ -7,7 +12,6 @@ gem "delayed_job_active_record"
|
|
7
12
|
gem "flutie"
|
8
13
|
gem "honeybadger"
|
9
14
|
gem "jquery-rails"
|
10
|
-
gem "normalize-rails", "~> 3.0.0"
|
11
15
|
gem "pg"
|
12
16
|
gem "puma"
|
13
17
|
gem "rack-canonical-host"
|
@@ -20,9 +24,13 @@ gem "sprockets", ">= 3.0.0"
|
|
20
24
|
gem "suspenders"
|
21
25
|
gem "title"
|
22
26
|
gem "uglifier"
|
27
|
+
<% if options[:webpack] %>
|
28
|
+
gem "webpacker"
|
29
|
+
<% end %>
|
23
30
|
|
24
31
|
group :development do
|
25
32
|
gem "listen"
|
33
|
+
gem "rack-mini-profiler", require: false
|
26
34
|
gem "spring"
|
27
35
|
gem "spring-commands-rspec"
|
28
36
|
gem "web-console"
|
@@ -36,11 +44,7 @@ group :development, :test do
|
|
36
44
|
gem "factory_girl_rails"
|
37
45
|
gem "pry-byebug"
|
38
46
|
gem "pry-rails"
|
39
|
-
gem "rspec-rails", "~> 3.
|
40
|
-
end
|
41
|
-
|
42
|
-
group :development, :staging do
|
43
|
-
gem "rack-mini-profiler", require: false
|
47
|
+
gem "rspec-rails", "~> 3.6"
|
44
48
|
end
|
45
49
|
|
46
50
|
group :test do
|
@@ -54,6 +58,6 @@ group :test do
|
|
54
58
|
gem "webmock"
|
55
59
|
end
|
56
60
|
|
57
|
-
group :
|
61
|
+
group :production do
|
58
62
|
gem "rack-timeout"
|
59
63
|
end
|
data/templates/Procfile
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
web: bundle exec puma -p $PORT -C ./config/puma.rb
|
2
|
-
worker: bundle exec
|
2
|
+
worker: bundle exec rails jobs:work
|
@@ -1,7 +1,8 @@
|
|
1
1
|
<% if ENV["SEGMENT_KEY"] %>
|
2
2
|
<script type="text/javascript">
|
3
|
-
window.analytics=window.analytics||[]
|
4
|
-
|
5
|
-
|
3
|
+
!function(){var analytics=window.analytics=window.analytics||[];if(!analytics.initialize)if(analytics.invoked)window.console&&console.error&&console.error("Segment snippet included twice.");else{analytics.invoked=!0;analytics.methods=["trackSubmit","trackClick","trackLink","trackForm","pageview","identify","reset","group","track","ready","alias","debug","page","once","off","on"];analytics.factory=function(t){return function(){var e=Array.prototype.slice.call(arguments);e.unshift(t);analytics.push(e);return analytics}};for(var t=0;t<analytics.methods.length;t++){var e=analytics.methods[t];analytics[e]=analytics.factory(e)}analytics.load=function(t){var e=document.createElement("script");e.type="text/javascript";e.async=!0;e.src=("https:"===document.location.protocol?"https://":"http://")+"cdn.segment.com/analytics.js/v1/"+t+"/analytics.min.js";var n=document.getElementsByTagName("script")[0];n.parentNode.insertBefore(e,n)};analytics.SNIPPET_VERSION="4.0.0";
|
4
|
+
analytics.load("<%= ENV["SEGMENT_KEY"] %>");
|
5
|
+
analytics.page();
|
6
|
+
}}();
|
6
7
|
</script>
|
7
8
|
<% end %>
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require "active_job/logging"
|
2
|
+
|
3
|
+
ActiveSupport::Notifications.unsubscribe("enqueue.active_job")
|
4
|
+
|
5
|
+
module ActiveJob
|
6
|
+
module Logging
|
7
|
+
class EnqueueLogSubscriber < LogSubscriber
|
8
|
+
define_method :enqueue, instance_method(:enqueue)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
ActiveJob::Logging::EnqueueLogSubscriber.attach_to(:active_job)
|
data/templates/application.scss
CHANGED
data/templates/bin_deploy
CHANGED
data/templates/bin_setup
CHANGED
@@ -11,10 +11,14 @@ gem install bundler --conservative
|
|
11
11
|
bundle check || bundle install
|
12
12
|
|
13
13
|
# Set up database and add any development seed data
|
14
|
-
bin/
|
14
|
+
bin/rails dev:prime
|
15
15
|
|
16
|
-
|
17
|
-
|
16
|
+
if [ ! -d .git/safe ] && echo $PATH | grep .git/safe > /dev/null; then
|
17
|
+
echo "-----------------------------------------------------------------------"
|
18
|
+
echo
|
19
|
+
echo "-> When you trust this repo, remember to run: mkdir -p .git/safe"
|
20
|
+
echo
|
21
|
+
fi
|
18
22
|
|
19
23
|
# Only if this isn't CI
|
20
24
|
# if [ -z "$CI" ]; then
|
@@ -11,9 +11,12 @@ fi
|
|
11
11
|
|
12
12
|
PARENT_APP_NAME=<%= app_name.dasherize %>-staging
|
13
13
|
APP_NAME=<%= app_name.dasherize %>-staging-pr-$1
|
14
|
-
|
14
|
+
|
15
|
+
heroku pg:backups:capture --app $PARENT_APP_NAME
|
16
|
+
|
17
|
+
URL=`heroku pg:backups public-url --app $PARENT_APP_NAME`
|
15
18
|
|
16
19
|
heroku pg:backups restore $URL DATABASE_URL --confirm $APP_NAME --app $APP_NAME
|
17
|
-
heroku run
|
20
|
+
heroku run rails db:migrate --exit-code --app $APP_NAME
|
18
21
|
heroku ps:scale worker=1 --app $APP_NAME
|
19
22
|
heroku restart --app $APP_NAME
|
@@ -1,12 +1,4 @@
|
|
1
1
|
if Rails.env.development? || Rails.env.test?
|
2
|
-
require "bundler/audit/
|
3
|
-
|
4
|
-
namespace :bundler do
|
5
|
-
desc "Updates the ruby-advisory-db and runs audit"
|
6
|
-
task :audit do
|
7
|
-
%w(update check).each do |command|
|
8
|
-
Bundler::Audit::CLI.start [command]
|
9
|
-
end
|
10
|
-
end
|
11
|
-
end
|
2
|
+
require "bundler/audit/task"
|
3
|
+
Bundler::Audit::Task.new
|
12
4
|
end
|
data/templates/secrets.yml
CHANGED
data/templates/spec_helper.rb
CHANGED
@@ -10,6 +10,7 @@ if ENV.fetch("COVERAGE", false)
|
|
10
10
|
end
|
11
11
|
|
12
12
|
require "webmock/rspec"
|
13
|
+
require "timecop"
|
13
14
|
|
14
15
|
# http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
15
16
|
RSpec.configure do |config|
|
@@ -27,3 +28,6 @@ RSpec.configure do |config|
|
|
27
28
|
end
|
28
29
|
|
29
30
|
WebMock.disable_net_connect!(allow_localhost: true)
|
31
|
+
|
32
|
+
# Only allow Timecop with block syntax
|
33
|
+
Timecop.safe_mode = true
|
@@ -2,12 +2,17 @@
|
|
2
2
|
*.DS_Store
|
3
3
|
*.swo
|
4
4
|
*.swp
|
5
|
+
.byebug_history
|
5
6
|
/.bundle
|
6
7
|
/.env.local
|
7
8
|
/coverage/*
|
8
9
|
/db/*.sqlite3
|
10
|
+
/db/*.sqlite3-journal
|
9
11
|
/log/*
|
10
|
-
/
|
12
|
+
/node_modules
|
11
13
|
/public/assets
|
14
|
+
/public/packs
|
15
|
+
/public/system
|
12
16
|
/tags
|
13
17
|
/tmp/*
|
18
|
+
/yarn-error.log
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: suspenders
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.45.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- thoughtbot
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-09-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bitters
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '1.
|
19
|
+
version: '1.7'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '1.
|
26
|
+
version: '1.7'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: bundler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -44,14 +44,14 @@ dependencies:
|
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: 5.
|
47
|
+
version: 5.1.3
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: 5.
|
54
|
+
version: 5.1.3
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rspec
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -98,6 +98,8 @@ files:
|
|
98
98
|
- lib/suspenders/adapters/heroku.rb
|
99
99
|
- lib/suspenders/app_builder.rb
|
100
100
|
- lib/suspenders/generators/app_generator.rb
|
101
|
+
- lib/suspenders/generators/enforce_ssl_generator.rb
|
102
|
+
- lib/suspenders/generators/initialize_active_job_generator.rb
|
101
103
|
- lib/suspenders/generators/static_generator.rb
|
102
104
|
- lib/suspenders/generators/stylesheet_base_generator.rb
|
103
105
|
- lib/suspenders/version.rb
|
@@ -121,6 +123,7 @@ files:
|
|
121
123
|
- templates/_flashes.html.erb
|
122
124
|
- templates/_javascript.html.erb
|
123
125
|
- templates/action_mailer.rb
|
126
|
+
- templates/active_job.rb
|
124
127
|
- templates/app.json.erb
|
125
128
|
- templates/application.scss
|
126
129
|
- templates/bin_deploy
|
@@ -165,7 +168,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
165
168
|
requirements:
|
166
169
|
- - ">="
|
167
170
|
- !ruby/object:Gem::Version
|
168
|
-
version: 2.4.
|
171
|
+
version: 2.4.1
|
169
172
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
170
173
|
requirements:
|
171
174
|
- - ">="
|
@@ -173,7 +176,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
173
176
|
version: '0'
|
174
177
|
requirements: []
|
175
178
|
rubyforge_project:
|
176
|
-
rubygems_version: 2.6.
|
179
|
+
rubygems_version: 2.6.13
|
177
180
|
signing_key:
|
178
181
|
specification_version: 4
|
179
182
|
summary: Generate a Rails app using thoughtbot's best practices.
|