dri 0.3.1 → 0.4.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 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