dri 0.10.2 → 1.1.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.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/.gitlab/changelog_config.yml +13 -0
  3. data/.gitlab/merge_request_templates/Default.md +27 -0
  4. data/.gitlab/merge_request_templates/Release.md +8 -23
  5. data/.gitlab-ci.yml +6 -4
  6. data/.rubocop.yml +9 -1
  7. data/.ruby-version +1 -1
  8. data/.tool-versions +1 -1
  9. data/CODE_OF_CONDUCT.md +74 -0
  10. data/Gemfile.lock +58 -32
  11. data/README.md +88 -113
  12. data/dri.gemspec +9 -4
  13. data/exe/dri +2 -1
  14. data/faq.yaml +7 -7
  15. data/lefthook.yml +24 -0
  16. data/lib/dri/api_client.rb +66 -25
  17. data/lib/dri/cli.rb +2 -11
  18. data/lib/dri/command.rb +21 -52
  19. data/lib/dri/commands/add/fast_quarantine.rb +72 -0
  20. data/lib/dri/commands/add.rb +45 -0
  21. data/lib/dri/commands/analyze/stack_traces.rb +1 -4
  22. data/lib/dri/commands/analyze.rb +0 -1
  23. data/lib/dri/commands/faq.rb +1 -2
  24. data/lib/dri/commands/fetch/failures.rb +102 -43
  25. data/lib/dri/commands/fetch/{featureflags.rb → feature_flags.rb} +1 -6
  26. data/lib/dri/commands/fetch/pipelines.rb +3 -7
  27. data/lib/dri/commands/fetch/runbooks.rb +1 -3
  28. data/lib/dri/commands/fetch/testcases.rb +1 -3
  29. data/lib/dri/commands/fetch/triaged.rb +2 -6
  30. data/lib/dri/commands/fetch.rb +0 -30
  31. data/lib/dri/commands/incidents.rb +2 -6
  32. data/lib/dri/commands/init.rb +1 -3
  33. data/lib/dri/commands/profile.rb +3 -5
  34. data/lib/dri/commands/publish/report.rb +24 -26
  35. data/lib/dri/commands/publish.rb +0 -1
  36. data/lib/dri/commands/rm/emoji.rb +1 -3
  37. data/lib/dri/commands/rm/profile.rb +1 -2
  38. data/lib/dri/commands/rm/reports.rb +1 -2
  39. data/lib/dri/commands/rm.rb +0 -3
  40. data/lib/dri/commands/view/fast_quarantine.rb +25 -0
  41. data/lib/dri/commands/view.rb +22 -0
  42. data/lib/dri/feature_flag_report.rb +1 -3
  43. data/lib/dri/refinements/gitlab.rb +22 -0
  44. data/lib/dri/refinements/string.rb +19 -0
  45. data/lib/dri/report.rb +13 -55
  46. data/lib/dri/support/configuration.rb +62 -0
  47. data/lib/dri/support/influxdb_tools.rb +37 -0
  48. data/lib/dri/utils/constants.rb +2 -1
  49. data/lib/dri/utils/helpers.rb +15 -0
  50. data/lib/dri/version.rb +1 -1
  51. data/lib/dri.rb +8 -1
  52. metadata +96 -16
  53. data/lib/dri/commands/fetch/quarantines.rb +0 -55
  54. data/lib/dri/gitlab/issues.rb +0 -19
  55. data/lib/dri/refinements/truncate.rb +0 -15
@@ -14,7 +14,6 @@ module Dri
14
14
  if options[:help]
15
15
  invoke :help, ['featureflags']
16
16
  else
17
- require_relative 'fetch/featureflags'
18
17
  Dri::Commands::Fetch::FeatureFlags.new(options).execute
19
18
  end
20
19
  end
@@ -26,7 +25,6 @@ module Dri
26
25
  if options[:help]
27
26
  invoke :help, ['triaged']
28
27
  else
29
- require_relative 'fetch/triaged'
30
28
  Dri::Commands::Fetch::Triaged.new(options).execute
31
29
  end
32
30
  end
@@ -40,7 +38,6 @@ module Dri
40
38
  if options[:help]
41
39
  invoke :help, ['testcases']
42
40
  else
43
- require_relative 'fetch/testcases'
44
41
  Dri::Commands::Fetch::Testcases.new(options).execute
45
42
  end
46
43
  end
@@ -48,8 +45,6 @@ module Dri
48
45
  desc 'failures', 'Display failures opened on a given period.'
49
46
  method_option :help, aliases: '-h', type: :boolean,
50
47
  desc: 'Display usage information'
51
- method_option :urgent, type: :boolean,
52
- desc: 'Shows failures that quickly escalated'
53
48
  method_option :sort_by, type: :string,
54
49
  desc: 'Shows failures in specified order'
55
50
  method_option :start_date, type: :string,
@@ -63,33 +58,10 @@ module Dri
63
58
  if options[:help]
64
59
  invoke :help, ['failures']
65
60
  else
66
- require_relative 'fetch/failures'
67
61
  Dri::Commands::Fetch::Failures.new(options).execute
68
62
  end
69
63
  end
70
64
 
71
- desc 'quarantines', 'Display open quarantine MRs'
72
- method_option :help, aliases: '-h', type: :boolean,
73
- desc: 'Display usage information'
74
- def quarantines(*)
75
- if options[:help]
76
- invoke :help, ['quarantines']
77
- else
78
- require_relative 'fetch/quarantines'
79
- Dri::Commands::Fetch::Quarantines.new(options, search: '[QUARANTINE]').execute
80
- end
81
- end
82
-
83
- desc 'dequarantines', 'Display open dequarantine MRs'
84
- method_option :help, aliases: '-h', type: :boolean,
85
- desc: 'Display usage information'
86
- def dequarantines(*)
87
- return invoke :help, %w[quarantines] if options[:help]
88
-
89
- require_relative 'fetch/quarantines'
90
- Dri::Commands::Fetch::Quarantines.new(options, search: '[DEQUARANTINE]').execute
91
- end
92
-
93
65
  desc 'pipelines', 'Display status of pipelines'
94
66
  method_option :help, aliases: '-h', type: :boolean,
95
67
  desc: 'Display pipelines usage information'
@@ -98,7 +70,6 @@ module Dri
98
70
  def pipelines(*)
99
71
  return invoke :help, %w[pipelines] if options[:help]
100
72
 
101
- require_relative 'fetch/pipelines'
102
73
  Dri::Commands::Fetch::Pipelines.new(options).execute
103
74
  end
104
75
 
@@ -109,7 +80,6 @@ module Dri
109
80
  def runbooks(*args)
110
81
  return invoke :help, %w[runbooks] if options[:help]
111
82
 
112
- require_relative 'fetch/runbooks'
113
83
  Dri::Commands::Fetch::Runbooks.new(options).execute(folder: args.first)
114
84
  end
115
85
  end
@@ -1,21 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../command'
4
- require_relative '../utils/table'
5
- require_relative '../utils/constants'
6
-
7
3
  module Dri
8
4
  module Commands
9
5
  class Incidents < Dri::Command
10
6
  include Dri::Utils::Table
11
7
  include Dri::Utils::Constants::Triage::Labels
12
- using Refinements
8
+ using Refinements::String
13
9
 
14
10
  def initialize(options)
15
11
  @options = options
16
12
  end
17
13
 
18
- def execute(input: $stdin, output: $stdout) # rubocop:disable Metrics/AbcSize
14
+ def execute(_input: $stdin, output: $stdout) # rubocop:disable Metrics/AbcSize
19
15
  verify_config_exists
20
16
 
21
17
  incident = add_color('Incident', :bright_yellow)
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../command'
4
-
5
3
  require "tty-font"
6
4
 
7
5
  module Dri
@@ -14,7 +12,7 @@ module Dri
14
12
  puts pastel.yellow(font.write("DRI"))
15
13
  end
16
14
 
17
- def execute(input: $stdin, output: $stdout) # rubocop:disable Metrics/AbcSize
15
+ def execute(_input: $stdin, output: $stdout) # rubocop:disable Metrics/AbcSize
18
16
  output.puts "🤖 Welcome to DRI 🤖\n"
19
17
 
20
18
  logger.info "🔎 Scanning for existing configurations...\n"
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../command'
4
-
5
3
  require 'tty-box'
6
4
 
7
5
  module Dri
@@ -11,7 +9,7 @@ module Dri
11
9
  @options = options
12
10
  end
13
11
 
14
- def execute(input: $stdin, output: $stdout)
12
+ def execute(_input: $stdin, output: $stdout)
15
13
  if config.exist? && @options["edit"]
16
14
  editor.open(config.source_file)
17
15
  return
@@ -39,13 +37,13 @@ module Dri
39
37
 
40
38
  def pretty_print_profile
41
39
  <<~PROFILE
42
- #{add_color('User:', :bright_cyan)} #{username}
40
+ #{add_color('User:', :bright_cyan)} #{username}#{' '}
43
41
  #{add_color('Token:', :bright_cyan)} #{token}
44
42
  #{add_color('OpsToken:', :bright_cyan)} #{ops_token}
45
43
  #{add_color('Timezone:', :bright_cyan)} #{timezone}
46
44
  #{add_color('Emoji:', :bright_cyan)} #{emoji}
47
45
  #{add_color('Report Path:', :bright_cyan)} #{handover_report_path}
48
-
46
+
49
47
  PROFILE
50
48
  end
51
49
  end
@@ -1,14 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../../command'
4
- require_relative '../../utils/markdown_lists'
5
- require_relative '../../utils/constants'
6
- require_relative '../../report'
7
- require_relative '../../feature_flag_report'
8
-
9
3
  require 'markdown-tables'
10
4
  require 'fileutils'
11
5
  require 'uri'
6
+ require 'date'
12
7
 
13
8
  module Dri
14
9
  module Commands
@@ -24,7 +19,7 @@ module Dri
24
19
  @today_iso_format = Time.now.strftime('%Y-%m-%dT00:00:00Z')
25
20
  end
26
21
 
27
- def execute(input: $stdin, output: $stdout) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/MethodLength
22
+ def execute(_input: $stdin, output: $stdout) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/MethodLength
28
23
  verify_config_exists
29
24
  report = Dri::Report.new(config)
30
25
 
@@ -161,43 +156,34 @@ module Dri
161
156
  logger.info 'Downloading the report... '
162
157
 
163
158
  spinner.start
164
-
165
- FileUtils.mkdir_p(handover_report_path)
166
- report_path = "#{handover_report_path.chomp('/')}/report-#{@date}-#{@time}.md"
167
-
168
- File.open(report_path, 'a') do |out_file|
169
- out_file.puts note
170
- end
171
-
159
+ report_md = File.join(handover_report_path, "report-#{@date}-#{@time}.md")
160
+ File.write(report_md, note)
172
161
  spinner.stop
173
162
 
174
163
  output.puts "Done! ✅\n"
175
- logger.success "Report is ready at: #{report_path}"
164
+ logger.success "Report is ready at: #{report_md}"
176
165
  exit 0
177
166
  end
178
167
 
179
168
  # sends note to the weekly triage report
180
169
  issues = api_client.fetch_current_triage_issue
181
- current_issue_iid = issues.first.iid
170
+ current_issue_iid = issues.iid
182
171
 
183
172
  note_action = 'posted'
184
173
  posted_note = nil
185
174
  if @options[:update]
186
- report_file = File.read("handover_reports/.tmp/report-#{@date}.json")
187
- report_json = JSON.parse(report_file) if report_file
175
+ unless File.exist?(report_json_file)
176
+ return logger.warn("Update action requires initial publish to be executed first!")
177
+ end
178
+
179
+ report_json = JSON.parse(File.read(report_json_file))
188
180
  posted_note = api_client.update_triage_report_note(
189
181
  iid: current_issue_iid, note_id: report_json['id'], body: note
190
182
  )
191
183
  note_action = 'updated'
192
184
  else
193
185
  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
186
+ File.write(report_json_file, posted_note.to_h.to_json)
201
187
  end
202
188
 
203
189
  output.puts "Done! ✅\n"
@@ -208,6 +194,18 @@ module Dri
208
194
 
209
195
  private
210
196
 
197
+ def report_json_file
198
+ @report_json ||= File.join(handover_tmp_dir, "report-#{@date}.json")
199
+ end
200
+
201
+ def handover_tmp_dir
202
+ @handover_tmp_dir ||= File.join(handover_report_path, ".tmp").tap { |dir| FileUtils.mkdir_p(dir) }
203
+ end
204
+
205
+ def handover_report_path
206
+ @handover_report_path ||= super.tap { |dir| FileUtils.mkdir_p(dir) }
207
+ end
208
+
211
209
  def format_feature_flag_changes(env, changes, labels, format_type)
212
210
  unless format_type == :table || format_type == :list
213
211
  raise ArgumentError, 'format_type must be one of type :table or :list'
@@ -23,7 +23,6 @@ module Dri
23
23
  if options[:help]
24
24
  invoke :help, ['report']
25
25
  else
26
- require_relative 'publish/report'
27
26
  Dri::Commands::Publish::Report.new(options).execute
28
27
  end
29
28
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../../command'
4
-
5
3
  module Dri
6
4
  module Commands
7
5
  class Rm
@@ -10,7 +8,7 @@ module Dri
10
8
  @options = options
11
9
  end
12
10
 
13
- def execute(input: $stdin, output: $stdout) # rubocop:disable Metrics/AbcSize
11
+ def execute(_input: $stdin, output: $stdout) # rubocop:disable Metrics/AbcSize
14
12
  verify_config_exists
15
13
 
16
14
  remove = prompt.yes? "Are you sure you want to remove all #{emoji} award emojis from issues?"
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../../command'
4
3
  require 'fileutils'
5
4
 
6
5
  module Dri
@@ -11,7 +10,7 @@ module Dri
11
10
  @options = options
12
11
  end
13
12
 
14
- def execute(input: $stdin, output: $stdout)
13
+ def execute(*)
15
14
  verify_config_exists
16
15
 
17
16
  remove = prompt.yes? "Are you sure you want to remove existing profile?"
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../../command'
4
3
  require 'fileutils'
5
4
 
6
5
  module Dri
@@ -11,7 +10,7 @@ module Dri
11
10
  @options = options
12
11
  end
13
12
 
14
- def execute(input: $stdin, output: $stdout)
13
+ def execute(*)
15
14
  FileUtils.rm_rf(handover_report_path) if prompt.yes?("Remove everything in #{handover_report_path}?")
16
15
  end
17
16
  end
@@ -14,7 +14,6 @@ module Dri
14
14
  if options[:help]
15
15
  invoke :help, ['profile']
16
16
  else
17
- require_relative 'rm/profile'
18
17
  Dri::Commands::Rm::Profile.new(options).execute
19
18
  end
20
19
  end
@@ -26,7 +25,6 @@ module Dri
26
25
  if options[:help]
27
26
  invoke :help, ['reports']
28
27
  else
29
- require_relative 'rm/reports'
30
28
  Dri::Commands::Rm::Reports.new(options).execute
31
29
  end
32
30
  end
@@ -38,7 +36,6 @@ module Dri
38
36
  if options[:help]
39
37
  invoke :help, ['emoji']
40
38
  else
41
- require_relative 'rm/emoji'
42
39
  Dri::Commands::Rm::Emoji.new(options).execute
43
40
  end
44
41
  end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dri
4
+ module Commands
5
+ class View
6
+ class FastQuarantine < Dri::Command
7
+ def initialize(options)
8
+ @options = options
9
+ end
10
+
11
+ def execute(*)
12
+ verify_config_exists
13
+
14
+ logger.info "Fetching fast quarantined tests..."
15
+
16
+ file_content = api_client.get_fast_quarantine_tests
17
+
18
+ file_content.each_line do |line|
19
+ puts "• #{line}"
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'thor'
4
+
5
+ module Dri
6
+ module Commands
7
+ class View < Thor
8
+ namespace :view
9
+
10
+ desc 'fastquarantine', 'View fast-quarantine tests'
11
+ method_option :help, aliases: '-h', type: :boolean,
12
+ desc: 'Display usage information'
13
+ def fastquarantine(*)
14
+ if options[:help]
15
+ invoke :help, ['fastquarantine']
16
+ else
17
+ Dri::Commands::View::FastQuarantine.new(options).execute
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative './utils/constants'
4
-
5
3
  module Dri
6
4
  class FeatureFlagReport
7
5
  include Dri::Utils::Constants::FeatureFlag::Labels
@@ -26,7 +24,7 @@ module Dri
26
24
  feature_flag_data = [summary, changed_on, url]
27
25
 
28
26
  labels = feature_flag.labels
29
- host_label = labels.select { |label| /^host::/.match(label) }.join('')
27
+ host_label = labels.select { |label| /^host::/.match(label) }.join
30
28
 
31
29
  case host_label
32
30
  when PRODUCTION
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Gitlab gem refinement for related merge requests
4
+ # TODO: Add method upstream (https://github.com/NARKOZ/gitlab/pull/683)
5
+ module Dri
6
+ module Refinements
7
+ module Gitlab
8
+ refine ::Gitlab::Client::Issues do
9
+ # List related merge requests
10
+ #
11
+ # @example
12
+ # Gitlab.related_issue_merge_requests(3, 42)
13
+ #
14
+ # @param [Integer, String] project The ID or name of a project.
15
+ # @param [Integer] id The ID of an issue.
16
+ def related_issue_merge_requests(project, id)
17
+ get("/projects/#{url_encode project}/issues/#{id}/related_merge_requests")
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dri
4
+ module Refinements
5
+ module String
6
+ refine ::String do
7
+ # Truncate string to limit of _n_ characters
8
+ # @param [Integer] limit the limit of characters
9
+ # @return [String] the resulting string after truncation
10
+ def truncate(limit = 50)
11
+ return freeze if size <= limit
12
+
13
+ # limit - 3 for the ellipses
14
+ self[0...(limit - 3)] << '...'
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
data/lib/dri/report.rb CHANGED
@@ -1,11 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative './utils/constants'
4
-
5
3
  module Dri
6
4
  class Report # rubocop:disable Metrics/ClassLength
7
5
  include Dri::Utils::Constants::Triage::Labels
8
- using Refinements
6
+ using Refinements::String
9
7
 
10
8
  attr_reader :header, :failures, :labels, :labels_incidents, :incidents
11
9
 
@@ -63,66 +61,17 @@ module Dri
63
61
 
64
62
  failure_type = filter_failure_type_labels(labels)
65
63
  assigned_status = assigned?(failure["assignees"])
66
- pipelines = filter_pipeline_labels(labels)
67
-
68
- linked_pipelines = link_pipelines(project_id, iid, pipelines, description)
64
+ pipelines = format_pipelines(labels)
69
65
 
70
66
  actions_status = actions_status_template(failure_type, assigned_status, actions_opts)
71
67
  actions_fixes = actions_fixes_template(related_mrs)
72
68
 
73
- @failures << [title, emojified_link, linked_pipelines, stack_trace, "#{actions_status}#{actions_fixes}"]
69
+ @failures << [title, emojified_link, pipelines, stack_trace, "#{actions_status}#{actions_fixes}"]
74
70
  end
75
71
 
76
72
  private
77
73
 
78
- def link_pipelines(project_id, iid, pipelines, description) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/MethodLength
79
- linked = []
80
- label_pipeline_map = {
81
- 'gitlab.com' => '/quality/production',
82
- 'canary.gitlab.com' => '/quality/canary',
83
- 'canary.staging.gitlab.com' => '/quality/staging-canary',
84
- 'main' => '/gitlab-org/gitlab-qa-mirror',
85
- 'master' => '/gitlab-org/gitlab-qa-mirror',
86
- 'pre.gitlab.com' => '/quality/preprod',
87
- 'staging-ref' => '/quality/staging-ref',
88
- 'staging.gitlab.com' => '/quality/staging',
89
- 'release' => '/quality/release'
90
- }
91
-
92
- failure_notes = @api_client.fetch_failure_notes(project_id, iid)
93
-
94
- return if pipelines.empty?
95
-
96
- pipelines.each do |pipeline|
97
- next unless label_pipeline_map.has_key?(pipeline)
98
-
99
- pipeline_in_notes_found = false
100
- pipeline_link = ''
101
- pipeline_markdown = pipeline.gsub(/.gitlab.com/, '')
102
-
103
- failure_notes.each do |note|
104
- next unless note.body.include?(label_pipeline_map.fetch(pipeline))
105
-
106
- pipeline_in_notes_found = true
107
- pipeline_link = URI.extract(note.body, %w[https])
108
- end
109
-
110
- unless pipeline_in_notes_found
111
- links_description = URI.extract(description, %w[https])
112
- pipeline_link = links_description.select { |link| link.include? label_pipeline_map.fetch(pipeline) }
113
- end
114
-
115
- unless pipeline_link.empty?
116
- pipeline_link_sanitized = pipeline_link.join.strip
117
- pipeline_markdown = "[#{pipeline_markdown}](#{pipeline_link_sanitized})"
118
- end
119
-
120
- linked << pipeline_markdown
121
- end
122
- linked.join(', ')
123
- end
124
-
125
- def actions_status_template(failure_type, assigned_status, actions_opts) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity/MethodLength
74
+ def actions_status_template(failure_type, assigned_status, actions_opts) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity/
126
75
  quarantined = ''
127
76
  reproduced = ''
128
77
  transient = ''
@@ -184,6 +133,15 @@ module Dri
184
133
  pipelines
185
134
  end
186
135
 
136
+ def format_pipelines(labels)
137
+ labels.filter_map do |label|
138
+ next unless label.include?(FOUND)
139
+
140
+ sanitized_label = label.gsub(FOUND, ' ').strip
141
+ sanitized_label.gsub(/.gitlab.com/, '')
142
+ end.join(', ')
143
+ end
144
+
187
145
  def filter_failure_type_labels(labels)
188
146
  labels.each do |label|
189
147
  @type = label.gsub!(FAILURE, ' ').to_s if label.include? FAILURE
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "tzinfo"
4
+ require "tty-config"
5
+
6
+ module Dri
7
+ module Support
8
+ class Configuration
9
+ include Utils::Helpers
10
+
11
+ TZ = {
12
+ "AMER" => "America/New_York",
13
+ "EMEA" => "Europe/London",
14
+ "APAC" => "Asia/Tokyo"
15
+ }.freeze
16
+
17
+ def initialize
18
+ @config = TTY::Config.new do |conf|
19
+ conf.filename = ".dri_profile"
20
+ conf.extname = ".yml"
21
+ conf.append_path Dir.home
22
+ conf.append_path Dir.pwd
23
+ end
24
+ end
25
+
26
+ attr_reader :config
27
+
28
+ def profile
29
+ @profile ||= config.read
30
+ end
31
+
32
+ def emoji
33
+ @emoji ||= profile["settings"]["emoji"]
34
+ end
35
+
36
+ def username
37
+ @username ||= profile["settings"]["user"]
38
+ end
39
+
40
+ def token
41
+ @token ||= profile["settings"]["token"]
42
+ end
43
+
44
+ def ops_token
45
+ @ops_token ||= profile["settings"]["ops_token"]
46
+ end
47
+
48
+ def handover_report_path
49
+ @handover_report_path ||= profile["settings"]["handover_report_path"] || File.join(Dir.home,
50
+ ".handover_reports")
51
+ end
52
+
53
+ def timezone
54
+ @timezone ||= profile["settings"]["timezone"]
55
+ end
56
+
57
+ def tz
58
+ @tz ||= TZInfo::Timezone.get(profile["settings"]["tz"] || TZ[timezone])
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dri
4
+ module Support
5
+ # Common tools for use with influxdb metrics setup
6
+ #
7
+ module InfluxdbTools
8
+ # @return [String] bucket for storing metrics from main runs
9
+ INFLUX_MAIN_TEST_METRICS_BUCKET = "e2e-test-stats-main"
10
+
11
+ private
12
+
13
+ # Query client
14
+ #
15
+ # @return [QueryApi]
16
+ def query_api
17
+ return nil unless influx_client
18
+
19
+ @query_api ||= influx_client.create_query_api
20
+ end
21
+
22
+ # InfluxDb client
23
+ #
24
+ # @return [InfluxDB2::Client]
25
+ def influx_client
26
+ return nil unless ENV["QA_INFLUXDB_URL"] && ENV["QA_INFLUXDB_TOKEN"]
27
+
28
+ @influx_client ||= InfluxDB2::Client.new(
29
+ ENV.fetch("QA_INFLUXDB_URL", nil),
30
+ ENV.fetch("QA_INFLUXDB_TOKEN", nil),
31
+ bucket: INFLUX_MAIN_TEST_METRICS_BUCKET,
32
+ org: "gitlab-qa"
33
+ )
34
+ end
35
+ end
36
+ end
37
+ end
@@ -11,13 +11,14 @@ module Dri
11
11
  FEATURE_FLAG_LOG_PROJECT_ID = 15208716
12
12
  INFRA_TEAM_PROD_PROJECT_ID = 7444821
13
13
  RUNBOOKS_PROJECT_ID = 41045213
14
+ FAST_QUARANTINE_PROJECT_ID = 45427186
14
15
  end
15
16
 
16
17
  module Triage
17
18
  module Labels
18
19
  FOUND = 'found:'
19
20
  FAILURE = 'failure::'
20
- FAILURE_NEW = "#{FAILURE}new"
21
+ FAILURE_NEW = "#{FAILURE}new".freeze
21
22
  QA = "QA"
22
23
  INCIDENT = 'Incident::'
23
24
  SERVICE = 'Service::'
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "tty-logger"
4
+
5
+ module Dri
6
+ module Utils
7
+ module Helpers
8
+ def logger
9
+ @logger ||= TTY::Logger.new
10
+ end
11
+
12
+ module_function :logger
13
+ end
14
+ end
15
+ end