ndr_dev_support 5.5.0 → 5.8.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +28 -0
- data/README.md +23 -2
- data/code_safety.yml +18 -14
- data/lib/minitest/rake_ci_plugin.rb +47 -7
- data/lib/ndr_dev_support/capistrano/svn_cache.rb +6 -0
- data/lib/ndr_dev_support/daemon/ci_server.rb +6 -2
- data/lib/ndr_dev_support/integration_testing.rb +3 -0
- data/lib/ndr_dev_support/integration_testing/flakey_tests.rb +55 -0
- data/lib/ndr_dev_support/rake_ci/brakeman_helper.rb +87 -2
- data/lib/ndr_dev_support/rake_ci/redmine/ticket_resolver.rb +11 -7
- data/lib/ndr_dev_support/version.rb +1 -1
- data/lib/tasks/ci/brakeman.rake +24 -37
- data/lib/tasks/ci/minitest.rake +3 -4
- data/lib/tasks/ci/redmine.rake +5 -4
- data/ndr_dev_support.gemspec +2 -2
- metadata +25 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 37a848fce50262a1d6c4b211e1e638317723bc9e45bbd4f8561bce0ce9e4ff1b
|
4
|
+
data.tar.gz: 2cc041c4aa592b91c8daea31b946f2909dcf46292d966e6a82e57cdf0b177403
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: be1ff5ae22a75022f0cabebb425e7d6dbfd34cf75e61856eaf40920446d38af62d9d39eba689f5aaa0cd815f11d42385842c97a6160c272f6b9cb7850921fe3b
|
7
|
+
data.tar.gz: f1a8251774d6917daf5d86ad22aa63f6afe2139ad4a106389a842dcd105fb0fe946ae490e0929fd73de4a442be9bac414150c49f1420cfbeeb947b60d6e14556
|
data/CHANGELOG.md
CHANGED
@@ -1,7 +1,35 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
*no unreleased changes*
|
3
3
|
|
4
|
+
## 5.8.1 / 2020-07-10
|
5
|
+
### Fixed
|
6
|
+
* Fix issue running `brakeman:fingerprint_details` task
|
7
|
+
|
8
|
+
## 5.8.0 / 2020-04-07
|
9
|
+
### Added
|
10
|
+
* Ability to select git CI branch by exporting `RAKE_CI_BRANCH_NAME`
|
11
|
+
|
12
|
+
## 5.7.1 / 2020-04-07
|
13
|
+
### Fixed
|
14
|
+
* Address issue updating redmine using commit message tags
|
15
|
+
|
16
|
+
## 5.7.0 / 2020-03-26
|
17
|
+
### Added
|
18
|
+
* Add `ci:brakeman:strict` alternative CI task. (#77)
|
19
|
+
* Send `brakeman_filtered_warnings` metrics. (#78)
|
20
|
+
* Allow redmine tickets to be updated (but not resolved) when the build fails (#73)
|
21
|
+
|
22
|
+
### Fixed
|
23
|
+
* Stop including asset compilation caches in the deployment archive.
|
24
|
+
* Ensure brakeman alerts aren't sent to Slack if they've been reviewed and filtered out
|
25
|
+
|
26
|
+
## 5.6.0 / 2020-02-14
|
27
|
+
### Added
|
28
|
+
* Add `flakey_test` to the minitest DSL, to allow sporadic failures to be retried
|
29
|
+
* CI: include minitest seed in slack output
|
30
|
+
|
4
31
|
## 5.5.0 / 2020-01-27
|
32
|
+
### Added
|
5
33
|
* bundle master RuboCop config, and allow it to be `required`
|
6
34
|
|
7
35
|
## 5.4.8 / 2020-01-24
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
## NdrDevSupport [![Build Status](https://travis-ci.org/PublicHealthEngland/ndr_dev_support.svg?branch=master)](https://travis-ci.org/PublicHealthEngland/ndr_dev_support) [![Gem Version](https://badge.fury.io/rb/ndr_dev_support.svg)](https://badge.fury.io/rb/ndr_dev_support)
|
1
|
+
## NdrDevSupport [![Maintainability](https://api.codeclimate.com/v1/badges/2b2a644964f2aa930f81/maintainability)](https://codeclimate.com/github/PublicHealthEngland/ndr_dev_support/maintainability) [![Build Status](https://travis-ci.org/PublicHealthEngland/ndr_dev_support.svg?branch=master)](https://travis-ci.org/PublicHealthEngland/ndr_dev_support) [![Gem Version](https://badge.fury.io/rb/ndr_dev_support.svg)](https://badge.fury.io/rb/ndr_dev_support)
|
2
2
|
|
3
3
|
This is the Public Health England (PHE) National Disease Registers (NDR) Developer Support ruby gem,
|
4
4
|
providing:
|
@@ -28,7 +28,7 @@ Or install it yourself as:
|
|
28
28
|
To add development support tasks (see below) to your project, add this line to your application's `Rakefile`:
|
29
29
|
|
30
30
|
```ruby
|
31
|
-
require 'ndr_dev_support/tasks'
|
31
|
+
require 'ndr_dev_support/tasks' if Rails.env.development? || Rails.env.test?
|
32
32
|
```
|
33
33
|
|
34
34
|
## Usage
|
@@ -135,6 +135,27 @@ Beyond standard Capybara testing DSL, ndr_dev_support bundles some additional fu
|
|
135
135
|
|
136
136
|
When using a headless browser for integration tests, the test database must be consistent between the test runner and the application being tested. With transactional tests in operation, this means that both must share a connection. It is up to the individual project to provide this facility; as of Rails 5.1, it is built in to the framework directly.
|
137
137
|
|
138
|
+
#### Flakey Tests
|
139
|
+
|
140
|
+
It is an unfortunate reality that sometimes tests are written that will fail sporadically. Whilst in such cases the test methodology should be addressed, investigations can be time-consuming.
|
141
|
+
Therefore, `ndr_dev_support` grudgingly provides "flakey test" support, to minimise disruption to CI pipelines whilst root causes are investigated.
|
142
|
+
|
143
|
+
```ruby
|
144
|
+
test 'thing that always passes' do
|
145
|
+
# reliable test
|
146
|
+
end
|
147
|
+
|
148
|
+
flakey_test 'thing that occassionally needs a second or third attempt' do
|
149
|
+
# less reliable test
|
150
|
+
end
|
151
|
+
|
152
|
+
flakey_test 'thing that often needs multiple attempts', attempts: 10 do
|
153
|
+
# really unreliable test (gulp...)
|
154
|
+
end
|
155
|
+
```
|
156
|
+
|
157
|
+
If tests still fail, they'll fail as normal. If tests pass after flakey failure, they'll be flagged to the RakeCI server, and rendered in purple on Slack.
|
158
|
+
|
138
159
|
### Deployment support
|
139
160
|
|
140
161
|
There are various capistrano plugins in the `ndr_dev_support/capistrano` directory - see each one for details.
|
data/code_safety.yml
CHANGED
@@ -19,7 +19,7 @@ file safety:
|
|
19
19
|
CHANGELOG.md:
|
20
20
|
comments:
|
21
21
|
reviewed_by: josh.pencheon
|
22
|
-
safe_revision:
|
22
|
+
safe_revision: b32e7980e8854b3021e513b2803f7424e78e28d9
|
23
23
|
CODE_OF_CONDUCT.md:
|
24
24
|
comments:
|
25
25
|
reviewed_by: timgentry
|
@@ -35,7 +35,7 @@ file safety:
|
|
35
35
|
README.md:
|
36
36
|
comments:
|
37
37
|
reviewed_by: josh.pencheon
|
38
|
-
safe_revision:
|
38
|
+
safe_revision: e389930b98976f20e3fc94c771e5c456b729f8cb
|
39
39
|
Rakefile:
|
40
40
|
comments:
|
41
41
|
reviewed_by: josh.pencheon
|
@@ -67,7 +67,7 @@ file safety:
|
|
67
67
|
lib/minitest/rake_ci_plugin.rb:
|
68
68
|
comments:
|
69
69
|
reviewed_by: josh.pencheon
|
70
|
-
safe_revision:
|
70
|
+
safe_revision: 958ef09c5cf50bb50348e6bff949e3e5989254f9
|
71
71
|
lib/ndr_dev_support.rb:
|
72
72
|
comments:
|
73
73
|
reviewed_by: josh.pencheon
|
@@ -99,7 +99,7 @@ file safety:
|
|
99
99
|
lib/ndr_dev_support/capistrano/svn_cache.rb:
|
100
100
|
comments:
|
101
101
|
reviewed_by: josh.pencheon
|
102
|
-
safe_revision:
|
102
|
+
safe_revision: 2baa360b06290775a961a7573fe08edd18f8312e
|
103
103
|
lib/ndr_dev_support/capistrano/sysadmin_scripts.rb:
|
104
104
|
comments:
|
105
105
|
reviewed_by: josh.pencheon
|
@@ -107,7 +107,7 @@ file safety:
|
|
107
107
|
lib/ndr_dev_support/daemon/ci_server.rb:
|
108
108
|
comments:
|
109
109
|
reviewed_by: josh.pencheon
|
110
|
-
safe_revision:
|
110
|
+
safe_revision: 3fdf010a91bd9927ef34e3df66b8a4bbbd20315a
|
111
111
|
lib/ndr_dev_support/daemon/stoppable.rb:
|
112
112
|
comments:
|
113
113
|
reviewed_by: josh.pencheon
|
@@ -115,7 +115,7 @@ file safety:
|
|
115
115
|
lib/ndr_dev_support/integration_testing.rb:
|
116
116
|
comments:
|
117
117
|
reviewed_by: josh.pencheon
|
118
|
-
safe_revision:
|
118
|
+
safe_revision: a2f178853da640112cf3063ca1d640157c9edb9f
|
119
119
|
lib/ndr_dev_support/integration_testing/drivers/chrome.rb:
|
120
120
|
comments:
|
121
121
|
reviewed_by: josh.pencheon
|
@@ -140,10 +140,14 @@ file safety:
|
|
140
140
|
comments:
|
141
141
|
reviewed_by: josh.pencheon
|
142
142
|
safe_revision: f1a32b1f2d1851b87a883dbf8620aa0e921e436c
|
143
|
+
lib/ndr_dev_support/integration_testing/flakey_tests.rb:
|
144
|
+
comments:
|
145
|
+
reviewed_by: josh.pencheon
|
146
|
+
safe_revision: a2f178853da640112cf3063ca1d640157c9edb9f
|
143
147
|
lib/ndr_dev_support/rake_ci/brakeman_helper.rb:
|
144
148
|
comments:
|
145
149
|
reviewed_by: josh.pencheon
|
146
|
-
safe_revision:
|
150
|
+
safe_revision: 053c9834ca5d402a1f8dc8d09257dc7075a5ec06
|
147
151
|
lib/ndr_dev_support/rake_ci/commit_cop.rb:
|
148
152
|
comments:
|
149
153
|
reviewed_by: josh.pencheon
|
@@ -175,7 +179,7 @@ file safety:
|
|
175
179
|
lib/ndr_dev_support/rake_ci/redmine/ticket_resolver.rb:
|
176
180
|
comments:
|
177
181
|
reviewed_by: josh.pencheon
|
178
|
-
safe_revision:
|
182
|
+
safe_revision: 788b8fc31952a6fb640101df96a370b21d269249
|
179
183
|
lib/ndr_dev_support/rake_ci/simple_cov_helper.rb:
|
180
184
|
comments:
|
181
185
|
reviewed_by: timgentry
|
@@ -211,7 +215,7 @@ file safety:
|
|
211
215
|
lib/ndr_dev_support/version.rb:
|
212
216
|
comments:
|
213
217
|
reviewed_by: josh.pencheon
|
214
|
-
safe_revision:
|
218
|
+
safe_revision: b32e7980e8854b3021e513b2803f7424e78e28d9
|
215
219
|
lib/tasks/audit_code.rake:
|
216
220
|
comments: Identical to the version reviewed by josh.pencheon when contained within
|
217
221
|
ndr_support
|
@@ -220,7 +224,7 @@ file safety:
|
|
220
224
|
lib/tasks/ci/brakeman.rake:
|
221
225
|
comments:
|
222
226
|
reviewed_by: josh.pencheon
|
223
|
-
safe_revision:
|
227
|
+
safe_revision: fe7dfc7f1775e8b85ae6968e8f475b9e930addf7
|
224
228
|
lib/tasks/ci/bundle_audit.rake:
|
225
229
|
comments:
|
226
230
|
reviewed_by: josh.pencheon
|
@@ -244,7 +248,7 @@ file safety:
|
|
244
248
|
lib/tasks/ci/minitest.rake:
|
245
249
|
comments:
|
246
250
|
reviewed_by: josh.pencheon
|
247
|
-
safe_revision:
|
251
|
+
safe_revision: 12aad1254186ee9ce0fde263bf8dccf46cdfebe2
|
248
252
|
lib/tasks/ci/notes.rake:
|
249
253
|
comments:
|
250
254
|
reviewed_by: timgentry
|
@@ -256,7 +260,7 @@ file safety:
|
|
256
260
|
lib/tasks/ci/redmine.rake:
|
257
261
|
comments:
|
258
262
|
reviewed_by: josh.pencheon
|
259
|
-
safe_revision:
|
263
|
+
safe_revision: 12aad1254186ee9ce0fde263bf8dccf46cdfebe2
|
260
264
|
lib/tasks/ci/rugged.rake:
|
261
265
|
comments:
|
262
266
|
reviewed_by: josh.pencheon
|
@@ -284,7 +288,7 @@ file safety:
|
|
284
288
|
ndr_dev_support.gemspec:
|
285
289
|
comments:
|
286
290
|
reviewed_by: josh.pencheon
|
287
|
-
safe_revision:
|
291
|
+
safe_revision: f4c1ea57d3eb817783fdc47a16169d215f9788a6
|
288
292
|
test/daemon/ci_server_test.rb:
|
289
293
|
comments:
|
290
294
|
reviewed_by: josh.pencheon
|
@@ -312,7 +316,7 @@ file safety:
|
|
312
316
|
test/rake_ci/redmine/ticket_resolver_test.rb:
|
313
317
|
comments:
|
314
318
|
reviewed_by: josh.pencheon
|
315
|
-
safe_revision:
|
319
|
+
safe_revision: 12aad1254186ee9ce0fde263bf8dccf46cdfebe2
|
316
320
|
test/test_helper.rb:
|
317
321
|
comments:
|
318
322
|
reviewed_by: josh.pencheon
|
@@ -5,12 +5,35 @@ require 'ndr_dev_support/rake_ci/concerns/commit_metadata_persistable'
|
|
5
5
|
|
6
6
|
# The plugin needs to extend Minitest
|
7
7
|
module Minitest
|
8
|
-
def self.plugin_rake_ci_init(
|
9
|
-
reporter << RakeCIReporter.new if RakeCIReporter.enabled?
|
8
|
+
def self.plugin_rake_ci_init(options)
|
9
|
+
reporter << RakeCIReporter.new(options[:io], options) if RakeCIReporter.enabled?
|
10
|
+
end
|
11
|
+
|
12
|
+
# Intermediate Reporter than can also track flakey failures
|
13
|
+
class FlakeyStatisticsReporter < StatisticsReporter
|
14
|
+
attr_accessor :flakey_results
|
15
|
+
|
16
|
+
def initialize(*)
|
17
|
+
super
|
18
|
+
|
19
|
+
self.flakey_results = []
|
20
|
+
end
|
21
|
+
|
22
|
+
def record(result)
|
23
|
+
super
|
24
|
+
|
25
|
+
return unless result.respond_to?(:flakes)
|
26
|
+
|
27
|
+
flakey_results << result if result.flakes.any?
|
28
|
+
end
|
29
|
+
|
30
|
+
def flakes
|
31
|
+
flakey_results.sum { |result| result.flakes.length }
|
32
|
+
end
|
10
33
|
end
|
11
34
|
|
12
35
|
# RakeCI Minitest Reporter
|
13
|
-
class RakeCIReporter <
|
36
|
+
class RakeCIReporter < FlakeyStatisticsReporter
|
14
37
|
def self.enable!
|
15
38
|
@enabled = true
|
16
39
|
end
|
@@ -55,6 +78,10 @@ module Minitest
|
|
55
78
|
snippets_for results.reject(&:skipped?).reject(&:error?)
|
56
79
|
end
|
57
80
|
|
81
|
+
def flake_snippets
|
82
|
+
snippets_for flakey_results
|
83
|
+
end
|
84
|
+
|
58
85
|
# Adapted from Rails' TestUnit reporter
|
59
86
|
def snippets_for(results, limit = 5)
|
60
87
|
executable = defined?(Rails) ? 'bin/rails test ' : 'bundle exec rake test TEST='
|
@@ -78,7 +105,7 @@ module Minitest
|
|
78
105
|
def current_statistics
|
79
106
|
@current_statistics ||= {
|
80
107
|
total_time: total_time, runs: count, assertions: assertions, failures: failures,
|
81
|
-
errors: errors, skips: skips
|
108
|
+
errors: errors, skips: skips, flakes: flakes
|
82
109
|
}
|
83
110
|
end
|
84
111
|
|
@@ -106,6 +133,7 @@ module Minitest
|
|
106
133
|
@current_attachments << failures_attachment if failures.positive?
|
107
134
|
@current_attachments << errors_attachment if errors.positive?
|
108
135
|
@current_attachments << pass_attachment if passing?
|
136
|
+
@current_attachments << flakes_attachment if flakes.positive?
|
109
137
|
@current_attachments
|
110
138
|
end
|
111
139
|
|
@@ -113,7 +141,15 @@ module Minitest
|
|
113
141
|
{
|
114
142
|
color: 'danger',
|
115
143
|
text: 'test failure'.pluralize(failures) + failure_snippets,
|
116
|
-
footer:
|
144
|
+
footer: footer
|
145
|
+
}
|
146
|
+
end
|
147
|
+
|
148
|
+
def flakes_attachment
|
149
|
+
{
|
150
|
+
color: '#bb44ff',
|
151
|
+
text: 'flakey test'.pluralize(flakes) + flake_snippets,
|
152
|
+
footer: footer
|
117
153
|
}
|
118
154
|
end
|
119
155
|
|
@@ -121,7 +157,7 @@ module Minitest
|
|
121
157
|
{
|
122
158
|
color: 'warning',
|
123
159
|
text: 'test error'.pluralize(errors) + error_snippets,
|
124
|
-
footer:
|
160
|
+
footer: footer
|
125
161
|
}
|
126
162
|
end
|
127
163
|
|
@@ -129,7 +165,7 @@ module Minitest
|
|
129
165
|
{
|
130
166
|
color: 'good',
|
131
167
|
text: newly_passing? ? 'Tests now pass! :tada:' : 'Tests passed',
|
132
|
-
footer:
|
168
|
+
footer: footer
|
133
169
|
}
|
134
170
|
end
|
135
171
|
|
@@ -150,5 +186,9 @@ module Minitest
|
|
150
186
|
def name
|
151
187
|
'minitest'
|
152
188
|
end
|
189
|
+
|
190
|
+
def footer
|
191
|
+
"bundle exec rake ci:minitest --seed #{options[:seed]}"
|
192
|
+
end
|
153
193
|
end
|
154
194
|
end
|
@@ -17,7 +17,13 @@ Capistrano::Configuration.instance(:must_exist).load do
|
|
17
17
|
system("rm -rf #{cache}")
|
18
18
|
end
|
19
19
|
end
|
20
|
+
|
21
|
+
desc 'Ensures compilation artefacts are removed from the compressed archive sent to the server'
|
22
|
+
task :augment_copy_exclude do
|
23
|
+
set :copy_exclude, (fetch(:copy_exclude) || []) + %w[node_modules tmp/*]
|
24
|
+
end
|
20
25
|
end
|
21
26
|
|
27
|
+
before 'deploy:update_code', 'ndr_dev_support:augment_copy_exclude'
|
22
28
|
before 'deploy:update_code', 'ndr_dev_support:remove_svn_cache_if_needed'
|
23
29
|
end
|
@@ -48,7 +48,7 @@ module NdrDevSupport
|
|
48
48
|
|
49
49
|
git_fetch
|
50
50
|
git_discard_changes
|
51
|
-
git_checkout(
|
51
|
+
git_checkout(git_branch_name)
|
52
52
|
|
53
53
|
objectids_between_master_and_remote.each do |oid|
|
54
54
|
log("testing #{oid}...")
|
@@ -72,6 +72,10 @@ module NdrDevSupport
|
|
72
72
|
raise exception
|
73
73
|
end
|
74
74
|
|
75
|
+
def git_branch_name
|
76
|
+
ENV.fetch('RAKE_CI_BRANCH_NAME', MASTER_BRANCH_NAME)
|
77
|
+
end
|
78
|
+
|
75
79
|
def git_fetch
|
76
80
|
system(svn_remote? ? 'git svn fetch' : 'git fetch')
|
77
81
|
end
|
@@ -117,7 +121,7 @@ module NdrDevSupport
|
|
117
121
|
def objectids_between_master_and_remote
|
118
122
|
walker = Rugged::Walker.new(@repo)
|
119
123
|
walker.push(repo.branches[remote_branch].target_id)
|
120
|
-
current_target_id = repo.branches[
|
124
|
+
current_target_id = repo.branches[git_branch_name].target_id
|
121
125
|
|
122
126
|
revisions = []
|
123
127
|
# walk backwards from the most recent commit, breaking at the current one
|
@@ -18,6 +18,9 @@ end
|
|
18
18
|
# Include our custom DSL extensions, that also cover screenshotting:
|
19
19
|
require 'ndr_dev_support/integration_testing/dsl'
|
20
20
|
|
21
|
+
# Include support for retrying tests that sporadically fail:
|
22
|
+
require 'ndr_dev_support/integration_testing/flakey_tests'
|
23
|
+
|
21
24
|
# Keeps the selenium webdrivers automatically updated:
|
22
25
|
require 'webdrivers'
|
23
26
|
Webdrivers.cache_time = 24.hours
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module NdrDevSupport
|
2
|
+
module IntegrationTesting
|
3
|
+
# Grudging handling of flakey integration tests. Allows tests to be declared
|
4
|
+
# with `flakey_test`. Our CI reporter gathers information on flakey failures.
|
5
|
+
module FlakeyTests
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
class_attribute :attempts_per_test, default: {}
|
10
|
+
end
|
11
|
+
|
12
|
+
class_methods do
|
13
|
+
def flakey_test(description, attempts: 3, &block)
|
14
|
+
test(description, &block).tap do |test_name|
|
15
|
+
self.attempts_per_test = attempts_per_test.merge(test_name.to_s => attempts)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def flakes
|
21
|
+
@flakes ||= []
|
22
|
+
end
|
23
|
+
|
24
|
+
def run
|
25
|
+
attempts_remaining = attempts_per_test[name]
|
26
|
+
return super unless attempts_remaining
|
27
|
+
|
28
|
+
previous_failure = failures.last
|
29
|
+
failed_attempts = []
|
30
|
+
|
31
|
+
loop do
|
32
|
+
break if attempts_remaining < 1
|
33
|
+
|
34
|
+
super
|
35
|
+
|
36
|
+
# No failure was added; we passed!
|
37
|
+
break if failures.last == previous_failure
|
38
|
+
|
39
|
+
# Ran out of attempts:
|
40
|
+
break if (attempts_remaining -= 1) < 1
|
41
|
+
|
42
|
+
# Loop round and have another go:
|
43
|
+
failed_attempts << failures.pop
|
44
|
+
end
|
45
|
+
|
46
|
+
# Attempts were only flakey if we eventually passed:
|
47
|
+
flakes.concat(failed_attempts) if failures.last == previous_failure
|
48
|
+
|
49
|
+
self
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
ActionDispatch::IntegrationTest.include(NdrDevSupport::IntegrationTesting::FlakeyTests)
|
@@ -10,7 +10,9 @@ module NdrDevSupport
|
|
10
10
|
|
11
11
|
attr_reader :new_fingerprints, :old_fingerprints, :tracker
|
12
12
|
|
13
|
-
def run
|
13
|
+
def run(strict:)
|
14
|
+
@strict = strict
|
15
|
+
|
14
16
|
@tracker = ::Brakeman.run(app_path: '.')
|
15
17
|
|
16
18
|
last_commit_fingerprints = load_last_commit_data
|
@@ -22,10 +24,16 @@ module NdrDevSupport
|
|
22
24
|
end
|
23
25
|
end
|
24
26
|
|
27
|
+
# All warnings (including those we've flagged as false positives)
|
25
28
|
def warnings
|
26
29
|
@tracker.warnings
|
27
30
|
end
|
28
31
|
|
32
|
+
# Only the warnings we haven't flagged as false positives (i.e. the outstanding ones)
|
33
|
+
def filtered_warnings
|
34
|
+
@tracker.filtered_warnings
|
35
|
+
end
|
36
|
+
|
29
37
|
def warning_counts_by_confidence
|
30
38
|
return @warning_counts_by_confidence if @warning_counts_by_confidence
|
31
39
|
|
@@ -36,13 +44,90 @@ module NdrDevSupport
|
|
36
44
|
@warning_counts_by_confidence
|
37
45
|
end
|
38
46
|
|
47
|
+
def filtered_warning_counts_by_confidence
|
48
|
+
return @filtered_warning_counts_by_confidence if @filtered_warning_counts_by_confidence
|
49
|
+
|
50
|
+
@filtered_warning_counts_by_confidence = {}
|
51
|
+
filtered_warnings.group_by(&:confidence).each do |confidence, grouped_warnings|
|
52
|
+
@filtered_warning_counts_by_confidence[confidence] = grouped_warnings.count
|
53
|
+
end
|
54
|
+
@filtered_warning_counts_by_confidence
|
55
|
+
end
|
56
|
+
|
39
57
|
def current_fingerprints
|
40
|
-
@current_fingerprints ||=
|
58
|
+
@current_fingerprints ||= filtered_warnings.map(&:fingerprint).to_set
|
41
59
|
end
|
42
60
|
|
43
61
|
def save_current_fingerprints
|
44
62
|
save_current_commit_data(current_fingerprints)
|
45
63
|
end
|
64
|
+
|
65
|
+
def metrics
|
66
|
+
metrics = []
|
67
|
+
|
68
|
+
::Brakeman::Warning::TEXT_CONFIDENCE.each do |confidence, text|
|
69
|
+
overall_metric = {
|
70
|
+
name: 'brakeman_warnings',
|
71
|
+
type: :gauge,
|
72
|
+
label_set: { confidence: text },
|
73
|
+
value: warning_counts_by_confidence[confidence] || 0
|
74
|
+
}
|
75
|
+
filtered_metric = {
|
76
|
+
name: 'brakeman_filtered_warnings',
|
77
|
+
type: :gauge,
|
78
|
+
label_set: { confidence: text },
|
79
|
+
value: filtered_warning_counts_by_confidence[confidence] || 0
|
80
|
+
}
|
81
|
+
metrics << overall_metric << filtered_metric
|
82
|
+
puts overall_metric.inspect
|
83
|
+
puts filtered_metric.inspect
|
84
|
+
end
|
85
|
+
|
86
|
+
metrics
|
87
|
+
end
|
88
|
+
|
89
|
+
def attachments
|
90
|
+
attachments = []
|
91
|
+
|
92
|
+
if @strict && current_fingerprints.any?
|
93
|
+
# all warnings found
|
94
|
+
attachment = {
|
95
|
+
color: 'danger',
|
96
|
+
title: "#{current_fingerprints.size} Brakeman warning(s) :rotating_light:",
|
97
|
+
text: '_Brakeman_ warning fingerprint(s):' \
|
98
|
+
"```#{current_fingerprints.to_a.join("\n")}```",
|
99
|
+
footer: 'bundle exec rake ci:brakeman:fingerprint_details FINGERPRINTS=...',
|
100
|
+
mrkdwn_in: ['text']
|
101
|
+
}
|
102
|
+
attachments << attachment
|
103
|
+
puts attachment.inspect
|
104
|
+
elsif new_fingerprints.any?
|
105
|
+
# new warnings found
|
106
|
+
attachment = {
|
107
|
+
color: 'danger',
|
108
|
+
title: "#{new_fingerprints.size} new Brakeman warning(s) :rotating_light:",
|
109
|
+
text: '_Brakeman_ warning fingerprint(s):' \
|
110
|
+
"```#{new_fingerprints.to_a.join("\n")}```",
|
111
|
+
footer: 'bundle exec rake ci:brakeman:fingerprint_details FINGERPRINTS=...',
|
112
|
+
mrkdwn_in: ['text']
|
113
|
+
}
|
114
|
+
attachments << attachment
|
115
|
+
puts attachment.inspect
|
116
|
+
end
|
117
|
+
|
118
|
+
unless old_fingerprints.empty?
|
119
|
+
# old warnings missing
|
120
|
+
attachment = {
|
121
|
+
color: 'good',
|
122
|
+
title: "#{old_fingerprints.size} Brakeman warning(s) resolved :+1:",
|
123
|
+
footer: 'bundle exec rake ci:brakeman'
|
124
|
+
}
|
125
|
+
attachments << attachment
|
126
|
+
puts attachment.inspect
|
127
|
+
end
|
128
|
+
|
129
|
+
attachments
|
130
|
+
end
|
46
131
|
end
|
47
132
|
end
|
48
133
|
end
|
@@ -36,13 +36,13 @@ module NdrDevSupport
|
|
36
36
|
@hostname = hostname
|
37
37
|
end
|
38
38
|
|
39
|
-
def process_commit(user, revision, message)
|
39
|
+
def process_commit(user, revision, message, tests_passed)
|
40
40
|
resolved_tickets = []
|
41
41
|
|
42
42
|
each_ticket_from(message) do |ticket, resolved|
|
43
|
-
update_ticket(message, user, revision, ticket, resolved)
|
43
|
+
update_ticket(message, user, revision, ticket, resolved, tests_passed)
|
44
44
|
|
45
|
-
resolved_tickets << ticket if resolved
|
45
|
+
resolved_tickets << ticket if resolved && tests_passed
|
46
46
|
end
|
47
47
|
|
48
48
|
resolved_tickets
|
@@ -62,13 +62,17 @@ module NdrDevSupport
|
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
65
|
-
def update_payload(message, user, revision, ticket_closed, resolved)
|
65
|
+
def update_payload(message, user, revision, ticket_closed, resolved, tests_passed)
|
66
|
+
if resolved && !ticket_closed && !tests_passed
|
67
|
+
message += "\n\n*Automated tests did not pass successfully, so ticket status left unchanged.*"
|
68
|
+
end
|
69
|
+
|
66
70
|
payload = {
|
67
71
|
notes: "_#{resolved ? 'Resolved' : 'Referenced'} by #{user} in #{revision}_:" \
|
68
72
|
"#{resolved ? message.gsub(CLOSE_REGEX, '+\1+') : message}"
|
69
73
|
}
|
70
74
|
|
71
|
-
payload[:status_id] = 3 if resolved && !ticket_closed
|
75
|
+
payload[:status_id] = 3 if resolved && !ticket_closed && tests_passed
|
72
76
|
payload
|
73
77
|
end
|
74
78
|
|
@@ -82,8 +86,8 @@ module NdrDevSupport
|
|
82
86
|
@http
|
83
87
|
end
|
84
88
|
|
85
|
-
def update_ticket(message, user, revision, ticket, resolved)
|
86
|
-
payload = update_payload(message, user, revision, ticket_closed?(ticket), resolved)
|
89
|
+
def update_ticket(message, user, revision, ticket, resolved, tests_passed)
|
90
|
+
payload = update_payload(message, user, revision, ticket_closed?(ticket), resolved, tests_passed)
|
87
91
|
|
88
92
|
http.send_request('PUT',
|
89
93
|
"/issues/#{ticket.to_i}.json",
|
data/lib/tasks/ci/brakeman.rake
CHANGED
@@ -11,48 +11,35 @@ namespace :ci do
|
|
11
11
|
|
12
12
|
brakeman = NdrDevSupport::RakeCI::BrakemanHelper.new
|
13
13
|
brakeman.commit = @commit
|
14
|
-
brakeman.run
|
15
|
-
|
16
|
-
Brakeman::Warning::TEXT_CONFIDENCE.each do |confidence, text|
|
17
|
-
metric = {
|
18
|
-
name: 'brakeman_warnings',
|
19
|
-
type: :gauge,
|
20
|
-
label_set: { confidence: text },
|
21
|
-
value: brakeman.warning_counts_by_confidence[confidence] || 0
|
22
|
-
}
|
23
|
-
@metrics << metric
|
24
|
-
puts metric.inspect
|
25
|
-
end
|
26
|
-
|
27
|
-
unless brakeman.new_fingerprints.empty?
|
28
|
-
# new warnings found
|
29
|
-
attachment = {
|
30
|
-
color: 'danger',
|
31
|
-
title: "#{brakeman.new_fingerprints.size} new Brakeman warning(s) :rotating_light:",
|
32
|
-
text: '_Brakeman_ warning fingerprint(s):' \
|
33
|
-
"```#{brakeman.new_fingerprints.to_a.join("\n")}```",
|
34
|
-
footer: 'bundle exec rake ci:brakeman:fingerprint_details FINGERPRINTS=...',
|
35
|
-
mrkdwn_in: ['text']
|
36
|
-
}
|
37
|
-
@attachments << attachment
|
38
|
-
puts attachment.inspect
|
39
|
-
end
|
14
|
+
brakeman.run(strict: false)
|
40
15
|
|
41
|
-
|
42
|
-
|
43
|
-
attachment = {
|
44
|
-
color: 'good',
|
45
|
-
title: "#{brakeman.old_fingerprints.size} Brakeman warning(s) resolved :+1:",
|
46
|
-
footer: 'bundle exec rake ci:brakeman'
|
47
|
-
}
|
48
|
-
@attachments << attachment
|
49
|
-
puts attachment.inspect
|
50
|
-
end
|
16
|
+
@metrics.concat(brakeman.metrics)
|
17
|
+
@attachments.concat(brakeman.attachments)
|
51
18
|
|
52
19
|
brakeman.save_current_fingerprints
|
53
20
|
end
|
54
21
|
|
55
22
|
namespace :brakeman do
|
23
|
+
desc "Brakeman (strict mode - all issues must be reviewed by Brakeman's interactive mode)"
|
24
|
+
task strict: 'ci:rugged:setup' do
|
25
|
+
next unless defined?(Rails)
|
26
|
+
|
27
|
+
require 'ndr_dev_support/rake_ci/brakeman_helper'
|
28
|
+
# Usage: bundle exec rake ci:brakeman:strict
|
29
|
+
|
30
|
+
@metrics ||= []
|
31
|
+
@attachments ||= []
|
32
|
+
|
33
|
+
brakeman = NdrDevSupport::RakeCI::BrakemanHelper.new
|
34
|
+
brakeman.commit = @commit
|
35
|
+
brakeman.run(strict: true)
|
36
|
+
|
37
|
+
@metrics.concat(brakeman.metrics)
|
38
|
+
@attachments.concat(brakeman.attachments)
|
39
|
+
|
40
|
+
brakeman.save_current_fingerprints
|
41
|
+
end
|
42
|
+
|
56
43
|
desc 'Brakeman fingerprint details'
|
57
44
|
task fingerprint_details: 'ci:rugged:setup' do
|
58
45
|
# Usage: bundle exec rake ci:brakeman:fingerprint_details FINGERPRINTS=fp1,fp2,...
|
@@ -70,7 +57,7 @@ namespace :ci do
|
|
70
57
|
|
71
58
|
brakeman = NdrDevSupport::RakeCI::BrakemanHelper.new
|
72
59
|
brakeman.commit = @commit
|
73
|
-
brakeman.run
|
60
|
+
brakeman.run(strict: false)
|
74
61
|
|
75
62
|
text_reporter = Brakeman::Report::Text.new(brakeman.tracker)
|
76
63
|
|
data/lib/tasks/ci/minitest.rake
CHANGED
@@ -47,10 +47,9 @@ namespace :ci do
|
|
47
47
|
# Test(s) ran
|
48
48
|
Rake::Task['ci:simplecov:process'].invoke
|
49
49
|
|
50
|
-
if
|
51
|
-
|
52
|
-
|
53
|
-
Rake::Task['ci:redmine:update_tickets'].invoke
|
50
|
+
if Rake::Task.task_defined?('ci:redmine:update_tickets')
|
51
|
+
tests_passed = hash[:statistics][:failures].zero? && hash[:statistics][:errors].zero?
|
52
|
+
Rake::Task['ci:redmine:update_tickets'].invoke(tests_passed)
|
54
53
|
end
|
55
54
|
|
56
55
|
@attachments.concat(hash[:attachments])
|
data/lib/tasks/ci/redmine.rake
CHANGED
@@ -12,7 +12,7 @@ namespace :ci do
|
|
12
12
|
end
|
13
13
|
|
14
14
|
desc 'Update Redmine tickets'
|
15
|
-
task update_tickets: ['ci:rugged:setup', 'ci:redmine:setup'] do
|
15
|
+
task :update_tickets, [:tests_passed] => ['ci:rugged:setup', 'ci:redmine:setup'] do |task, args|
|
16
16
|
api_key = ENV['REDMINE_API_KEY']
|
17
17
|
hostname = ENV['REDMINE_HOSTNAME']
|
18
18
|
next if api_key.nil? || hostname.nil?
|
@@ -27,7 +27,7 @@ namespace :ci do
|
|
27
27
|
ticket_resolver = NdrDevSupport::RakeCI::Redmine::TicketResolver.new(api_key, hostname)
|
28
28
|
resolved_tickets = ticket_resolver.process_commit(@commit.author[:name],
|
29
29
|
@friendly_revision_name,
|
30
|
-
@commit.message)
|
30
|
+
@commit.message, args.tests_passed)
|
31
31
|
rescue
|
32
32
|
@attachments << {
|
33
33
|
color: 'danger',
|
@@ -41,7 +41,8 @@ namespace :ci do
|
|
41
41
|
resolved_tickets.map! { |ticket_id| "https://#{hostname}/issues/#{ticket_id}" }
|
42
42
|
|
43
43
|
old_attachment = @attachments.detect { |att| att[:text] =~ /Tests( now)? pass/ }
|
44
|
-
basic_text
|
44
|
+
basic_text = old_attachment.try(:[], :text) || 'Tests passed'
|
45
|
+
footer = old_attachment.try(:[], :footer) || 'bundle exec rake ci:minitest'
|
45
46
|
|
46
47
|
@attachments.delete(old_attachment) if old_attachment
|
47
48
|
|
@@ -51,7 +52,7 @@ namespace :ci do
|
|
51
52
|
title: "#{issue_s.capitalize} Resolved",
|
52
53
|
text: "#{basic_text}, so #{issue_s} #{resolved_tickets.join(', ')}" \
|
53
54
|
" #{resolved_tickets.count == 1 ? 'has' : 'have'} been resolved",
|
54
|
-
footer:
|
55
|
+
footer: footer,
|
55
56
|
mrkdwn_in: ['text']
|
56
57
|
}
|
57
58
|
@attachments << attachment
|
data/ndr_dev_support.gemspec
CHANGED
@@ -36,6 +36,7 @@ Gem::Specification.new do |spec|
|
|
36
36
|
# Integration test dependencies:
|
37
37
|
spec.add_dependency 'capybara', '>= 3.20'
|
38
38
|
spec.add_dependency 'capybara-screenshot'
|
39
|
+
spec.add_dependency 'minitest', '~> 5.0'
|
39
40
|
spec.add_dependency 'poltergeist', '>= 1.8.0'
|
40
41
|
spec.add_dependency 'selenium-webdriver'
|
41
42
|
spec.add_dependency 'show_me_the_cookies'
|
@@ -55,7 +56,6 @@ Gem::Specification.new do |spec|
|
|
55
56
|
spec.add_dependency 'capistrano', '~> 2.15'
|
56
57
|
|
57
58
|
spec.add_development_dependency 'bundler'
|
58
|
-
spec.add_development_dependency 'minitest', '~> 5.0'
|
59
59
|
spec.add_development_dependency 'mocha'
|
60
|
-
spec.add_development_dependency 'rake', '~>
|
60
|
+
spec.add_development_dependency 'rake', '~> 12.3', '>= 12.3.3'
|
61
61
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ndr_dev_support
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.
|
4
|
+
version: 5.8.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- NCRS Development Team
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-07-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: pry
|
@@ -136,6 +136,20 @@ dependencies:
|
|
136
136
|
- - ">="
|
137
137
|
- !ruby/object:Gem::Version
|
138
138
|
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: minitest
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - "~>"
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '5.0'
|
146
|
+
type: :runtime
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - "~>"
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '5.0'
|
139
153
|
- !ruby/object:Gem::Dependency
|
140
154
|
name: poltergeist
|
141
155
|
requirement: !ruby/object:Gem::Requirement
|
@@ -332,20 +346,6 @@ dependencies:
|
|
332
346
|
- - ">="
|
333
347
|
- !ruby/object:Gem::Version
|
334
348
|
version: '0'
|
335
|
-
- !ruby/object:Gem::Dependency
|
336
|
-
name: minitest
|
337
|
-
requirement: !ruby/object:Gem::Requirement
|
338
|
-
requirements:
|
339
|
-
- - "~>"
|
340
|
-
- !ruby/object:Gem::Version
|
341
|
-
version: '5.0'
|
342
|
-
type: :development
|
343
|
-
prerelease: false
|
344
|
-
version_requirements: !ruby/object:Gem::Requirement
|
345
|
-
requirements:
|
346
|
-
- - "~>"
|
347
|
-
- !ruby/object:Gem::Version
|
348
|
-
version: '5.0'
|
349
349
|
- !ruby/object:Gem::Dependency
|
350
350
|
name: mocha
|
351
351
|
requirement: !ruby/object:Gem::Requirement
|
@@ -366,14 +366,20 @@ dependencies:
|
|
366
366
|
requirements:
|
367
367
|
- - "~>"
|
368
368
|
- !ruby/object:Gem::Version
|
369
|
-
version: '
|
369
|
+
version: '12.3'
|
370
|
+
- - ">="
|
371
|
+
- !ruby/object:Gem::Version
|
372
|
+
version: 12.3.3
|
370
373
|
type: :development
|
371
374
|
prerelease: false
|
372
375
|
version_requirements: !ruby/object:Gem::Requirement
|
373
376
|
requirements:
|
374
377
|
- - "~>"
|
375
378
|
- !ruby/object:Gem::Version
|
376
|
-
version: '
|
379
|
+
version: '12.3'
|
380
|
+
- - ">="
|
381
|
+
- !ruby/object:Gem::Version
|
382
|
+
version: 12.3.3
|
377
383
|
description: Provides support to developers of NDR projects
|
378
384
|
email: []
|
379
385
|
executables: []
|
@@ -415,6 +421,7 @@ files:
|
|
415
421
|
- lib/ndr_dev_support/integration_testing/drivers/poltergeist.rb
|
416
422
|
- lib/ndr_dev_support/integration_testing/drivers/switchable.rb
|
417
423
|
- lib/ndr_dev_support/integration_testing/dsl.rb
|
424
|
+
- lib/ndr_dev_support/integration_testing/flakey_tests.rb
|
418
425
|
- lib/ndr_dev_support/rake_ci/brakeman_helper.rb
|
419
426
|
- lib/ndr_dev_support/rake_ci/commit_cop.rb
|
420
427
|
- lib/ndr_dev_support/rake_ci/commit_cop/concerns/deputisable.rb
|