dri 0.7.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e6ee21fc2a0243e0850f7bab281b0611021807a1a4559e89433741b1faed40f2
4
- data.tar.gz: 5b97afcdbc1e1e9307b084eab6e2afddbff94556cc102f2b174a0dedc3f51c33
3
+ metadata.gz: 2b398cef45fa101592e0abecf4d014969e4e26dac5b5e3fd9f7f774b6108618f
4
+ data.tar.gz: 96a6b402d7dfcccf9fe2e69e01a4ece8af13d56be0213dc8ffa3824ea9a5ed2a
5
5
  SHA512:
6
- metadata.gz: f5b54fee2e4f0d99d0d013d0c9a211306eda149dabb6c0cedf05ec0c5a92274dd4038377fc270b6185782ba2dfdbe5c2be6028136c77a4e77dceb21989a82894
7
- data.tar.gz: c2d5056697c04ea976e00db46f183cd716091e3681687ad369c6dc3c11dab7ecd5592022460948a19ce779da7b114c2c90c4ba3c712a0bfe6256524cf6859934
6
+ metadata.gz: 9d94573de9142a648b643819381244382a65fedd7c180ae5b78013ea2738204e54e543e43ed5ad6209c2a3ae5a3af4cd1ecb2a7937afa5607b3c04435ce5a2a2
7
+ data.tar.gz: 48e010a476d8b1a2b48b3b74ba485e7a9c533aa17f96e4639eead23e486f2a309a8f60fed3c282a9b85ec38154cc2bb0b26fdbf28d3389981d1bf26578336b87
@@ -0,0 +1,28 @@
1
+ ## Diff
2
+ <!-- Replace `v0.9.0` with the previous DRI release, and `6a9c4fcc150741d578ec75141d3706891b6694bc` with the latest commit from https://gitlab.com/gitlab-org/quality/dri/-/commits/master that will be included in the release -->
3
+ https://gitlab.com/gitlab-org/quality/dri/-/compare/v0.9.0...6a9c4fcc150741d578ec75141d3706891b6694bc
4
+
5
+ ## Release Notes
6
+
7
+ ```markdown
8
+ ### Features
9
+ - !aaa <Title of the aaa MR>
10
+
11
+ ### Bug Fixes
12
+ - !bbb <Title of the bbb MR>
13
+
14
+ ### Maintenance
15
+ - !ccc <Title of the ccc MR>
16
+ ```
17
+
18
+ ## Checklists
19
+
20
+ ### Before merging:
21
+ - [ ] MR title is set to `Bump version to <version>`, where `<version>` is the new version, according to [SemVer](https://semver.org/).
22
+ - [ ] Diff link is up-to-date.
23
+ - [ ] Release notes are accurate.
24
+ - [ ] `lib/dri/version.rb` is updated with the new version number.
25
+ - [ ] `bundle update` was run to update `Gemfile.lock` with the new version number.
26
+
27
+ ### After merging:
28
+ - [ ] Update the release notes for the [newly created tag](https://gitlab.com/gitlab-org/quality/dri/-/tags) with the release notes from this MR.
data/.gitlab-ci.yml CHANGED
@@ -15,18 +15,18 @@
15
15
  - vendor/bundle
16
16
  policy: pull
17
17
  rules:
18
- - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
18
+ - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
19
19
  - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
20
20
 
21
21
  include:
22
22
  - project: gitlab-org/quality/pipeline-common
23
- ref: 0.15.1
23
+ ref: 1.2.3
24
24
  file:
25
25
  - /ci/gem-release.yml
26
26
  - /ci/ref-update.gitlab-ci.yml
27
27
 
28
28
  variables:
29
- RUBY_VERSION: "2.7"
29
+ RUBY_VERSION: "3.0"
30
30
 
31
31
  stages:
32
32
  - build
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 3.0.4
1
+ 3.0.5
data/.tool-versions CHANGED
@@ -1 +1 @@
1
- ruby 3.0.4
1
+ ruby 3.0.5
data/Gemfile.lock CHANGED
@@ -1,19 +1,20 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- dri (0.7.0)
4
+ dri (0.9.0)
5
5
  amatch (~> 0.4.1)
6
- gitlab (~> 4.18)
7
- httparty (~> 0.20.0)
6
+ gitlab (~> 4.19)
7
+ httparty (~> 0.21.0)
8
8
  json (~> 2.6.1)
9
9
  markdown-tables (~> 1.1.1)
10
10
  pastel (~> 0.8.0)
11
- thor (~> 1.0.1)
11
+ thor (~> 1.2.0)
12
12
  tty-box (~> 0.7.0)
13
- tty-config (~> 0.4.0)
14
- tty-editor (~> 0.6)
13
+ tty-config (~> 0.6.0)
14
+ tty-editor (~> 0.7)
15
15
  tty-font (~> 0.5)
16
16
  tty-logger (~> 0.6.0)
17
+ tty-markdown (~> 0.7.0)
17
18
  tty-prompt (~> 0.23.1)
18
19
  tty-spinner (~> 0.9)
19
20
  tty-table (~> 0.12.0)
@@ -21,19 +22,19 @@ PATH
21
22
  GEM
22
23
  remote: https://rubygems.org/
23
24
  specs:
24
- activesupport (7.0.2.3)
25
+ activesupport (7.0.4.2)
25
26
  concurrent-ruby (~> 1.0, >= 1.0.2)
26
27
  i18n (>= 1.6, < 2)
27
28
  minitest (>= 5.1)
28
29
  tzinfo (~> 2.0)
29
- addressable (2.8.0)
30
- public_suffix (>= 2.0.2, < 5.0)
30
+ addressable (2.8.1)
31
+ public_suffix (>= 2.0.2, < 6.0)
31
32
  amatch (0.4.1)
32
33
  mize
33
34
  tins (~> 1.0)
34
35
  ast (2.4.2)
35
36
  coderay (1.1.3)
36
- concurrent-ruby (1.1.10)
37
+ concurrent-ruby (1.2.2)
37
38
  crack (0.4.5)
38
39
  rexml
39
40
  diff-lcs (1.5.0)
@@ -48,37 +49,38 @@ GEM
48
49
  rubocop-rails (~> 2.9)
49
50
  rubocop-rspec (~> 1.44)
50
51
  hashdiff (1.0.1)
51
- httparty (0.20.0)
52
- mime-types (~> 3.0)
52
+ httparty (0.21.0)
53
+ mini_mime (>= 1.0.0)
53
54
  multi_xml (>= 0.5.2)
54
- i18n (1.10.0)
55
+ i18n (1.12.0)
55
56
  concurrent-ruby (~> 1.0)
56
- json (2.6.2)
57
+ json (2.6.3)
58
+ kramdown (2.4.0)
59
+ rexml
57
60
  markdown-tables (1.1.1)
58
61
  method_source (1.0.0)
59
- mime-types (3.4.1)
60
- mime-types-data (~> 3.2015)
61
- mime-types-data (3.2022.0105)
62
- minitest (5.15.0)
63
- mize (0.4.0)
62
+ mini_mime (1.1.2)
63
+ minitest (5.18.0)
64
+ mize (0.4.1)
64
65
  protocol (~> 2.0)
65
66
  multi_xml (0.6.0)
66
67
  parallel (1.22.1)
67
- parser (3.1.1.0)
68
+ parser (3.2.1.0)
68
69
  ast (~> 2.4.1)
69
70
  pastel (0.8.0)
70
71
  tty-color (~> 0.5)
71
72
  protocol (2.0.0)
72
73
  ruby_parser (~> 3.0)
73
- pry (0.14.1)
74
+ pry (0.14.2)
74
75
  coderay (~> 1.1)
75
76
  method_source (~> 1.0)
76
- public_suffix (4.0.6)
77
- rack (2.2.3)
77
+ public_suffix (5.0.1)
78
+ rack (3.0.4.2)
78
79
  rainbow (3.1.1)
79
80
  rake (13.0.6)
80
- regexp_parser (2.2.1)
81
+ regexp_parser (2.7.0)
81
82
  rexml (3.2.5)
83
+ rouge (3.30.0)
82
84
  rspec (3.10.0)
83
85
  rspec-core (~> 3.10.0)
84
86
  rspec-expectations (~> 3.10.0)
@@ -101,11 +103,11 @@ GEM
101
103
  rubocop-ast (>= 0.6.0)
102
104
  ruby-progressbar (~> 1.7)
103
105
  unicode-display_width (>= 1.4.0, < 2.0)
104
- rubocop-ast (1.16.0)
105
- parser (>= 3.1.1.0)
106
+ rubocop-ast (1.27.0)
107
+ parser (>= 3.2.1.0)
106
108
  rubocop-gitlab-security (0.1.1)
107
109
  rubocop (>= 0.51)
108
- rubocop-graphql (0.14.2)
110
+ rubocop-graphql (0.19.0)
109
111
  rubocop (>= 0.87, < 2)
110
112
  rubocop-performance (1.9.2)
111
113
  rubocop (>= 0.90.0, < 2.0)
@@ -117,8 +119,8 @@ GEM
117
119
  rubocop-rspec (1.44.1)
118
120
  rubocop (~> 0.87)
119
121
  rubocop-ast (>= 0.7.1)
120
- ruby-progressbar (1.11.0)
121
- ruby_parser (3.19.1)
122
+ ruby-progressbar (1.13.0)
123
+ ruby_parser (3.20.0)
122
124
  sexp_processor (~> 4.16)
123
125
  sexp_processor (4.16.1)
124
126
  strings (0.2.1)
@@ -129,22 +131,29 @@ GEM
129
131
  sync (0.5.0)
130
132
  terminal-table (3.0.2)
131
133
  unicode-display_width (>= 1.1.1, < 3)
132
- thor (1.0.1)
133
- timecop (0.9.5)
134
- tins (1.31.1)
134
+ thor (1.2.1)
135
+ timecop (0.9.6)
136
+ tins (1.32.1)
135
137
  sync
136
138
  tty-box (0.7.0)
137
139
  pastel (~> 0.8)
138
140
  strings (~> 0.2.0)
139
141
  tty-cursor (~> 0.7)
140
142
  tty-color (0.6.0)
141
- tty-config (0.4.0)
143
+ tty-config (0.6.0)
142
144
  tty-cursor (0.7.1)
143
145
  tty-editor (0.7.0)
144
146
  tty-prompt (~> 0.22)
145
147
  tty-font (0.5.0)
146
148
  tty-logger (0.6.0)
147
149
  pastel (~> 0.8)
150
+ tty-markdown (0.7.1)
151
+ kramdown (>= 1.16.2, < 3.0)
152
+ pastel (~> 0.8)
153
+ rouge (~> 3.14)
154
+ strings (~> 0.2.0)
155
+ tty-color (~> 0.5)
156
+ tty-screen (~> 0.8)
148
157
  tty-prompt (0.23.1)
149
158
  pastel (~> 0.8)
150
159
  tty-reader (~> 0.8)
@@ -159,11 +168,11 @@ GEM
159
168
  pastel (~> 0.8)
160
169
  strings (~> 0.2.0)
161
170
  tty-screen (~> 0.8)
162
- tzinfo (2.0.4)
171
+ tzinfo (2.0.6)
163
172
  concurrent-ruby (~> 1.0)
164
173
  unicode-display_width (1.8.0)
165
174
  unicode_utils (1.4.0)
166
- webmock (3.14.0)
175
+ webmock (3.18.1)
167
176
  addressable (>= 2.8.0)
168
177
  crack (>= 0.3.2)
169
178
  hashdiff (>= 0.4.0, < 2.0.0)
@@ -182,4 +191,4 @@ DEPENDENCIES
182
191
  webmock (~> 3.5)
183
192
 
184
193
  BUNDLED WITH
185
- 2.3.16
194
+ 2.4.7
data/README.md CHANGED
@@ -59,6 +59,7 @@ $ dri profile
59
59
  - quarantines
60
60
  - dequarantines
61
61
  - featureflags
62
+ - runbooks
62
63
  - [4. publish](#4-publish)
63
64
  - report
64
65
  - [5. rm](#5-rm)
@@ -139,6 +140,13 @@ $ dri fetch pipelines
139
140
  Fetches a table containing last executed pipeline and its test report link for all monitored pipelines.
140
141
  The timestamps are in UTC
141
142
 
143
+ ```shell
144
+ $ dri fetch runbooks [runbook]
145
+ ```
146
+
147
+ Fetches a runbook from the [runbooks](https://gitlab.com/gitlab-org/quality/runbooks) project.
148
+ If `[runbook]` is omitted, the command will prompt the user to select from a list of available runbooks.
149
+
142
150
  #### 4. publish
143
151
 
144
152
  ```shell
@@ -156,12 +164,13 @@ $ dri publish report --format=table # formats the report in a table (default)
156
164
  $ dri publish report --dry-run # the report is only generated locally
157
165
  $ dri publish report --actions # activate the actions prompt for each failure
158
166
  $ dri publish report --feature-flags # includes a summary of the feature flag changes on each environment
167
+ $ dri publish report --update # update the report note if has already been posted
159
168
  ```
160
169
 
161
170
  **Note:** These options above can be combined like:
162
171
 
163
172
  ```shell
164
- $ dri publish report --format=list --dry-run --actions
173
+ $ dri publish report --format=list --dry-run --actions --update
165
174
  ```
166
175
 
167
176
  **Actions**
data/dri.gemspec CHANGED
@@ -23,17 +23,18 @@ Gem::Specification.new do |spec|
23
23
  spec.require_paths = ['lib']
24
24
 
25
25
  spec.add_dependency 'amatch', '~> 0.4.1'
26
- spec.add_dependency "gitlab", "~> 4.18"
27
- spec.add_dependency 'httparty', '~> 0.20.0'
26
+ spec.add_dependency "gitlab", "~> 4.19"
27
+ spec.add_dependency 'httparty', '~> 0.21.0'
28
28
  spec.add_dependency 'json', '~> 2.6.1'
29
29
  spec.add_dependency 'markdown-tables', '~> 1.1.1'
30
30
  spec.add_dependency 'pastel', '~> 0.8.0'
31
- spec.add_dependency 'thor', '~> 1.0.1'
31
+ spec.add_dependency 'thor', '~> 1.2.0'
32
32
  spec.add_dependency 'tty-box', '~> 0.7.0'
33
- spec.add_dependency 'tty-config', '~> 0.4.0'
34
- spec.add_dependency 'tty-editor', '~> 0.6'
33
+ spec.add_dependency 'tty-config', '~> 0.6.0'
34
+ spec.add_dependency 'tty-editor', '~> 0.7'
35
35
  spec.add_dependency 'tty-font', '~> 0.5'
36
36
  spec.add_dependency 'tty-logger', '~> 0.6.0'
37
+ spec.add_dependency 'tty-markdown', '~> 0.7.0'
37
38
  spec.add_dependency 'tty-prompt', '~> 0.23.1'
38
39
  spec.add_dependency 'tty-spinner', '~> 0.9'
39
40
  spec.add_dependency 'tty-table', '~> 0.12.0'
@@ -6,16 +6,16 @@ require "tty-config"
6
6
  require "cgi"
7
7
  require "gitlab"
8
8
 
9
+ require_relative './utils/constants'
10
+
9
11
  module Dri
10
12
  TokenNotProvidedError = Class.new(StandardError)
11
13
  class ApiClient # rubocop:disable Metrics/ClassLength
14
+ include Dri::Utils::Constants::ProjectIDs
15
+ include Dri::Utils::Constants::Triage::Labels
16
+
12
17
  API_URL = "https://gitlab.com/api/v4"
13
18
  OPS_API_URL = "https://ops.gitlab.net/api/v4"
14
- TESTCASES_PROJECT_ID = 11229385
15
- TRIAGE_PROJECT_ID = 15291320
16
- GITLAB_PROJECT_ID = 278964
17
- FEATURE_FLAG_LOG_PROJECT_ID = 15208716
18
- INFRA_TEAM_PROD_PROJECT_ID = 7444821
19
19
 
20
20
  def initialize(config, ops = false)
21
21
  @token = config.read.dig("settings", "token")
@@ -28,14 +28,31 @@ module Dri
28
28
  @ops_instance = ops
29
29
  end
30
30
 
31
- # Fetch triaged failures
31
+ # Fetch all triaged failures
32
32
  #
33
33
  # @param [String] emoji
34
34
  # @param [String] state
35
- # @return [Gitlab::ObjectifiedHash]
36
- def fetch_triaged_failures(emoji:, state:)
35
+ # @return [Array<Gitlab::ObjectifiedHash>]
36
+ def fetch_all_triaged_failures(emoji:, state:)
37
+ project_ids = [GITLAB_PROJECT_ID, CUSTOMERSDOT_PROJECT_ID]
38
+ failures = []
39
+
40
+ project_ids.each do |project_id|
41
+ failures += fetch_triaged_failures(project_id: project_id, emoji: emoji, state: state)
42
+ end
43
+
44
+ failures
45
+ end
46
+
47
+ # Fetch triaged failures for a given project
48
+ #
49
+ # @param [Integer] project_id
50
+ # @param [String] emoji
51
+ # @param [String] state
52
+ # @return [Array<Gitlab::ObjectifiedHash>]
53
+ def fetch_triaged_failures(project_id:, emoji:, state:)
37
54
  gitlab.issues(
38
- GITLAB_PROJECT_ID,
55
+ project_id,
39
56
  order_by: "updated_at",
40
57
  my_reaction_emoji: emoji,
41
58
  scope: "all",
@@ -61,7 +78,7 @@ module Dri
61
78
  # @param [Integer] issue_iid
62
79
  # @param [Integer] project_id
63
80
  # @return [Array<Gitlab::ObjectifiedHash>]
64
- def fetch_awarded_emojis(issue_iid, project_id: GITLAB_PROJECT_ID)
81
+ def fetch_awarded_emojis(issue_iid, project_id:)
65
82
  gitlab.award_emojis(project_id, issue_iid, "issue")
66
83
  end
67
84
 
@@ -76,14 +93,14 @@ module Dri
76
93
  labels: "#{pipeline}::failed",
77
94
  state: state,
78
95
  scope: "all",
79
- "not[labels]": "quarantine"
96
+ "not[labels]": QUARANTINE
80
97
  ).auto_paginate
81
98
  end
82
99
 
83
100
  # Fetch issues related to failing test cases
84
101
  #
85
102
  # @return [Array<Gitlab::ObjectifiedHash>]
86
- def fetch_test_failure_issues(labels: 'failure::new')
103
+ def fetch_test_failure_issues(labels: FAILURE_NEW)
87
104
  gitlab.issues(
88
105
  GITLAB_PROJECT_ID,
89
106
  labels: labels,
@@ -94,10 +111,11 @@ module Dri
94
111
 
95
112
  # Fetch related issue mrs
96
113
  #
114
+ # @param [Integer] project_id
97
115
  # @param [Integer] issue_iid
98
116
  # @return [Array<Gitlab::ObjectifiedHash>]
99
- def fetch_related_mrs(issue_iid)
100
- gitlab.related_issue_merge_requests(GITLAB_PROJECT_ID, issue_iid)
117
+ def fetch_related_mrs(project_id, issue_iid)
118
+ gitlab.related_issue_merge_requests(project_id, issue_iid)
101
119
  end
102
120
 
103
121
  # Fetch MRs
@@ -130,15 +148,42 @@ module Dri
130
148
  gitlab.create_issue_note(TRIAGE_PROJECT_ID, iid, body)
131
149
  end
132
150
 
133
- # Fetch new failures
151
+ # Update triage report note
152
+ #
153
+ # @param [Integer] iid
154
+ # @param [Integer] note_id
155
+ # @param [String] body
156
+ # @return [Gitlab::ObjectifiedHash]
157
+ def update_triage_report_note(iid:, note_id:, body:)
158
+ gitlab.edit_issue_note(TRIAGE_PROJECT_ID, iid, note_id, body)
159
+ end
160
+
161
+ # Fetch all new failures
134
162
  #
135
163
  # @param [String] date
136
164
  # @param [String] state
137
165
  # @return [Array<Gitlab::ObjectifiedHash>]
138
- def fetch_failures(date:, state:)
166
+ def fetch_all_new_failures(date:, state:)
167
+ project_ids = [GITLAB_PROJECT_ID, CUSTOMERSDOT_PROJECT_ID]
168
+ failures = []
169
+
170
+ project_ids.each do |project_id|
171
+ failures += fetch_new_failures(project_id: project_id, date: date, state: state)
172
+ end
173
+
174
+ failures
175
+ end
176
+
177
+ # Fetch new failures for a given project
178
+ #
179
+ # @param [Integer] project_id
180
+ # @param [String] date
181
+ # @param [String] state
182
+ # @return [Array<Gitlab::ObjectifiedHash>]
183
+ def fetch_new_failures(project_id:, date:, state:)
139
184
  gitlab.issues(
140
- GITLAB_PROJECT_ID,
141
- labels: "failure::new",
185
+ project_id,
186
+ labels: FAILURE_NEW,
142
187
  order_by: "updated_at",
143
188
  state: state,
144
189
  scope: "all",
@@ -149,10 +194,11 @@ module Dri
149
194
 
150
195
  # Fetch failure notes
151
196
  #
197
+ # @param [Integer] project_id
152
198
  # @param [Integer] issue_iid
153
199
  # @return [Array<Gitlab::ObjectifiedHash>]
154
- def fetch_failure_notes(issue_iid)
155
- gitlab.issue_notes(GITLAB_PROJECT_ID, issue_iid, per_page: 100).auto_paginate
200
+ def fetch_failure_notes(project_id, issue_iid)
201
+ gitlab.issue_notes(project_id, issue_iid, per_page: 100).auto_paginate
156
202
  end
157
203
 
158
204
  # Delete award emoji
@@ -233,6 +279,28 @@ module Dri
233
279
  gitlab.pipeline_jobs(project_id, pipeline_id, options).auto_paginate
234
280
  end
235
281
 
282
+ # Fetch runbooks from the runbooks project
283
+ #
284
+ # @param [Integer] project_id
285
+ # @return [Array<Gitlab::ObjectifedHash>]
286
+ def list_runbooks(project_id = RUNBOOKS_PROJECT_ID)
287
+ tree = gitlab.tree(project_id, { recursive: true, ref: 'main' }).auto_paginate
288
+
289
+ tree.select do |node|
290
+ node.type == 'tree' && !node.name.start_with?('_')
291
+ end
292
+ end
293
+
294
+ # Fetches file contents at <path>
295
+ #
296
+ # @param [String] path
297
+ # @param [String] ref
298
+ # @param [Integer] project_id
299
+ # @return [Gitlab::ObjectifiedHash]
300
+ def get_file(path, ref:, project_id:)
301
+ gitlab.get_file(project_id, path, ref)
302
+ end
303
+
236
304
  private
237
305
 
238
306
  attr_reader :token, :ops_token
@@ -2,6 +2,7 @@
2
2
 
3
3
  require_relative '../../command'
4
4
  require_relative '../../utils/table'
5
+ require_relative '../../utils/constants'
5
6
  require 'amatch'
6
7
  require 'fileutils'
7
8
 
@@ -11,10 +12,11 @@ module Dri
11
12
  class StackTraces < Dri::Command
12
13
  include Amatch
13
14
  include Dri::Utils::Table
15
+ include Dri::Utils::Constants::Triage::Labels
14
16
 
15
17
  def initialize(options)
16
18
  @options = options
17
- @labels = options[:labels] || 'failure::new'
19
+ @labels = options[:labels] || FAILURE_NEW
18
20
  @similarity_score_threshold = options[:similarity_score_threshold] || 0.9
19
21
  end
20
22
 
@@ -29,7 +31,7 @@ module Dri
29
31
  logger.info "#{Time.now.utc} API response completed"
30
32
 
31
33
  if response.empty?
32
- logger.info 'There are no failure::new issues identified!'
34
+ logger.info "There are no #{FAILURE_NEW} issues identified!"
33
35
  exit 0
34
36
  end
35
37
 
@@ -2,12 +2,14 @@
2
2
 
3
3
  require_relative '../../command'
4
4
  require_relative '../../utils/table'
5
+ require_relative '../../utils/constants'
5
6
 
6
7
  module Dri
7
8
  module Commands
8
9
  class Fetch
9
10
  class Failures < Dri::Command
10
11
  include Dri::Utils::Table
12
+ include Dri::Utils::Constants::Triage::Labels
11
13
  using Refinements
12
14
 
13
15
  SORT_BY_OPTIONS = {
@@ -34,33 +36,34 @@ module Dri
34
36
  author = add_color('Author', :bright_yellow)
35
37
  url = add_color('URL', :bright_yellow)
36
38
 
37
- failures = []
39
+ sorted_failures = []
38
40
  labels = [title, triaged, environment, author, url]
39
41
  triaged_counter = 0
40
42
 
41
43
  logger.info "Fetching today's failures..."
42
44
 
43
45
  spinner.run do # rubocop:disable Metrics/BlockLength
44
- response = api_client.fetch_failures(date: @today_iso_format, state: 'opened')
46
+ failures = api_client.fetch_all_new_failures(date: @today_iso_format, state: 'opened')
45
47
 
46
- if response.empty?
48
+ if failures.empty?
47
49
  logger.info 'Life is great, there are no new failures today!'
48
50
  exit 0
49
51
  end
50
52
 
51
- response.each do |failure|
53
+ failures.each do |failure|
54
+ project_id = failure.project_id
52
55
  title = failure.title.truncate(60)
53
56
  author = failure.to_h.dig('author', 'username')
54
57
  url = failure.web_url
55
58
  triaged = add_color('x', :red)
56
- envs = failure.labels.select { |l| l.include?('found:') }.map do |l|
59
+ envs = failure.labels.select { |l| l.include?(FOUND) }.map do |l|
57
60
  env = l.split(':').last.gsub('.gitlab.com', '')
58
61
 
59
62
  env == 'gitlab.com' ? 'production' : env
60
63
  end
61
64
  urgent = urgent_environments.all? { |env| envs.include?(env) }
62
65
 
63
- emoji_awards = api_client.fetch_awarded_emojis(failure.iid).find do |e|
66
+ emoji_awards = api_client.fetch_awarded_emojis(failure.iid, project_id: project_id).find do |e|
64
67
  e.name == emoji && e.to_h.dig('user', 'username') == username
65
68
  end
66
69
 
@@ -70,26 +73,26 @@ module Dri
70
73
  end
71
74
 
72
75
  if @options[:urgent]
73
- failures << [title, triaged, envs.first, author, url] if urgent
76
+ sorted_failures << [title, triaged, envs.first, author, url] if urgent
74
77
  else
75
- failures << [title, triaged, envs.first, author, url]
78
+ sorted_failures << [title, triaged, envs.first, author, url]
76
79
  end
77
80
  end
78
81
 
79
- failures.sort_by! { |failure| failure[SORT_BY_OPTIONS[@options[:sort_by]&.to_sym || :environment]] }
82
+ sorted_failures.sort_by! { |failure| failure[SORT_BY_OPTIONS[@options[:sort_by]&.to_sym || :environment]] }
80
83
  end
81
84
 
82
85
  msg = if @options[:urgent]
83
86
  <<~MSG
84
- Found: #{failures.size} urgent failures, occurring in both canary.gitlab.com and canary.staging.gitlab.com.
87
+ Found: #{sorted_failures.size} urgent failures, occurring in both canary.gitlab.com and canary.staging.gitlab.com.
85
88
  MSG
86
89
  else
87
90
  <<~MSG
88
- Found: #{failures.size} failures, of these #{triaged_counter} have been triaged with a #{emoji}.
91
+ Found: #{sorted_failures.size} failures, of these #{triaged_counter} have been triaged with a #{emoji}.
89
92
  MSG
90
93
  end
91
94
 
92
- print_table(labels, failures, alignments: [:left, :center, :center, :left])
95
+ print_table(labels, sorted_failures, alignments: [:left, :center, :center, :left])
93
96
  output.puts(msg)
94
97
  end
95
98
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  require_relative '../../command'
4
4
  require_relative '../../utils/table'
5
- require_relative '../../utils/feature_flag_consts'
5
+ require_relative '../../utils/constants'
6
6
  require_relative '../../feature_flag_report'
7
7
 
8
8
  module Dri
@@ -10,7 +10,7 @@ module Dri
10
10
  class Fetch
11
11
  class FeatureFlags < Dri::Command
12
12
  include Dri::Utils::Table
13
- include Dri::Utils::FeatureFlagConsts
13
+ include Dri::Utils::Constants::FeatureFlag
14
14
 
15
15
  def initialize(options)
16
16
  @options = options
@@ -10,6 +10,7 @@ module Dri
10
10
  class Fetch
11
11
  class Pipelines < Dri::Command # rubocop:disable Metrics/ClassLength
12
12
  include Dri::Utils::Table
13
+ include Dri::Utils::Constants
13
14
  using Refinements
14
15
 
15
16
  NUM_OF_TESTS_LIVE_ENV = 1000
@@ -27,7 +28,7 @@ module Dri
27
28
  table_labels = define_table_labels
28
29
 
29
30
  spinner.run do
30
- Dri::Utils::Constants::PIPELINE_ENVIRONMENTS.each do |environment, details|
31
+ PIPELINE_ENVIRONMENTS.each do |environment, details|
31
32
  logger.info "Fetching last executed #{environment} pipeline"
32
33
  pipelines << fetch_pipeline(pipeline_name: environment.to_s, details: details)
33
34
  logger.info "Fetching complete for #{environment} ✓"
@@ -2,12 +2,14 @@
2
2
 
3
3
  require_relative '../../command'
4
4
  require_relative '../../utils/table'
5
+ require_relative '../../utils/constants'
5
6
 
6
7
  module Dri
7
8
  module Commands
8
9
  class Fetch
9
10
  class Quarantines < Dri::Command
10
11
  include Dri::Utils::Table
12
+ include Dri::Utils::Constants::Triage::Labels
11
13
  using Refinements
12
14
 
13
15
  def initialize(options, search: '[QUARANTINE]')
@@ -30,7 +32,7 @@ module Dri
30
32
  spinner.run do
31
33
  response = api_client.fetch_mrs(
32
34
  project_id: 'gitlab-org/gitlab',
33
- labels: 'QA,Quality',
35
+ labels: "#{QA},#{QUALITY}",
34
36
  search: @search,
35
37
  in: :title,
36
38
  state: :opened
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../command'
4
+ require_relative '../../utils/constants'
5
+ require 'tty-markdown'
6
+ require 'tty-prompt'
7
+ require 'base64'
8
+
9
+ module Dri
10
+ module Commands
11
+ class Fetch
12
+ class Runbooks < Dri::Command
13
+ def initialize(options)
14
+ @options = options
15
+ end
16
+
17
+ def execute(folder: nil, input: $stdin, output: $stdout)
18
+ return fetch_summary(output: output) unless folder
19
+
20
+ fetch_runbook("#{folder}/index.md", output: output)
21
+ end
22
+
23
+ def fetch_summary(output:)
24
+ logger.info 'Fetching runbooks'
25
+ prompt = TTY::Prompt.new
26
+ runbooks = api_client.list_runbooks
27
+
28
+ return output.puts 'No runbooks could be found' if runbooks.empty?
29
+
30
+ choices = runbooks.map(&:path)
31
+ path = prompt.select('Which runbook would you like to look at?', choices)
32
+
33
+ fetch_runbook("#{path}/index.md", output: output)
34
+ end
35
+
36
+ def fetch_runbook(path, output:)
37
+ runbook = nil
38
+ spinner.run do
39
+ runbook = api_client.get_file(
40
+ path,
41
+ ref: 'main',
42
+ project_id: Utils::Constants::ProjectIDs::RUNBOOKS_PROJECT_ID
43
+ )
44
+ rescue Gitlab::Error::NotFound
45
+ logger.error "The runbook #{path} could not be found."
46
+ end
47
+
48
+ return unless runbook
49
+
50
+ content = Base64.decode64(runbook.content)
51
+ markdown(content, output)
52
+ end
53
+
54
+ private
55
+
56
+ def markdown(str, io)
57
+ io.puts TTY::Markdown.parse(str, symbols: :ascii)
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -2,12 +2,14 @@
2
2
 
3
3
  require_relative '../../command'
4
4
  require_relative '../../utils/table'
5
+ require_relative '../../utils/constants'
5
6
 
6
7
  module Dri
7
8
  module Commands
8
9
  class Fetch
9
10
  class Triaged < Dri::Command
10
11
  include Dri::Utils::Table
12
+ include Dri::Utils::Constants::Triage::Labels
11
13
  using Refinements
12
14
 
13
15
  def initialize(options)
@@ -27,21 +29,21 @@ module Dri
27
29
  logger.info "Fetching your triaged failures..."
28
30
  spinner.start
29
31
 
30
- response = api_client.fetch_triaged_failures(emoji: emoji, state: 'opened')
32
+ failures = api_client.fetch_all_triaged_failures(emoji: emoji, state: 'opened')
31
33
 
32
- if response.empty?
34
+ if failures.empty?
33
35
  logger.info "There are no failures triaged yet with #{add_color(emoji, :black, :on_white)}."
34
36
  exit 0
35
37
  end
36
38
 
37
- response.each do |triaged|
39
+ failures.each do |triaged|
38
40
  title = triaged["title"].truncate(70)
39
41
  url = triaged["web_url"]
40
42
  labels = triaged["labels"]
41
43
  type = ""
42
44
 
43
45
  labels.each do |label|
44
- type = label.gsub!('failure::', ' ').to_s if label.include? "failure::"
46
+ type = label.gsub!(FAILURE, ' ').to_s if label.include? FAILURE
45
47
  end
46
48
 
47
49
  failures_triaged << [title, url, type]
@@ -94,6 +94,17 @@ module Dri
94
94
  require_relative 'fetch/pipelines'
95
95
  Dri::Commands::Fetch::Pipelines.new(options).execute
96
96
  end
97
+
98
+ desc 'runbooks', 'Fetch runbooks'
99
+ method_option :help, aliases: '-h', type: :boolean,
100
+ desc: 'Display usage information'
101
+
102
+ def runbooks(*args)
103
+ return invoke :help, %w[runbooks] if options[:help]
104
+
105
+ require_relative 'fetch/runbooks'
106
+ Dri::Commands::Fetch::Runbooks.new(options).execute(folder: args.first)
107
+ end
97
108
  end
98
109
  end
99
110
  end
@@ -2,11 +2,13 @@
2
2
 
3
3
  require_relative '../command'
4
4
  require_relative '../utils/table'
5
+ require_relative '../utils/constants'
5
6
 
6
7
  module Dri
7
8
  module Commands
8
9
  class Incidents < Dri::Command
9
10
  include Dri::Utils::Table
11
+ include Dri::Utils::Constants::Triage::Labels
10
12
  using Refinements
11
13
 
12
14
  def initialize(options)
@@ -42,8 +44,8 @@ module Dri
42
44
  service = "N/A"
43
45
 
44
46
  labels.each do |label|
45
- status = label.gsub!('Incident::', ' ').to_s if label.include? "Incident::"
46
- service = label.gsub!('Service::', ' ').to_s if label.include? "Service::"
47
+ status = label.gsub!(INCIDENT, ' ').to_s if label.include? INCIDENT
48
+ service = label.gsub!(SERVICE, ' ').to_s if label.include? SERVICE
47
49
  end
48
50
 
49
51
  incidents << [title, service, status, url]
@@ -2,7 +2,7 @@
2
2
 
3
3
  require_relative '../../command'
4
4
  require_relative '../../utils/markdown_lists'
5
- require_relative '../../utils/feature_flag_consts'
5
+ require_relative '../../utils/constants'
6
6
  require_relative '../../report'
7
7
  require_relative '../../feature_flag_report'
8
8
 
@@ -14,7 +14,7 @@ module Dri
14
14
  module Commands
15
15
  class Publish
16
16
  class Report < Dri::Command # rubocop:disable Metrics/ClassLength
17
- include Dri::Utils::FeatureFlagConsts
17
+ include Dri::Utils::Constants::FeatureFlag
18
18
 
19
19
  def initialize(options)
20
20
  @options = options
@@ -32,13 +32,13 @@ module Dri
32
32
 
33
33
  spinner.start
34
34
 
35
- issues = api_client.fetch_triaged_failures(emoji: emoji, state: 'opened')
35
+ failures = api_client.fetch_all_triaged_failures(emoji: emoji, state: 'opened')
36
36
  incidents = api_client.fetch_triaged_incidents(emoji: emoji)
37
37
 
38
38
  spinner.stop
39
39
 
40
- if issues.empty? && incidents.empty?
41
- logger.warn "Found no issues nor incidents associated with \"#{emoji}\" emoji. Will exit. Bye 👋"
40
+ if failures.empty? && incidents.empty?
41
+ logger.warn "Found no failures nor incidents associated with \"#{emoji}\" emoji. Will exit. Bye 👋"
42
42
  exit 1
43
43
  end
44
44
 
@@ -58,18 +58,18 @@ module Dri
58
58
 
59
59
  spinner.start
60
60
 
61
- issues.each do |issue|
61
+ failures.each do |failure|
62
62
  actions = []
63
63
 
64
64
  if @options[:actions]
65
65
  actions = prompt.multi_select(
66
- "Please mark the actions on #{add_color(issue.title, :yellow)}: ",
66
+ "Please mark the actions on #{add_color(failure.title, :yellow)}: ",
67
67
  action_options,
68
68
  per_page: 9
69
69
  )
70
70
  end
71
71
 
72
- report.add_failure(issue, actions)
72
+ report.add_failure(failure, actions)
73
73
  end
74
74
 
75
75
  unless incidents.empty?
@@ -180,11 +180,29 @@ module Dri
180
180
  issues = api_client.fetch_current_triage_issue
181
181
  current_issue_iid = issues.first.iid
182
182
 
183
- api_client.post_triage_report_note(iid: current_issue_iid, body: note)
183
+ note_action = 'posted'
184
+ posted_note = nil
185
+ if @options[:update]
186
+ report_file = File.read("handover_reports/.tmp/report-#{@date}.json")
187
+ report_json = JSON.parse(report_file) if report_file
188
+ posted_note = api_client.update_triage_report_note(
189
+ iid: current_issue_iid, note_id: report_json['id'], body: note
190
+ )
191
+ note_action = 'updated'
192
+ else
193
+ posted_note = api_client.post_triage_report_note(iid: current_issue_iid, body: note)
194
+
195
+ FileUtils.mkdir_p("#{Dir.pwd}/handover_reports/.tmp")
196
+ report_path = "handover_reports/.tmp/report-#{@date}.json"
197
+
198
+ File.open(report_path, 'w') do |out_file|
199
+ out_file.write(posted_note.to_h.to_json)
200
+ end
201
+ end
184
202
 
185
203
  output.puts "Done! ✅\n"
186
204
  logger.success(<<~MSG)
187
- Thanks @#{username}, your report was posted at https://gitlab.com/gitlab-org/quality/pipeline-triage/-/issues/#{current_issue_iid} 🎉
205
+ Thanks @#{username}, your report was #{note_action} at https://gitlab.com/gitlab-org/quality/pipeline-triage/-/issues/#{current_issue_iid}#note_#{posted_note.id} 🎉
188
206
  MSG
189
207
  end
190
208
 
@@ -16,6 +16,9 @@ module Dri
16
16
  desc: 'Updates actions on failures'
17
17
  method_option :feature_flags, type: :boolean,
18
18
  desc: 'Adds summary of feature flag changes'
19
+ method_option :update, aliases: '-u', type: :boolean,
20
+ desc: 'Updates an existing report'
21
+
19
22
  def report(*)
20
23
  if options[:help]
21
24
  invoke :help, ['report']
@@ -24,7 +24,7 @@ module Dri
24
24
 
25
25
  spinner.start
26
26
 
27
- failures_with_award_emoji = api_client.fetch_triaged_failures(emoji: emoji, state: 'opened')
27
+ failures_with_award_emoji = api_client.fetch_all_triaged_failures(emoji: emoji, state: 'opened')
28
28
  incidents_with_award_emoji = api_client.fetch_triaged_incidents(emoji: emoji)
29
29
 
30
30
  issues_with_award_emoji = failures_with_award_emoji + incidents_with_award_emoji
@@ -1,10 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative './utils/feature_flag_consts'
3
+ require_relative './utils/constants'
4
4
 
5
5
  module Dri
6
6
  class FeatureFlagReport
7
- include Dri::Utils::FeatureFlagConsts
7
+ include Dri::Utils::Constants::FeatureFlag::Labels
8
8
 
9
9
  attr_reader :header, :labels, :prod, :staging, :staging_ref, :preprod
10
10
 
data/lib/dri/report.rb CHANGED
@@ -1,7 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative './utils/constants'
4
+
3
5
  module Dri
4
6
  class Report # rubocop:disable Metrics/ClassLength
7
+ include Dri::Utils::Constants::Triage::Labels
5
8
  using Refinements
6
9
 
7
10
  attr_reader :header, :failures, :labels, :labels_incidents, :incidents
@@ -31,24 +34,23 @@ module Dri
31
34
  service = 'N/A'
32
35
 
33
36
  labels.each do |label|
34
- status = label.gsub!('Incident::', ' ').to_s if label.include? "Incident::"
35
- service = label.gsub!('Service::', ' ').to_s if label.include? "Service::"
37
+ status = label.gsub!(INCIDENT, ' ').to_s if label.include? INCIDENT
38
+ service = label.gsub!(SERVICE, ' ').to_s if label.include? SERVICE
36
39
  end
37
40
 
38
41
  @incidents << [title, service, status, url]
39
42
  end
40
43
 
41
44
  def add_failure(failure, actions_opts = [])
45
+ project_id = failure["project_id"]
42
46
  iid = failure["iid"]
43
47
  title = format_title(failure["title"])
44
48
  link = failure["web_url"]
45
49
  labels = failure["labels"]
46
- created_at = failure["created_at"]
47
- assignees = failure["assignees"]
48
50
  description = failure["description"]
49
51
 
50
- related_mrs = @api_client.fetch_related_mrs(iid)
51
- emoji = classify_failure_emoji(created_at)
52
+ related_mrs = @api_client.fetch_related_mrs(project_id, iid)
53
+ emoji = classify_failure_emoji(failure["created_at"])
52
54
  emojified_link = "#{emoji} #{link}"
53
55
 
54
56
  stack_blob = if description.empty?
@@ -60,10 +62,10 @@ module Dri
60
62
  stack_trace = ":link:[`#{stack_blob}...`](#{link}#stack-trace)"
61
63
 
62
64
  failure_type = filter_failure_type_labels(labels)
63
- assigned_status = assigned?(assignees)
65
+ assigned_status = assigned?(failure["assignees"])
64
66
  pipelines = filter_pipeline_labels(labels)
65
67
 
66
- linked_pipelines = link_pipelines(iid, pipelines, description)
68
+ linked_pipelines = link_pipelines(project_id, iid, pipelines, description)
67
69
 
68
70
  actions_status = actions_status_template(failure_type, assigned_status, actions_opts)
69
71
  actions_fixes = actions_fixes_template(related_mrs)
@@ -73,7 +75,7 @@ module Dri
73
75
 
74
76
  private
75
77
 
76
- def link_pipelines(iid, pipelines, description) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/MethodLength
78
+ def link_pipelines(project_id, iid, pipelines, description) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/MethodLength
77
79
  linked = []
78
80
  label_pipeline_map = {
79
81
  'gitlab.com' => '/quality/production',
@@ -88,7 +90,7 @@ module Dri
88
90
  'release' => '/quality/release'
89
91
  }
90
92
 
91
- failure_notes = @api_client.fetch_failure_notes(iid)
93
+ failure_notes = @api_client.fetch_failure_notes(project_id, iid)
92
94
 
93
95
  return if pipelines.empty?
94
96
 
@@ -173,10 +175,10 @@ module Dri
173
175
  pipelines = []
174
176
 
175
177
  labels.each do |label|
176
- matchers = { 'found:' => ' ' }
178
+ matchers = { FOUND => ' ' }
177
179
 
178
- if label.include? "found:"
179
- pipeline = label.gsub(/found:/) { |match| matchers[match] }
180
+ if label.include? FOUND
181
+ pipeline = label.gsub(/#{FOUND}/o) { |match| matchers[match] }
180
182
  pipelines << pipeline.strip
181
183
  end
182
184
  end
@@ -185,7 +187,7 @@ module Dri
185
187
 
186
188
  def filter_failure_type_labels(labels)
187
189
  labels.each do |label|
188
- @type = label.gsub!('failure::', ' ').to_s if label.include? "failure::"
190
+ @type = label.gsub!(FAILURE, ' ').to_s if label.include? FAILURE
189
191
  end
190
192
  @type
191
193
  end
@@ -3,6 +3,40 @@
3
3
  module Dri
4
4
  module Utils
5
5
  module Constants
6
+ module ProjectIDs
7
+ TESTCASES_PROJECT_ID = 11229385
8
+ TRIAGE_PROJECT_ID = 15291320
9
+ GITLAB_PROJECT_ID = 278964
10
+ CUSTOMERSDOT_PROJECT_ID = 2670515
11
+ FEATURE_FLAG_LOG_PROJECT_ID = 15208716
12
+ INFRA_TEAM_PROD_PROJECT_ID = 7444821
13
+ RUNBOOKS_PROJECT_ID = 41045213
14
+ end
15
+
16
+ module Triage
17
+ module Labels
18
+ FOUND = 'found:'
19
+ FAILURE = 'failure::'
20
+ FAILURE_NEW = "#{FAILURE}new"
21
+ INCIDENT = 'Incident::'
22
+ SERVICE = 'Service::'
23
+ QA = 'QA'
24
+ QUALITY = 'Quality'
25
+ QUARANTINE = 'quarantine'
26
+ end
27
+ end
28
+
29
+ module FeatureFlag
30
+ module Labels
31
+ PRODUCTION = 'host::gitlab.com'
32
+ STAGING = 'host::staging.gitlab.com'
33
+ STAGING_REF = 'host::staging-ref.gitlab.com'
34
+ PREPROD = 'host::pre.gitlab.com'
35
+ end
36
+
37
+ TITLE_SUBSTRINGS = ["set to \"true\"", "set to \"false\""].freeze
38
+ end
39
+
6
40
  PIPELINE_ENVIRONMENTS =
7
41
  {
8
42
  production: {
data/lib/dri/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Dri
4
- VERSION = "0.7.0"
4
+ VERSION = "0.9.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dri
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - GitLab Quality
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-09-12 00:00:00.000000000 Z
11
+ date: 2023-03-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: amatch
@@ -30,28 +30,28 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '4.18'
33
+ version: '4.19'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '4.18'
40
+ version: '4.19'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: httparty
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 0.20.0
47
+ version: 0.21.0
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: 0.20.0
54
+ version: 0.21.0
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: json
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -100,14 +100,14 @@ dependencies:
100
100
  requirements:
101
101
  - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: 1.0.1
103
+ version: 1.2.0
104
104
  type: :runtime
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: 1.0.1
110
+ version: 1.2.0
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: tty-box
113
113
  requirement: !ruby/object:Gem::Requirement
@@ -128,28 +128,28 @@ dependencies:
128
128
  requirements:
129
129
  - - "~>"
130
130
  - !ruby/object:Gem::Version
131
- version: 0.4.0
131
+ version: 0.6.0
132
132
  type: :runtime
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
136
  - - "~>"
137
137
  - !ruby/object:Gem::Version
138
- version: 0.4.0
138
+ version: 0.6.0
139
139
  - !ruby/object:Gem::Dependency
140
140
  name: tty-editor
141
141
  requirement: !ruby/object:Gem::Requirement
142
142
  requirements:
143
143
  - - "~>"
144
144
  - !ruby/object:Gem::Version
145
- version: '0.6'
145
+ version: '0.7'
146
146
  type: :runtime
147
147
  prerelease: false
148
148
  version_requirements: !ruby/object:Gem::Requirement
149
149
  requirements:
150
150
  - - "~>"
151
151
  - !ruby/object:Gem::Version
152
- version: '0.6'
152
+ version: '0.7'
153
153
  - !ruby/object:Gem::Dependency
154
154
  name: tty-font
155
155
  requirement: !ruby/object:Gem::Requirement
@@ -178,6 +178,20 @@ dependencies:
178
178
  - - "~>"
179
179
  - !ruby/object:Gem::Version
180
180
  version: 0.6.0
181
+ - !ruby/object:Gem::Dependency
182
+ name: tty-markdown
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - "~>"
186
+ - !ruby/object:Gem::Version
187
+ version: 0.7.0
188
+ type: :runtime
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - "~>"
193
+ - !ruby/object:Gem::Version
194
+ version: 0.7.0
181
195
  - !ruby/object:Gem::Dependency
182
196
  name: tty-prompt
183
197
  requirement: !ruby/object:Gem::Requirement
@@ -315,6 +329,7 @@ files:
315
329
  - ".editorconfig"
316
330
  - ".gitignore"
317
331
  - ".gitlab-ci.yml"
332
+ - ".gitlab/merge_request_templates/Release.md"
318
333
  - ".rspec"
319
334
  - ".rubocop.yml"
320
335
  - ".ruby-version"
@@ -339,6 +354,7 @@ files:
339
354
  - lib/dri/commands/fetch/featureflags.rb
340
355
  - lib/dri/commands/fetch/pipelines.rb
341
356
  - lib/dri/commands/fetch/quarantines.rb
357
+ - lib/dri/commands/fetch/runbooks.rb
342
358
  - lib/dri/commands/fetch/testcases.rb
343
359
  - lib/dri/commands/fetch/triaged.rb
344
360
  - lib/dri/commands/incidents.rb
@@ -355,7 +371,6 @@ files:
355
371
  - lib/dri/refinements/truncate.rb
356
372
  - lib/dri/report.rb
357
373
  - lib/dri/utils/constants.rb
358
- - lib/dri/utils/feature_flag_consts.rb
359
374
  - lib/dri/utils/markdown_lists.rb
360
375
  - lib/dri/utils/table.rb
361
376
  - lib/dri/version.rb
@@ -1,13 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Dri
4
- module Utils
5
- module FeatureFlagConsts
6
- PRODUCTION = 'host::gitlab.com'
7
- STAGING = 'host::staging.gitlab.com'
8
- STAGING_REF = 'host::staging-ref.gitlab.com'
9
- PREPROD = 'host::pre.gitlab.com'
10
- TITLE_SUBSTRINGS = ["set to \"true\"", "set to \"false\""].freeze
11
- end
12
- end
13
- end