gitlab-dangerfiles 3.10.0 → 3.11.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: ad2ad158af390c0b6b52fdd86927b4dd0a6118b7b2eca3ad60aaa88ac40b840a
4
- data.tar.gz: 2872e01e85bf7190e2a3fd4cab71868f2e4924234443797e7479a3ab03497120
3
+ metadata.gz: 2ee27fb91564bfb45f28aed3fca576c6731c91ae9f69719e2ebb0ce5807ff1ee
4
+ data.tar.gz: 3bcd268c5fc1a91141a447ff6bb1b0c63841fe4dab2c65fffc61c7c488048275
5
5
  SHA512:
6
- metadata.gz: 7dccc5481318999e83be3a9535983ebbf69d731d5394cf66543df0fd77bf7e274d1b012255c9582a503caae5248956aa2441af1b9ad6ffddf6c5bc2bc730013b
7
- data.tar.gz: 5d217f45be9fb3c68032bbffd9a7eee4eb4cdb4056200c8dabdaf8255aa084a28ff3cd3ac74a5fa2588634607c4a5d23ffc6d58cc709e9343296112b6b3457b3
6
+ metadata.gz: d5cab2d3171779a9f28c00452e4e0435a6aa93852d80847b4da3b03f38fe294e7c855232b1402d6f3ac14f99b04518993b5fb6401da928ed9189f86a44948769
7
+ data.tar.gz: dc580aa4781087b6598c8d4f2befb2fec6b9d87ae4ce964227b35a4fbc537c62f2bad0e4d947a65154753157a896cb890472be33d99f0e15463d63beed17b6ee
@@ -2,7 +2,7 @@
2
2
  commit from this merge request, and `<NEW_VERSION>` with the upcoming version number. -->
3
3
  ## Diff
4
4
 
5
- https://gitlab.com/gitlab-org/ruby/gems/gitlab-dangerfiles/compare/v<PREVIOUS_VERSION>...<COMMIT_UPDATING_VERSION>
5
+ https://gitlab.com/gitlab-org/ruby/gems/gitlab-dangerfiles/-/compare/v<PREVIOUS_VERSION>...<COMMIT_UPDATING_VERSION>
6
6
 
7
7
  ## Checklist
8
8
 
@@ -33,6 +33,34 @@ module Danger
33
33
  end
34
34
  end
35
35
 
36
+ def prepare_categories(changes_keys)
37
+ categories = Set.new(changes_keys)
38
+
39
+ # Ensure to spin for database reviewer/maintainer when ~database is applied (e.g. to review SQL queries)
40
+ categories << :database if labels.include?("database")
41
+
42
+ # Ensure to spin for Analytics Instrumentation reviewer when ~"analytics instrumentation::review pending" is applied
43
+ categories << :analytics_instrumentation if labels.include?("analytics instrumentation::review pending")
44
+
45
+ # Skip Analytics Instrumentation reviews for growth experiment MRs
46
+ categories.delete(:analytics_instrumentation) if labels.include?("growth experiment")
47
+
48
+ prepare_ux_category!(categories) if labels.include?("UX")
49
+
50
+ # Remove disabled categories
51
+ categories.subtract(helper.config.disabled_roulette_categories)
52
+
53
+ categories
54
+ end
55
+
56
+ def assign_pedroms_for_ux_wider_community_contribution(spins)
57
+ # We want at least a UX reviewer who can review any wider community
58
+ # contribution even without a team designer. We assign this to Pedro.
59
+ ux_spin = look_for_fallback_designer_for_ux_wider_community_contribution?(spins)
60
+
61
+ ux_spin && ux_spin.reviewer = teammate_pedroms
62
+ end
63
+
36
64
  # Finds the +Gitlab::Dangerfiles::Teammate+ object whose username matches the MR author username.
37
65
  #
38
66
  # @return [Gitlab::Dangerfiles::Teammate]
@@ -124,6 +152,10 @@ module Danger
124
152
  @warnings ||= []
125
153
  end
126
154
 
155
+ def teammate_pedroms
156
+ @teammate_pedroms ||= find_member("pedroms")
157
+ end
158
+
127
159
  private
128
160
 
129
161
  def spin_for_approval_rule?(rule)
@@ -175,8 +207,8 @@ module Danger
175
207
  # @return [Boolean]
176
208
  def import_and_integrate_reject_category?(category, project)
177
209
  # Reject Import and Integrate categories if the MR author has reviewing abilities for the category.
178
- team_mr_author&.import_integrate_be?(project, category, helper.mr_labels) ||
179
- team_mr_author&.import_integrate_fe?(project, category, helper.mr_labels)
210
+ team_mr_author&.import_integrate_be?(project, category, labels) ||
211
+ team_mr_author&.import_integrate_fe?(project, category, labels)
180
212
  end
181
213
 
182
214
  def random
@@ -185,7 +217,7 @@ module Danger
185
217
 
186
218
  def spin_role_for_category(team, role, project, category)
187
219
  team.select do |member|
188
- member.public_send("#{role}?", project, category, helper.mr_labels)
220
+ member.public_send("#{role}?", project, category, labels)
189
221
  end
190
222
  end
191
223
 
@@ -258,6 +290,38 @@ module Danger
258
290
  Spin.new(category, reviewer, maintainer, false, timezone_experiment)
259
291
  end
260
292
 
293
+ def prepare_ux_category!(categories)
294
+ # Ensure to spin for UX reviewer when ~UX is applied (e.g. to review changes to the UI)
295
+ if labels.include?("Community contribution")
296
+ categories << :ux
297
+ else
298
+ begin
299
+ # We only want to spin a reviewer for merge requests which has a
300
+ # designer for the team. There's no easy way to tell this, so we
301
+ # pretend this is a community contribution, in which case we only
302
+ # pick the team designer. If there's no one got picked, it means
303
+ # there's no designer for this team.
304
+ labels << "Community contribution"
305
+
306
+ ux_spin = spin(nil, [:ux]).first
307
+
308
+ categories << :ux if ux_spin.reviewer || ux_spin.maintainer
309
+ ensure
310
+ # Make sure we delete the label afterward
311
+ labels.delete("Community contribution")
312
+ end
313
+ end
314
+ end
315
+
316
+ def look_for_fallback_designer_for_ux_wider_community_contribution?(spins)
317
+ labels.include?("Community contribution") &&
318
+ spins.find do |spin|
319
+ spin.category == :ux &&
320
+ spin.reviewer.nil? &&
321
+ spin.maintainer.nil?
322
+ end
323
+ end
324
+
261
325
  # Fetches the given +url+ and parse its response as JSON.
262
326
  #
263
327
  # @param [String] url
@@ -316,14 +380,20 @@ module Danger
316
380
  helper.config.project_name
317
381
  end
318
382
 
383
+ # Return the labels from the merge requests. This is cached.
384
+ #
385
+ # @return [String]
386
+ def labels
387
+ @labels ||= helper.mr_labels
388
+ end
389
+
319
390
  # Like +team+, but only returns teammates in the current project, based on
320
391
  # project_name.
321
392
  #
322
393
  # @return [Array<Gitlab::Dangerfiles::Teammate>]
323
394
  def project_team(project_name)
324
395
  company_members.select do |member|
325
- member.in_project?(project_name) ||
326
- member.in_project?("gitlab") # Used for universal reviewer
396
+ member.in_project?(project_name)
327
397
  end
328
398
  rescue => err
329
399
  warn("Reviewer roulette failed to load team data: #{err.message}")
@@ -81,30 +81,16 @@ def warning_list(roulette)
81
81
  end
82
82
 
83
83
  changes = helper.changes_by_category
84
-
85
- # Replicating label based categories from:
86
- # https://gitlab.com/gitlab-org/gitlab/-/blob/master/danger/roulette/Dangerfile
87
- categories = Set.new(changes.keys)
88
-
89
- # Ensure to spin for database reviewer/maintainer when ~database is applied (e.g. to review SQL queries)
90
- categories << :database if helper.mr_labels.include?('database')
91
-
92
- # Ensure to spin for UX reviewer when ~UX is applied (e.g. to review changes to the UI) except when it's from wider community contribution where we want to assign from the corresponding group
93
- categories << :ux if helper.mr_labels.include?('UX') && !helper.mr_labels.include?('Community contribution')
94
-
95
- # Ensure to spin for Analytics Instrumentation reviewer when ~"analytics instrumentation::review pending" is applied
96
- categories << :analytics_instrumentation if helper.mr_labels.include?("analytics instrumentation::review pending")
97
-
98
- # Skip Analytics Instrumentation reviews for growth experiment MRs
99
- categories.delete(:analytics_instrumentation) if helper.mr_labels.include?("growth experiment")
100
-
101
- # Remove disabled categories
102
- categories.subtract(helper.config.disabled_roulette_categories)
84
+ categories = roulette.prepare_categories(changes.keys)
103
85
 
104
86
  if changes.any?
105
87
  show_category_column = categories.size > 1 || categories.first != :none
106
88
  random_roulette_spins = roulette.spin(nil, categories)
107
89
 
90
+ if categories.include?(:ux)
91
+ roulette.assign_pedroms_for_ux_wider_community_contribution(random_roulette_spins)
92
+ end
93
+
108
94
  rows = random_roulette_spins.map do |spin|
109
95
  markdown_row_for_spins(spin.category, [spin], show_category_column: show_category_column)
110
96
  end
@@ -21,19 +21,11 @@ module Gitlab
21
21
  end
22
22
  private_class_method :name_to_class
23
23
 
24
- def has_capability?(...)
25
- has_particular_capability?(...) || has_universal_capability?(...)
26
- end
27
-
28
- private
29
-
30
- def has_particular_capability?(teammate)
24
+ def has_capability?(teammate)
31
25
  teammate.capabilities(project).include?(capability)
32
26
  end
33
27
 
34
- def has_universal_capability?(teammate)
35
- false
36
- end
28
+ private
37
29
 
38
30
  def capability
39
31
  @capability ||= "#{kind} #{name}"
@@ -46,21 +38,17 @@ module Gitlab
46
38
  end
47
39
 
48
40
  class Test < Category
49
- private
50
-
51
- def has_particular_capability?(teammate)
41
+ def has_capability?(teammate)
52
42
  return false if kind != :reviewer
53
43
 
54
44
  area = teammate.role[/Software Engineer in Test(?:.*?, (\w+))/, 1]
55
45
 
56
- area && labels.any?("devops::#{area.downcase}")
46
+ !!area && labels.any?("devops::#{area.downcase}")
57
47
  end
58
48
  end
59
49
 
60
50
  class Tooling < Category
61
- private
62
-
63
- def has_particular_capability?(teammate)
51
+ def has_capability?(teammate)
64
52
  if super
65
53
  true
66
54
  elsif %i[trainee_maintainer maintainer].include?(kind)
@@ -72,59 +60,52 @@ module Gitlab
72
60
  end
73
61
 
74
62
  class ImportIntegrateBE < Category
75
- private
76
-
77
- def has_particular_capability?(teammate)
63
+ def has_capability?(teammate)
78
64
  kind == :reviewer &&
79
65
  teammate.role.match?(/Backend Engineer.+Manage:Import and Integrate/)
80
66
  end
81
67
  end
82
68
 
83
69
  class ImportIntegrateFE < Category
84
- private
85
-
86
- def has_particular_capability?(teammate)
70
+ def has_capability?(teammate)
87
71
  kind == :reviewer &&
88
72
  teammate.role.match?(/Frontend Engineer.+Manage:Import and Integrate/)
89
73
  end
90
74
  end
91
75
 
92
76
  class UX < Category
77
+ def has_capability?(teammate)
78
+ super &&
79
+
80
+ if labels.any?("Community contribution")
81
+ can_review_wider_community_contribution?(teammate)
82
+ else
83
+ can_review_team_memeber_contribution?(teammate)
84
+ end
85
+ end
86
+
93
87
  private
94
88
 
95
- def has_particular_capability?(teammate)
96
- if labels.any?("Community contribution")
97
- can_review_wider_community_contribution?(teammate)
98
- else
99
- super
100
- end
89
+ def can_review_wider_community_contribution?(teammate)
90
+ # We want the designer for the team to review the wider community
91
+ # contribution because they're more familiar with that area.
92
+ the_designer_for_the_team?(teammate)
101
93
  end
102
94
 
103
- def has_universal_capability?(teammate)
104
- # No universal reviewer for community contribution.
105
- # If we do, then picking from corresponding group won't be accurate.
106
- # After solving the following issue, then we can revisit this:
107
- # https://gitlab.com/gitlab-org/ruby/gems/gitlab-dangerfiles/-/issues/58
108
- return false if labels.any?("Community contribution")
109
-
110
- teammate.projects.each_value.any? do |capabilities|
111
- capabilities.include?(capability)
112
- end
95
+ def can_review_team_memeber_contribution?(teammate)
96
+ # We don't want the designer for the team to review merge
97
+ # requests for the same team which is designed by themselves.
98
+ # So they can only review if they're not the designer for the team.
99
+ !the_designer_for_the_team?(teammate)
113
100
  end
114
101
 
115
- def can_review_wider_community_contribution?(teammate)
102
+ def the_designer_for_the_team?(teammate)
116
103
  # Pick corresponding group for community contribution
117
- # Role can be:
118
- # Product Designer, Create:Source Code
119
- # Product Designer, Verify:Pipeline Insights, Verify:Runner
120
- # Product Designer, Release
121
104
  # Specialty can be:
122
105
  # Source Code
123
106
  # [Growth: Activation, Growth: Expansion]
124
107
  # Runner
125
- areas = teammate.role[/Product Designer(?:.*?, (.+))/, 1]&.split(",")
126
-
127
- group_labels = [*teammate.specialty, *areas].map do |field|
108
+ group_labels = Array(teammate.specialty).map do |field|
128
109
  group = field.strip.sub(/^.+: ?/, "").downcase
129
110
 
130
111
  "group::#{group}"
@@ -1,5 +1,5 @@
1
1
  module Gitlab
2
2
  module Dangerfiles
3
- VERSION = "3.10.0"
3
+ VERSION = "3.11.0"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gitlab-dangerfiles
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.10.0
4
+ version: 3.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - GitLab
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-05-08 00:00:00.000000000 Z
11
+ date: 2023-06-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake