gitlab-dangerfiles 3.6.0 → 3.6.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +3 -0
- data/README.md +4 -0
- data/lib/danger/plugins/internal/helper.rb +9 -1
- data/lib/danger/plugins/roulette.rb +7 -1
- data/lib/gitlab/dangerfiles/base_linter.rb +10 -0
- data/lib/gitlab/dangerfiles/category.rb +97 -0
- data/lib/gitlab/dangerfiles/teammate.rb +10 -37
- data/lib/gitlab/dangerfiles/version.rb +1 -1
- data/lib/gitlab/dangerfiles/weightage/reviewers.rb +6 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 34ff9782c4b20cd3c7dbb4a25d7ecdf66cf49ef303e1deb0bb04074e1c4fca21
|
4
|
+
data.tar.gz: b21f8643147b7147fca7e5cba536c67bf98d65f827cb169d72fd2ac5ff3de355
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7f9f43daf58a905f330ad98020327073a47692f24c0494d407d7e76aa8b18819b74839772c58b19d9081b04034154a06e8dee588c70898b71db08bab03fa31a9
|
7
|
+
data.tar.gz: f30572b11ac8e2d9a4ab9cc35c19000c68ecdaefd72f8e276f18e73da3beeb64b81a44d2e4919977c0aabecafec5d3fa64a25443604c27168865a5acb7c6bf97
|
data/.rubocop.yml
CHANGED
@@ -32,6 +32,9 @@ Style/HashSyntax:
|
|
32
32
|
Style/StringLiterals:
|
33
33
|
EnforcedStyle: double_quotes
|
34
34
|
|
35
|
+
Style/TrailingCommaInHashLiteral:
|
36
|
+
EnforcedStyleForMultiline: consistent_comma
|
37
|
+
|
35
38
|
# Was problematic, and not included in the .rubocop_todo.yml
|
36
39
|
GitlabSecurity/PublicSend:
|
37
40
|
Enabled: false
|
data/README.md
CHANGED
@@ -128,8 +128,12 @@ project. To use it in your project, perform the following steps:
|
|
128
128
|
see how to set it up.
|
129
129
|
1. When using the default roulette, use `import_defaults` or import it manually when setting
|
130
130
|
up the gitlab-dangerfiles instance:
|
131
|
+
|
131
132
|
```ruby
|
133
|
+
require 'gitlab-dangerfiles'
|
134
|
+
|
132
135
|
Gitlab::Dangerfiles.for_project(self) do |dangerfiles|
|
136
|
+
dangerfiles.import_plugins
|
133
137
|
dangerfiles.import_dangerfiles(only: %w[simple_roulette])
|
134
138
|
end
|
135
139
|
```
|
@@ -17,6 +17,7 @@ module Danger
|
|
17
17
|
none: "",
|
18
18
|
qa: "~QA",
|
19
19
|
ux: "~UX",
|
20
|
+
codeowners: '~"Code Owners"',
|
20
21
|
test: "~test for `spec/features/*`",
|
21
22
|
# Deprecated as of 2.3.0 in favor of tooling
|
22
23
|
engineering_productivity: '~"Engineering Productivity" for CI, Danger',
|
@@ -26,6 +27,7 @@ module Danger
|
|
26
27
|
integrations_be: '~"group::integrations" (backend)',
|
27
28
|
integrations_fe: '~"group::integrations" (frontend)',
|
28
29
|
"Authentication and Authorization": '~"group::authentication and authorization"',
|
30
|
+
Compliance: '~"group::compliance"',
|
29
31
|
}.freeze
|
30
32
|
|
31
33
|
# Allows to set specific rule's configuration by passing a block.
|
@@ -234,7 +236,13 @@ module Danger
|
|
234
236
|
# @return [String] the GFM for a category label, making its best guess if it's not
|
235
237
|
# a category we know about.
|
236
238
|
def label_for_category(category)
|
237
|
-
CATEGORY_LABELS
|
239
|
+
CATEGORY_LABELS[category] ||
|
240
|
+
|
241
|
+
if category.start_with?("`")
|
242
|
+
category.to_s
|
243
|
+
else
|
244
|
+
%Q{~"#{category}"}
|
245
|
+
end
|
238
246
|
end
|
239
247
|
|
240
248
|
# @return [String] +""+ when not in the CI context, and the MR Source Project ID as a string otherwise.
|
@@ -20,7 +20,13 @@ module Danger
|
|
20
20
|
|
21
21
|
Approval = Struct.new(:category, :spin) do
|
22
22
|
def self.from_approval_rule(rule, maintainer)
|
23
|
-
category =
|
23
|
+
category =
|
24
|
+
if rule["section"] == "codeowners"
|
25
|
+
"`#{rule["name"]}`"
|
26
|
+
else
|
27
|
+
rule["section"]
|
28
|
+
end.to_sym
|
29
|
+
|
24
30
|
spin = Spin.new(category, nil, maintainer, :reviewer)
|
25
31
|
|
26
32
|
new(category, spin)
|
@@ -14,6 +14,7 @@ module Gitlab
|
|
14
14
|
{
|
15
15
|
subject_too_short: "The %s must contain at least #{MIN_SUBJECT_WORDS_COUNT} words",
|
16
16
|
subject_too_long: "The %s may not be longer than #{MAX_LINE_LENGTH} characters",
|
17
|
+
subject_starts_with_a_space: "The %s must not start with a space",
|
17
18
|
subject_starts_with_lowercase: "The %s must start with a capital letter",
|
18
19
|
subject_ends_with_a_period: "The %s must not end with a period",
|
19
20
|
}
|
@@ -49,6 +50,10 @@ module Gitlab
|
|
49
50
|
add_problem(:subject_too_long, self.class.subject_description)
|
50
51
|
end
|
51
52
|
|
53
|
+
if subject_starts_with_a_space?
|
54
|
+
add_problem(:subject_starts_with_a_space, self.class.subject_description)
|
55
|
+
end
|
56
|
+
|
52
57
|
if subject_starts_with_lowercase?
|
53
58
|
add_problem(:subject_starts_with_lowercase, self.class.subject_description)
|
54
59
|
end
|
@@ -78,8 +83,13 @@ module Gitlab
|
|
78
83
|
line.length > MAX_LINE_LENGTH
|
79
84
|
end
|
80
85
|
|
86
|
+
def subject_starts_with_a_space?
|
87
|
+
subject.start_with?(" ")
|
88
|
+
end
|
89
|
+
|
81
90
|
def subject_starts_with_lowercase?
|
82
91
|
return false if subject.empty?
|
92
|
+
return false if subject_starts_with_a_space?
|
83
93
|
return false if ("A".."Z").cover?(subject[0])
|
84
94
|
|
85
95
|
first_char = subject.sub(/\A(\[[^\]]+\]|[^:\s]+:)\s/, "")[0]
|
@@ -0,0 +1,97 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Gitlab
|
4
|
+
module Dangerfiles
|
5
|
+
CategoryStruct = Struct.new(:name, :project, :kind, :labels, keyword_init: true)
|
6
|
+
|
7
|
+
class Category < CategoryStruct
|
8
|
+
def self.for(name, **arguments)
|
9
|
+
(name_to_class[name] || self).new(name: name, **arguments)
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.name_to_class
|
13
|
+
@name_to_class ||= {
|
14
|
+
test: Test,
|
15
|
+
tooling: Tooling,
|
16
|
+
integrations_be: IntegrationsBE,
|
17
|
+
integrations_fe: IntegrationsFE,
|
18
|
+
ux: UX,
|
19
|
+
}.freeze
|
20
|
+
end
|
21
|
+
private_class_method :name_to_class
|
22
|
+
|
23
|
+
def has_capability?(...)
|
24
|
+
has_particular_capability?(...) || has_universal_capability?(...)
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def has_particular_capability?(teammate)
|
30
|
+
teammate.capabilities(project).include?(capability)
|
31
|
+
end
|
32
|
+
|
33
|
+
def has_universal_capability?(teammate)
|
34
|
+
false
|
35
|
+
end
|
36
|
+
|
37
|
+
def capability
|
38
|
+
# name can be nil
|
39
|
+
@capability ||= "#{kind} #{name}".strip
|
40
|
+
end
|
41
|
+
|
42
|
+
class Test < Category
|
43
|
+
private
|
44
|
+
|
45
|
+
def has_particular_capability?(teammate)
|
46
|
+
return false if kind != :reviewer
|
47
|
+
|
48
|
+
area = teammate.role[/Software Engineer in Test(?:.*?, (\w+))/, 1]
|
49
|
+
|
50
|
+
area && labels.any?("devops::#{area.downcase}")
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
class Tooling < Category
|
55
|
+
private
|
56
|
+
|
57
|
+
def has_particular_capability?(teammate)
|
58
|
+
if super
|
59
|
+
true
|
60
|
+
elsif %i[trainee_maintainer maintainer].include?(kind)
|
61
|
+
false
|
62
|
+
else # fallback to backend reviewer
|
63
|
+
teammate.capabilities(project).include?("#{kind} backend")
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
class IntegrationsBE < Category
|
69
|
+
private
|
70
|
+
|
71
|
+
def has_particular_capability?(teammate)
|
72
|
+
kind == :reviewer &&
|
73
|
+
teammate.role.match?(/Backend Engineer.+Manage:Integrations/)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
class IntegrationsFE < Category
|
78
|
+
private
|
79
|
+
|
80
|
+
def has_particular_capability?(teammate)
|
81
|
+
kind == :reviewer &&
|
82
|
+
teammate.role.match?(/Frontend Engineer.+Manage:Integrations/)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
class UX < Category
|
87
|
+
private
|
88
|
+
|
89
|
+
def has_universal_capability?(teammate)
|
90
|
+
teammate.projects.each_value.find do |capabilities|
|
91
|
+
capabilities.include?(capability)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -1,9 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative "category"
|
4
|
+
|
3
5
|
module Gitlab
|
4
6
|
module Dangerfiles
|
5
7
|
class Teammate
|
6
|
-
attr_reader :options, :username, :name, :role, :projects, :available, :hungry, :reduced_capacity, :tz_offset_hours
|
8
|
+
attr_reader :options, :username, :name, :role, :projects, :available, :hungry, :reduced_capacity, :tz_offset_hours,
|
9
|
+
:only_maintainer_reviews
|
7
10
|
|
8
11
|
# The options data are produced by https://gitlab.com/gitlab-org/gitlab-roulette/-/blob/master/lib/team_member.rb
|
9
12
|
def initialize(options = {})
|
@@ -18,6 +21,7 @@ module Gitlab
|
|
18
21
|
@hungry = options["hungry"]
|
19
22
|
@reduced_capacity = options["reduced_capacity"]
|
20
23
|
@tz_offset_hours = options["tz_offset_hours"]
|
24
|
+
@only_maintainer_reviews = options["only_maintainer_reviews"]
|
21
25
|
end
|
22
26
|
|
23
27
|
def to_h
|
@@ -74,6 +78,10 @@ module Gitlab
|
|
74
78
|
(Time.now.utc + tz_offset_hours * 3600).hour
|
75
79
|
end
|
76
80
|
|
81
|
+
def capabilities(project)
|
82
|
+
projects.fetch(project, [])
|
83
|
+
end
|
84
|
+
|
77
85
|
protected
|
78
86
|
|
79
87
|
def floored_offset_hours
|
@@ -123,42 +131,7 @@ module Gitlab
|
|
123
131
|
end
|
124
132
|
|
125
133
|
def has_capability?(project, category, kind, labels)
|
126
|
-
|
127
|
-
when :test
|
128
|
-
area = role[/Software Engineer in Test(?:.*?, (\w+))/, 1]
|
129
|
-
|
130
|
-
area && labels.any?("devops::#{area.downcase}") if kind == :reviewer
|
131
|
-
when :tooling, :engineering_productivity # Deprecated as of 2.3.0 in favor of tooling
|
132
|
-
return true if capabilities(project).include?("#{kind} #{category}")
|
133
|
-
return false if %i[trainee_maintainer maintainer].include?(kind)
|
134
|
-
|
135
|
-
capabilities(project).include?("#{kind} backend") # fallback to backend reviewer
|
136
|
-
when :integrations_be
|
137
|
-
kind == :reviewer &&
|
138
|
-
role.match?(/Backend Engineer.+Ecosystem:Integrations/)
|
139
|
-
when :integrations_fe
|
140
|
-
kind == :reviewer &&
|
141
|
-
role.match?(/Frontend Engineer.+Ecosystem:Integrations/)
|
142
|
-
when nil
|
143
|
-
capabilities(project).include?("#{kind}")
|
144
|
-
else
|
145
|
-
capabilities(project).include?("#{kind} #{category}")
|
146
|
-
end || has_universal_capability?(category, kind, labels)
|
147
|
-
end
|
148
|
-
|
149
|
-
def has_universal_capability?(category, kind, labels)
|
150
|
-
case category
|
151
|
-
when :ux
|
152
|
-
capacity = "#{kind} #{category}"
|
153
|
-
|
154
|
-
projects.each_value.find do |capabilities|
|
155
|
-
capabilities.include?(capacity)
|
156
|
-
end
|
157
|
-
end
|
158
|
-
end
|
159
|
-
|
160
|
-
def capabilities(project)
|
161
|
-
projects.fetch(project, [])
|
134
|
+
Category.for(category, project: project, kind: kind, labels: labels).has_capability?(self)
|
162
135
|
end
|
163
136
|
|
164
137
|
def pluralize(count, singular, plural)
|
@@ -33,6 +33,7 @@ module Gitlab
|
|
33
33
|
# https://gitlab.com/gitlab-org/gitlab/issues/26723
|
34
34
|
|
35
35
|
remove_traintainers_from_reviewers!
|
36
|
+
remove_maintainer_only_from_reviewers!
|
36
37
|
|
37
38
|
weighted_reviewers + weighted_traintainers
|
38
39
|
end
|
@@ -49,6 +50,11 @@ module Gitlab
|
|
49
50
|
reviewers.reject! { |reviewer| traintainers.include?(reviewer) }
|
50
51
|
end
|
51
52
|
|
53
|
+
def remove_maintainer_only_from_reviewers!
|
54
|
+
# Using a maintainer-only reviewer emoji, team members can ensure they only get maintainer reviews
|
55
|
+
reviewers.reject! { |reviewer| reviewer&.only_maintainer_reviews }
|
56
|
+
end
|
57
|
+
|
52
58
|
def weighted_reviewers
|
53
59
|
reviewers.each_with_object([]) do |reviewer, total_reviewers|
|
54
60
|
add_weighted_reviewer(total_reviewers, reviewer, DEFAULT_REVIEWER_WEIGHT)
|
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.6.
|
4
|
+
version: 3.6.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- GitLab
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-12-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -183,6 +183,7 @@ files:
|
|
183
183
|
- lib/gitlab/Dangerfile
|
184
184
|
- lib/gitlab/dangerfiles.rb
|
185
185
|
- lib/gitlab/dangerfiles/base_linter.rb
|
186
|
+
- lib/gitlab/dangerfiles/category.rb
|
186
187
|
- lib/gitlab/dangerfiles/changes.rb
|
187
188
|
- lib/gitlab/dangerfiles/commit_linter.rb
|
188
189
|
- lib/gitlab/dangerfiles/config.rb
|