roo_on_rails 1.10.0 → 1.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +672 -0
  3. data/.circleci/config.yml.erb +86 -0
  4. data/.gitignore +2 -1
  5. data/.rspec +2 -0
  6. data/CHANGELOG.md +27 -0
  7. data/README.md +75 -26
  8. data/README.routemaster_client.md +2 -0
  9. data/exe/roo_on_rails +96 -7
  10. data/lib/roo_on_rails/checks/base.rb +34 -17
  11. data/lib/roo_on_rails/checks/documentation/playbook.rb +2 -6
  12. data/lib/roo_on_rails/checks/environment.rb +2 -4
  13. data/lib/roo_on_rails/checks/environment_independent.rb +22 -0
  14. data/lib/roo_on_rails/checks/heroku/app_exists.rb +9 -2
  15. data/lib/roo_on_rails/checks/heroku/drains_metrics.rb +2 -2
  16. data/lib/roo_on_rails/checks/heroku/metrics_bridge_configured.rb +6 -2
  17. data/lib/roo_on_rails/checks/heroku/preboot_enabled.rb +3 -3
  18. data/lib/roo_on_rails/checks/papertrail/drain_exists.rb +4 -4
  19. data/lib/roo_on_rails/checks/papertrail/system_exists.rb +2 -2
  20. data/lib/roo_on_rails/checks/papertrail/system_named.rb +1 -1
  21. data/lib/roo_on_rails/checks/sidekiq/settings.rb +1 -1
  22. data/lib/roo_on_rails/checks/sidekiq/sidekiq.rb +1 -0
  23. data/lib/roo_on_rails/context_logging.rb +1 -0
  24. data/lib/roo_on_rails/harness.rb +8 -14
  25. data/lib/roo_on_rails/logfmt.rb +3 -15
  26. data/lib/roo_on_rails/logger.rb +104 -0
  27. data/lib/roo_on_rails/railties/database.rb +8 -6
  28. data/lib/roo_on_rails/railties/env.rb +11 -0
  29. data/lib/roo_on_rails/railties/google_oauth.rb +3 -7
  30. data/lib/roo_on_rails/railties/http.rb +31 -27
  31. data/lib/roo_on_rails/railties/logging.rb +16 -0
  32. data/lib/roo_on_rails/railties/new_relic.rb +15 -14
  33. data/lib/roo_on_rails/railties/rake_tasks.rb +0 -2
  34. data/lib/roo_on_rails/railties/routemaster.rb +9 -8
  35. data/lib/roo_on_rails/railties/sidekiq.rb +12 -8
  36. data/lib/roo_on_rails/routemaster/publisher.rb +14 -1
  37. data/lib/roo_on_rails/routemaster/publishers.rb +3 -3
  38. data/lib/roo_on_rails/sidekiq/process_scaling.rb +1 -1
  39. data/lib/roo_on_rails/tasks/db.rake +3 -2
  40. data/lib/roo_on_rails/version.rb +1 -1
  41. data/lib/roo_on_rails.rb +2 -1
  42. metadata +8 -7
  43. data/gemfiles/rails_3.gemfile.lock +0 -278
  44. data/gemfiles/rails_4.gemfile.lock +0 -293
  45. data/gemfiles/rails_5.gemfile.lock +0 -299
  46. data/gemfiles/rails_5_1.gemfile.lock +0 -300
  47. data/lib/roo_on_rails/railtie.rb +0 -16
@@ -0,0 +1,86 @@
1
+ # To update the build configuration, edit the "builds" array below and run:
2
+ # erb .circleci/config.yml.erb > .circleci/config.yml
3
+ <%
4
+ builds = [
5
+ ['2.2.6', 'rails_3'],
6
+ ['2.3.3', 'rails_3'],
7
+ ['2.2.6', 'rails_4'],
8
+ ['2.3.3', 'rails_4'],
9
+ ['2.4.0', 'rails_4'],
10
+ ['2.2.6', 'rails_5'],
11
+ ['2.3.3', 'rails_5'],
12
+ ['2.4.0', 'rails_5'],
13
+ ['2.2.6', 'rails_5_1'],
14
+ ['2.3.3', 'rails_5_1'],
15
+ ['2.4.0', 'rails_5_1'],
16
+ ]
17
+ %>
18
+ version: 2
19
+ jobs:
20
+ <% builds.each do |ruby,variant| %>
21
+ build_<%= ruby %>_<%= variant %>:
22
+ docker:
23
+ - image: deliveroo/multiruby
24
+ - image: postgres:9.6-alpine
25
+ environment:
26
+ PGDATA: /dev/shm/pgdata
27
+ - image: redis:3-alpine
28
+ steps:
29
+ - checkout
30
+
31
+ - run:
32
+ name: Setup RAM disk
33
+ command: |
34
+ rm -rf ~/project/tmp ;
35
+ mkdir /dev/shm/tmp ;
36
+ ln -s /dev/shm/tmp ~/project/tmp
37
+
38
+ - run:
39
+ name: Select build variant (Ruby <%= ruby %>, <%= variant %>)
40
+ command: |
41
+ rbenv local <%= ruby %> ;
42
+ gem install bundler ;
43
+ bundle config --local gemfile $PWD/gemfiles/<%= variant %>.gemfile
44
+
45
+ - restore_cache:
46
+ keys:
47
+ - v2-bundle-<%= ruby %>-<%= variant %>-{{ .Branch }}
48
+ - v2-bundle-<%= ruby %>-<%= variant %>
49
+ - v2-bundle-<%= ruby %>
50
+
51
+ - run:
52
+ name: Install dependencies
53
+ command: |
54
+ bundle install --jobs=3 --retry=3 --path=$PWD/vendor/bundle
55
+
56
+ - run:
57
+ name: Run test suite
58
+ command: |
59
+ unset RACK_ENV &&
60
+ unset RAILS_ENV &&
61
+ bundle exec rspec
62
+
63
+ - save_cache:
64
+ key: v2-bundle-<%= ruby %>-<%= variant %>-{{ .Branch }}
65
+ paths:
66
+ - ~/project/vendor/bundle
67
+ - ~/project/vendor/bundle-scaffold
68
+ - save_cache:
69
+ key: v2-bundle-<%= ruby %>-<%= variant %>
70
+ paths:
71
+ - ~/project/vendor/bundle
72
+ - ~/project/vendor/bundle-scaffold
73
+ - save_cache:
74
+ key: v2-bundle-<%= ruby %>
75
+ paths:
76
+ - ~/project/vendor/bundle
77
+ - ~/project/vendor/bundle-scaffold
78
+ <% end %>
79
+
80
+ workflows:
81
+ version: 2
82
+ test:
83
+ jobs:
84
+ <% builds.each do |ruby,variant| %>
85
+ - build_<%= ruby %>_<%= variant %>
86
+ <% end %>
data/.gitignore CHANGED
@@ -1,6 +1,7 @@
1
1
  /.bundle/
2
2
  /.yardoc
3
3
  /Gemfile.lock
4
+ /gemfiles/*.lock
4
5
  /_yardoc/
5
6
  /coverage/
6
7
  /doc/
@@ -8,4 +9,4 @@
8
9
  /spec/reports/
9
10
  /tmp/
10
11
  /vendor/
11
- /.idea
12
+ /.idea
data/.rspec CHANGED
@@ -1,2 +1,4 @@
1
1
  --format documentation
2
2
  --color
3
+ --order rand
4
+ --profile
data/CHANGELOG.md CHANGED
@@ -1,3 +1,30 @@
1
+ # v1.11.0 (2017-08-11)
2
+
3
+ Features (library):
4
+
5
+ - Replaces the Rails logger with a structured logger (#60)
6
+ - Auto-fills the Routemaster `t` timestamp field, where appropriate, from the
7
+ model's `created_at` and `updated_at` fields if available (#64)
8
+
9
+ Features (app harness):
10
+
11
+ - The `roo_on_rails` test harness now defaults to not fixing issues, and has extra
12
+ `--env` and `--fix` flags (#57)
13
+ - All checks will now run regardless of previous failure to avoid
14
+ back-and-forthing (#57)
15
+ - Tolerates apps with abbreviated environment names (#55)
16
+
17
+ Bug fixes:
18
+
19
+ - Bugfix for supporting non-default publishers after a `reload!` in the rails console (#62)
20
+ - Friendlier error message when facing Heroku permission errors (#58)
21
+ - Support apps without ActiveRecord (#40)
22
+
23
+ Misc:
24
+
25
+ - Now using CircleCI for builds (#61, #63)
26
+ - Document Datadog integration (#59)
27
+
1
28
  # v1.10.0 (2017-08-11)
2
29
 
3
30
  Features:
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- ## `roo_on_rails` [![Gem Version](https://badge.fury.io/rb/roo_on_rails.svg)](https://badge.fury.io/rb/roo_on_rails) [![Build Status](https://travis-ci.org/deliveroo/roo_on_rails.svg?branch=master)](https://travis-ci.org/deliveroo/roo_on_rails) [![Code Climate](https://codeclimate.com/repos/58809e664ab8420081007382/badges/3489b7689ab2e0cf5d61/gpa.svg)](https://codeclimate.com/repos/58809e664ab8420081007382/feed)
1
+ ## `roo_on_rails` [![Gem Version](https://badge.fury.io/rb/roo_on_rails.svg)](https://badge.fury.io/rb/roo_on_rails) [![Build Status](https://circleci.com/gh/deliveroo/roo_on_rails.svg?style=shield&circle-token=f8ad2021dfc72fd86850fd0b7224759f34a91281)](https://circleci.com/gh/deliveroo/roo_on_rails) [![Code Climate](https://codeclimate.com/repos/58809e664ab8420081007382/badges/3489b7689ab2e0cf5d61/gpa.svg)](https://codeclimate.com/repos/58809e664ab8420081007382/feed)
2
2
 
3
3
 
4
4
  `roo_on_rails` is:
@@ -24,6 +24,7 @@
24
24
  - [HireFire (for Sidekiq workers)](#hirefire-for-sidekiq-workers)
25
25
  - [Logging](#logging)
26
26
  - [Google OAuth authentication](#google-oauth-authentication)
27
+ - [Datadog Integration](#datadog-integration)
27
28
  - [Routemaster Client](#routemaster-client)
28
29
  - [Command features](#command-features)
29
30
  - [Usage](#usage)
@@ -149,38 +150,47 @@ be used:
149
150
 
150
151
  ### Logging
151
152
 
152
- For clearer and machine-parseable log output, there in an extension to be able
153
- to add context to your logs which is output as
154
- [logfmt](https://brandur.org/logfmt) key/value pairs after the log message.
153
+ For clearer and machine-parseable log output, the Rails logger is replaced by an
154
+ extended logger to add context to your logs, which is output as
155
+ [logfmt](https://brandur.org/logfmt) key/value pairs along with the log message.
156
+
157
+ You can use the logger as usual:
155
158
 
156
159
  ```ruby
157
- # application.rb
160
+ Rails.logger.info { 'hello world' }
161
+ ```
158
162
 
159
- require 'roo_on_rails/context_logging'
163
+ From your console, the output will include the timestamp, severity, and message:
160
164
 
161
- class Application < Rails::Application
165
+ ```
166
+ [2017-08-25 14:34:54.899] INFO | hello world
167
+ ```
162
168
 
163
- # add this block somewhere within the application class
164
- logger = config.logger
165
- if logger.nil?
166
- logger = ActiveSupport::Logger.new($stdout)
167
- logger.formatter = config.log_formatter
168
- end
169
- logger = ActiveSupport::TaggedLogging.new(logger) unless logger.respond_to?(:tagged)
170
- config.logger = RooOnRails::ContextLogging.new(logger)
169
+ In production (or whenever the output isn't a TTY), the timestamp is stripped
170
+ (as it's provided by the logging pipes) and the output is fully valid `logfmt`:
171
171
 
172
- end
172
+ ```
173
+ at=INFO msg="hello world"
173
174
  ```
174
175
 
175
- You can then add context using the `with` method:
176
+ One can also add context using the `with` method:
176
177
 
177
178
  ```ruby
178
179
  logger.with(a: 1, b: 2) { logger.info 'Stuff' }
180
+ # => at=INFO msg=Stuff a=1 b=2
181
+ ```
182
+
183
+ ```ruby
179
184
  logger.with(a: 1) { logger.with(b: 2) { logger.info('Stuff') } }
185
+ # => at=INFO msg=Stuff a=1 b=2
186
+ ```
187
+
188
+ ```ruby
180
189
  logger.with(a: 1, b: 2).info('Stuff')
190
+ # => at=INFO msg=Stuff a=1 b=2
181
191
  ```
182
192
 
183
- See the [class documentation](lib/roo_on_rails/context_logging.rb) for further
193
+ See the [class documentation](lib/roo_on_rails/logger.rb) for further
184
194
  details.
185
195
 
186
196
  ### Google OAuth authentication
@@ -199,6 +209,44 @@ application.
199
209
 
200
210
  A simple but secure example is detailed in `README.google_oauth2.md`.
201
211
 
212
+ ### Datadog Integration
213
+
214
+ #### Heroku metrics
215
+
216
+ To send system metrics to Datadog (CPU, memory usage, HTTP throughput per
217
+ status, latency, etc), your application need to send their logs to
218
+ [the metrics bridge](https://github.com/deliveroo/heroku-datadog-drain-golang).
219
+
220
+ This is automatically configured when running `roo_on_rails harness`.
221
+
222
+ #### Custom application metrics
223
+
224
+ Sending custom metrics to Datadog through Statsd requires an agent running in
225
+ each dyno.
226
+ You need to add the buildpack
227
+ [`heroku-buildpack-datadog`](https://github.com/deliveroo/heroku-buildpack-datadog).
228
+
229
+ Once this is done, you can send metrics with e.g.:
230
+
231
+ ```ruby
232
+ RooOnRails.statsd.increment('my.metric', tags: 'tag:value')
233
+ ```
234
+
235
+ Tags `env:{name}`, `source:{dyno}`, and `app:{name}` will automatically be added
236
+ to all your metrics.
237
+
238
+ The following environment variables are being used. The default values are fine
239
+ except for `STATSD_ENV` which should be set.
240
+
241
+ - `STATSD_ENV`
242
+ - `STATSD_HOST`
243
+ - `STATSD_PORT`
244
+
245
+ These extra required variables are automatically set by Heroku:
246
+
247
+ - `DYNO`
248
+ - `HEROKU_APP_NAME`
249
+
202
250
  ### Routemaster Client
203
251
 
204
252
  When `ROUTEMASTER_ENABLED` is set to `true` we attempt to configure [`routemaster-client`](https://github.com/deliveroo/routemaster-client) on your application. In order for this to happen you need to set the following environment variables:
@@ -215,7 +263,7 @@ If you then want to enable the publishing of events onto the event bus, you need
215
263
  Run the following from your app's top-level directory:
216
264
 
217
265
  ```
218
- bundle exec roo_on_rails
266
+ roo_on_rails harness
219
267
  ```
220
268
 
221
269
  That command will sequentially run a number of checks. For it to run successfully, you will need:
@@ -223,17 +271,18 @@ That command will sequentially run a number of checks. For it to run successfull
223
271
  - a GitHub API token that can read your GitHub repository's settings placed in `~/.roo_on_rails/github-token`
224
272
  - the Heroku toolbelt installed and logged in
225
273
  - admin privileges on the `roo-dd-bridge-production` (this will be addressed eventually)
226
- - checks are run sequentially for staging and then for production. The process halts at any non-fixable failing check. To process only specific environments, you can set a config variable while running the command, like so:
227
274
 
275
+ The command can automatically fix most of the failing checks automatically;
276
+ simply run it with the `--fix` flag:
277
+
278
+ ```
279
+ roo_on_rails harness --fix
228
280
  ```
229
- # the default behaviour:
230
- ROO_ON_RAILS_ENVIRONMENTS=staging,production bundle exec roo_on_rails
231
281
 
232
- # run checks only on staging:
233
- ROO_ON_RAILS_ENVIRONMENTS=staging bundle exec roo_on_rails
282
+ To run checks for only one environment, use the `--env` flag:
234
283
 
235
- # run checks only on production:
236
- ROO_ON_RAILS_ENVIRONMENTS=production bundle exec roo_on_rails
284
+ ```
285
+ roo_on_rails harness --env staging
237
286
  ```
238
287
 
239
288
 
@@ -78,6 +78,8 @@ class RiderPublisher < ApplicationPublisher
78
78
  end
79
79
  ```
80
80
 
81
+ `#publish?`, `#topics`, `#async?`, `#data` and `#timestamp` can be overriden; see [the `Publisher` class](lib/roo_on_rails_routemaster/publisher.rb) for the default implementations.
82
+
81
83
  ### Register the publishers with Routemaster
82
84
 
83
85
  The final step is to tell Routemaster that these publishers exist, so that it can listen to their events. We're going to do this in an initialiser:
data/exe/roo_on_rails CHANGED
@@ -3,12 +3,101 @@
3
3
  require 'rubygems'
4
4
  require 'roo_on_rails/config'
5
5
 
6
- if ARGV.include? 'sidekiq'
7
- require 'roo_on_rails/sidekiq/loader'
8
- RooOnRails::Sidekiq::Loader.run
9
- else
10
- require 'roo_on_rails/harness'
11
- module RooOnRails
12
- Harness.new(try_fix: true, context: Config.load).run
6
+ module RooOnRails
7
+ module CLI
8
+ class Base
9
+ attr_reader :argv
10
+
11
+ def initialize(argv)
12
+ @argv = argv
13
+ end
14
+
15
+ def usage
16
+ raise NotImplementedError
17
+ end
18
+
19
+ protected
20
+
21
+ def _log(message)
22
+ $stderr.puts message
23
+ end
24
+
25
+ def _assert_argv_length(range)
26
+ return if range.include?(argv.length)
27
+ _log 'Wrong number of arguments.'
28
+ _log "Usage: #{usage}"
29
+ exit 1
30
+ end
31
+ end
32
+
33
+ class Sidekiq < Base
34
+ def usage
35
+ 'roo_on_rails sidekiq'
36
+ end
37
+
38
+ def run
39
+ _assert_argv_length(0..0)
40
+ require 'roo_on_rails/sidekiq/loader'
41
+ RooOnRails::Sidekiq::Loader.run
42
+ end
43
+ end
44
+
45
+ class Harness < Base
46
+ def usage
47
+ 'roo_on_rails harness [-f|--fix]'
48
+ end
49
+
50
+ def run
51
+ _parser.parse!(argv)
52
+ _assert_argv_length(0..0)
53
+ require 'roo_on_rails/harness'
54
+ RooOnRails::Harness.new(try_fix: _options[:fix], context: Config.load).run
55
+ end
56
+
57
+ private
58
+
59
+ def _options
60
+ @options ||= { fix: false, env: nil }
61
+ end
62
+
63
+ def _parser
64
+ require 'optionparser'
65
+
66
+ OptionParser.new do |o|
67
+ o.banner = usage
68
+
69
+ o.on('-f', '--fix', 'Attempt to fix failed checks') do
70
+ _options[:fix] = true
71
+ end
72
+
73
+ o.on('-e', '--env', 'Application environments to check (comma-separated)') do |v|
74
+ _options[:env] = v
75
+ end
76
+ end
77
+ end
78
+ end
79
+
80
+ class Toplevel < Base
81
+ def usage
82
+ 'roo_on_rails [sidekiq|harness] [options]'
83
+ end
84
+
85
+ def run
86
+ case argv.first
87
+ when 'sidekiq' then
88
+ argv.shift
89
+ Sidekiq.new(argv).run
90
+ when 'harness', nil then
91
+ argv.shift
92
+ Harness.new(argv).run
93
+ else
94
+ _log 'Incorrect arguments.'
95
+ _log "Usage: #{usage}"
96
+ exit 1
97
+ end
98
+ end
99
+ end
13
100
  end
14
101
  end
102
+
103
+ RooOnRails::CLI::Toplevel.new(ARGV).run
@@ -24,18 +24,30 @@ module RooOnRails
24
24
  end
25
25
 
26
26
  def run
27
- resolve dependencies
28
- return true if @dry_run
27
+ dependency_status = resolve dependencies
28
+
29
29
  say intro
30
- call
30
+ unless dependency_status
31
+ final_fail! 'Unmet dependencies.'
32
+ return
33
+ end
34
+
35
+ return true if @dry_run
36
+
37
+ begin
38
+ call
39
+ rescue Failure
40
+ return false unless @fix
41
+ say "\t· attempting to fix", %i[yellow]
42
+ fix
43
+ @fix = false
44
+ say "\t· re-checking", %i[yellow]
45
+ retry
46
+ end
47
+
31
48
  true
32
- rescue Failure => e
33
- raise if e === FinalFailure
34
- raise unless @fix
35
- say "\t· attempting to fix", %i[yellow]
36
- fix
37
- say "\t· re-checking", %i[yellow]
38
- call
49
+ rescue FinalFailure
50
+ false
39
51
  end
40
52
 
41
53
  protected
@@ -44,7 +56,7 @@ module RooOnRails
44
56
 
45
57
  # Returns prerequisite checks. Can be overriden.
46
58
  def dependencies
47
- self.class.requires.map { |k|
59
+ @dependencies ||= self.class.requires.map { |k|
48
60
  k.new(fix: @fix, context: @context, shell: @shell, **@options)
49
61
  }
50
62
  end
@@ -54,11 +66,11 @@ module RooOnRails
54
66
  end
55
67
 
56
68
  def call
57
- fail! "this check wasn't implemented"
69
+ final_fail! "this check wasn't implemented"
58
70
  end
59
71
 
60
72
  def fix
61
- fail! "can't fix this on my own"
73
+ final_fail! "can't fix this on my own"
62
74
  end
63
75
 
64
76
  def pass(msg)
@@ -84,10 +96,15 @@ module RooOnRails
84
96
 
85
97
  # Run each dependency, then mark them as run.
86
98
  def resolve(deps)
87
- deps.each do |dep|
88
- context.deps ||= {}
89
- context.deps[dep.signature.join('/')] ||= dep.run
90
- end
99
+ context.deps ||= {}
100
+ deps.map { |dep|
101
+ sig = dep.signature.join('/')
102
+ if context.deps.key?(sig)
103
+ context.deps[sig]
104
+ else
105
+ context.deps[sig] = dep.run
106
+ end
107
+ }.to_a.all?
91
108
  end
92
109
  end
93
110
  end
@@ -13,15 +13,11 @@ module RooOnRails
13
13
 
14
14
  def call
15
15
  fail! "no playbook at #{LOCATION}." if playbook_missing?
16
- fail! 'playbook still contains FIXME template sections' if playbook_unfinished?
17
- pass 'playbook found, legion on-call engineers thank you.'
16
+ final_fail! 'playbook still contains FIXME template sections' if playbook_unfinished?
17
+ pass 'playbook found, legion on-call engineers thank you.'
18
18
  end
19
19
 
20
20
  def fix
21
- if !playbook_missing? && playbook_unfinished?
22
- fail! 'please add detail to your playbook, removing FIXME sections'
23
- end
24
-
25
21
  FileUtils.cp(
26
22
  File.join(__dir__, 'playbook_template.md'),
27
23
  LOCATION
@@ -1,5 +1,4 @@
1
1
  require 'roo_on_rails/checks/env_specific'
2
- require 'roo_on_rails/checks/github/branch_protection'
3
2
  require 'roo_on_rails/checks/heroku/app_exists'
4
3
  require 'roo_on_rails/checks/heroku/preboot_enabled'
5
4
  require 'roo_on_rails/checks/heroku/app_exists'
@@ -9,19 +8,18 @@ require 'roo_on_rails/checks/papertrail/all'
9
8
  module RooOnRails
10
9
  module Checks
11
10
  class Environment < EnvSpecific
12
- requires GitHub::BranchProtection
13
11
  requires Heroku::DrainsMetrics
14
12
  requires Heroku::PrebootEnabled
15
13
  requires Papertrail::All
16
14
 
17
15
  def call
18
- # nothing to do
16
+ pass 'all good'
19
17
  end
20
18
 
21
19
  protected
22
20
 
23
21
  def intro
24
- "Validated #{bold @env} environment"
22
+ "Validating #{bold @env} environment"
25
23
  end
26
24
  end
27
25
  end
@@ -0,0 +1,22 @@
1
+ require 'roo_on_rails/checks/base'
2
+ require 'roo_on_rails/checks/github/branch_protection'
3
+ require 'roo_on_rails/checks/sidekiq/settings'
4
+ require 'roo_on_rails/checks/documentation/playbook'
5
+
6
+ module RooOnRails
7
+ module Checks
8
+ class EnvironmentIndependent < Base
9
+ requires GitHub::BranchProtection
10
+ requires Documentation::Playbook
11
+ requires Sidekiq::Settings
12
+
13
+ def intro
14
+ 'Validating environment-independent setup'
15
+ end
16
+
17
+ def call
18
+ say 'All good', :green
19
+ end
20
+ end
21
+ end
22
+ end
@@ -16,6 +16,10 @@ module RooOnRails
16
16
  # Output context:
17
17
  # - heroku.app.{env}: an app name.
18
18
  class AppExists < EnvSpecific
19
+ ACCEPTABLE_ENV_NAMES = {
20
+ 'production' => %w(prd production),
21
+ 'staging' => %w(stg staging)
22
+ }.freeze
19
23
  requires Git::Origin, Heroku::Token
20
24
 
21
25
  def intro
@@ -25,7 +29,6 @@ module RooOnRails
25
29
  def call
26
30
  all_apps = client.app.list.map { |a| a['name'] }
27
31
  matches = all_apps.select { |a| candidates.include?(a) }
28
-
29
32
  if matches.empty?
30
33
  fail! "no apps with matching names detected"
31
34
  end
@@ -45,11 +48,15 @@ module RooOnRails
45
48
  context.app_name_stem || context.git_repo.delete('.')
46
49
  end
47
50
 
51
+ def env_suffixes
52
+ ACCEPTABLE_ENV_NAMES.fetch(env, [env])
53
+ end
54
+
48
55
  def candidates
49
56
  [
50
57
  ['deliveroo', 'roo', nil],
51
58
  [name_stem],
52
- [env],
59
+ env_suffixes,
53
60
  ].tap { |a|
54
61
  a.replace a.first.product(*a[1..-1])
55
62
  }.map { |c|
@@ -18,7 +18,7 @@ module RooOnRails
18
18
  requires Heroku::AppExists, MetricsBridgeConfigured
19
19
 
20
20
  def intro
21
- "Checking for metrics drain on #{bold app_name}"
21
+ 'Checking for metrics drain...'
22
22
  end
23
23
 
24
24
  def call
@@ -28,7 +28,7 @@ module RooOnRails
28
28
 
29
29
  fail! 'No matching drain found' if url.nil?
30
30
  final_fail! 'Misconfigured drain found' if url != drain_uri
31
- pass 'Drain is connected'
31
+ pass "Drain is connected to #{bold app_name}"
32
32
  end
33
33
 
34
34
  private
@@ -22,7 +22,7 @@ module RooOnRails
22
22
  BRIDGE_APP = 'roo-dd-bridge-production'.freeze
23
23
 
24
24
  def intro
25
- "Checking whether metrics bridge is configured for #{bold app_name}"
25
+ 'Checking whether metrics bridge is configured...'
26
26
  end
27
27
 
28
28
  def call
@@ -33,7 +33,7 @@ module RooOnRails
33
33
  fail! 'Bridge lacks credentials for this app' unless config[token_var]
34
34
  fail! 'Bridge lacks tags for this app' unless config[tags_var]
35
35
 
36
- pass 'Bridge is configured'
36
+ pass "Bridge is configured for #{bold app_name}"
37
37
  context.heroku.metric_bridge_token![env] = config[token_var]
38
38
  end
39
39
 
@@ -48,10 +48,14 @@ module RooOnRails
48
48
  token_var => SecureRandom.hex(16),
49
49
  app_list_var => app_list.to_a.join(',')
50
50
  )
51
+ rescue Excon::Error::Forbidden
52
+ fail! "You are missing 'operate' permissions for #{bold BRIDGE_APP}"
51
53
  end
52
54
 
53
55
  def current_config
54
56
  client.config_var.info_for_app(BRIDGE_APP)
57
+ rescue Excon::Error::Forbidden
58
+ fail! "You are missing 'deploy' permissions for #{bold BRIDGE_APP}"
55
59
  end
56
60
 
57
61
  def app_list_var
@@ -12,15 +12,15 @@ module RooOnRails
12
12
  requires Git::Origin, Heroku::AppExists
13
13
 
14
14
  def intro
15
- "Checking preboot status on #{bold app_name}"
15
+ 'Checking preboot status...'
16
16
  end
17
17
 
18
18
  def call
19
19
  status = client.app_feature.info(app_name, 'preboot')
20
20
  if status['enabled']
21
- pass 'preboot enabled'
21
+ pass "preboot enabled on #{bold app_name}"
22
22
  else
23
- fail! 'preboot disabled'
23
+ fail! "preboot disabled on #{bold app_name}"
24
24
  end
25
25
  end
26
26