dri 0.1.3 → 0.2.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/.gitlab-ci.yml +9 -2
- data/.rubocop.yml +53 -0
- data/.ruby-version +1 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +59 -7
- data/README.md +22 -0
- data/Rakefile +3 -1
- data/bin/console +1 -0
- data/dri.gemspec +25 -22
- data/exe/dri +3 -3
- data/lib/dri/api_client.rb +22 -10
- data/lib/dri/cli.rb +2 -2
- data/lib/dri/command.rb +5 -5
- data/lib/dri/commands/fetch/failures.rb +15 -14
- data/lib/dri/commands/fetch/featureflags.rb +95 -0
- data/lib/dri/commands/fetch/quarantines.rb +16 -9
- data/lib/dri/commands/fetch/testcases.rb +17 -10
- data/lib/dri/commands/fetch/triaged.rb +9 -7
- data/lib/dri/commands/fetch.rb +26 -4
- data/lib/dri/commands/init.rb +7 -5
- data/lib/dri/commands/profile.rb +14 -5
- data/lib/dri/commands/publish/report.rb +24 -9
- data/lib/dri/commands/publish.rb +4 -5
- data/lib/dri/commands/rm/emoji.rb +5 -5
- data/lib/dri/commands/rm/profile.rb +2 -2
- data/lib/dri/commands/rm.rb +0 -1
- data/lib/dri/refinements/truncate.rb +1 -1
- data/lib/dri/report.rb +56 -41
- data/lib/dri/utils/markdown_lists.rb +7 -9
- data/lib/dri/utils/table.rb +20 -0
- data/lib/dri/version.rb +3 -1
- data/lib/dri.rb +2 -0
- metadata +59 -41
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3ae68ce5f20bab397121604708b813e8f488316559f82392a389f1750e57c89c
|
4
|
+
data.tar.gz: 30b16b0291beb7e18cc74acb9c54100c869544bba883c79729f577c8bda5dd7f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ad35cf45172de050ecd86c376527abc98ba535f9ad97f54f84f7be3875882c46ae897039d26a4c9f4db3c7df598608c81e8613518b7c7eeb44b7903610899406
|
7
|
+
data.tar.gz: a790667c5528fc3ad94f610b2add55b36a4fb5efd9bad3e8e10a78d44e58a8140721d4717a75def60ca829715389bebf001704a38a1a8127e1e6872228dd0fe6
|
data/.gitlab-ci.yml
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
.job_base:
|
2
|
-
image: ruby:
|
2
|
+
image: ruby:2.7
|
3
3
|
variables:
|
4
4
|
BUNDLE_PATH: vendor/bundle
|
5
5
|
BUNDLE_SUPPRESS_INSTALL_USING_MESSAGES: "true"
|
6
6
|
before_script:
|
7
|
+
- gem install bundler -v 2.3.9 --no-document
|
7
8
|
- bundle install
|
8
9
|
cache:
|
9
10
|
key:
|
@@ -33,8 +34,14 @@ build_gem:
|
|
33
34
|
script:
|
34
35
|
- gem build
|
35
36
|
|
37
|
+
rubocop:
|
38
|
+
stage: test
|
39
|
+
extends: .job_base
|
40
|
+
script:
|
41
|
+
- bundle exec rubocop --color
|
42
|
+
|
36
43
|
rspec:
|
37
44
|
stage: test
|
38
45
|
extends: .job_base
|
39
46
|
script:
|
40
|
-
- bundle exec rspec
|
47
|
+
- bundle exec rspec --color
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
inherit_gem:
|
2
|
+
gitlab-styles:
|
3
|
+
- rubocop-all.yml
|
4
|
+
- rubocop-gemspec.yml
|
5
|
+
- rubocop-lint.yml
|
6
|
+
- rubocop-naming.yml
|
7
|
+
- rubocop-performance.yml
|
8
|
+
- rubocop-rspec.yml
|
9
|
+
- rubocop-security.yml
|
10
|
+
- rubocop-style.yml
|
11
|
+
|
12
|
+
AllCops:
|
13
|
+
TargetRubyVersion: 2.7
|
14
|
+
|
15
|
+
RSpec/MultipleMemoizedHelpers:
|
16
|
+
Max: 25
|
17
|
+
AllowSubject: true
|
18
|
+
|
19
|
+
CodeReuse/ActiveRecord:
|
20
|
+
Exclude:
|
21
|
+
- spec/**/*.rb
|
22
|
+
|
23
|
+
Metrics/AbcSize:
|
24
|
+
Enabled: true
|
25
|
+
Max: 30
|
26
|
+
|
27
|
+
Metrics/BlockLength:
|
28
|
+
Enabled: true
|
29
|
+
Exclude:
|
30
|
+
- spec/**/*.rb
|
31
|
+
- dri.gemspec
|
32
|
+
|
33
|
+
Metrics/MethodLength:
|
34
|
+
Enabled: true
|
35
|
+
Max: 30
|
36
|
+
|
37
|
+
Layout/BeginEndAlignment:
|
38
|
+
Enabled: true
|
39
|
+
|
40
|
+
Layout/EmptyLinesAroundAttributeAccessor:
|
41
|
+
Enabled: true
|
42
|
+
|
43
|
+
Layout/SpaceAroundMethodCallOperator:
|
44
|
+
Enabled: true
|
45
|
+
|
46
|
+
Lint/HashCompareByIdentity:
|
47
|
+
Enabled: true
|
48
|
+
|
49
|
+
Lint/RedundantSafeNavigation:
|
50
|
+
Enabled: true
|
51
|
+
|
52
|
+
Style/ClassEqualityComparison:
|
53
|
+
Enabled: true
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.7.5
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
dri (0.1.
|
4
|
+
dri (0.1.3)
|
5
5
|
httparty (~> 0.20.0)
|
6
6
|
json (~> 2.6.1)
|
7
7
|
markdown-tables (~> 1.1.1)
|
@@ -19,39 +19,88 @@ PATH
|
|
19
19
|
GEM
|
20
20
|
remote: https://rubygems.org/
|
21
21
|
specs:
|
22
|
+
activesupport (7.0.2.3)
|
23
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
24
|
+
i18n (>= 1.6, < 2)
|
25
|
+
minitest (>= 5.1)
|
26
|
+
tzinfo (~> 2.0)
|
22
27
|
addressable (2.8.0)
|
23
28
|
public_suffix (>= 2.0.2, < 5.0)
|
29
|
+
ast (2.4.2)
|
30
|
+
concurrent-ruby (1.1.10)
|
24
31
|
crack (0.4.5)
|
25
32
|
rexml
|
26
33
|
diff-lcs (1.5.0)
|
34
|
+
gitlab-styles (7.0.0)
|
35
|
+
rubocop (~> 0.91, >= 0.91.1)
|
36
|
+
rubocop-gitlab-security (~> 0.1.1)
|
37
|
+
rubocop-graphql (~> 0.10)
|
38
|
+
rubocop-performance (~> 1.9.2)
|
39
|
+
rubocop-rails (~> 2.9)
|
40
|
+
rubocop-rspec (~> 1.44)
|
27
41
|
hashdiff (1.0.1)
|
28
42
|
httparty (0.20.0)
|
29
43
|
mime-types (~> 3.0)
|
30
44
|
multi_xml (>= 0.5.2)
|
45
|
+
i18n (1.10.0)
|
46
|
+
concurrent-ruby (~> 1.0)
|
31
47
|
json (2.6.1)
|
32
48
|
markdown-tables (1.1.1)
|
33
49
|
mime-types (3.4.1)
|
34
50
|
mime-types-data (~> 3.2015)
|
35
51
|
mime-types-data (3.2022.0105)
|
52
|
+
minitest (5.15.0)
|
36
53
|
multi_xml (0.6.0)
|
54
|
+
parallel (1.22.1)
|
55
|
+
parser (3.1.1.0)
|
56
|
+
ast (~> 2.4.1)
|
37
57
|
pastel (0.8.0)
|
38
58
|
tty-color (~> 0.5)
|
39
59
|
public_suffix (4.0.6)
|
40
|
-
|
60
|
+
rack (2.2.3)
|
61
|
+
rainbow (3.1.1)
|
62
|
+
rake (13.0.6)
|
63
|
+
regexp_parser (2.2.1)
|
41
64
|
rexml (3.2.5)
|
42
65
|
rspec (3.10.0)
|
43
66
|
rspec-core (~> 3.10.0)
|
44
67
|
rspec-expectations (~> 3.10.0)
|
45
68
|
rspec-mocks (~> 3.10.0)
|
46
|
-
rspec-core (3.10.
|
69
|
+
rspec-core (3.10.2)
|
47
70
|
rspec-support (~> 3.10.0)
|
48
|
-
rspec-expectations (3.10.
|
71
|
+
rspec-expectations (3.10.2)
|
49
72
|
diff-lcs (>= 1.2.0, < 2.0)
|
50
73
|
rspec-support (~> 3.10.0)
|
51
|
-
rspec-mocks (3.10.
|
74
|
+
rspec-mocks (3.10.3)
|
52
75
|
diff-lcs (>= 1.2.0, < 2.0)
|
53
76
|
rspec-support (~> 3.10.0)
|
54
|
-
rspec-support (3.10.
|
77
|
+
rspec-support (3.10.3)
|
78
|
+
rubocop (0.93.1)
|
79
|
+
parallel (~> 1.10)
|
80
|
+
parser (>= 2.7.1.5)
|
81
|
+
rainbow (>= 2.2.2, < 4.0)
|
82
|
+
regexp_parser (>= 1.8)
|
83
|
+
rexml
|
84
|
+
rubocop-ast (>= 0.6.0)
|
85
|
+
ruby-progressbar (~> 1.7)
|
86
|
+
unicode-display_width (>= 1.4.0, < 2.0)
|
87
|
+
rubocop-ast (1.16.0)
|
88
|
+
parser (>= 3.1.1.0)
|
89
|
+
rubocop-gitlab-security (0.1.1)
|
90
|
+
rubocop (>= 0.51)
|
91
|
+
rubocop-graphql (0.14.2)
|
92
|
+
rubocop (>= 0.87, < 2)
|
93
|
+
rubocop-performance (1.9.2)
|
94
|
+
rubocop (>= 0.90.0, < 2.0)
|
95
|
+
rubocop-ast (>= 0.4.0)
|
96
|
+
rubocop-rails (2.9.1)
|
97
|
+
activesupport (>= 4.2.0)
|
98
|
+
rack (>= 1.1)
|
99
|
+
rubocop (>= 0.90.0, < 2.0)
|
100
|
+
rubocop-rspec (1.44.1)
|
101
|
+
rubocop (~> 0.87)
|
102
|
+
rubocop-ast (>= 0.7.1)
|
103
|
+
ruby-progressbar (1.11.0)
|
55
104
|
strings (0.2.1)
|
56
105
|
strings-ansi (~> 0.2)
|
57
106
|
unicode-display_width (>= 1.5, < 3.0)
|
@@ -85,7 +134,9 @@ GEM
|
|
85
134
|
pastel (~> 0.8)
|
86
135
|
strings (~> 0.2.0)
|
87
136
|
tty-screen (~> 0.8)
|
88
|
-
|
137
|
+
tzinfo (2.0.4)
|
138
|
+
concurrent-ruby (~> 1.0)
|
139
|
+
unicode-display_width (1.8.0)
|
89
140
|
unicode_utils (1.4.0)
|
90
141
|
webmock (3.14.0)
|
91
142
|
addressable (>= 2.8.0)
|
@@ -98,6 +149,7 @@ PLATFORMS
|
|
98
149
|
|
99
150
|
DEPENDENCIES
|
100
151
|
dri!
|
152
|
+
gitlab-styles (~> 7.0.0)
|
101
153
|
rake
|
102
154
|
rspec (~> 3.10.0)
|
103
155
|
timecop (~> 0.9.1)
|
data/README.md
CHANGED
@@ -56,6 +56,9 @@ $ dri profile
|
|
56
56
|
- failures
|
57
57
|
- testcases
|
58
58
|
- triaged
|
59
|
+
- quarantines
|
60
|
+
- dequarantines
|
61
|
+
- featureflags
|
59
62
|
- [4. publish](#4-publish)
|
60
63
|
- report
|
61
64
|
- [5. rm](#5-rm)
|
@@ -107,6 +110,25 @@ $ dri fetch triaged
|
|
107
110
|
|
108
111
|
Fetches triaged failures which use the triage emoji specified in `dri profile`.
|
109
112
|
|
113
|
+
```shell
|
114
|
+
$ dri fetch quarantines
|
115
|
+
```
|
116
|
+
|
117
|
+
Fetches open quarantine Merge Requests to be reviewed
|
118
|
+
|
119
|
+
```shell
|
120
|
+
$ dri fetch dequarantines
|
121
|
+
```
|
122
|
+
|
123
|
+
Fetches open dequarantine Merge Requests to be reviewed
|
124
|
+
|
125
|
+
```shell
|
126
|
+
$ dri fetch featureflags
|
127
|
+
```
|
128
|
+
|
129
|
+
Fetches a list of today's feature flag changes, including the date and time in UTC of when the change occurred as well as a link to the corresponding issue from the feature-flag-log project.
|
130
|
+
Results are organized by environment (production, staging, staging ref and preprod).
|
131
|
+
|
110
132
|
#### 4. publish
|
111
133
|
|
112
134
|
```shell
|
data/Rakefile
CHANGED
data/bin/console
CHANGED
data/dri.gemspec
CHANGED
@@ -1,41 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative 'lib/dri/version'
|
2
4
|
|
3
5
|
Gem::Specification.new do |spec|
|
4
|
-
spec.name =
|
5
|
-
spec.license =
|
6
|
+
spec.name = 'dri'
|
7
|
+
spec.license = 'MIT'
|
6
8
|
spec.version = Dri::VERSION
|
7
|
-
spec.authors = [
|
8
|
-
spec.email = [
|
9
|
+
spec.authors = ['GitLab Quality']
|
10
|
+
spec.email = ['quality+dri@gitlab.com']
|
9
11
|
|
10
|
-
spec.summary =
|
12
|
+
spec.summary = 'CLI app to help triage GitLab QA pipelines'
|
11
13
|
spec.homepage = 'https://gitlab.com/gitlab-org/quality/dri'
|
12
|
-
spec.required_ruby_version = Gem::Requirement.new(
|
14
|
+
spec.required_ruby_version = Gem::Requirement.new('>= 2.7.0')
|
13
15
|
|
14
16
|
# Specify which files should be added to the gem when it is released.
|
15
17
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
16
|
-
spec.files
|
18
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
17
19
|
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
18
20
|
end
|
19
|
-
spec.bindir =
|
21
|
+
spec.bindir = 'exe'
|
20
22
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
21
|
-
spec.require_paths = [
|
23
|
+
spec.require_paths = ['lib']
|
22
24
|
|
23
|
-
spec.add_dependency
|
24
|
-
spec.add_dependency
|
25
|
-
spec.add_dependency
|
26
|
-
spec.add_dependency
|
27
|
-
spec.add_dependency
|
25
|
+
spec.add_dependency 'httparty', '~> 0.20.0'
|
26
|
+
spec.add_dependency 'json', '~> 2.6.1'
|
27
|
+
spec.add_dependency 'markdown-tables', '~> 1.1.1'
|
28
|
+
spec.add_dependency 'pastel', '~> 0.8.0'
|
29
|
+
spec.add_dependency 'thor', '~> 1.0.1'
|
28
30
|
spec.add_dependency 'tty-box', '~> 0.7.0'
|
31
|
+
spec.add_dependency 'tty-config', '~> 0.4.0'
|
32
|
+
spec.add_dependency 'tty-editor', '~> 0.6'
|
33
|
+
spec.add_dependency 'tty-font', '~> 0.5'
|
29
34
|
spec.add_dependency 'tty-logger', '~> 0.6.0'
|
30
|
-
spec.add_dependency
|
31
|
-
spec.add_dependency
|
32
|
-
spec.add_dependency
|
33
|
-
spec.add_dependency "markdown-tables", "~> 1.1.1"
|
34
|
-
spec.add_dependency 'json', '~> 2.6.1'
|
35
|
-
spec.add_dependency 'httparty', '~> 0.20.0'
|
35
|
+
spec.add_dependency 'tty-prompt', '~> 0.23.1'
|
36
|
+
spec.add_dependency 'tty-spinner', '~> 0.9'
|
37
|
+
spec.add_dependency 'tty-table', '~> 0.12.0'
|
36
38
|
|
37
|
-
spec.add_development_dependency
|
39
|
+
spec.add_development_dependency 'gitlab-styles', '~> 7.0.0'
|
40
|
+
spec.add_development_dependency 'rake'
|
38
41
|
spec.add_development_dependency 'rspec', '~> 3.10.0'
|
39
|
-
spec.add_development_dependency 'webmock', '~> 3.5'
|
40
42
|
spec.add_development_dependency "timecop", "~> 0.9.1"
|
43
|
+
spec.add_development_dependency 'webmock', '~> 3.5'
|
41
44
|
end
|
data/exe/dri
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
lib_path = File.expand_path('../lib', __dir__)
|
5
|
-
|
5
|
+
$LOAD_PATH.unshift(lib_path) unless $LOAD_PATH.include?(lib_path)
|
6
6
|
require 'dri/cli'
|
7
7
|
|
8
8
|
Signal.trap('INT') do
|
@@ -12,7 +12,7 @@ end
|
|
12
12
|
|
13
13
|
begin
|
14
14
|
Dri::CLI.start
|
15
|
-
rescue Dri::CLI::Error =>
|
16
|
-
puts "ERROR: #{
|
15
|
+
rescue Dri::CLI::Error => e
|
16
|
+
puts "ERROR: #{e.message}"
|
17
17
|
exit 1
|
18
18
|
end
|
data/lib/dri/api_client.rb
CHANGED
@@ -6,12 +6,12 @@ require "tty-config"
|
|
6
6
|
require 'cgi'
|
7
7
|
|
8
8
|
module Dri
|
9
|
-
class ApiClient
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
9
|
+
class ApiClient # rubocop:disable Metrics/ClassLength
|
10
|
+
API_URL = 'https://gitlab.com/api/v4'
|
11
|
+
TESTCASES_PROJECT_ID = '11229385'
|
12
|
+
TRIAGE_PROJECT_ID = '15291320'
|
13
|
+
GITLAB_PROJECT_ID = '278964'
|
14
|
+
FEATURE_FLAG_LOG_PROJECT_ID = '15208716'
|
15
15
|
|
16
16
|
def initialize(config)
|
17
17
|
profile = config.read
|
@@ -64,7 +64,9 @@ module Dri
|
|
64
64
|
def fetch_mrs(project_id:, **options)
|
65
65
|
uri = URI(API_URL)
|
66
66
|
uri.query = HTTParty::HashConversions.to_params(options)
|
67
|
-
|
67
|
+
|
68
|
+
# CGI.escape('gitlab-org/gitlab') => 'gitlab-org%2Fgitlab'
|
69
|
+
uri.path = File.join(uri.path, 'projects', CGI.escape(project_id), 'merge_requests')
|
68
70
|
|
69
71
|
fetch_json(uri.to_s)
|
70
72
|
end
|
@@ -106,6 +108,16 @@ module Dri
|
|
106
108
|
delete_json(url)
|
107
109
|
end
|
108
110
|
|
111
|
+
def fetch_feature_flag_logs(date:, page:)
|
112
|
+
url = ["#{API_URL}/projects/"]
|
113
|
+
url << "#{FEATURE_FLAG_LOG_PROJECT_ID}/issues"
|
114
|
+
url << "?created_after=#{date}"
|
115
|
+
url << "&per_page=100"
|
116
|
+
url << "&page=#{page}"
|
117
|
+
|
118
|
+
fetch_json(url.join)
|
119
|
+
end
|
120
|
+
|
109
121
|
private
|
110
122
|
|
111
123
|
def post_json(url, body)
|
@@ -116,7 +128,7 @@ module Dri
|
|
116
128
|
}
|
117
129
|
}
|
118
130
|
|
119
|
-
response =
|
131
|
+
response = HTTParty.post(url, options)
|
120
132
|
handle_response(response)
|
121
133
|
end
|
122
134
|
|
@@ -126,12 +138,12 @@ module Dri
|
|
126
138
|
end
|
127
139
|
|
128
140
|
def handle_response(response)
|
129
|
-
#puts response.to_json
|
141
|
+
# puts response.to_json
|
130
142
|
response
|
131
143
|
end
|
132
144
|
|
133
145
|
def fetch_json(url)
|
134
|
-
response =
|
146
|
+
response = HTTParty.get(url, headers: header)
|
135
147
|
|
136
148
|
if response.code != 200
|
137
149
|
puts "Response error code \"#{response.code}\" - Unable to sync with GitLab"
|
data/lib/dri/cli.rb
CHANGED
@@ -25,14 +25,14 @@ module Dri
|
|
25
25
|
end
|
26
26
|
|
27
27
|
class_option :no_color, type: :boolean, default: false,
|
28
|
-
|
28
|
+
desc: "Disable colorization in output"
|
29
29
|
|
30
30
|
desc 'version', 'dri version'
|
31
31
|
def version
|
32
32
|
require_relative 'version'
|
33
33
|
puts "v#{Dri::VERSION}"
|
34
34
|
end
|
35
|
-
map %w
|
35
|
+
map %w[--version -v] => :version
|
36
36
|
|
37
37
|
require_relative 'commands/rm'
|
38
38
|
register Dri::Commands::Rm, 'rm', 'rm [SUBCOMMAND]', 'Remove triage-related items'
|
data/lib/dri/command.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require_relative 'command'
|
3
4
|
require_relative 'api_client'
|
4
5
|
|
@@ -13,7 +14,6 @@ module Dri
|
|
13
14
|
extend Forwardable
|
14
15
|
|
15
16
|
def_delegators :command, :run
|
16
|
-
attr_reader :config, :emoji, :token, :username, :timezone, :profile
|
17
17
|
|
18
18
|
def pastel(**options)
|
19
19
|
Pastel.new(**options)
|
@@ -56,10 +56,10 @@ module Dri
|
|
56
56
|
end
|
57
57
|
|
58
58
|
def verify_config_exists
|
59
|
-
if
|
60
|
-
|
61
|
-
|
62
|
-
|
59
|
+
return if config.exist?
|
60
|
+
|
61
|
+
logger.error "Oops, could not find a configuration. Try using #{add_color('dri init', :yellow)} first."
|
62
|
+
exit 1
|
63
63
|
end
|
64
64
|
|
65
65
|
def add_color(str, *color)
|
@@ -1,13 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative '../../command'
|
4
|
-
|
5
|
-
require 'tty-table'
|
4
|
+
require_relative '../../utils/table'
|
6
5
|
|
7
6
|
module Dri
|
8
7
|
module Commands
|
9
8
|
class Fetch
|
10
9
|
class Failures < Dri::Command
|
10
|
+
include Dri::Utils::Table
|
11
11
|
using Refinements
|
12
12
|
|
13
13
|
def initialize(options)
|
@@ -15,7 +15,7 @@ module Dri
|
|
15
15
|
@today_iso_format = Time.now.strftime('%Y-%m-%dT00:00:00Z')
|
16
16
|
end
|
17
17
|
|
18
|
-
def execute(input: $stdin, output: $stdout)
|
18
|
+
def execute(input: $stdin, output: $stdout) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/MethodLength
|
19
19
|
verify_config_exists
|
20
20
|
|
21
21
|
title = add_color('Title', :bright_yellow)
|
@@ -25,13 +25,12 @@ module Dri
|
|
25
25
|
|
26
26
|
failures = []
|
27
27
|
urgent = []
|
28
|
-
labels = [
|
28
|
+
labels = [title, triaged, author, url]
|
29
29
|
triaged_counter = 0
|
30
30
|
|
31
31
|
logger.info "Fetching today's failures..."
|
32
32
|
|
33
|
-
spinner.run do
|
34
|
-
|
33
|
+
spinner.run do # rubocop:disable Metrics/BlockLength
|
35
34
|
response = api_client.fetch_failures(date: @today_iso_format, state: 'opened')
|
36
35
|
|
37
36
|
if response.nil?
|
@@ -47,7 +46,7 @@ module Dri
|
|
47
46
|
triaged = add_color('x', :red)
|
48
47
|
|
49
48
|
emoji_awards = api_client.fetch_awarded_emojis(award_emoji_url).find do |e|
|
50
|
-
e['name'] == emoji && e['user']['username'] == username
|
49
|
+
(e['name'] == emoji) && (e['user']['username'] == username)
|
51
50
|
end
|
52
51
|
|
53
52
|
if emoji_awards
|
@@ -59,7 +58,7 @@ module Dri
|
|
59
58
|
labels = failure['labels']
|
60
59
|
|
61
60
|
labels.each do |label|
|
62
|
-
if label.include?
|
61
|
+
if label.include?('found:canary.gitlab.com' && 'found:canary.staging.gitlab.com')
|
63
62
|
urgent << [title, triaged, author, url]
|
64
63
|
end
|
65
64
|
end
|
@@ -70,13 +69,15 @@ module Dri
|
|
70
69
|
end
|
71
70
|
|
72
71
|
if @options[:urgent]
|
73
|
-
|
74
|
-
puts
|
75
|
-
|
72
|
+
print_table(labels, urgent, alignments: [:left, :center, :center, :left])
|
73
|
+
output.puts(<<~MSG)
|
74
|
+
Found: #{urgent.size} urgent failures, occurring in both canary.gitlab.com and canary.staging.gitlab.com.
|
75
|
+
MSG
|
76
76
|
else
|
77
|
-
|
78
|
-
puts
|
79
|
-
|
77
|
+
print_table(labels, failures, alignments: [:left, :center, :center, :left])
|
78
|
+
output.puts(<<~MSG)
|
79
|
+
Found: #{failures.size} failures, of these #{triaged_counter} have been triaged with a #{emoji}.
|
80
|
+
MSG
|
80
81
|
end
|
81
82
|
end
|
82
83
|
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../command'
|
4
|
+
require_relative '../../utils/table'
|
5
|
+
|
6
|
+
module Dri
|
7
|
+
module Commands
|
8
|
+
class Fetch
|
9
|
+
class FeatureFlags < Dri::Command
|
10
|
+
include Dri::Utils::Table
|
11
|
+
|
12
|
+
PRODUCTION = 'host::gitlab.com'
|
13
|
+
STAGING = 'host::staging.gitlab.com'
|
14
|
+
STAGING_REF = 'host::staging-ref.gitlab.com'
|
15
|
+
PREPROD = 'host::pre.gitlab.com'
|
16
|
+
|
17
|
+
def initialize(options)
|
18
|
+
@options = options
|
19
|
+
@today_iso_format = Time.now.strftime('%Y-%m-%dT00:00:00Z')
|
20
|
+
end
|
21
|
+
|
22
|
+
def execute(input: $stdin, output: $stdout) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/MethodLength
|
23
|
+
verify_config_exists
|
24
|
+
|
25
|
+
summary = add_color('Summary', :bright_yellow)
|
26
|
+
changed_on = add_color('Changed(UTC)', :bright_yellow)
|
27
|
+
url = add_color('URL', :bright_yellow)
|
28
|
+
|
29
|
+
prod_feature_flags = []
|
30
|
+
staging_feature_flags = []
|
31
|
+
staging_ref_feature_flags = []
|
32
|
+
preprod_feature_flags = []
|
33
|
+
|
34
|
+
headers = [summary, changed_on, url]
|
35
|
+
|
36
|
+
logger.info "Fetching today's feature flag changes..."
|
37
|
+
|
38
|
+
spinner.run do # rubocop:disable Metrics/BlockLength
|
39
|
+
page = 1
|
40
|
+
loop do # rubocop:disable Metrics/BlockLength
|
41
|
+
response = api_client.fetch_feature_flag_logs(date: @today_iso_format, page: page)
|
42
|
+
|
43
|
+
if response.nil? && page == 1
|
44
|
+
logger.info 'It\'s been quiet...no feature flag changes for today 👀'
|
45
|
+
exit 0
|
46
|
+
end
|
47
|
+
|
48
|
+
response.each do |feature_flag|
|
49
|
+
summary = feature_flag['title']
|
50
|
+
|
51
|
+
substrings = ["set to \"true\"", "set to \"false\""]
|
52
|
+
next unless substrings.any? { |substr| summary.include?(substr) }
|
53
|
+
|
54
|
+
changed_on = feature_flag['description'][/(?<=Changed on \(in UTC\): ).+?(?=\n)/].delete('`')
|
55
|
+
url = feature_flag['web_url']
|
56
|
+
|
57
|
+
feature_flag_data = [summary, changed_on, url]
|
58
|
+
|
59
|
+
labels = feature_flag['labels']
|
60
|
+
host_label = labels.select { |label| /^host::/.match(label) }.join('')
|
61
|
+
|
62
|
+
case host_label
|
63
|
+
when PRODUCTION
|
64
|
+
prod_feature_flags << feature_flag_data
|
65
|
+
when STAGING
|
66
|
+
staging_feature_flags << feature_flag_data
|
67
|
+
when STAGING_REF
|
68
|
+
staging_ref_feature_flags << feature_flag_data
|
69
|
+
when PREPROD
|
70
|
+
preprod_feature_flags << feature_flag_data
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
page += 1
|
75
|
+
break if response.count < 100 || response.nil?
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
print_results('Production', headers, prod_feature_flags, output) unless prod_feature_flags.empty?
|
80
|
+
print_results('Staging', headers, staging_feature_flags, output) unless staging_feature_flags.empty?
|
81
|
+
print_results('Staging Ref', headers, staging_ref_feature_flags, output) unless staging_ref_feature_flags.empty? # rubocop:disable Layout/LineLength
|
82
|
+
print_results('Preprod', headers, preprod_feature_flags, output) unless preprod_feature_flags.empty?
|
83
|
+
end
|
84
|
+
|
85
|
+
private
|
86
|
+
|
87
|
+
def print_results(env, headers, rows, output_src)
|
88
|
+
puts "\n#{add_color(env, :bright_blue)}"
|
89
|
+
print_table(headers, rows)
|
90
|
+
output_src.puts "\nFound: #{rows.count} feature flag change(s) set to true or false on #{env}."
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|