gitlab-dangerfiles 1.1.1 → 2.0.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 +4 -4
- data/.yardopts +5 -0
- data/Gemfile +1 -0
- data/LICENSE.txt +1 -1
- data/README.md +46 -6
- data/gitlab-dangerfiles.gemspec +3 -3
- data/lib/danger/plugins/helper.rb +180 -87
- data/lib/danger/plugins/roulette.rb +74 -42
- data/lib/danger/rules/changes_size/Dangerfile +10 -0
- data/lib/gitlab/dangerfiles.rb +81 -2
- data/lib/gitlab/dangerfiles/changes.rb +22 -0
- data/lib/gitlab/dangerfiles/commit_linter.rb +1 -1
- data/lib/gitlab/dangerfiles/config.rb +17 -0
- data/lib/gitlab/dangerfiles/emoji_checker.rb +1 -0
- data/lib/gitlab/dangerfiles/teammate.rb +0 -5
- data/lib/gitlab/dangerfiles/version.rb +1 -1
- data/lib/gitlab/dangerfiles/weightage.rb +1 -0
- data/lib/gitlab/dangerfiles/weightage/maintainers.rb +1 -0
- data/lib/gitlab/dangerfiles/weightage/reviewers.rb +1 -0
- metadata +9 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0d3407bad03ff3220a55329e625c1fd5a962b4ffe29b4ab1da68a7e998761024
|
4
|
+
data.tar.gz: a9f31b18452500fa6e437a847b1d726cbbe2c47a1912c5e40fd18196ca3716fa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3390ab204b7572654e748198fb1d03b70056ab26b32a8ea29cc2c624e307e59c5cfab5306afb8900c71df62671b984ccdbb21e7c1e9adb16b2ab43a9299774c0
|
7
|
+
data.tar.gz: '06879db4e54bff63e540793f8c94f3c9412d6481641144bfa80934bb36a82872c76e9693c86aa9b381d78528da06a27795f620ff9127829e4904938807958ede'
|
data/.yardopts
ADDED
data/Gemfile
CHANGED
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
# Gitlab::Dangerfiles
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
TODO: Delete this and the text above, and describe your gem
|
3
|
+
The goal of this gem is to centralize Danger plugins and rules that to be used by multiple GitLab projects.
|
6
4
|
|
7
5
|
## Installation
|
8
6
|
|
@@ -14,15 +12,57 @@ gem 'gitlab-dangerfiles'
|
|
14
12
|
|
15
13
|
And then execute:
|
16
14
|
|
17
|
-
|
15
|
+
```sh
|
16
|
+
$ bundle install
|
17
|
+
```
|
18
18
|
|
19
19
|
Or install it yourself as:
|
20
20
|
|
21
|
-
|
21
|
+
```sh
|
22
|
+
$ gem install gitlab-dangerfiles
|
23
|
+
```
|
22
24
|
|
23
25
|
## Usage
|
24
26
|
|
25
|
-
|
27
|
+
### Importing plugins and rules
|
28
|
+
|
29
|
+
In your project's `Dangerfile`, add the following two line to import the plugins and rules from this gem:
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
# Get an instance of Gitlab::Dangerfiles
|
33
|
+
gitlab_dangerfiles = Gitlab::Dangerfiles::Engine.new(self)
|
34
|
+
|
35
|
+
# Import all plugins from the gem
|
36
|
+
gitlab_dangerfiles.import_plugins
|
37
|
+
|
38
|
+
# Import all rules from the gem
|
39
|
+
gitlab_dangerfiles.import_dangerfiles
|
40
|
+
|
41
|
+
# Or import a subset of rules from the gem
|
42
|
+
gitlab_dangerfiles.import_dangerfiles(rules: [:changes_size])
|
43
|
+
```
|
44
|
+
|
45
|
+
### Plugins
|
46
|
+
|
47
|
+
Danger plugins are located under `lib/danger/plugins`.
|
48
|
+
|
49
|
+
- `Danger::Helper` available in `Dangerfile`s as `helper`
|
50
|
+
- `Danger::Roulette` available in `Dangerfile`s as `roulette`
|
51
|
+
|
52
|
+
For the full documentation about the plugins, please see https://www.rubydoc.info/gems/gitlab-dangerfiles.
|
53
|
+
|
54
|
+
### Rules
|
55
|
+
|
56
|
+
|
57
|
+
Danger rules are located under `lib/danger/rules`.
|
58
|
+
|
59
|
+
#### `changes_size`
|
60
|
+
|
61
|
+
##### Available configurations
|
62
|
+
|
63
|
+
- `code_size_thresholds`: A hash of the form `{ high: 42, medium: 12 }` where
|
64
|
+
`:high` is the lines changed threshold which triggers an error, and
|
65
|
+
`:medium` is the lines changed threshold which triggers a warning.
|
26
66
|
|
27
67
|
## Development
|
28
68
|
|
data/gitlab-dangerfiles.gemspec
CHANGED
@@ -3,8 +3,8 @@ require_relative "lib/gitlab/dangerfiles/version"
|
|
3
3
|
Gem::Specification.new do |spec|
|
4
4
|
spec.name = "gitlab-dangerfiles"
|
5
5
|
spec.version = Gitlab::Dangerfiles::VERSION
|
6
|
-
spec.authors = ["
|
7
|
-
spec.email = ["
|
6
|
+
spec.authors = ["GitLab"]
|
7
|
+
spec.email = ["gitlab_rubygems@gitlab.com"]
|
8
8
|
|
9
9
|
spec.summary = %q{This gem provides common Dangerfile and plugins for GitLab projects.}
|
10
10
|
spec.description = %q{This gem provides common Dangerfile and plugins for GitLab projects.}
|
@@ -16,7 +16,7 @@ Gem::Specification.new do |spec|
|
|
16
16
|
|
17
17
|
spec.metadata["homepage_uri"] = spec.homepage
|
18
18
|
spec.metadata["source_code_uri"] = "https://gitlab.com/gitlab-org/gitlab-dangerfiles"
|
19
|
-
spec.metadata["changelog_uri"] = "https://gitlab.com/gitlab-org/gitlab-dangerfiles"
|
19
|
+
spec.metadata["changelog_uri"] = "https://gitlab.com/gitlab-org/gitlab-dangerfiles/-/releases"
|
20
20
|
|
21
21
|
# Specify which files should be added to the gem when it is released.
|
22
22
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
@@ -4,6 +4,7 @@ require "net/http"
|
|
4
4
|
require "json"
|
5
5
|
|
6
6
|
require_relative "../../gitlab/dangerfiles/changes"
|
7
|
+
require_relative "../../gitlab/dangerfiles/config"
|
7
8
|
require_relative "../../gitlab/dangerfiles/teammate"
|
8
9
|
require_relative "../../gitlab/dangerfiles/title_linting"
|
9
10
|
|
@@ -11,7 +12,6 @@ module Danger
|
|
11
12
|
# Common helper functions for our danger scripts.
|
12
13
|
class Helper < Danger::Plugin
|
13
14
|
RELEASE_TOOLS_BOT = "gitlab-release-tools-bot"
|
14
|
-
DRAFT_REGEX = /\A*#{Regexp.union(/(?i)(\[WIP\]\s*|WIP:\s*|WIP$)/, /(?i)(\[draft\]|\(draft\)|draft:|draft\s\-\s|draft$)/)}+\s*/i.freeze
|
15
15
|
CATEGORY_LABELS = {
|
16
16
|
docs: "~documentation", # Docs are reviewed along DevOps stages, so don't need roulette for now.
|
17
17
|
none: "",
|
@@ -22,36 +22,47 @@ module Danger
|
|
22
22
|
product_intelligence: '~"product intelligence"',
|
23
23
|
}.freeze
|
24
24
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
25
|
+
# Allows to set specific rule's configuration by passing a block.
|
26
|
+
#
|
27
|
+
# @yield [c] Yield a Gitlab::Dangerfiles::Config object
|
28
|
+
#
|
29
|
+
# @yieldparam [Gitlab::Dangerfiles::Config] The Gitlab::Dangerfiles::Config object
|
30
|
+
# @yieldreturn [Gitlab::Dangerfiles::Config] The Gitlab::Dangerfiles::Config object
|
31
|
+
#
|
32
|
+
# @example
|
33
|
+
# helper.config do |config|
|
34
|
+
# config.code_size_thresholds = { high: 42, medium: 12 }
|
35
|
+
# end
|
36
|
+
#
|
37
|
+
# @return [Gitlab::Dangerfiles::Config]
|
38
|
+
def config
|
39
|
+
(@config ||= Gitlab::Dangerfiles::Config.new).tap do |c|
|
40
|
+
yield c if block_given?
|
41
|
+
end
|
34
42
|
end
|
35
43
|
|
36
|
-
|
37
|
-
|
44
|
+
# @example
|
45
|
+
# <a href='https://gitlab.com/artsy/eigen/blob/561827e46167077b5e53515b4b7349b8ae04610b/file.txt'>file.txt</a>
|
46
|
+
#
|
47
|
+
# @param [String, Array<String>] paths
|
48
|
+
# A list of strings to convert to gitlab anchors
|
49
|
+
# @param [Boolean] full_path
|
50
|
+
# Shows the full path as the link's text, defaults to +true+.
|
51
|
+
#
|
52
|
+
# @see https://danger.systems/reference.html Danger reference where #html_link is described
|
53
|
+
# @see https://github.com/danger/danger/blob/eca19719d3e585fe1cc46bc5377f9aa955ebf609/lib/danger/danger_core/plugins/dangerfile_gitlab_plugin.rb#L216 Danger reference where #html_link is implemented
|
54
|
+
#
|
55
|
+
# @return [String] a list of HTML anchors for a file, or multiple files
|
56
|
+
def html_link(paths, full_path: true)
|
57
|
+
ci? ? gitlab_helper.html_link(paths, full_path: full_path) : paths
|
38
58
|
end
|
39
59
|
|
60
|
+
# @return [Boolean] whether we're in the CI context or not.
|
40
61
|
def ci?
|
41
62
|
!gitlab_helper.nil?
|
42
63
|
end
|
43
64
|
|
44
|
-
# @
|
45
|
-
def http_get_json(url)
|
46
|
-
rsp = Net::HTTP.get_response(URI.parse(url))
|
47
|
-
|
48
|
-
unless rsp.is_a?(Net::HTTPOK)
|
49
|
-
raise HTTPError, "Failed to read #{url}: #{rsp.code} #{rsp.message}"
|
50
|
-
end
|
51
|
-
|
52
|
-
JSON.parse(rsp.body)
|
53
|
-
end
|
54
|
-
|
65
|
+
# @return [Array<String>] a list of filenames added in this MR.
|
55
66
|
def added_files
|
56
67
|
@added_files ||= if changes_from_api
|
57
68
|
changes_from_api.select { |file| file["new_file"] }.map { |file| file["new_path"] }
|
@@ -60,6 +71,7 @@ module Danger
|
|
60
71
|
end
|
61
72
|
end
|
62
73
|
|
74
|
+
# @return [Array<String>] a list of filenames modifier in this MR.
|
63
75
|
def modified_files
|
64
76
|
@modified_files ||= if changes_from_api
|
65
77
|
changes_from_api.select { |file| !file["new_file"] && !file["deleted_file"] && !file["renamed_file"] }.map { |file| file["new_path"] }
|
@@ -68,6 +80,7 @@ module Danger
|
|
68
80
|
end
|
69
81
|
end
|
70
82
|
|
83
|
+
# @return [Array<String>] a list of filenames renamed in this MR.
|
71
84
|
def renamed_files
|
72
85
|
@renamed_files ||= if changes_from_api
|
73
86
|
changes_from_api.select { |file| file["renamed_file"] }.each_with_object([]) do |file, memo|
|
@@ -78,6 +91,7 @@ module Danger
|
|
78
91
|
end
|
79
92
|
end
|
80
93
|
|
94
|
+
# @return [Array<String>] a list of filenames deleted in this MR.
|
81
95
|
def deleted_files
|
82
96
|
@deleted_files ||= if changes_from_api
|
83
97
|
changes_from_api.select { |file| file["deleted_file"] }.map { |file| file["new_path"] }
|
@@ -86,43 +100,20 @@ module Danger
|
|
86
100
|
end
|
87
101
|
end
|
88
102
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
end
|
97
|
-
|
98
|
-
def changes_from_api
|
99
|
-
return nil unless ci?
|
100
|
-
return nil if defined?(@force_changes_from_git)
|
101
|
-
|
102
|
-
@changes_from_api ||= gitlab_helper.mr_changes.to_h["changes"]
|
103
|
-
rescue
|
104
|
-
# Fallback to the Git strategy in any case
|
105
|
-
@force_changes_from_git = true
|
106
|
-
nil
|
107
|
-
end
|
108
|
-
|
109
|
-
# Returns a list of all files that have been added, modified or renamed.
|
110
|
-
# `modified_files` might contain paths that already have been renamed,
|
111
|
-
# so we need to remove them from the list.
|
112
|
-
#
|
113
|
-
# Considering these changes:
|
103
|
+
# @example
|
104
|
+
# # Considering these changes:
|
105
|
+
# # - A new_file.rb
|
106
|
+
# # - D deleted_file.rb
|
107
|
+
# # - M modified_file.rb
|
108
|
+
# # - R renamed_file_before.rb -> renamed_file_after.rb
|
109
|
+
# # it will return:
|
114
110
|
#
|
115
|
-
#
|
116
|
-
# - D deleted_file.rb
|
117
|
-
# - M modified_file.rb
|
118
|
-
# - R renamed_file_before.rb -> renamed_file_after.rb
|
111
|
+
# #=> ['new_file.rb', 'modified_file.rb', 'renamed_file_after.rb']
|
119
112
|
#
|
120
|
-
# it will return
|
121
|
-
# ```
|
122
|
-
# [ 'new_file.rb', 'modified_file.rb', 'renamed_file_after.rb' ]
|
123
|
-
# ```
|
124
113
|
#
|
125
|
-
# @return [Array<String>]
|
114
|
+
# @return [Array<String>] a list of all files that have been added, modified or renamed.
|
115
|
+
# +modified_files+ might contain paths that already have been renamed,
|
116
|
+
# so we need to remove them from the list.
|
126
117
|
def all_changed_files
|
127
118
|
Set.new
|
128
119
|
.merge(added_files)
|
@@ -133,16 +124,19 @@ module Danger
|
|
133
124
|
.sort
|
134
125
|
end
|
135
126
|
|
136
|
-
#
|
127
|
+
# @param filename [String] A file name for which we want the diff.
|
137
128
|
#
|
138
|
-
#
|
129
|
+
# @example
|
130
|
+
# # Considering changing a line in lib/gitlab/usage_data.rb, it will return:
|
139
131
|
#
|
140
|
-
#
|
141
|
-
#
|
142
|
-
#
|
143
|
-
#
|
144
|
-
|
145
|
-
|
132
|
+
# ["--- a/lib/gitlab/usage_data.rb",
|
133
|
+
# "+++ b/lib/gitlab/usage_data.rb",
|
134
|
+
# "+ # Test change",
|
135
|
+
# "- # Old change"]
|
136
|
+
#
|
137
|
+
# @return [Array<String>] an array of changed lines in Git diff format.
|
138
|
+
def changed_lines(filename)
|
139
|
+
diff = diff_for_file(filename)
|
146
140
|
return [] unless diff
|
147
141
|
|
148
142
|
diff.split("\n").select { |line| %r{^[+-]}.match?(line) }
|
@@ -152,6 +146,14 @@ module Danger
|
|
152
146
|
gitlab_helper&.mr_author == RELEASE_TOOLS_BOT
|
153
147
|
end
|
154
148
|
|
149
|
+
# @param items [Array<String>] An array of items to transform into a bullet list.
|
150
|
+
#
|
151
|
+
# @example
|
152
|
+
# markdown_list(%w[foo bar])
|
153
|
+
# # => * foo
|
154
|
+
# * bar
|
155
|
+
#
|
156
|
+
# @return [String] a bullet list for the given +items+. If there are more than 10 items, wrap the list in a +<details></details>+ block.
|
155
157
|
def markdown_list(items)
|
156
158
|
list = items.map { |item| "* `#{item}`" }.join("\n")
|
157
159
|
|
@@ -162,14 +164,24 @@ module Danger
|
|
162
164
|
end
|
163
165
|
end
|
164
166
|
|
165
|
-
# @
|
167
|
+
# @param categories [{Regexp => Array<Symbol>}, {Array<Regexp> => Array<Symbol>}] A hash of the form +{ filename_regex => categories, [filename_regex, changes_regex] => categories }+.
|
168
|
+
# +filename_regex+ is the regex pattern to match file names. +changes_regex+ is the regex pattern to
|
169
|
+
# match changed lines in files that match +filename_regex+
|
170
|
+
#
|
171
|
+
# @return [{Symbol => Array<String>}] a hash of the type +{ category1: ["file1", "file2"], category2: ["file3", "file4"] }+
|
172
|
+
# using filename regex (+filename_regex+) and specific change regex (+changes_regex+) from the given +categories+ hash.
|
166
173
|
def changes_by_category(categories)
|
167
174
|
all_changed_files.each_with_object(Hash.new { |h, k| h[k] = [] }) do |file, hash|
|
168
175
|
categories_for_file(file, categories).each { |category| hash[category] << file }
|
169
176
|
end
|
170
177
|
end
|
171
178
|
|
172
|
-
# @
|
179
|
+
# @param categories [{Regexp => Array<Symbol>}, {Array<Regexp> => Array<Symbol>}] A hash of the form +{ filename_regex => categories, [filename_regex, changes_regex] => categories }+.
|
180
|
+
# +filename_regex+ is the regex pattern to match file names. +changes_regex+ is the regex pattern to
|
181
|
+
# match changed lines in files that match +filename_regex+
|
182
|
+
#
|
183
|
+
# @return [Gitlab::Dangerfiles::Changes] a +Gitlab::Dangerfiles::Changes+ object that represents the changes of an MR
|
184
|
+
# using filename regex (+filename_regex+) and specific change regex (+changes_regex+) from the given +categories+ hash.
|
173
185
|
def changes(categories)
|
174
186
|
Gitlab::Dangerfiles::Changes.new([]).tap do |changes|
|
175
187
|
added_files.each do |file|
|
@@ -194,16 +206,19 @@ module Danger
|
|
194
206
|
end
|
195
207
|
end
|
196
208
|
|
197
|
-
#
|
198
|
-
#
|
209
|
+
# @param filename [String] A file name.
|
210
|
+
# @param categories [{Regexp => Array<Symbol>}, {Array<Regexp> => Array<Symbol>}] A hash of the form +{ filename_regex => categories, [filename_regex, changes_regex] => categories }+.
|
211
|
+
# +filename_regex+ is the regex pattern to match file names. +changes_regex+ is the regex pattern to
|
212
|
+
# match changed lines in files that match +filename_regex+
|
199
213
|
#
|
200
|
-
# @return Array<Symbol>
|
201
|
-
|
214
|
+
# @return [Array<Symbol>] the categories a file is in, e.g., +[:frontend]+, +[:backend]+, or +%i[frontend engineering_productivity]+
|
215
|
+
# using filename regex (+filename_regex+) and specific change regex (+changes_regex+) from the given +categories+ hash.
|
216
|
+
def categories_for_file(filename, categories)
|
202
217
|
_, categories = categories.find do |key, _|
|
203
218
|
filename_regex, changes_regex = Array(key)
|
204
219
|
|
205
|
-
found = filename_regex.match?(
|
206
|
-
found &&= changed_lines(
|
220
|
+
found = filename_regex.match?(filename)
|
221
|
+
found &&= changed_lines(filename).any? { |changed_line| changes_regex.match?(changed_line) } if changes_regex
|
207
222
|
|
208
223
|
found
|
209
224
|
end
|
@@ -211,114 +226,192 @@ module Danger
|
|
211
226
|
Array(categories || :unknown)
|
212
227
|
end
|
213
228
|
|
214
|
-
#
|
215
|
-
# a category we know about.
|
229
|
+
# @param category [Symbol] A category.
|
216
230
|
#
|
217
|
-
# @return[String]
|
231
|
+
# @return [String] the GFM for a category label, making its best guess if it's not
|
232
|
+
# a category we know about.
|
218
233
|
def label_for_category(category)
|
219
234
|
CATEGORY_LABELS.fetch(category, "~#{category}")
|
220
235
|
end
|
221
236
|
|
222
|
-
|
223
|
-
usernames.map { |u| Gitlab::Dangerfiles::Teammate.new("username" => u) }
|
224
|
-
end
|
225
|
-
|
237
|
+
# @return [String] +""+ when not in the CI context, and the MR IID as a string otherwise.
|
226
238
|
def mr_iid
|
227
239
|
return "" unless ci?
|
228
240
|
|
229
|
-
gitlab_helper.mr_json["iid"]
|
241
|
+
gitlab_helper.mr_json["iid"].to_s
|
230
242
|
end
|
231
243
|
|
244
|
+
# @return [String] +`whoami`+ when not in the CI context, and the MR author username otherwise.
|
232
245
|
def mr_author
|
233
246
|
return `whoami`.strip unless ci?
|
234
247
|
|
235
248
|
gitlab_helper.mr_author
|
236
249
|
end
|
237
250
|
|
251
|
+
# @return [String] +""+ when not in the CI context, and the MR title otherwise.
|
238
252
|
def mr_title
|
239
253
|
return "" unless ci?
|
240
254
|
|
241
255
|
gitlab_helper.mr_json["title"]
|
242
256
|
end
|
243
257
|
|
258
|
+
# @return [String] +""+ when not in the CI context, and the MR URL otherwise.
|
244
259
|
def mr_web_url
|
245
260
|
return "" unless ci?
|
246
261
|
|
247
262
|
gitlab_helper.mr_json["web_url"]
|
248
263
|
end
|
249
264
|
|
265
|
+
# @return [Array<String>] +[]+ when not in the CI context, and the MR labels otherwise.
|
250
266
|
def mr_labels
|
251
267
|
return [] unless ci?
|
252
268
|
|
253
269
|
gitlab_helper.mr_labels
|
254
270
|
end
|
255
271
|
|
272
|
+
# @return [String] +`git rev-parse --abbrev-ref HEAD`+ when not in the CI context, and the MR source branch otherwise.
|
256
273
|
def mr_source_branch
|
257
274
|
return `git rev-parse --abbrev-ref HEAD`.strip unless ci?
|
258
275
|
|
259
276
|
gitlab_helper.mr_json["source_branch"]
|
260
277
|
end
|
261
278
|
|
279
|
+
# @return [String] +""+ when not in the CI context, and the MR target branch otherwise.
|
262
280
|
def mr_target_branch
|
263
281
|
return "" unless ci?
|
264
282
|
|
265
283
|
gitlab_helper.mr_json["target_branch"]
|
266
284
|
end
|
267
285
|
|
286
|
+
# @return [Boolean] whether a MR is a Draft or not.
|
268
287
|
def draft_mr?
|
269
288
|
Gitlab::Dangerfiles::TitleLinting.has_draft_flag?(mr_title)
|
270
289
|
end
|
271
290
|
|
291
|
+
# @return [Boolean] whether a MR is opened in the security mirror or not.
|
272
292
|
def security_mr?
|
273
293
|
mr_web_url.include?("/gitlab-org/security/")
|
274
294
|
end
|
275
295
|
|
296
|
+
# @return [Boolean] whether a MR title includes "cherry-pick" or not.
|
276
297
|
def cherry_pick_mr?
|
277
298
|
Gitlab::Dangerfiles::TitleLinting.has_cherry_pick_flag?(mr_title)
|
278
299
|
end
|
279
300
|
|
301
|
+
# @return [Boolean] whether a MR title includes "RUN ALL RSPEC" or not.
|
280
302
|
def run_all_rspec_mr?
|
281
303
|
Gitlab::Dangerfiles::TitleLinting.has_run_all_rspec_flag?(mr_title)
|
282
304
|
end
|
283
305
|
|
306
|
+
# @return [Boolean] whether a MR title includes "RUN AS-IF-FOSS" or not.
|
284
307
|
def run_as_if_foss_mr?
|
285
308
|
Gitlab::Dangerfiles::TitleLinting.has_run_as_if_foss_flag?(mr_title)
|
286
309
|
end
|
287
310
|
|
311
|
+
# @return [Boolean] whether a MR targets a stable branch or not.
|
288
312
|
def stable_branch?
|
289
313
|
/\A\d+-\d+-stable-ee/i.match?(mr_target_branch)
|
290
314
|
end
|
291
315
|
|
316
|
+
# Whether a MR has any database-scoped labels (i.e. +"database::*"+) set or not.
|
317
|
+
#
|
318
|
+
# @return [Boolean]
|
319
|
+
def has_database_scoped_labels?
|
320
|
+
mr_labels.any? { |label| label.start_with?("database::") }
|
321
|
+
end
|
322
|
+
|
323
|
+
# @return [Boolean] whether a MR has any CI-related changes (i.e. +".gitlab-ci.yml"+ or +".gitlab/ci/*"+) or not.
|
324
|
+
def has_ci_changes?
|
325
|
+
changed_files(%r{\A(\.gitlab-ci\.yml|\.gitlab/ci/)}).any?
|
326
|
+
end
|
327
|
+
|
328
|
+
# @param labels [Array<String>] An array of labels.
|
329
|
+
#
|
330
|
+
# @return [Boolean] whether a MR has the given +labels+ set or not.
|
292
331
|
def mr_has_labels?(*labels)
|
293
332
|
labels = labels.flatten.uniq
|
294
333
|
|
295
334
|
(labels & mr_labels) == labels
|
296
335
|
end
|
297
336
|
|
337
|
+
# @param labels [Array<String>] An array of labels.
|
338
|
+
# @param sep [String] A separator.
|
339
|
+
#
|
340
|
+
# @example
|
341
|
+
# labels_list(["foo", "bar baz"], sep: "; ")
|
342
|
+
# # => '~"foo"; ~"bar baz"'
|
343
|
+
#
|
344
|
+
# @return [String] the list of +labels+ ready for being used in a Markdown comment, separated by +sep+.
|
298
345
|
def labels_list(labels, sep: ", ")
|
299
346
|
labels.map { |label| %Q{~"#{label}"} }.join(sep)
|
300
347
|
end
|
301
348
|
|
349
|
+
# @deprecated Use {#quick_action_label} instead.
|
302
350
|
def prepare_labels_for_mr(labels)
|
351
|
+
quick_action_label(labels)
|
352
|
+
end
|
353
|
+
|
354
|
+
# @param labels [Array<String>] An array of labels.
|
355
|
+
#
|
356
|
+
# @example
|
357
|
+
# quick_action_label(["foo", "bar baz"])
|
358
|
+
# # => '/label ~"foo" ~"bar baz"'
|
359
|
+
#
|
360
|
+
# @return [String] a quick action to set the +given+ labels. Returns +""+ if +labels+ is empty.
|
361
|
+
def quick_action_label(labels)
|
303
362
|
return "" unless labels.any?
|
304
363
|
|
305
364
|
"/label #{labels_list(labels, sep: " ")}"
|
306
365
|
end
|
307
366
|
|
367
|
+
# @param regex [Regexp] A Regexp to match against.
|
368
|
+
#
|
369
|
+
# @return [Array<String>] changed files matching the given +regex+.
|
308
370
|
def changed_files(regex)
|
309
371
|
all_changed_files.grep(regex)
|
310
372
|
end
|
311
373
|
|
312
|
-
|
313
|
-
|
374
|
+
# @return [Array<String>] the group labels (i.e. +"group::*"+) set on the MR.
|
375
|
+
def group_label
|
376
|
+
mr_labels.find { |label| label.start_with?("group::") }
|
314
377
|
end
|
315
378
|
|
316
|
-
|
317
|
-
|
379
|
+
private
|
380
|
+
|
381
|
+
# @return [Danger::RequestSources::GitLab, nil] the +gitlab+ helper, or +nil+ when it's not available.
|
382
|
+
def gitlab_helper
|
383
|
+
# Unfortunately the following does not work:
|
384
|
+
# - respond_to?(:gitlab)
|
385
|
+
# - respond_to?(:gitlab, true)
|
386
|
+
gitlab
|
387
|
+
rescue NoMethodError
|
388
|
+
nil
|
318
389
|
end
|
319
390
|
|
320
|
-
|
321
|
-
|
391
|
+
# @param filename [String] A filename for which we want the diff.
|
392
|
+
#
|
393
|
+
# @return [String] the raw diff as a string for the given +filename+.
|
394
|
+
def diff_for_file(filename)
|
395
|
+
if changes_from_api
|
396
|
+
changes_hash = changes_from_api.find { |file| file["new_path"] == filename }
|
397
|
+
changes_hash["diff"] if changes_hash
|
398
|
+
else
|
399
|
+
git.diff_for_file(filename)&.patch
|
400
|
+
end
|
401
|
+
end
|
402
|
+
|
403
|
+
# Fetches MR changes from the API instead of Git (default).
|
404
|
+
#
|
405
|
+
# @return [Array<Hash>, nil]
|
406
|
+
def changes_from_api
|
407
|
+
return nil unless ci?
|
408
|
+
return nil if defined?(@force_changes_from_git)
|
409
|
+
|
410
|
+
@changes_from_api ||= gitlab_helper.mr_changes.to_h["changes"]
|
411
|
+
rescue
|
412
|
+
# Fallback to the Git strategy in any case
|
413
|
+
@force_changes_from_git = true
|
414
|
+
nil
|
322
415
|
end
|
323
416
|
end
|
324
417
|
end
|
@@ -16,13 +16,21 @@ module Danger
|
|
16
16
|
}.freeze
|
17
17
|
|
18
18
|
Spin = Struct.new(:category, :reviewer, :maintainer, :optional_role, :timezone_experiment)
|
19
|
+
HTTPError = Class.new(StandardError)
|
19
20
|
|
21
|
+
# Finds the +Gitlab::Dangerfiles::Teammate+ object whose username matches the MR author username.
|
22
|
+
#
|
23
|
+
# @return [Gitlab::Dangerfiles::Teammate]
|
20
24
|
def team_mr_author
|
21
|
-
|
25
|
+
company_members.find { |person| person.username == helper.mr_author }
|
22
26
|
end
|
23
27
|
|
24
28
|
# Assigns GitLab team members to be reviewer and maintainer
|
25
|
-
# for
|
29
|
+
# for the given +categories+.
|
30
|
+
#
|
31
|
+
# @param project [String] A project path.
|
32
|
+
# @param categories [Array<Symbol>] An array of categories symbols.
|
33
|
+
# @param timezone_experiment [Boolean] Whether to select reviewers based in timezone or not.
|
26
34
|
#
|
27
35
|
# @return [Array<Spin>]
|
28
36
|
def spin(project, categories = [nil], timezone_experiment: false)
|
@@ -33,6 +41,7 @@ module Danger
|
|
33
41
|
end
|
34
42
|
|
35
43
|
backend_spin = spins.find { |spin| spin.category == :backend }
|
44
|
+
frontend_spin = spins.find { |spin| spin.category == :frontend }
|
36
45
|
|
37
46
|
spins.each do |spin|
|
38
47
|
including_timezone = INCLUDE_TIMEZONE_FOR_CATEGORY.fetch(spin.category, timezone_experiment)
|
@@ -61,64 +70,32 @@ module Danger
|
|
61
70
|
end
|
62
71
|
when :product_intelligence
|
63
72
|
spin.optional_role = :maintainer
|
73
|
+
|
74
|
+
if spin.maintainer.nil?
|
75
|
+
# Fetch an already picked maintainer, or pick one otherwise
|
76
|
+
spin.maintainer = backend_spin&.maintainer || frontend_spin&.maintainer || spin_for_category(project, :backend, timezone_experiment: including_timezone).maintainer
|
77
|
+
end
|
64
78
|
end
|
65
79
|
end
|
66
80
|
|
67
81
|
spins
|
68
82
|
end
|
69
83
|
|
70
|
-
# Looks up the current list of GitLab team members and parses it into a
|
71
|
-
# useful form
|
72
|
-
#
|
73
|
-
# @return [Array<Teammate>]
|
74
|
-
def team
|
75
|
-
@team ||= begin
|
76
|
-
data = helper.http_get_json(ROULETTE_DATA_URL)
|
77
|
-
data.map { |hash| Gitlab::Dangerfiles::Teammate.new(hash) }
|
78
|
-
rescue JSON::ParserError
|
79
|
-
raise "Failed to parse JSON response from #{ROULETTE_DATA_URL}"
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
# Like +team+, but only returns teammates in the current project, based on
|
84
|
-
# project_name.
|
85
|
-
#
|
86
|
-
# @return [Array<Teammate>]
|
87
|
-
def project_team(project_name)
|
88
|
-
team.select { |member| member.in_project?(project_name) }
|
89
|
-
rescue => err
|
90
|
-
warn("Reviewer roulette failed to load team data: #{err.message}")
|
91
|
-
[]
|
92
|
-
end
|
93
|
-
|
94
|
-
# Known issue: If someone is rejected due to OOO, and then becomes not OOO, the
|
95
|
-
# selection will change on next spin
|
96
|
-
# @param [Array<Teammate>] people
|
97
|
-
def spin_for_person(people, random:, timezone_experiment: false)
|
98
|
-
shuffled_people = people.shuffle(random: random)
|
99
|
-
|
100
|
-
if timezone_experiment
|
101
|
-
shuffled_people.find(&method(:valid_person_with_timezone?))
|
102
|
-
else
|
103
|
-
shuffled_people.find(&method(:valid_person?))
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
84
|
private
|
108
85
|
|
109
|
-
# @param [Teammate] person
|
86
|
+
# @param [Gitlab::Dangerfiles::Teammate] person
|
110
87
|
# @return [Boolean]
|
111
88
|
def valid_person?(person)
|
112
89
|
!mr_author?(person) && person.available
|
113
90
|
end
|
114
91
|
|
115
|
-
# @param [Teammate] person
|
92
|
+
# @param [Gitlab::Dangerfiles::Teammate] person
|
116
93
|
# @return [Boolean]
|
117
94
|
def valid_person_with_timezone?(person)
|
118
95
|
valid_person?(person) && HOURS_WHEN_PERSON_CAN_BE_PICKED.cover?(person.local_hour)
|
119
96
|
end
|
120
97
|
|
121
|
-
# @param [Teammate] person
|
98
|
+
# @param [Gitlab::Dangerfiles::Teammate] person
|
122
99
|
# @return [Boolean]
|
123
100
|
def mr_author?(person)
|
124
101
|
person.username == helper.mr_author
|
@@ -134,6 +111,22 @@ module Danger
|
|
134
111
|
end
|
135
112
|
end
|
136
113
|
|
114
|
+
# Known issue: If someone is rejected due to OOO, and then becomes not OOO, the
|
115
|
+
# selection will change on next spin.
|
116
|
+
#
|
117
|
+
# @param [Array<Gitlab::Dangerfiles::Teammate>] people
|
118
|
+
#
|
119
|
+
# @return [Gitlab::Dangerfiles::Teammate]
|
120
|
+
def spin_for_person(people, random:, timezone_experiment: false)
|
121
|
+
shuffled_people = people.shuffle(random: random)
|
122
|
+
|
123
|
+
if timezone_experiment
|
124
|
+
shuffled_people.find(&method(:valid_person_with_timezone?))
|
125
|
+
else
|
126
|
+
shuffled_people.find(&method(:valid_person?))
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
137
130
|
def spin_for_category(project, category, timezone_experiment: false)
|
138
131
|
team = project_team(project)
|
139
132
|
reviewers, traintainers, maintainers =
|
@@ -151,5 +144,44 @@ module Danger
|
|
151
144
|
|
152
145
|
Spin.new(category, reviewer, maintainer, false, timezone_experiment)
|
153
146
|
end
|
147
|
+
|
148
|
+
# Fetches the given +url+ and parse its response as JSON.
|
149
|
+
#
|
150
|
+
# @param [String] url
|
151
|
+
#
|
152
|
+
# @return [Hash, Array]
|
153
|
+
def http_get_json(url)
|
154
|
+
rsp = Net::HTTP.get_response(URI.parse(url))
|
155
|
+
|
156
|
+
unless rsp.is_a?(Net::HTTPOK)
|
157
|
+
raise HTTPError, "Failed to read #{url}: #{rsp.code} #{rsp.message}"
|
158
|
+
end
|
159
|
+
|
160
|
+
JSON.parse(rsp.body)
|
161
|
+
end
|
162
|
+
|
163
|
+
# Looks up the current list of GitLab team members and parses it into a
|
164
|
+
# useful form.
|
165
|
+
#
|
166
|
+
# @return [Array<Gitlab::Dangerfiles::Teammate>]
|
167
|
+
def company_members
|
168
|
+
@company_members ||= begin
|
169
|
+
data = http_get_json(ROULETTE_DATA_URL)
|
170
|
+
data.map { |hash| Gitlab::Dangerfiles::Teammate.new(hash) }
|
171
|
+
rescue JSON::ParserError
|
172
|
+
raise "Failed to parse JSON response from #{ROULETTE_DATA_URL}"
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
# Like +team+, but only returns teammates in the current project, based on
|
177
|
+
# project_name.
|
178
|
+
#
|
179
|
+
# @return [Array<Gitlab::Dangerfiles::Teammate>]
|
180
|
+
def project_team(project_name)
|
181
|
+
company_members.select { |member| member.in_project?(project_name) }
|
182
|
+
rescue => err
|
183
|
+
warn("Reviewer roulette failed to load team data: #{err.message}")
|
184
|
+
[]
|
185
|
+
end
|
154
186
|
end
|
155
187
|
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
thresholds = helper.config.code_size_thresholds
|
4
|
+
lines_changed = git.lines_of_code
|
5
|
+
|
6
|
+
if lines_changed > thresholds[:high]
|
7
|
+
warn "This merge request is definitely too big (#{lines_changed} lines changed), please split it into multiple merge requests."
|
8
|
+
elsif lines_changed > thresholds[:medium]
|
9
|
+
warn "This merge request is quite big (#{lines_changed} lines changed), please consider splitting it into multiple merge requests."
|
10
|
+
end
|
data/lib/gitlab/dangerfiles.rb
CHANGED
@@ -2,8 +2,87 @@ require "gitlab/dangerfiles/version"
|
|
2
2
|
|
3
3
|
module Gitlab
|
4
4
|
module Dangerfiles
|
5
|
-
|
6
|
-
|
5
|
+
RULES_DIR = File.expand_path("../danger/rules", __dir__)
|
6
|
+
EXISTING_RULES = Dir.glob(File.join(RULES_DIR, "*")).each_with_object([]) do |path, memo|
|
7
|
+
if File.directory?(path)
|
8
|
+
memo << File.basename(path)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
LOCAL_RULES = %w[
|
12
|
+
changes_size
|
13
|
+
].freeze
|
14
|
+
CI_ONLY_RULES = %w[
|
15
|
+
].freeze
|
16
|
+
|
17
|
+
# This class provides utility methods to import plugins and dangerfiles easily.
|
18
|
+
class Engine
|
19
|
+
# @param dangerfile [Danger::Dangerfile] A +Danger::Dangerfile+ object.
|
20
|
+
#
|
21
|
+
# @example
|
22
|
+
# # In your main Dangerfile:
|
23
|
+
# dangerfiles = Gitlab::Dangerfiles::Engine.new(self)
|
24
|
+
#
|
25
|
+
# @return [Gitlab::Dangerfiles::Engine]
|
26
|
+
def initialize(dangerfile)
|
27
|
+
@dangerfile = dangerfile
|
28
|
+
end
|
29
|
+
|
30
|
+
# Import all available plugins.
|
31
|
+
#
|
32
|
+
# @example
|
33
|
+
# # In your main Dangerfile:
|
34
|
+
# dangerfiles = Gitlab::Dangerfiles::Engine.new(self)
|
35
|
+
#
|
36
|
+
# # Import all plugins
|
37
|
+
# dangerfiles.import_plugins
|
38
|
+
def import_plugins
|
39
|
+
danger_plugin.import_plugin(File.expand_path("../danger/plugins/*.rb", __dir__))
|
40
|
+
end
|
41
|
+
|
42
|
+
# Import available Dangerfiles.
|
43
|
+
#
|
44
|
+
# @param rules [Symbol, Array<String>] Can be either +:all+ (default) to import all rules,
|
45
|
+
# or an array of rules.
|
46
|
+
# Available rules are: +changes_size+.
|
47
|
+
#
|
48
|
+
# @example
|
49
|
+
# # In your main Dangerfile:
|
50
|
+
# dangerfiles = Gitlab::Dangerfiles::Engine.new(self)
|
51
|
+
#
|
52
|
+
# # Import all rules
|
53
|
+
# dangerfiles.import_dangerfiles
|
54
|
+
#
|
55
|
+
# # Or import only a subset of rules
|
56
|
+
# dangerfiles.import_dangerfiles(rules: %w[changes_size])
|
57
|
+
def import_dangerfiles(rules: :all)
|
58
|
+
filtered_rules(rules).each do |rule|
|
59
|
+
danger_plugin.import_dangerfile(path: File.join(RULES_DIR, rule))
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
attr_reader :dangerfile
|
66
|
+
|
67
|
+
def allowed_rules
|
68
|
+
return LOCAL_RULES unless helper_plugin.respond_to?(:ci?)
|
69
|
+
|
70
|
+
helper_plugin.ci? ? LOCAL_RULES | CI_ONLY_RULES : LOCAL_RULES
|
71
|
+
end
|
72
|
+
|
73
|
+
def filtered_rules(rules)
|
74
|
+
rules = EXISTING_RULES if rules == :all
|
75
|
+
|
76
|
+
Array(rules).map(&:to_s) & EXISTING_RULES & allowed_rules
|
77
|
+
end
|
78
|
+
|
79
|
+
def danger_plugin
|
80
|
+
@danger_plugin ||= dangerfile.plugins[Danger::DangerfileDangerPlugin]
|
81
|
+
end
|
82
|
+
|
83
|
+
def helper_plugin
|
84
|
+
@helper_plugin ||= dangerfile.plugins[Danger::Helper]
|
85
|
+
end
|
7
86
|
end
|
8
87
|
end
|
9
88
|
end
|
@@ -4,41 +4,63 @@ require_relative "title_linting"
|
|
4
4
|
|
5
5
|
module Gitlab
|
6
6
|
module Dangerfiles
|
7
|
+
# @!attribute file
|
8
|
+
# @return [String] the file name that's changed.
|
9
|
+
# @!attribute change_type
|
10
|
+
# @return [Symbol] the type of change (+:added+, +:modified+, +:deleted+, +:renamed_before+, +:renamed_after+).
|
11
|
+
# @!attribute category
|
12
|
+
# @return [Symbol] the category of the change.
|
13
|
+
# This is defined by consumers of the gem through +helper.changes_by_category+ or +helper.changes+.
|
7
14
|
Change = Struct.new(:file, :change_type, :category)
|
8
15
|
|
9
16
|
class Changes < ::SimpleDelegator
|
17
|
+
# Return an +Gitlab::Dangerfiles::Changes+ object with only the changes for the added files.
|
18
|
+
#
|
19
|
+
# @return [Gitlab::Dangerfiles::Changes]
|
10
20
|
def added
|
11
21
|
select_by_change_type(:added)
|
12
22
|
end
|
13
23
|
|
24
|
+
# @return [Gitlab::Dangerfiles::Changes] the changes for the modified files.
|
14
25
|
def modified
|
15
26
|
select_by_change_type(:modified)
|
16
27
|
end
|
17
28
|
|
29
|
+
# @return [Gitlab::Dangerfiles::Changes] the changes for the deleted files.
|
18
30
|
def deleted
|
19
31
|
select_by_change_type(:deleted)
|
20
32
|
end
|
21
33
|
|
34
|
+
# @return [Gitlab::Dangerfiles::Changes] the changes for the renamed files (before the rename).
|
22
35
|
def renamed_before
|
23
36
|
select_by_change_type(:renamed_before)
|
24
37
|
end
|
25
38
|
|
39
|
+
# @return [Gitlab::Dangerfiles::Changes] the changes for the renamed files (after the rename).
|
26
40
|
def renamed_after
|
27
41
|
select_by_change_type(:renamed_after)
|
28
42
|
end
|
29
43
|
|
44
|
+
# @param category [Symbol] A category of change.
|
45
|
+
#
|
46
|
+
# @return [Boolean] whether there are any change for the given +category+.
|
30
47
|
def has_category?(category)
|
31
48
|
any? { |change| change.category == category }
|
32
49
|
end
|
33
50
|
|
51
|
+
# @param category [Symbol] a category of change.
|
52
|
+
#
|
53
|
+
# @return [Gitlab::Dangerfiles::Changes] changes for the given +category+.
|
34
54
|
def by_category(category)
|
35
55
|
Changes.new(select { |change| change.category == category })
|
36
56
|
end
|
37
57
|
|
58
|
+
# @return [Array<Symbol>] an array of the unique categories of changes.
|
38
59
|
def categories
|
39
60
|
map(&:category).uniq
|
40
61
|
end
|
41
62
|
|
63
|
+
# @return [Array<String>] an array of the changed files.
|
42
64
|
def files
|
43
65
|
map(&:file)
|
44
66
|
end
|
@@ -15,7 +15,7 @@ module Gitlab
|
|
15
15
|
{
|
16
16
|
separator_missing: "The commit subject and body must be separated by a blank line",
|
17
17
|
details_too_many_changes: "Commits that change #{MAX_CHANGED_LINES_IN_COMMIT} or more lines across " \
|
18
|
-
"at least #{MAX_CHANGED_FILES_IN_COMMIT} files
|
18
|
+
"at least #{MAX_CHANGED_FILES_IN_COMMIT} files should describe these changes in the commit body",
|
19
19
|
details_line_too_long: "The commit body should not contain more than #{MAX_LINE_LENGTH} characters per line",
|
20
20
|
message_contains_text_emoji: "Avoid the use of Markdown Emoji such as `:+1:`. These add limited value " \
|
21
21
|
"to the commit message, and are displayed as plain text outside of GitLab",
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Gitlab
|
4
|
+
module Dangerfiles
|
5
|
+
class Config
|
6
|
+
# @!attribute code_size_thresholds
|
7
|
+
# @return [{ high: Integer, medium: Integer }] a hash of the form +{ high: 42, medium: 12 }+ where +:high+ is the lines changed threshold which triggers an error, and +:medium+ is the lines changed threshold which triggers a warning. Also, see +DEFAULT_CHANGES_SIZE_THRESHOLDS+ for the format of the hash.
|
8
|
+
attr_accessor :code_size_thresholds
|
9
|
+
|
10
|
+
DEFAULT_CHANGES_SIZE_THRESHOLDS = { high: 2_000, medium: 500 }.freeze
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
@code_size_thresholds = DEFAULT_CHANGES_SIZE_THRESHOLDS
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -101,11 +101,6 @@ module Gitlab
|
|
101
101
|
return true if capabilities(project).include?("#{kind} engineering_productivity")
|
102
102
|
|
103
103
|
capabilities(project).include?("#{kind} backend")
|
104
|
-
when :product_intelligence
|
105
|
-
return false unless role[/Engineer, Product Intelligence/]
|
106
|
-
|
107
|
-
# any reviewer of project from Product Intelligence team can review MR
|
108
|
-
kind == :reviewer && capabilities(project).any?
|
109
104
|
when nil
|
110
105
|
capabilities(project).include?("#{kind}")
|
111
106
|
else
|
@@ -18,6 +18,7 @@ module Gitlab
|
|
18
18
|
# | hungry traintainer | 8 |
|
19
19
|
# +------------------------------+--------------------------------+
|
20
20
|
#
|
21
|
+
# @api private
|
21
22
|
class Reviewers
|
22
23
|
DEFAULT_REVIEWER_WEIGHT = Gitlab::Dangerfiles::Weightage::CAPACITY_MULTIPLIER * Gitlab::Dangerfiles::Weightage::BASE_REVIEWER_WEIGHT
|
23
24
|
TRAINTAINER_WEIGHT = 3
|
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:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
-
|
7
|
+
- GitLab
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-04-
|
11
|
+
date: 2021-04-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: danger-gitlab
|
@@ -110,7 +110,7 @@ dependencies:
|
|
110
110
|
version: '0'
|
111
111
|
description: This gem provides common Dangerfile and plugins for GitLab projects.
|
112
112
|
email:
|
113
|
-
-
|
113
|
+
- gitlab_rubygems@gitlab.com
|
114
114
|
executables: []
|
115
115
|
extensions: []
|
116
116
|
extra_rdoc_files: []
|
@@ -119,6 +119,7 @@ files:
|
|
119
119
|
- ".gitlab-ci.yml"
|
120
120
|
- ".gitlab/merge_request_templates/Release.md"
|
121
121
|
- ".rspec"
|
122
|
+
- ".yardopts"
|
122
123
|
- CODE_OF_CONDUCT.md
|
123
124
|
- Gemfile
|
124
125
|
- Guardfile
|
@@ -132,12 +133,14 @@ files:
|
|
132
133
|
- gitlab-dangerfiles.gemspec
|
133
134
|
- lib/danger/plugins/helper.rb
|
134
135
|
- lib/danger/plugins/roulette.rb
|
136
|
+
- lib/danger/rules/changes_size/Dangerfile
|
135
137
|
- lib/gitlab-dangerfiles.rb
|
136
138
|
- lib/gitlab/Dangerfile
|
137
139
|
- lib/gitlab/dangerfiles.rb
|
138
140
|
- lib/gitlab/dangerfiles/base_linter.rb
|
139
141
|
- lib/gitlab/dangerfiles/changes.rb
|
140
142
|
- lib/gitlab/dangerfiles/commit_linter.rb
|
143
|
+
- lib/gitlab/dangerfiles/config.rb
|
141
144
|
- lib/gitlab/dangerfiles/emoji_checker.rb
|
142
145
|
- lib/gitlab/dangerfiles/merge_request_linter.rb
|
143
146
|
- lib/gitlab/dangerfiles/spec_helper.rb
|
@@ -154,7 +157,7 @@ metadata:
|
|
154
157
|
allowed_push_host: https://rubygems.org
|
155
158
|
homepage_uri: https://gitlab.com/gitlab-org/gitlab-dangerfiles
|
156
159
|
source_code_uri: https://gitlab.com/gitlab-org/gitlab-dangerfiles
|
157
|
-
changelog_uri: https://gitlab.com/gitlab-org/gitlab-dangerfiles
|
160
|
+
changelog_uri: https://gitlab.com/gitlab-org/gitlab-dangerfiles/-/releases
|
158
161
|
post_install_message:
|
159
162
|
rdoc_options: []
|
160
163
|
require_paths:
|
@@ -170,7 +173,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
170
173
|
- !ruby/object:Gem::Version
|
171
174
|
version: '0'
|
172
175
|
requirements: []
|
173
|
-
rubygems_version: 3.1.
|
176
|
+
rubygems_version: 3.1.6
|
174
177
|
signing_key:
|
175
178
|
specification_version: 4
|
176
179
|
summary: This gem provides common Dangerfile and plugins for GitLab projects.
|