code42template 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +5 -0
  3. data/.ruby-version +1 -0
  4. data/.travis.yml +11 -0
  5. data/Gemfile +3 -0
  6. data/NEWS.md +56 -0
  7. data/README.md +280 -0
  8. data/Rakefile +8 -0
  9. data/bin/code42template +24 -0
  10. data/bin/rake +16 -0
  11. data/bin/rspec +16 -0
  12. data/bin/setup +13 -0
  13. data/code42template.gemspec +30 -0
  14. data/lib/code42template/actions.rb +28 -0
  15. data/lib/code42template/adapters/heroku.rb +174 -0
  16. data/lib/code42template/app_builder.rb +251 -0
  17. data/lib/code42template/generators/app_generator.rb +208 -0
  18. data/lib/code42template/version.rb +9 -0
  19. data/lib/code42template.rb +5 -0
  20. data/spec/adapters/heroku_spec.rb +56 -0
  21. data/spec/code42template.rb +58 -0
  22. data/spec/fakes/bin/heroku +5 -0
  23. data/spec/fakes/bin/hub +5 -0
  24. data/spec/features/heroku_spec.rb +83 -0
  25. data/spec/features/new_project_spec.rb +186 -0
  26. data/spec/fixtures/feature_smoke_test.rb +15 -0
  27. data/spec/fixtures/home_controller.rb +4 -0
  28. data/spec/fixtures/index.html.erb +1 -0
  29. data/spec/fixtures/routes.rb +3 -0
  30. data/spec/fixtures/smoke_test.rb +10 -0
  31. data/spec/spec_helper.rb +14 -0
  32. data/spec/support/code42template.rb +83 -0
  33. data/spec/support/fake_heroku.rb +83 -0
  34. data/templates/Gemfile.erb +42 -0
  35. data/templates/Procfile +3 -0
  36. data/templates/README.md.erb +10 -0
  37. data/templates/active_job.rb +1 -0
  38. data/templates/application.js +1 -0
  39. data/templates/bin_deploy +12 -0
  40. data/templates/bin_setup +21 -0
  41. data/templates/bin_setup_review_app.erb +19 -0
  42. data/templates/code42_gitignore +16 -0
  43. data/templates/config_locales_pt-BR.yml.erb +17 -0
  44. data/templates/dotfiles/.babelrc +5 -0
  45. data/templates/dotfiles/.codeclimate.yml +3 -0
  46. data/templates/dotfiles/.env +8 -0
  47. data/templates/dotfiles/.rspec +2 -0
  48. data/templates/dotfiles/.rubocop.yml +20 -0
  49. data/templates/feature_helper.rb.erb +5 -0
  50. data/templates/health.rake +22 -0
  51. data/templates/karma.conf.js +48 -0
  52. data/templates/mocha-webpack.opts +4 -0
  53. data/templates/package.json +39 -0
  54. data/templates/postgresql_database.yml.erb +22 -0
  55. data/templates/puma.rb +28 -0
  56. data/templates/rails_helper.rb +59 -0
  57. data/templates/secrets.yml +14 -0
  58. data/templates/setup +32 -0
  59. data/templates/sidekiq.yml +7 -0
  60. data/templates/spec/javascripts/.gitkeep +0 -0
  61. data/templates/spec/javascripts/index.browser.js +5 -0
  62. data/templates/spec/javascripts/index.integration.js +5 -0
  63. data/templates/spec/javascripts/integration/smoke.spec.js +7 -0
  64. data/templates/spec/javascripts/unit/smoke.spec.js +7 -0
  65. data/templates/spec_helper.rb +15 -0
  66. data/templates/travis.yml.erb +12 -0
  67. data/templates/webpack.config.js +68 -0
  68. data/templates/webpack.config.test.browser.js +17 -0
  69. data/templates/webpack.config.test.js +5 -0
  70. data/templates/webpack.rake +26 -0
  71. metadata +158 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 25f9b6b6283c1adf734c7de322de2cad8a852a2b
4
+ data.tar.gz: 542e7cfd66f20c16858cab5a6fb45a1360326d7c
5
+ SHA512:
6
+ metadata.gz: 4d469c1365c42a9e90dad4acd623984f85f1ee14d406c9f8ad596b713b0011cb33847a82ba34039571824a6520b83f1c60d6a635735be9725e6fcec7ed6b1010
7
+ data.tar.gz: 98b2e35b070cdadbbf7f7976df6b2e8a8b3dfa5723cc2eca0b1aae609419af9d39ce1efddc31bc68a4596de2f9caaa00c7e0d4303ff3150f89d82f857e9536bd
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ *.swp
3
+ Gemfile.lock
4
+ /.bundle
5
+ /tmp
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.3.1
data/.travis.yml ADDED
@@ -0,0 +1,11 @@
1
+ language: ruby
2
+ rvm: 2.3.0
3
+ cache: bundler
4
+ sudo: false
5
+ before_install:
6
+ - "echo '--colour' > ~/.rspec"
7
+ - git config --global user.name 'Travis CI'
8
+ - git config --global user.email 'travis-ci@example.com'
9
+ install: bundle install
10
+ notifications:
11
+ email: false
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/NEWS.md ADDED
@@ -0,0 +1,56 @@
1
+ 0.0.1 (January 28 2016)
2
+
3
+ * Initial setup
4
+ * Ruby 2.3.0
5
+ * Rails 4.2.5
6
+ * App layout and flashes
7
+ * Customize error pages
8
+ * Git init and .gitignore
9
+ * Postgresql as database
10
+ * pt-BR locale
11
+ * Readme
12
+ * Remove config and routes comment lines
13
+ * Setup script
14
+ * Setup secret token
15
+
16
+ 1.0.0 (April 06 2016)
17
+
18
+ * Add `quiet_assets` as development dependency
19
+ * Generate rake, rails and rspec binstubs with Spring
20
+ * Make Shoulda Matchers work with Spring
21
+ * Add `binding_of_caller` gem
22
+ * Add `better_errors` gem
23
+ * Add `pry-byebug` and `pry-rails` gems
24
+ * Add `bullet` as development dependency
25
+ * Add Bundler Audit to scan Gemfile for insecure dependencies per CVEs.
26
+ * Add Dotenv to development and test environments to load environment variables from the `.env` file.
27
+ * Add `brakeman`
28
+ * Add `letter_opener`
29
+ * Add `rubocop`
30
+
31
+ 1.0.1 (July 02 2016)
32
+
33
+ * Fix bug: remove missing jquery from generated application.js
34
+
35
+ 2.0.0 (July 27 2016)
36
+
37
+ * Setup rspec with reasonable default settings out of the box
38
+ * Setup capybara and database\_cleaner out of the box
39
+ * Include optional config for phantomjs / poltergeist
40
+ * Include webpack (webpack-rails) and NPM to replace sprockets' JS
41
+ * use foreman to manage processes: rails server, webpack dev server and sidekiq
42
+ * Include JS test runners: karma and mocha
43
+ * Upgrade Ruby to 2.3.1
44
+ * Upgrade Rails to 5.0
45
+ * Drop quiet\_assets in favor of Rails 5' native similar feature
46
+ * Add Heroku support upon app creation
47
+ * Tune up deploy with Heroku
48
+ * Add Puma as the default application server
49
+ * Add codeclimate configuration
50
+ * Add sidekiq / ActiveJob as background job runner
51
+ * Add rubocop configuration
52
+ * Add rake health command and make CI use it
53
+ * Cleanup unnecessary gems
54
+ * Improve bin/setup script
55
+ * Do not remove comments from generated files anymore
56
+ * Improve README
data/README.md ADDED
@@ -0,0 +1,280 @@
1
+ # Code42Template
2
+
3
+ This is the base application used at [Codeminer
4
+ 42](http://www.codeminer42.com/). It uses **Rails 5** to manage the backend and
5
+ **Node.js / Webpack** to manage the frontend. The purpose of this project is
6
+ to:
7
+
8
+ - Provide a minimal and well-configured application generator.
9
+ - Improve some Rails defaults.
10
+ - Unleash the full power of the JavaScript ecosystem within Rails by making it
11
+ a **first class citizen**. We replace JS sprockets with **Webpack**.
12
+ - Enforce **code style guidelines**.
13
+ - Provide _basic_ **security**.
14
+ - Have Ruby and JS test frameworks configured out of the box with a few
15
+ hand-picked tools.
16
+ - Provide opinionated defaults on infrastructure: **Travis** for CI and
17
+ **Heroku** deploys working out of the box. We want apps to leverage the best
18
+ Heroku has to offer, such as decreased devops maintenance burden, pipelines,
19
+ review apps, etc.
20
+
21
+ This template does **NOT** aim to:
22
+
23
+ - Encourage having too many dependencies. Dependencies are not cheap, and each
24
+ bundled tool must have a _good_ reason to be included.
25
+ - Make you use JavaScript for everything, but rather to provide better
26
+ tools to work with the language. Just because we use Webpack it does not
27
+ mean you have to turn your app into an SPA.
28
+ - Provide "pattern" gems (e.g. decorator). Patterns are usually
29
+ project-specific and most of them can be achieved **without** any gems or
30
+ libraries.
31
+ - Be a silver bullet. This is tailored for the majority of Rails applications
32
+ you may want to build, but we know it won't work sometimes.
33
+
34
+ ## Pre-requisites
35
+
36
+ - [Ruby](https://www.ruby-lang.org) >= 2.3.1
37
+ - [Bundler](http://bundler.io/)
38
+ - Either [rbenv](https://github.com/rbenv/rbenv) /
39
+ [ruby-build](https://github.com/rbenv/ruby-build) or
40
+ [rvm](https://github.com/rvm/rvm)
41
+ - [Node.js](https://nodejs.org) >= 6.2.0
42
+ - [NPM](https://www.npmjs.com/)
43
+ - [nvm](https://github.com/creationix/nvm)
44
+ - [Git](https://git-scm.com/)
45
+ - [PostgreSQL](https://www.postgresql.org/)
46
+ - [Heroku Toolbelt](https://toolbelt.heroku.com/)
47
+ - [Redis](http://redis.io/) - primarily for use with [Sidekiq](http://sidekiq.org/)
48
+ - [PhantomJS](http://phantomjs.org/)
49
+
50
+
51
+ ## Installation
52
+
53
+ Install the gem:
54
+
55
+ ```sh
56
+ gem install code42template
57
+ ```
58
+
59
+ This will make the `code42template` command accessible throughout your `PATH`.
60
+
61
+ ## Configuring your environment
62
+
63
+ ### PostgreSQL
64
+
65
+ **development** and **test** databases are automatically setup for you.
66
+ While running the generator it's assumed that:
67
+
68
+ - The PostgreSQL server is running.
69
+ - You have a PostgreSQL user named after your UNIX login.
70
+ - Your PostgreSQL user has a _blank_ password.
71
+
72
+ It's OK if your PG settings happen to be different from this; DB creation will
73
+ fail, but you can do it manually thereafter.
74
+
75
+ At a basic level, here's how to setup PostgreSQL on Linux:
76
+
77
+ ```sh
78
+ # Creates a user
79
+ sudo -u postgres createuser -s my_user_name
80
+
81
+ # Runs psql
82
+ sudo -u postgres psql
83
+
84
+ # Change your use password within psql. Leave it blank.
85
+ [local] thiago@thiago=# \password my_user_name
86
+ ```
87
+
88
+ ### Heroku
89
+
90
+ Automatic Heroku setup is optional, but if you want to use it we assume you've
91
+ already logged in with your Heroku credentials. If you haven't, you'll need to
92
+ run `heroku login`. Also remember to set the correct account if you happen to
93
+ use the [multiple accounts](https://github.com/heroku/heroku-accounts) plugin.
94
+
95
+ ## Generating your app
96
+
97
+ You can generate a new app with the following command:
98
+
99
+ ```sh
100
+ code42template myapp
101
+ ```
102
+
103
+ To generate and configure your new app with Heroku:
104
+
105
+ ```sh
106
+ code42template myapp --heroku true
107
+ ```
108
+
109
+ ## Starting up your app
110
+
111
+ ```sh
112
+ $ cd my_app_folder
113
+ $ foreman start
114
+ ```
115
+
116
+ This command runs Webpack dev server, Rails server and Sidekiq all at once.
117
+ Note that Your redis server has to be up and running because of Sidekiq. To
118
+ customize these processes you can edit `Procfile`.
119
+
120
+ Now you can work as you'd usually work in any Rails application, with automatic
121
+ Ruby and JS file reloads out of the box.
122
+
123
+ ## Basic hands-on guide
124
+
125
+ ### App setup
126
+
127
+ Your team can use the following command after cloning the git repository:
128
+
129
+ ```sh
130
+ bin/setup
131
+ ```
132
+ ### Deploy
133
+
134
+ Deploy your app with the following command:
135
+
136
+ ```sh
137
+ # Replace `MY_ENV` with `production` or `staging`.
138
+ bin/deploy MY_ENV
139
+ ```
140
+
141
+ This command pushes your code to Heroku, migrates your database and restarts
142
+ your dynos. It will work out of the box if you've generated your app with
143
+ `--heroku true`. If not, please create `staging` and `production` git remotes
144
+ pointing to the respective Heroku remotes.
145
+
146
+ ### Health check
147
+
148
+ Check your app's health with the `rake health` command. It runs the following
149
+ tasks:
150
+
151
+ - `rspec` runs your Ruby and Rails specs.
152
+ - If you app happens to be below 90% test coverage the `rspec` command will fail.
153
+ - `npm run test`: runs JS unit and integration tests
154
+ - `bundle-audit` and `brakeman` check if your app does not have basic
155
+ security holes.
156
+ - `rubocop` makes sure your code adheres to style guidelines.
157
+
158
+ ### Continuous integration
159
+
160
+ A `travis.yml` file is also included: it runs the `rake health` command, among
161
+ other setup tasks. You must still manually configure your remote repo with
162
+ Travis integration, though.
163
+
164
+ ### Improved JavaScript
165
+
166
+ JS files must live at the `app/assets/javascripts` folder. JS packages can be
167
+ managed with NPM and the `package.json` file.
168
+
169
+ You can write your JS code in **ES2015** because of
170
+ [babel](https://babeljs.io/). ES2015 Import statements will automatically work
171
+ without having to specify the full path.
172
+
173
+ ### CSS
174
+
175
+ We still use the asset pipeline for CSS.
176
+
177
+ ### Testing
178
+
179
+ #### Ruby tests
180
+
181
+ Use the following command to run all your specs:
182
+
183
+ ```sh
184
+ rspec
185
+ ```
186
+
187
+ We use the following tools:
188
+
189
+ - [rspec](https://github.com/rspec/rspec)
190
+ - [capybara](https://github.com/jnicklas/capybara) and
191
+ [database_cleaner](https://github.com/DatabaseCleaner/database_cleaner)
192
+ - [factory_girl](https://github.com/thoughtbot/factory_girl)
193
+ - [poltergeist](https://github.com/teampoltergeist/poltergeist) (for JS feature
194
+ tests)
195
+ - [simplecov](https://github.com/colszowka/simplecov) for helping out with test
196
+ coverage
197
+
198
+
199
+ Refer to the [rspec-rails](https://github.com/rspec/rspec-rails) to learn which
200
+ kinds of specs are available.
201
+
202
+ Note that you can require the following files to setup your tests:
203
+
204
+ - For light unit tests you can require `spec_helper.rb`. It won't boot up
205
+ the Rails environment.
206
+ - For tests needing Rails you can require `rails_helper.rb`.
207
+ - For feature tests require `feature_helper.rb`. It will compile your assets
208
+ and make feature tests run correctly.
209
+
210
+ Regarding feature tests, they are configured to run seamlessly with Webpack.
211
+
212
+ #### JavaScript tests
213
+
214
+ JavaScript tests must live at the `spec/javascripts` folder. Some smoke
215
+ tests are included in every app.
216
+
217
+ - `mocha` is used for unit tests. Unit tests **must not depend** on global JS
218
+ objects such as `window`. They must live at `spec/javascripts/unit` and can be
219
+ run with:
220
+
221
+ npm test:unit
222
+ npm test:unit:watch # runs tests automatically in every change
223
+
224
+ - `karma` and `phantomjs` are used for integration tests. That means you _can_
225
+ use browser-only global JS objects such as `window`. They must live at
226
+ `spec/javascript/integration` and can be run with:
227
+
228
+ npm test:integration
229
+ npm test:integration:watch
230
+
231
+ - Run _all_ the tests (unit + integration) with the following command:
232
+
233
+ npm test
234
+
235
+ - Debug your tests in the browser with webpack-dev-server. This command will
236
+ output a URL where you can run all tests:
237
+
238
+ npm test:browser
239
+
240
+ ### Application server
241
+
242
+ We use [puma](https://github.com/puma/puma) as our application server, which
243
+ happens to be [Heroku's default
244
+ recommendation](https://devcenter.heroku.com/changelog-items/594).
245
+
246
+ ### Background jobs
247
+
248
+ Our tool of choice is Sidekiq, which is configured as ActiveJob's backend. We
249
+ include a `sidekiq.yml` configuration file with default settings, but you are
250
+ encouraged to tune it to your application needs.
251
+
252
+ ### Debugging
253
+
254
+ - [pry-rails](https://github.com/rweng/pry-rails)
255
+ - [pry-byebug](https://github.com/deivid-rodriguez/pry-byebug)
256
+ - [better-errors](https://github.com/charliesome/better_errors) instead of Web
257
+ Console.
258
+
259
+ ### Performance and Profiling
260
+
261
+ * [rack-mini-profiler](https://github.com/MiniProfiler/rack-mini-profiler) for
262
+ helping out with performance issues
263
+ * [spring](https://github.com/rails/spring) for fast Rails actions via
264
+ pre-loading
265
+ * [bullet](https://github.com/flyerhzm/bullet) yeah, it's very easy to miss out
266
+ N+1 queries, that's why we include this gem by default
267
+
268
+ Spring binstubs are automatically generated within the `bin` folder.
269
+
270
+ ### Environment variables
271
+
272
+ * [Dotenv](https://github.com/bkeepers/dotenv) for loading environment variables
273
+
274
+ ## Credits
275
+
276
+ The template uses the [Suspenders](https://github.com/thoughtbot/suspenders)
277
+ gem from Thoughtbot as starting point.
278
+
279
+ [![codeminer42](http://s3.amazonaws.com/cm42_prod/assets/logo-codeminer-horizontal-c0516b1b78a8713270da02c3a0645560.png)](http://codeminer42.com)
280
+
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require 'bundler/setup'
2
+ require 'bundler/gem_tasks'
3
+ require 'rspec/core/rake_task'
4
+
5
+ RSpec::Core::RakeTask.new(:rspec)
6
+
7
+ desc 'Run the test suite'
8
+ task :default => :rspec
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env ruby
2
+ require 'pathname'
3
+
4
+ source_path = (Pathname.new(__FILE__).dirname + '../lib').expand_path
5
+ $LOAD_PATH << source_path
6
+
7
+ require 'code42template/version'
8
+
9
+ if Code42Template::RUBY_VERSION != ::RUBY_VERSION
10
+ abort "ERROR: You must use this tool with Ruby version #{Code42Template::RUBY_VERSION}"
11
+ end
12
+
13
+ require 'code42template'
14
+
15
+ if ['-v', '--version'].include? ARGV[0]
16
+ puts Code42Template::VERSION
17
+ exit 0
18
+ end
19
+
20
+ templates_root = File.expand_path(File.join("..", "templates"), File.dirname(__FILE__))
21
+ Code42Template::AppGenerator.source_root templates_root
22
+ Code42Template::AppGenerator.source_paths << Rails::Generators::AppGenerator.source_root << templates_root
23
+
24
+ Code42Template::AppGenerator.start
data/bin/rake ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'rake' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('rake', 'rake')
data/bin/rspec ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'rspec' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('rspec-core', 'rspec')
data/bin/setup ADDED
@@ -0,0 +1,13 @@
1
+ #!/bin/sh
2
+
3
+ # Run this script immediately after cloning the codebase.
4
+
5
+ # Exit if any subcommand fails
6
+ set -e
7
+
8
+ # Set up Ruby dependencies via Bundler
9
+ bundle install
10
+
11
+ # Add binstubs to PATH in ~/.zshenv like this:
12
+ # export PATH=".git/safe/../../bin:$PATH"
13
+ mkdir -p .git/safe
@@ -0,0 +1,30 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path('../lib', __FILE__)
3
+ require 'code42template/version'
4
+ require 'date'
5
+
6
+ Gem::Specification.new do |s|
7
+ s.required_ruby_version = ">= #{Code42Template::RUBY_VERSION}"
8
+ s.authors = ['codeminer42']
9
+ s.date = Date.today.strftime('%Y-%m-%d')
10
+
11
+ s.description = <<-HERE
12
+ code42template is the base Rails project used at Codeminer 42.
13
+ HERE
14
+
15
+ s.email = 'suporte@codeminer42.com'
16
+ s.executables = ['code42template']
17
+ s.extra_rdoc_files = %w[README.md]
18
+ s.files = `git ls-files`.split("\n")
19
+ s.homepage = 'https://github.com/Codeminer42/code42template'
20
+ s.name = 'code42template'
21
+ s.rdoc_options = ['--charset=UTF-8']
22
+ s.require_paths = ['lib']
23
+ s.summary = "Generate a minimal Rails / Webpack app."
24
+ s.version = Code42Template::VERSION
25
+
26
+ s.add_dependency 'bundler'
27
+ s.add_dependency 'rails', Code42Template::RAILS_VERSION
28
+
29
+ s.add_development_dependency 'rspec'
30
+ end
@@ -0,0 +1,28 @@
1
+ module Code42Template
2
+ module Actions
3
+ def replace_in_file(relative_path, find, replace)
4
+ path = File.join(destination_root, relative_path)
5
+ contents = IO.read(path)
6
+ unless contents.gsub!(find, replace)
7
+ raise "#{find.inspect} not found in #{relative_path}"
8
+ end
9
+ File.open(path, "w") { |file| file.write(contents) }
10
+ end
11
+
12
+ def configure_application_file(config)
13
+ inject_into_file(
14
+ "config/application.rb",
15
+ "\n\n #{config}",
16
+ before: "\n end"
17
+ )
18
+ end
19
+
20
+ def configure_environment(rails_env, config)
21
+ inject_into_file(
22
+ "config/environments/#{rails_env}.rb",
23
+ "\n\n #{config}",
24
+ before: "\nend"
25
+ )
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,174 @@
1
+ module Code42Template
2
+ module Adapters
3
+ class Heroku
4
+ HEROKU_BUILDPACK_URLS = %w(
5
+ heroku/nodejs
6
+ heroku/ruby
7
+ https://github.com/febeling/webpack-rails-buildpack.git
8
+ )
9
+
10
+ def initialize(app_builder)
11
+ @app_builder = app_builder
12
+ end
13
+
14
+ def create_heroku_apps(flags)
15
+ create_staging_heroku_app(flags)
16
+ create_production_heroku_app(flags)
17
+ end
18
+
19
+ def create_deploy_script
20
+ @app_builder.copy_file "bin_deploy", "bin/deploy"
21
+ @app_builder.run "chmod a+x bin/deploy"
22
+ end
23
+
24
+ def update_readme_with_deploy
25
+ instructions = <<~MARKDOWN
26
+ ## Deploying
27
+
28
+ If you have previously run the `./bin/setup` script,
29
+ you can deploy to staging and production with:
30
+
31
+ $ ./bin/deploy staging
32
+ $ ./bin/deploy production
33
+
34
+ We currently use the following buildpacks:
35
+
36
+ - heroku/nodejs
37
+ - heroku/ruby
38
+ - https://github.com/febeling/webpack-rails-buildpack.git
39
+
40
+ Please be sure to configure these buildpacks in the same sequence
41
+ presented here in both staging and production, or else the deploy will
42
+ not work.
43
+ MARKDOWN
44
+
45
+ @app_builder.append_file "README.md", instructions
46
+ end
47
+
48
+ def set_heroku_remotes
49
+ remotes = <<~SHELL
50
+ #{command_to_join_heroku_app('staging')}
51
+ #{command_to_join_heroku_app('production')}
52
+
53
+ git config heroku.remote staging
54
+ SHELL
55
+
56
+ @app_builder.append_file 'bin/setup', remotes
57
+ end
58
+
59
+ def create_staging_heroku_app(flags)
60
+ app_name = heroku_app_name_for('staging')
61
+
62
+ run_toolbelt_command "create #{app_name} #{flags}", "staging"
63
+ end
64
+
65
+ def create_production_heroku_app(flags)
66
+ app_name = heroku_app_name_for('production')
67
+
68
+ run_toolbelt_command "create #{app_name} #{flags}", "production"
69
+ end
70
+
71
+ def set_heroku_rails_secrets
72
+ %w(staging production).each do |environment|
73
+ run_toolbelt_command(
74
+ "config:add SECRET_KEY_BASE=#{generate_secret}",
75
+ environment,
76
+ )
77
+ end
78
+ end
79
+
80
+ def set_heroku_rails_environment
81
+ %w(staging production).each do |environment|
82
+ run_toolbelt_command("config:add RAILS_ENV=production", environment)
83
+ end
84
+ end
85
+
86
+ def create_review_apps_setup_script
87
+ @app_builder.template(
88
+ 'bin_setup_review_app.erb',
89
+ 'bin/setup_review_app',
90
+ force: true,
91
+ )
92
+ @app_builder.run 'chmod a+x bin/setup_review_app'
93
+ end
94
+
95
+ def create_heroku_pipeline
96
+ run_toolbelt_command(
97
+ "pipelines:create #{heroku_app_name} \
98
+ -a #{heroku_app_name}-staging --stage staging",
99
+ 'staging',
100
+ )
101
+
102
+ run_toolbelt_command(
103
+ "pipelines:add #{heroku_app_name} \
104
+ -a #{heroku_app_name}-production --stage production",
105
+ 'production',
106
+ )
107
+ end
108
+
109
+ def configure_heroku_buildpacks
110
+ %w(staging production).each do |environment|
111
+ app_name = heroku_app_name_for(environment)
112
+
113
+ run_toolbelt_command("buildpacks:clear -a #{app_name}", environment)
114
+
115
+ HEROKU_BUILDPACK_URLS.each do |buildpack_url|
116
+ run_toolbelt_command(
117
+ "buildpacks:add #{buildpack_url} -a #{app_name}",
118
+ environment
119
+ )
120
+ end
121
+ end
122
+ end
123
+
124
+ def set_heroku_serve_static_files
125
+ %w(staging production).each do |environment|
126
+ run_toolbelt_command(
127
+ 'config:add RAILS_SERVE_STATIC_FILES=true',
128
+ environment,
129
+ )
130
+ end
131
+ end
132
+
133
+ def set_heroku_application_host
134
+ %w(staging production).each do |environment|
135
+ run_toolbelt_command(
136
+ "config:add APPLICATION_HOST=#{heroku_app_name}-#{environment}.herokuapp.com",
137
+ environment,
138
+ )
139
+ end
140
+ end
141
+
142
+ private
143
+
144
+ def command_to_join_heroku_app(environment)
145
+ heroku_app_name = heroku_app_name_for(environment)
146
+
147
+ <<~SHELL
148
+ if heroku join --app #{heroku_app_name} &> /dev/null; then
149
+ git remote add #{environment} git@heroku.com:#{heroku_app_name}.git || true
150
+ printf 'You are a collaborator on the "#{heroku_app_name}" Heroku app\n'
151
+ else
152
+ printf 'Ask for access to the "#{heroku_app_name}" Heroku app\n'
153
+ fi
154
+ SHELL
155
+ end
156
+
157
+ def heroku_app_name
158
+ @app_builder.app_name.dasherize
159
+ end
160
+
161
+ def heroku_app_name_for(environment)
162
+ "#{heroku_app_name}-#{environment}"
163
+ end
164
+
165
+ def generate_secret
166
+ SecureRandom.hex(64)
167
+ end
168
+
169
+ def run_toolbelt_command(command, environment)
170
+ @app_builder.run("heroku #{command} --remote #{environment}")
171
+ end
172
+ end
173
+ end
174
+ end