dri 0.3.1 → 0.4.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: 345d930ab1d8693abc08cea84c56059acf4617b7b98b3d585ce6838c2be76ed5
4
- data.tar.gz: 43fe7a822eb463770ade0125528e3a18a58bf12b1c8dd0c83daffffb4fac01ff
3
+ metadata.gz: 8718d907e41f0cfb472a255898ed513af0fe81ae4cfe782c7aa7d270cb0c2b9f
4
+ data.tar.gz: 718f976b309b6eb0cab9f65b32e58de5876edd5507aafcc20a2f098068bb5929
5
5
  SHA512:
6
- metadata.gz: 799aeafefdbf86bca0a6b317806cd8054df97b2871bba345d9c3c44c0a0ae716d152f85afd1e5536b2dafb3e4399f2b757912558d6a59bc3661bb2e6699fc120
7
- data.tar.gz: b0a1e74085cd70be58b8fcef39f436cf9c16b0d49c39d48833a86d74814b6fe7b654fb833be252c6c26bd68945691d4465f3c351ee41837a7454bb17b601e820
6
+ metadata.gz: 643631388b378a127bca182911c9dfb304a1134b568fb71c716976f637f31f2a8d5056c2e30f0f9e2a72e7528e9e7f58a0bda4c0cbc1066efab02c3159353777
7
+ data.tar.gz: 46514571671417008fe79dadc26cee33b97ad642e61822e2a2097f4e83d774290d1389f3d7d5c6a8ddf7be7a1974d733b4f5cacef3e7c0084af16a37db30ee0d
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.7.5
1
+ 3.0.4
data/Gemfile.lock CHANGED
@@ -1,7 +1,8 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- dri (0.1.3)
4
+ dri (0.3.1)
5
+ gitlab (~> 4.18)
5
6
  httparty (~> 0.20.0)
6
7
  json (~> 2.6.1)
7
8
  markdown-tables (~> 1.1.1)
@@ -27,10 +28,14 @@ GEM
27
28
  addressable (2.8.0)
28
29
  public_suffix (>= 2.0.2, < 5.0)
29
30
  ast (2.4.2)
31
+ coderay (1.1.3)
30
32
  concurrent-ruby (1.1.10)
31
33
  crack (0.4.5)
32
34
  rexml
33
35
  diff-lcs (1.5.0)
36
+ gitlab (4.18.0)
37
+ httparty (~> 0.18)
38
+ terminal-table (>= 1.5.1)
34
39
  gitlab-styles (7.0.0)
35
40
  rubocop (~> 0.91, >= 0.91.1)
36
41
  rubocop-gitlab-security (~> 0.1.1)
@@ -44,8 +49,9 @@ GEM
44
49
  multi_xml (>= 0.5.2)
45
50
  i18n (1.10.0)
46
51
  concurrent-ruby (~> 1.0)
47
- json (2.6.1)
52
+ json (2.6.2)
48
53
  markdown-tables (1.1.1)
54
+ method_source (1.0.0)
49
55
  mime-types (3.4.1)
50
56
  mime-types-data (~> 3.2015)
51
57
  mime-types-data (3.2022.0105)
@@ -56,6 +62,9 @@ GEM
56
62
  ast (~> 2.4.1)
57
63
  pastel (0.8.0)
58
64
  tty-color (~> 0.5)
65
+ pry (0.14.1)
66
+ coderay (~> 1.1)
67
+ method_source (~> 1.0)
59
68
  public_suffix (4.0.6)
60
69
  rack (2.2.3)
61
70
  rainbow (3.1.1)
@@ -106,6 +115,8 @@ GEM
106
115
  unicode-display_width (>= 1.5, < 3.0)
107
116
  unicode_utils (~> 1.4)
108
117
  strings-ansi (0.2.0)
118
+ terminal-table (3.0.2)
119
+ unicode-display_width (>= 1.1.1, < 3)
109
120
  thor (1.0.1)
110
121
  timecop (0.9.5)
111
122
  tty-box (0.7.0)
@@ -150,6 +161,7 @@ PLATFORMS
150
161
  DEPENDENCIES
151
162
  dri!
152
163
  gitlab-styles (~> 7.0.0)
164
+ pry (~> 0.14.1)
153
165
  rake
154
166
  rspec (~> 3.10.0)
155
167
  timecop (~> 0.9.1)
data/dri.gemspec CHANGED
@@ -22,6 +22,7 @@ Gem::Specification.new do |spec|
22
22
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
23
23
  spec.require_paths = ['lib']
24
24
 
25
+ spec.add_dependency "gitlab", "~> 4.18"
25
26
  spec.add_dependency 'httparty', '~> 0.20.0'
26
27
  spec.add_dependency 'json', '~> 2.6.1'
27
28
  spec.add_dependency 'markdown-tables', '~> 1.1.1'
@@ -37,6 +38,7 @@ Gem::Specification.new do |spec|
37
38
  spec.add_dependency 'tty-table', '~> 0.12.0'
38
39
 
39
40
  spec.add_development_dependency 'gitlab-styles', '~> 7.0.0'
41
+ spec.add_development_dependency "pry", "~> 0.14.1"
40
42
  spec.add_development_dependency 'rake'
41
43
  spec.add_development_dependency 'rspec', '~> 3.10.0'
42
44
  spec.add_development_dependency "timecop", "~> 0.9.1"
@@ -4,9 +4,10 @@ require "httparty"
4
4
  require "json"
5
5
  require "tty-config"
6
6
  require 'cgi'
7
+ require 'gitlab'
7
8
 
8
9
  module Dri
9
- class ApiClient # rubocop:disable Metrics/ClassLength
10
+ class ApiClient
10
11
  API_URL = 'https://gitlab.com/api/v4'
11
12
  TESTCASES_PROJECT_ID = '11229385'
12
13
  TRIAGE_PROJECT_ID = '15291320'
@@ -15,41 +16,53 @@ module Dri
15
16
  INFRA_TEAM_PROD_PROJECT_ID = '7444821'
16
17
 
17
18
  def initialize(config)
18
- profile = config.read
19
- @token = profile["settings"]["token"]
20
- end
21
-
22
- def header
23
- @header ||= { 'Content-Type' => 'application/json', "Authorization" => "Bearer #{@token}" }
19
+ @token = config.read.dig("settings", "token")
24
20
  end
25
21
 
22
+ # Fetch triaged failures
23
+ #
24
+ # @param [String] emoji
25
+ # @param [String] state
26
+ # @return [Gitlab::ObjectifiedHash]
26
27
  def fetch_triaged_failures(emoji:, state:)
27
- url = ["#{API_URL}/issues"]
28
- url << "?order_by=updated_at&my_reaction_emoji=#{emoji}"
29
- url << "&scope=all&state=#{state}"
30
-
31
- fetch_json(url.join)
28
+ gitlab.issues(
29
+ GITLAB_PROJECT_ID,
30
+ order_by: "updated_at",
31
+ my_reaction_emoji: emoji,
32
+ scope: "all",
33
+ state: state
34
+ )
32
35
  end
33
36
 
34
- def fetch_awarded_emojis(url)
35
- fetch_json(url)
37
+ # Fetch award emojis
38
+ #
39
+ # @param [Integer] issue_iid
40
+ # @return [Array<Gitlab::ObjectifiedHash>]
41
+ def fetch_awarded_emojis(issue_iid)
42
+ gitlab.award_emojis(GITLAB_PROJECT_ID, issue_iid, "issue")
36
43
  end
37
44
 
45
+ # Fetch failing testcases
46
+ #
47
+ # @param [String] pipeline
48
+ # @param [String] state
49
+ # @return [Array<Gitlab::ObjectifiedHash>]
38
50
  def fetch_failing_testcases(pipeline, state:)
39
- url = ["#{API_URL}/projects/"]
40
- url << "#{TESTCASES_PROJECT_ID}/issues?labels=#{pipeline}::failed"
41
- url << "&state=#{state}&not[labels]=quarantine"
42
- url << "&scope=all"
43
-
44
- fetch_json(url.join)
51
+ gitlab.issues(
52
+ TESTCASES_PROJECT_ID,
53
+ labels: "#{pipeline}::failed",
54
+ state: state,
55
+ scope: "all",
56
+ "not[labels]": "quarantine"
57
+ ).auto_paginate
45
58
  end
46
59
 
47
- def fetch_related_mrs(issue_iid:)
48
- url = ["#{API_URL}/projects/"]
49
- url << "#{GITLAB_PROJECT_ID}/issues/"
50
- url << "#{issue_iid}/related_merge_requests"
51
-
52
- fetch_json(url.join)
60
+ # Fetch related issue mrs
61
+ #
62
+ # @param [Integer] issue_iid
63
+ # @return [Array<Gitlab::ObjectifiedHash>]
64
+ def fetch_related_mrs(issue_iid)
65
+ gitlab.related_issue_merge_requests(GITLAB_PROJECT_ID, issue_iid)
53
66
  end
54
67
 
55
68
  # Fetch MRs
@@ -63,104 +76,91 @@ module Dri
63
76
  # @option options [String] milestone
64
77
  # @option options [String] labels
65
78
  def fetch_mrs(project_id:, **options)
66
- uri = URI(API_URL)
67
- uri.query = HTTParty::HashConversions.to_params(options)
68
-
69
- # CGI.escape('gitlab-org/gitlab') => 'gitlab-org%2Fgitlab'
70
- uri.path = File.join(uri.path, 'projects', CGI.escape(project_id), 'merge_requests')
71
-
72
- fetch_json(uri.to_s)
79
+ gitlab.merge_requests(project_id, per_page: 100, **options).auto_paginate
73
80
  end
74
81
 
82
+ # Fetch current triage issue
83
+ #
84
+ # @return [Gitlab::ObjectifiedHash]
75
85
  def fetch_current_triage_issue
76
- url = ["#{API_URL}/projects/"]
77
- url << "#{TRIAGE_PROJECT_ID}/issues?state=opened"
78
- url << "&order_by=updated_at"
79
-
80
- fetch_json(url.join)
86
+ gitlab.issues(TRIAGE_PROJECT_ID, state: "opened", order_by: "updated_at")
81
87
  end
82
88
 
89
+ # Create triage report note
90
+ #
91
+ # @param [Integer] iid
92
+ # @param [String] body
93
+ # @return [Gitlab::ObjectifiedHash]
83
94
  def post_triage_report_note(iid:, body:)
84
- url = ["#{API_URL}/projects/"]
85
- url << "#{TRIAGE_PROJECT_ID}/issues/#{iid}/notes"
86
-
87
- post_json(url.join, body)
95
+ gitlab.create_issue_note(TRIAGE_PROJECT_ID, iid, body)
88
96
  end
89
97
 
98
+ # Fetch new failures
99
+ #
100
+ # @param [String] date
101
+ # @param [String] state
102
+ # @return [Array<Gitlab::ObjectifiedHash>]
90
103
  def fetch_failures(date:, state:)
91
- url = ["#{API_URL}/issues"]
92
- url << "?labels=failure::new"
93
- url << "&order_by=updated_at&state=#{state}"
94
- url << "&scope=all"
95
- url << "&created_after=#{date}"
96
- url << "&per_page=100"
97
-
98
- fetch_json(url.join)
99
- end
100
-
101
- def fetch_failure_notes(issue_iid:)
102
- url = ["#{API_URL}/projects/"]
103
- url << "#{GITLAB_PROJECT_ID}/issues/"
104
- url << "#{issue_iid}/notes?per_page=15"
105
-
106
- fetch_json(url.join)
107
- end
108
-
109
- def delete_award_emoji(url)
110
- delete_json(url)
104
+ gitlab.issues(
105
+ GITLAB_PROJECT_ID,
106
+ labels: "failure::new",
107
+ order_by: "updated_at",
108
+ state: state,
109
+ scope: "all",
110
+ created_after: date,
111
+ per_page: 100
112
+ )
113
+ end
114
+
115
+ # Fetch failure notes
116
+ #
117
+ # @param [Integer] issue_iid
118
+ # @return [Array<Gitlab::ObjectifiedHash>]
119
+ def fetch_failure_notes(issue_iid)
120
+ gitlab.issue_notes(GITLAB_PROJECT_ID, issue_iid, per_page: 100).auto_paginate
111
121
  end
112
122
 
113
- def fetch_feature_flag_logs(date:, page:)
114
- url = ["#{API_URL}/projects/"]
115
- url << "#{FEATURE_FLAG_LOG_PROJECT_ID}/issues"
116
- url << "?created_after=#{date}"
117
- url << "&per_page=100"
118
- url << "&page=#{page}"
119
-
120
- fetch_json(url.join)
123
+ # Delete award emoji
124
+ #
125
+ # @param [Integer] issue_iid
126
+ # @param [Integer] emoji_id
127
+ # @return [Gitlab::ObjectifiedHash]
128
+ def delete_award_emoji(issue_iid, emoji_id)
129
+ gitlab.delete_award_emoji(
130
+ GITLAB_PROJECT_ID,
131
+ issue_iid,
132
+ "issue",
133
+ emoji_id
134
+ )
135
+ end
136
+
137
+ # Fetch feature flag log issues
138
+ #
139
+ # @param [String] date
140
+ # @return [Array<Gitlab::ObjectifiedHash>]
141
+ def fetch_feature_flag_logs(date)
142
+ gitlab.issues(FEATURE_FLAG_LOG_PROJECT_ID, created_after: date, per_page: 100).auto_paginate
121
143
  end
122
144
 
145
+ # Fetch ongoing incidents
146
+ #
147
+ # @return [Array<Gitlab::ObjectifiedHash>]
123
148
  def incidents
124
- url = ["#{API_URL}/projects/"]
125
- url << "#{INFRA_TEAM_PROD_PROJECT_ID}/issues"
126
- url << "?order_by=updated_at&state=opened"
127
- url << "&labels=incident"
128
-
129
- fetch_json(url.join)
149
+ gitlab.issues(INFRA_TEAM_PROD_PROJECT_ID, order_by: "updated_at", state: "opened", labels: "incident")
130
150
  end
131
151
 
132
152
  private
133
153
 
134
- def post_json(url, body)
135
- options = {
136
- body: { body: body },
137
- headers: {
138
- "Authorization" => "Bearer #{@token}"
139
- }
140
- }
154
+ attr_reader :token
141
155
 
142
- response = HTTParty.post(url, options)
143
- handle_response(response)
144
- end
145
-
146
- def delete_json(url)
147
- response = HTTParty.delete(url, headers: header)
148
- handle_response(response)
149
- end
150
-
151
- def handle_response(response)
152
- response
153
- end
154
-
155
- def fetch_json(url)
156
- response = HTTParty.get(url, headers: header)
157
-
158
- if response.code != 200
159
- puts "Response error code \"#{response.code}\" - Unable to sync with GitLab"
160
- exit 1
161
- end
162
-
163
- handle_response(JSON.parse(response.body))
156
+ # Gitlab client
157
+ #
158
+ # @return [Gitlab::Client]
159
+ def gitlab
160
+ @gitlab ||= Gitlab.client(
161
+ endpoint: API_URL,
162
+ private_token: token
163
+ )
164
164
  end
165
165
  end
166
166
  end
data/lib/dri/command.rb CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  require_relative 'command'
4
4
  require_relative 'api_client'
5
+ require_relative 'gitlab/issues'
5
6
 
6
7
  require 'dri/refinements/truncate'
7
8
 
@@ -40,20 +40,19 @@ module Dri
40
40
  spinner.run do # rubocop:disable Metrics/BlockLength
41
41
  response = api_client.fetch_failures(date: @today_iso_format, state: 'opened')
42
42
 
43
- if response.nil?
43
+ if response.empty?
44
44
  logger.info 'Life is great, there are no new failures today!'
45
45
  exit 0
46
46
  end
47
47
 
48
48
  response.each do |failure|
49
- title = failure['title'].truncate(60)
50
- author = failure['author']['username']
51
- url = failure['web_url']
52
- award_emoji_url = failure['_links']['award_emoji']
49
+ title = failure.title.truncate(60)
50
+ author = failure.to_h.dig('author', 'username')
51
+ url = failure.web_url
53
52
  triaged = add_color('x', :red)
54
53
 
55
- emoji_awards = api_client.fetch_awarded_emojis(award_emoji_url).find do |e|
56
- (e['name'] == emoji) && (e['user']['username'] == username)
54
+ emoji_awards = api_client.fetch_awarded_emojis(failure.iid).find do |e|
55
+ e.name == emoji && e.to_h.dig('user', 'username') == username
57
56
  end
58
57
 
59
58
  if emoji_awards
@@ -62,7 +61,7 @@ module Dri
62
61
  end
63
62
 
64
63
  if @options[:urgent]
65
- labels = failure['labels']
64
+ labels = failure.labels
66
65
 
67
66
  labels.each do |label|
68
67
  if label.include?('found:canary.gitlab.com' && 'found:canary.staging.gitlab.com')
@@ -35,44 +35,37 @@ module Dri
35
35
 
36
36
  logger.info "Fetching today's feature flag changes..."
37
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
38
+ spinner.run do
39
+ response = api_client.fetch_feature_flag_logs(@today_iso_format)
40
+ if response.empty?
41
+ logger.info 'It\'s been quiet...no feature flag changes for today 👀'
42
+ break
43
+ end
47
44
 
48
- response.each do |feature_flag|
49
- summary = feature_flag['title']
45
+ response.each do |feature_flag|
46
+ summary = feature_flag.title
50
47
 
51
- substrings = ["set to \"true\"", "set to \"false\""]
52
- next unless substrings.any? { |substr| summary.include?(substr) }
48
+ substrings = ["set to \"true\"", "set to \"false\""]
49
+ next unless substrings.any? { |substr| summary.include?(substr) }
53
50
 
54
- changed_on = feature_flag['description'][/(?<=Changed on \(in UTC\): ).+?(?=\n)/].delete('`')
55
- url = feature_flag['web_url']
51
+ changed_on = feature_flag.description[/(?<=Changed on \(in UTC\): ).+?(?=\n)/].delete('`')
52
+ url = feature_flag.web_url
56
53
 
57
- feature_flag_data = [summary, changed_on, url]
54
+ feature_flag_data = [summary, changed_on, url]
58
55
 
59
- labels = feature_flag['labels']
60
- host_label = labels.select { |label| /^host::/.match(label) }.join('')
56
+ labels = feature_flag.labels
57
+ host_label = labels.select { |label| /^host::/.match(label) }.join('')
61
58
 
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
59
+ case host_label
60
+ when PRODUCTION
61
+ prod_feature_flags << feature_flag_data
62
+ when STAGING
63
+ staging_feature_flags << feature_flag_data
64
+ when STAGING_REF
65
+ staging_ref_feature_flags << feature_flag_data
66
+ when PREPROD
67
+ preprod_feature_flags << feature_flag_data
72
68
  end
73
-
74
- page += 1
75
- break if response.count < 100 || response.nil?
76
69
  end
77
70
  end
78
71
 
@@ -37,8 +37,8 @@ module Dri
37
37
  )
38
38
 
39
39
  mrs = response.each_with_object([]) do |mr, found_mrs|
40
- title = mr['title'][13..].truncate(60) # remove the "[QUARANTINE] " prefix
41
- url = mr['web_url']
40
+ title = mr.title[13..].truncate(60) # remove the "[QUARANTINE] " prefix
41
+ url = mr.web_url
42
42
 
43
43
  found_mrs << [title, url]
44
44
  end
@@ -47,8 +47,8 @@ module Dri
47
47
 
48
48
  output.puts "♦♦♦♦♦ #{add_color(pipeline, :black, :on_white)}♦♦♦♦♦\n\n"
49
49
 
50
- response.each do |pipeline|
51
- output.puts "#{title_label} #{pipeline['title']}\n#{url_label} #{pipeline['web_url']}"
50
+ response.each do |test_case|
51
+ output.puts "#{title_label} #{test_case.title}\n#{url_label} #{test_case.web_url}"
52
52
  output.puts "#{divider}\n"
53
53
  end
54
54
  end
@@ -31,13 +31,13 @@ module Dri
31
31
 
32
32
  if response.nil?
33
33
  logger.info 'Hooray, no active incidents 🎉.'
34
- exit 0
34
+ break
35
35
  end
36
36
 
37
37
  response.each do |incident|
38
- title = incident['title'].truncate(70)
39
- url = incident['web_url']
40
- labels = incident['labels']
38
+ title = incident.title.truncate(70)
39
+ url = incident.web_url
40
+ labels = incident.labels
41
41
  status = "N/A"
42
42
  service = "N/A"
43
43
 
@@ -29,18 +29,13 @@ module Dri
29
29
  spinner.stop
30
30
 
31
31
  issues_with_award_emoji.each do |issue|
32
- logger.info "Removing #{emoji} from #{issue['web_url']}..."
32
+ logger.info "Removing #{emoji} from #{issue.web_url}..."
33
33
 
34
- award_emoji_url = issue["_links"]["award_emoji"]
34
+ response = api_client.fetch_awarded_emojis(issue.iid)
35
35
 
36
- response = api_client.fetch_awarded_emojis(award_emoji_url)
36
+ emoji_found = response.find { |e| e.name == emoji && e.to_h.dig('user', 'username') == username }
37
37
 
38
- emoji_found = response.find { |e| e['name'] == emoji && e['user']['username'] == username }
39
-
40
- unless emoji_found.nil?
41
- url = "#{award_emoji_url}/#{emoji_found['id']}"
42
- api_client.delete_award_emoji(url)
43
- end
38
+ api_client.delete_award_emoji(issue.iid, emoji_found.id) unless emoji_found.nil?
44
39
  end
45
40
  output.puts "Done! ✅"
46
41
  logger.success "Removed #{emoji} from #{issues_with_award_emoji.size} issue(s)."
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Gitlab gem monkeypatch for related merge requests
4
+ # TODO: Add method upstream
5
+ #
6
+ class Gitlab::Client
7
+ module Issues
8
+ # List related merge requests
9
+ #
10
+ # @example
11
+ # Gitlab.related_issue_merge_requests(3, 42)
12
+ #
13
+ # @param [Integer, String] project The ID or name of a project.
14
+ # @param [Integer] id The ID of an issue.
15
+ def related_issue_merge_requests(project, id)
16
+ get("/projects/#{url_encode project}/issues/#{id}/related_merge_requests")
17
+ end
18
+ end
19
+ end
data/lib/dri/report.rb CHANGED
@@ -30,7 +30,7 @@ module Dri
30
30
  assignees = failure["assignees"]
31
31
  description = failure["description"]
32
32
 
33
- related_mrs = @api_client.fetch_related_mrs(issue_iid: iid)
33
+ related_mrs = @api_client.fetch_related_mrs(iid)
34
34
  emoji = classify_failure_emoji(created_at)
35
35
  emojified_link = "#{emoji} #{link}"
36
36
 
@@ -71,7 +71,7 @@ module Dri
71
71
  'release' => '/quality/release'
72
72
  }
73
73
 
74
- failure_notes = @api_client.fetch_failure_notes(issue_iid: iid)
74
+ failure_notes = @api_client.fetch_failure_notes(iid)
75
75
 
76
76
  return if pipelines.empty?
77
77
 
@@ -83,10 +83,10 @@ module Dri
83
83
  pipeline_markdown = pipeline.gsub(/.gitlab.com/, '')
84
84
 
85
85
  failure_notes.each do |note|
86
- next unless note["body"].include?(label_pipeline_map.fetch(pipeline))
86
+ next unless note.body.include?(label_pipeline_map.fetch(pipeline))
87
87
 
88
88
  pipeline_in_notes_found = true
89
- pipeline_link = URI.extract(note["body"], %w[https])
89
+ pipeline_link = URI.extract(note.body, %w[https])
90
90
  end
91
91
 
92
92
  unless pipeline_in_notes_found
@@ -193,7 +193,7 @@ module Dri
193
193
  path = "Failure in `#{path.strip}`" if path.delete_prefix!('Failure in ')
194
194
  path = path.strip.gsub(' ', '&nbsp;') if desc
195
195
 
196
- "#{path} | #{desc}"
196
+ [path, desc].compact.join(' | ')
197
197
  end
198
198
  end
199
199
  end
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.3.1"
4
+ VERSION = "0.4.0"
5
5
  end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dri
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.4.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-05-16 00:00:00.000000000 Z
11
+ date: 2022-05-25 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: gitlab
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '4.18'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '4.18'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: httparty
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -206,6 +220,20 @@ dependencies:
206
220
  - - "~>"
207
221
  - !ruby/object:Gem::Version
208
222
  version: 7.0.0
223
+ - !ruby/object:Gem::Dependency
224
+ name: pry
225
+ requirement: !ruby/object:Gem::Requirement
226
+ requirements:
227
+ - - "~>"
228
+ - !ruby/object:Gem::Version
229
+ version: 0.14.1
230
+ type: :development
231
+ prerelease: false
232
+ version_requirements: !ruby/object:Gem::Requirement
233
+ requirements:
234
+ - - "~>"
235
+ - !ruby/object:Gem::Version
236
+ version: 0.14.1
209
237
  - !ruby/object:Gem::Dependency
210
238
  name: rake
211
239
  requirement: !ruby/object:Gem::Requirement
@@ -305,6 +333,7 @@ files:
305
333
  - lib/dri/commands/rm/emoji.rb
306
334
  - lib/dri/commands/rm/profile.rb
307
335
  - lib/dri/commands/rm/reports.rb
336
+ - lib/dri/gitlab/issues.rb
308
337
  - lib/dri/refinements/truncate.rb
309
338
  - lib/dri/report.rb
310
339
  - lib/dri/templates/incidents/.gitkeep