roo_on_rails 1.10.0 → 1.11.0
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.
- checksums.yaml +4 -4
- data/.circleci/config.yml +672 -0
- data/.circleci/config.yml.erb +86 -0
- data/.gitignore +2 -1
- data/.rspec +2 -0
- data/CHANGELOG.md +27 -0
- data/README.md +75 -26
- data/README.routemaster_client.md +2 -0
- data/exe/roo_on_rails +96 -7
- data/lib/roo_on_rails/checks/base.rb +34 -17
- data/lib/roo_on_rails/checks/documentation/playbook.rb +2 -6
- data/lib/roo_on_rails/checks/environment.rb +2 -4
- data/lib/roo_on_rails/checks/environment_independent.rb +22 -0
- data/lib/roo_on_rails/checks/heroku/app_exists.rb +9 -2
- data/lib/roo_on_rails/checks/heroku/drains_metrics.rb +2 -2
- data/lib/roo_on_rails/checks/heroku/metrics_bridge_configured.rb +6 -2
- data/lib/roo_on_rails/checks/heroku/preboot_enabled.rb +3 -3
- data/lib/roo_on_rails/checks/papertrail/drain_exists.rb +4 -4
- data/lib/roo_on_rails/checks/papertrail/system_exists.rb +2 -2
- data/lib/roo_on_rails/checks/papertrail/system_named.rb +1 -1
- data/lib/roo_on_rails/checks/sidekiq/settings.rb +1 -1
- data/lib/roo_on_rails/checks/sidekiq/sidekiq.rb +1 -0
- data/lib/roo_on_rails/context_logging.rb +1 -0
- data/lib/roo_on_rails/harness.rb +8 -14
- data/lib/roo_on_rails/logfmt.rb +3 -15
- data/lib/roo_on_rails/logger.rb +104 -0
- data/lib/roo_on_rails/railties/database.rb +8 -6
- data/lib/roo_on_rails/railties/env.rb +11 -0
- data/lib/roo_on_rails/railties/google_oauth.rb +3 -7
- data/lib/roo_on_rails/railties/http.rb +31 -27
- data/lib/roo_on_rails/railties/logging.rb +16 -0
- data/lib/roo_on_rails/railties/new_relic.rb +15 -14
- data/lib/roo_on_rails/railties/rake_tasks.rb +0 -2
- data/lib/roo_on_rails/railties/routemaster.rb +9 -8
- data/lib/roo_on_rails/railties/sidekiq.rb +12 -8
- data/lib/roo_on_rails/routemaster/publisher.rb +14 -1
- data/lib/roo_on_rails/routemaster/publishers.rb +3 -3
- data/lib/roo_on_rails/sidekiq/process_scaling.rb +1 -1
- data/lib/roo_on_rails/tasks/db.rake +3 -2
- data/lib/roo_on_rails/version.rb +1 -1
- data/lib/roo_on_rails.rb +2 -1
- metadata +8 -7
- data/gemfiles/rails_3.gemfile.lock +0 -278
- data/gemfiles/rails_4.gemfile.lock +0 -293
- data/gemfiles/rails_5.gemfile.lock +0 -299
- data/gemfiles/rails_5_1.gemfile.lock +0 -300
- 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
data/.rspec
CHANGED
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` [](https://badge.fury.io/rb/roo_on_rails) [](https://badge.fury.io/rb/roo_on_rails) [](https://circleci.com/gh/deliveroo/roo_on_rails) [](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,
|
153
|
-
to add context to your logs which is output as
|
154
|
-
[logfmt](https://brandur.org/logfmt) key/value pairs
|
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
|
-
|
160
|
+
Rails.logger.info { 'hello world' }
|
161
|
+
```
|
158
162
|
|
159
|
-
|
163
|
+
From your console, the output will include the timestamp, severity, and message:
|
160
164
|
|
161
|
-
|
165
|
+
```
|
166
|
+
[2017-08-25 14:34:54.899] INFO | hello world
|
167
|
+
```
|
162
168
|
|
163
|
-
|
164
|
-
|
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
|
-
|
172
|
+
```
|
173
|
+
at=INFO msg="hello world"
|
173
174
|
```
|
174
175
|
|
175
|
-
|
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/
|
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
|
-
|
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
|
-
|
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
|
-
|
236
|
-
|
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
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
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
|
-
|
27
|
+
dependency_status = resolve dependencies
|
28
|
+
|
29
29
|
say intro
|
30
|
-
|
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
|
33
|
-
|
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
|
-
|
69
|
+
final_fail! "this check wasn't implemented"
|
58
70
|
end
|
59
71
|
|
60
72
|
def fix
|
61
|
-
|
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
|
88
|
-
|
89
|
-
|
90
|
-
|
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
|
-
|
17
|
-
pass
|
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
|
-
|
16
|
+
pass 'all good'
|
19
17
|
end
|
20
18
|
|
21
19
|
protected
|
22
20
|
|
23
21
|
def intro
|
24
|
-
"
|
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
|
-
|
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
|
-
|
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
|
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
|
-
|
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
|
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
|
-
|
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
|
21
|
+
pass "preboot enabled on #{bold app_name}"
|
22
22
|
else
|
23
|
-
fail!
|
23
|
+
fail! "preboot disabled on #{bold app_name}"
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|