gitlab-dangerfiles 3.0.0 → 3.3.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: 1bcd8631096b4c3a5c7c6df1c8a1c49fda0a4b4936c9f815996ca7702be99f3e
4
- data.tar.gz: ce6a7cc2c2b69e49a262882eddba550d4245c578bfc235be594a27cd0d04d737
3
+ metadata.gz: bf965c37aaf01dff0630442feecb4fbe6e8d96bb2c9f7f714c631487c9eb894e
4
+ data.tar.gz: 720fe1ddfd202e0b199dfbd63fdb360a8a7e58d355182b7055ff0fdebb74c886
5
5
  SHA512:
6
- metadata.gz: 60b36a45528577103064018e02315f365f729c4842f77ef794001fe4697760f2baf60ecaf29a19c5a1c0be25c239832b5d93908a4d6ddb5df7dc22380968f317
7
- data.tar.gz: f1591f53f037986f147f9549bfe98faeecee825c20d916e4370d9f76d562a18456fe8ac993e507987013bdaa52b95845776bac3c66fe6ab844d2f74b13084339
6
+ metadata.gz: 31a832aa516290296662a7949b01a13c7dd47e7c05ad6c6e78cb1f189f2190b99094e97a07875d65f4cb6b5504a8816d1a26aa39a618480899f2026c58c2c311
7
+ data.tar.gz: 4f18f92c83494aff49ceec1a05f2b380bd9be7aee17a50a4126ec25c011cfc468a672da200d4a93420d4c47bbec19d6678dc389e083a56945d94d52a58862107
data/README.md CHANGED
@@ -135,7 +135,9 @@ project. To use it in your project, perform the following steps:
135
135
 
136
136
  #### `type_label`
137
137
 
138
- This rule ensures the merge request has a proper [type label](https://about.gitlab.com/handbook/engineering/metrics/#work-type-classification) set.
138
+ This rule warns when the merge request is missing a [type label](https://about.gitlab.com/handbook/engineering/metrics/#work-type-classification).
139
+
140
+ If the `DANGER_ERROR_WHEN_TYPE_LABEL_IS_MISSING` environment variable evaluates to `true`, Danger will error when a type label is missing.
139
141
 
140
142
  If the `changelog` plugin is available, it also tries to infer a type label from the `Changelog` trailer of the MR.
141
143
 
@@ -170,6 +172,31 @@ include:
170
172
 
171
173
  See a [real world example](https://gitlab.com/gitlab-org/ruby/gems/gitlab-styles/-/merge_requests/105).
172
174
 
175
+ #### Without `Gemfile`
176
+
177
+ Danger is a Ruby project and uses [`bundler`](https://bundler.io/) to manage
178
+ its dependencies. This requires a project to have a `Gemfile` and
179
+ `Gemfile.lock` commited. This is helpful especially if Danger is also used
180
+ locally - with `lefthook`, for example.
181
+
182
+ In order to skip Ruby and `bundler` dependency in a project, use `bundle` commands directly
183
+ in the CI configuration:
184
+
185
+ ```yaml
186
+ include:
187
+ - project: 'gitlab-org/quality/pipeline-common'
188
+ file: '/ci/danger-review.yml'
189
+
190
+ danger-review:
191
+ before_script:
192
+ - bundle init
193
+ # For latest version
194
+ - bundle add gitlab-dangerfiles
195
+ # OR
196
+ # For a pinned version
197
+ - bundle add gitlab-dangerfiles --version 3.1.0
198
+ ```
199
+
173
200
  ## Rake tasks
174
201
 
175
202
  You can import this gem's Rake tasks by adding the following to your project's `Rakefile`:
@@ -190,7 +217,9 @@ Latest documentation can be found at <https://www.rubydoc.info/gems/gitlab-dange
190
217
 
191
218
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
192
219
 
193
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
220
+ To install this gem onto your local machine, run `bundle exec rake install`.
221
+
222
+ To release a new version, update the version number in `version.rb`, and get the MR merged by a maintainer. This will be then be packaged into a gem and pushed to [rubygems.org](https://rubygems.org) by the CI/CD.
194
223
 
195
224
  ## Contributing
196
225
 
@@ -17,7 +17,7 @@ module Danger
17
17
  none: "",
18
18
  qa: "~QA",
19
19
  ux: "~UX",
20
- test: "~test ~Quality for `spec/features/*`",
20
+ test: "~test for `spec/features/*`",
21
21
  # Deprecated as of 2.3.0 in favor of tooling
22
22
  engineering_productivity: '~"Engineering Productivity" for CI, Danger',
23
23
  tooling: '~"maintenance::workflow" / ~"maintenance::pipelines" for CI, Danger',
@@ -192,7 +192,10 @@ module Danger
192
192
  #
193
193
  # @return [Array<Gitlab::Dangerfiles::Teammate>]
194
194
  def project_team(project_name)
195
- company_members.select { |member| member.in_project?(project_name) }
195
+ company_members.select do |member|
196
+ member.in_project?(project_name) ||
197
+ member.in_project?("gitlab") # Used for backup reviewer
198
+ end
196
199
  rescue => err
197
200
  warn("Reviewer roulette failed to load team data: #{err.message}")
198
201
  []
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ if git.commits.size > 20
4
+ failure 'This MR has more than 20 commits. You need to rebase this branch to have fewer commits.'
5
+ end
@@ -60,37 +60,44 @@ def note_for_spin_role(spin, role)
60
60
  spin.public_send(role)&.markdown_name(author: roulette.team_mr_author)
61
61
  end
62
62
 
63
- def markdown_row_for_spins(category = nil, spins_array)
63
+ def markdown_row_for_spins(category = nil, spins_array, has_categories:)
64
64
  reviewer_note = note_for_spins_role(spins_array, :reviewer)
65
65
  maintainer_note = note_for_spins_role(spins_array, :maintainer)
66
66
 
67
67
  row = +"| #{reviewer_note} | #{maintainer_note} |"
68
- row.prepend("| #{helper.label_for_category(category)} ") if categories_defined?
69
-
68
+ row.prepend("| #{helper.label_for_category(category)} ") if has_categories
70
69
  row
71
70
  end
72
71
 
73
- def categories_defined?
74
- helper.config.files_to_category.any?
75
- end
72
+ changes = helper.changes_by_category
76
73
 
77
- def categories(changes)
78
- categories_defined? ? changes.keys : [nil]
79
- end
74
+ # Replicating label based categories from:
75
+ # https://gitlab.com/gitlab-org/gitlab/-/blob/master/danger/roulette/Dangerfile
76
+ categories = Set.new(changes.keys - [:unknown])
80
77
 
81
- def table_header
82
- categories_defined? ? TABLE_HEADER_WITH_CATEGORIES : TABLE_HEADER_WITHOUT_CATEGORIES
83
- end
78
+ # Ensure to spin for database reviewer/maintainer when ~database is applied (e.g. to review SQL queries)
79
+ categories << :database if helper.mr_labels.include?('database')
84
80
 
85
- changes = helper.changes_by_category
81
+ # 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
82
+ categories << :ux if helper.mr_labels.include?('UX') && !helper.mr_labels.include?('Community contribution')
83
+
84
+ # Ensure to spin for Product Intelligence reviewer when ~"product intelligence::review pending" is applied
85
+ categories << :product_intelligence if helper.mr_labels.include?("product intelligence::review pending")
86
+
87
+ # Skip Product intelligence reviews for growth experiment MRs
88
+ categories.delete(:product_intelligence) if helper.mr_labels.include?("growth experiment")
86
89
 
87
90
  if changes.any?
88
- random_roulette_spins = roulette.spin(nil, categories(changes))
91
+ has_categories = categories.any?
92
+ categories = [nil] unless has_categories
93
+ random_roulette_spins = roulette.spin(nil, categories)
89
94
 
90
95
  rows = random_roulette_spins.map do |spin|
91
- markdown_row_for_spins(spin.category, [spin])
96
+ markdown_row_for_spins(spin.category, [spin], has_categories: has_categories)
92
97
  end
93
98
 
99
+ table_header = has_categories ? TABLE_HEADER_WITH_CATEGORIES : TABLE_HEADER_WITHOUT_CATEGORIES
100
+
94
101
  markdown(MESSAGE)
95
102
  markdown(TABLE_MARKDOWN + table_header + rows.join("\n")) unless rows.empty?
96
103
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ TYPE_LABEL_MISSING_MESSAGE = "Please add a [merge request type](https://about.gitlab.com/handbook/engineering/metrics/#work-type-classification) to this merge request."
4
+
3
5
  require_relative "../../../gitlab/dangerfiles/type_label_guesser"
4
6
 
5
7
  if respond_to?(:changelog) && !helper.has_scoped_label_with_scope?("type")
@@ -7,6 +9,10 @@ if respond_to?(:changelog) && !helper.has_scoped_label_with_scope?("type")
7
9
  helper.labels_to_add.concat(type_label_guesser.labels_from_changelog_categories(changelog.categories))
8
10
  end
9
11
 
10
- unless helper.has_scoped_label_with_scope?("type")
11
- warn "Please add a [merge request type](https://about.gitlab.com/handbook/engineering/metrics/#work-type-classification) to this merge request."
12
+ return if helper.has_scoped_label_with_scope?("type")
13
+
14
+ if ENV["DANGER_ERROR_WHEN_TYPE_LABEL_IS_MISSING"]
15
+ fail TYPE_LABEL_MISSING_MESSAGE
16
+ else
17
+ warn TYPE_LABEL_MISSING_MESSAGE
12
18
  end
@@ -130,11 +130,22 @@ module Gitlab
130
130
  capabilities(project).include?("#{kind}")
131
131
  else
132
132
  capabilities(project).include?("#{kind} #{category}")
133
+ end || has_backup_capability?(category, kind, labels)
134
+ end
135
+
136
+ def has_backup_capability?(category, kind, labels)
137
+ case category
138
+ when :ux
139
+ capacity = "#{kind} #{category}"
140
+
141
+ projects.each_value.find do |capabilities|
142
+ capabilities.include?(capacity)
143
+ end
133
144
  end
134
145
  end
135
146
 
136
147
  def capabilities(project)
137
- Array(projects.fetch(project, []))
148
+ projects.fetch(project, [])
138
149
  end
139
150
 
140
151
  def pluralize(count, singular, plural)
@@ -1,5 +1,5 @@
1
1
  module Gitlab
2
2
  module Dangerfiles
3
- VERSION = "3.0.0"
3
+ VERSION = "3.3.0"
4
4
  end
5
5
  end
@@ -13,15 +13,15 @@ module Gitlab
13
13
  # | reduced capacity reviewer | 1 |
14
14
  # | reviewer | 2 |
15
15
  # | hungry reviewer | 4 |
16
- # | reduced capacity traintainer | 3 |
17
- # | traintainer | 6 |
18
- # | hungry traintainer | 8 |
16
+ # | reduced capacity traintainer | 1 |
17
+ # | traintainer | 2 |
18
+ # | hungry traintainer | 6 |
19
19
  # +------------------------------+--------------------------------+
20
20
  #
21
21
  # @api private
22
22
  class Reviewers
23
23
  DEFAULT_REVIEWER_WEIGHT = Gitlab::Dangerfiles::Weightage::CAPACITY_MULTIPLIER * Gitlab::Dangerfiles::Weightage::BASE_REVIEWER_WEIGHT
24
- TRAINTAINER_WEIGHT = 3
24
+ TRAINTAINER_WEIGHT = 2
25
25
 
26
26
  def initialize(reviewers, traintainers)
27
27
  @reviewers = reviewers
@@ -32,6 +32,8 @@ module Gitlab
32
32
  # TODO: take CODEOWNERS into account?
33
33
  # https://gitlab.com/gitlab-org/gitlab/issues/26723
34
34
 
35
+ remove_traintainers_from_reviewers!
36
+
35
37
  weighted_reviewers + weighted_traintainers
36
38
  end
37
39
 
@@ -39,25 +41,33 @@ module Gitlab
39
41
 
40
42
  attr_reader :reviewers, :traintainers
41
43
 
44
+ def remove_traintainers_from_reviewers!
45
+ # Sometimes folks will add themselves as traintainers and not remove themselves as reviewers.
46
+ # There seems no way currently to ensure only one of these entries exists for a person.
47
+ # We need to protect ourselves from that scenario here as the code assumes a reviewer will only
48
+ # appear in reviewers or traintainers, not both.
49
+ reviewers.reject! { |reviewer| traintainers.include?(reviewer) }
50
+ end
51
+
42
52
  def weighted_reviewers
43
53
  reviewers.each_with_object([]) do |reviewer, total_reviewers|
44
- add_weighted_reviewer(total_reviewers, reviewer, Gitlab::Dangerfiles::Weightage::BASE_REVIEWER_WEIGHT)
54
+ add_weighted_reviewer(total_reviewers, reviewer, DEFAULT_REVIEWER_WEIGHT)
45
55
  end
46
56
  end
47
57
 
48
58
  def weighted_traintainers
49
59
  traintainers.each_with_object([]) do |reviewer, total_traintainers|
50
- add_weighted_reviewer(total_traintainers, reviewer, TRAINTAINER_WEIGHT)
60
+ add_weighted_reviewer(total_traintainers, reviewer, DEFAULT_REVIEWER_WEIGHT + TRAINTAINER_WEIGHT)
51
61
  end
52
62
  end
53
63
 
54
- def add_weighted_reviewer(reviewers, reviewer, weight)
64
+ def add_weighted_reviewer(reviewers, reviewer, added_weight_for_hungry)
55
65
  if reviewer.reduced_capacity
56
- reviewers.fill(reviewer, reviewers.size, weight)
66
+ reviewers.fill(reviewer, reviewers.size, Gitlab::Dangerfiles::Weightage::BASE_REVIEWER_WEIGHT)
57
67
  elsif reviewer.hungry
58
- reviewers.fill(reviewer, reviewers.size, weight * Gitlab::Dangerfiles::Weightage::CAPACITY_MULTIPLIER + DEFAULT_REVIEWER_WEIGHT)
68
+ reviewers.fill(reviewer, reviewers.size, DEFAULT_REVIEWER_WEIGHT + added_weight_for_hungry)
59
69
  else
60
- reviewers.fill(reviewer, reviewers.size, weight * Gitlab::Dangerfiles::Weightage::CAPACITY_MULTIPLIER)
70
+ reviewers.fill(reviewer, reviewers.size, DEFAULT_REVIEWER_WEIGHT)
61
71
  end
62
72
  end
63
73
  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.0.0
4
+ version: 3.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - GitLab
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-03-22 00:00:00.000000000 Z
11
+ date: 2022-06-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -169,6 +169,7 @@ files:
169
169
  - lib/danger/rules/changelog/Dangerfile
170
170
  - lib/danger/rules/changes_size/Dangerfile
171
171
  - lib/danger/rules/commit_messages/Dangerfile
172
+ - lib/danger/rules/commits_counter/Dangerfile
172
173
  - lib/danger/rules/simple_roulette/Dangerfile
173
174
  - lib/danger/rules/type_label/Dangerfile
174
175
  - lib/danger/rules/z_add_labels/Dangerfile