gitlab-dangerfiles 2.7.1 → 2.9.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitlab/merge_request_templates/Release.md +9 -8
- data/.gitlab-ci.yml +3 -7
- data/Dangerfile +1 -3
- data/Guardfile +2 -0
- data/README.md +12 -3
- data/gitlab-dangerfiles.gemspec +3 -3
- data/lib/danger/plugins/changelog.rb +234 -0
- data/lib/danger/plugins/internal/helper.rb +32 -11
- data/lib/danger/plugins/roulette.rb +10 -1
- data/lib/danger/rules/changelog/Dangerfile +3 -0
- data/lib/danger/rules/type_label/Dangerfile +5 -0
- data/lib/danger/rules/z_add_labels/Dangerfile +21 -0
- data/lib/gitlab/dangerfiles/spec_helper.rb +2 -46
- data/lib/gitlab/dangerfiles/version.rb +1 -1
- data/lib/gitlab/dangerfiles.rb +3 -0
- metadata +10 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fe54dfd04f6f991218f15df710dbc9e0669e07f4f83c07f6c62ce10048fad8fb
|
4
|
+
data.tar.gz: af0c4147142df3f3f524c9c955bfd62bd2a249e04f69c72873f63db987c09b40
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9ce6c07674bfa305f3b95ff85d9b50e1e2bb453d14468693ffcac6a2a31375d615642ccc7387a41076335956a0079c7423e69be8ccfd9a02fde849ff6a48251b
|
7
|
+
data.tar.gz: 5f938ce58903b1e77ce025059375112b54b86b8f8aa88a061c5ab3f1346d0faf2302f1a89bf4e18a3ee0921c039ebfd9763791f186695fad31c6d087e5059e06
|
@@ -1,12 +1,13 @@
|
|
1
|
-
<!-- Replace `<
|
2
|
-
|
3
|
-
|
1
|
+
<!-- Replace `<PREVIOUS_VERSION>` with the previous version number here, `<COMMIT_UPDATING_VERSION>` with the latest
|
2
|
+
commit from this merge request, and `<NEW_VERSION>` with the upcoming version number. -->
|
3
|
+
## Diff
|
4
4
|
|
5
|
-
-
|
6
|
-
- [ ] Diff link is up-to-date.
|
7
|
-
- [ ] Based on the diff, `version.rb` is updated, according to [SemVer](https://semver.org).
|
5
|
+
https://gitlab.com/gitlab-org/ruby/gems/gitlab-dangerfiles/compare/v<PREVIOUS_VERSION>...<COMMIT_UPDATING_VERSION>
|
8
6
|
|
9
|
-
|
10
|
-
|
7
|
+
## Checklist
|
8
|
+
|
9
|
+
- [ ] Diff link is up-to-date.
|
10
|
+
- [ ] Check the release notes: https://gitlab.com/api/v4/projects/gitlab-org%2Fruby%2Fgems%2Fgitlab-dangerfiles/repository/changelog?version=<NEW_VERSION>
|
11
|
+
- [ ] Based on the diff and the release notes, `version.rb` is updated, according to [SemVer](https://semver.org).
|
11
12
|
|
12
13
|
/label ~"type::maintenance" ~"static code analysis"
|
data/.gitlab-ci.yml
CHANGED
@@ -28,12 +28,6 @@ workflow:
|
|
28
28
|
- Gemfile.lock
|
29
29
|
policy: pull
|
30
30
|
|
31
|
-
danger-review:
|
32
|
-
extends: .default
|
33
|
-
stage: test
|
34
|
-
script:
|
35
|
-
- bundle exec danger --fail-on-errors=true --verbose
|
36
|
-
|
37
31
|
test:rspec:
|
38
32
|
extends: .default
|
39
33
|
stage: test
|
@@ -52,7 +46,9 @@ include:
|
|
52
46
|
- template: Security/SAST.gitlab-ci.yml
|
53
47
|
- template: Security/Secret-Detection.gitlab-ci.yml
|
54
48
|
- project: 'gitlab-org/quality/pipeline-common'
|
55
|
-
file:
|
49
|
+
file:
|
50
|
+
- '/ci/danger-review.yml'
|
51
|
+
- '/ci/gem-release.yml'
|
56
52
|
|
57
53
|
# run security jobs on MRs
|
58
54
|
# see: https://gitlab.com/gitlab-org/gitlab/-/issues/218444#note_478761991
|
data/Dangerfile
CHANGED
data/Guardfile
CHANGED
data/README.md
CHANGED
@@ -72,6 +72,7 @@ end
|
|
72
72
|
Danger plugins are located under `lib/danger/plugins`.
|
73
73
|
|
74
74
|
- `Danger::Helper` available in `Dangerfile`s as `helper`
|
75
|
+
- `Danger::Changelog` available in `Dangerfile`s as `changelog`
|
75
76
|
- `Danger::Roulette` available in `Dangerfile`s as `roulette`
|
76
77
|
|
77
78
|
For the full documentation about the plugins, please see https://www.rubydoc.info/gems/gitlab-dangerfiles.
|
@@ -94,6 +95,10 @@ Alternatively, you can also get/set configuration on the engine directly via `Gi
|
|
94
95
|
|
95
96
|
Danger rules are located under `lib/danger/rules`.
|
96
97
|
|
98
|
+
#### `changelog`
|
99
|
+
|
100
|
+
This rule ensures the merge request follows our [Changelog guidelines](https://docs.gitlab.com/ee/development/changelog.html#changelog-entries).
|
101
|
+
|
97
102
|
#### `changes_size`
|
98
103
|
|
99
104
|
##### Available configurations
|
@@ -109,7 +114,7 @@ Danger rules are located under `lib/danger/rules`.
|
|
109
114
|
- `max_commits_count`: The maximum number of allowed non-squashed/non-fixup commits for a given MR.
|
110
115
|
A warning is triggered if the MR has more commits.
|
111
116
|
|
112
|
-
|
117
|
+
#### `simple_roulette`
|
113
118
|
|
114
119
|
The library includes a simplified default reviewer roulette that you can use in your
|
115
120
|
project. To use it in your project, perform the following steps:
|
@@ -124,6 +129,10 @@ project. To use it in your project, perform the following steps:
|
|
124
129
|
end
|
125
130
|
```
|
126
131
|
|
132
|
+
#### `type_label`
|
133
|
+
|
134
|
+
This rule ensures the merge request has a proper [type label](https://about.gitlab.com/handbook/engineering/metrics/#work-type-classification) set..
|
135
|
+
|
127
136
|
### CI configuration
|
128
137
|
|
129
138
|
In order to run `danger` on GitLab CI, perform the following steps:
|
@@ -140,8 +149,8 @@ include:
|
|
140
149
|
- '/ci/danger-review.yml'
|
141
150
|
```
|
142
151
|
|
143
|
-
3. Create a [Project access token](https://docs.gitlab.com/ee/user/project/settings/project_access_tokens.html)
|
144
|
-
with scope `api` and role `
|
152
|
+
3. Create a [Project or group access token](https://docs.gitlab.com/ee/user/project/settings/project_access_tokens.html)
|
153
|
+
with scope `api` and role `Developer`.
|
145
154
|
4. Add a [CI/CD variable](https://docs.gitlab.com/ee/ci/variables/#add-a-cicd-variable-to-a-project)
|
146
155
|
`DANGER_GITLAB_API_TOKEN` (`Masked` but not `Protected`) and use Project access token as value.
|
147
156
|
|
data/gitlab-dangerfiles.gemspec
CHANGED
@@ -8,15 +8,15 @@ Gem::Specification.new do |spec|
|
|
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.}
|
11
|
-
spec.homepage = "https://gitlab.com/gitlab-org/gitlab-dangerfiles"
|
11
|
+
spec.homepage = "https://gitlab.com/gitlab-org/ruby/gems/gitlab-dangerfiles"
|
12
12
|
spec.license = "MIT"
|
13
13
|
spec.required_ruby_version = Gem::Requirement.new(">= 2.5.0")
|
14
14
|
|
15
15
|
spec.metadata["allowed_push_host"] = "https://rubygems.org"
|
16
16
|
|
17
17
|
spec.metadata["homepage_uri"] = spec.homepage
|
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/-/releases"
|
18
|
+
spec.metadata["source_code_uri"] = "https://gitlab.com/gitlab-org/ruby/gems/gitlab-dangerfiles"
|
19
|
+
spec.metadata["changelog_uri"] = "https://gitlab.com/gitlab-org/ruby/gems/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.
|
@@ -0,0 +1,234 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Danger
|
4
|
+
# Contains method to check the presense and validity of changelogs.
|
5
|
+
class Changelog < Danger::Plugin
|
6
|
+
NO_CHANGELOG_LABELS = [
|
7
|
+
"type::tooling",
|
8
|
+
"tooling::pipelines",
|
9
|
+
"tooling::workflow",
|
10
|
+
"ci-build",
|
11
|
+
"meta",
|
12
|
+
].freeze
|
13
|
+
NO_CHANGELOG_CATEGORIES = %i[docs none].freeze
|
14
|
+
CHANGELOG_TRAILER_REGEX = /^(?<name>Changelog):\s*(?<category>.+)$/i.freeze
|
15
|
+
CHANGELOG_EE_TRAILER_REGEX = /^EE: true$/.freeze
|
16
|
+
CHANGELOG_MODIFIED_URL_TEXT = "**CHANGELOG.md was edited.** Please remove the additions and follow the [changelog guidelines](https://docs.gitlab.com/ee/development/changelog.html).\n\n"
|
17
|
+
CHANGELOG_MISSING_URL_TEXT = "**[CHANGELOG missing](https://docs.gitlab.com/ee/development/changelog.html)**:\n\n"
|
18
|
+
|
19
|
+
OPTIONAL_CHANGELOG_MESSAGE = {
|
20
|
+
local: "If this merge request [doesn't need a CHANGELOG entry](https://docs.gitlab.com/ee/development/changelog.html#what-warrants-a-changelog-entry), feel free to ignore this message.",
|
21
|
+
ci: <<~MSG,
|
22
|
+
If you want to create a changelog entry for GitLab FOSS, add the `Changelog` trailer to the commit message you want to add to the changelog.
|
23
|
+
|
24
|
+
If you want to create a changelog entry for GitLab EE, also [add the `EE: true` trailer](https://docs.gitlab.com/ee/development/changelog.html#gitlab-enterprise-changes) to your commit message.
|
25
|
+
|
26
|
+
If this merge request [doesn't need a CHANGELOG entry](https://docs.gitlab.com/ee/development/changelog.html#what-warrants-a-changelog-entry), feel free to ignore this message.
|
27
|
+
MSG
|
28
|
+
}.freeze
|
29
|
+
SEE_DOC = "See the [changelog documentation](https://docs.gitlab.com/ee/development/changelog.html)."
|
30
|
+
|
31
|
+
REQUIRED_CHANGELOG_REASONS = {
|
32
|
+
db_changes: "introduces a database migration",
|
33
|
+
feature_flag_removed: "removes a feature flag",
|
34
|
+
}.freeze
|
35
|
+
REQUIRED_CHANGELOG_MESSAGE = {
|
36
|
+
local: "This merge request requires a changelog entry because it [%<reason>s](https://docs.gitlab.com/ee/development/changelog.html#what-warrants-a-changelog-entry).",
|
37
|
+
ci: <<~MSG,
|
38
|
+
To create a changelog entry, add the `Changelog` trailer to one of your Git commit messages.
|
39
|
+
|
40
|
+
This merge request requires a changelog entry because it [%<reason>s](https://docs.gitlab.com/ee/development/changelog.html#what-warrants-a-changelog-entry).
|
41
|
+
MSG
|
42
|
+
}.freeze
|
43
|
+
|
44
|
+
def self.categories
|
45
|
+
@categories ||= YAML
|
46
|
+
.load_file("#{ENV["CI_PROJECT_DIR"]}/.gitlab/changelog_config.yml")
|
47
|
+
.fetch("categories")
|
48
|
+
.keys
|
49
|
+
.freeze rescue []
|
50
|
+
end
|
51
|
+
|
52
|
+
class ChangelogCheckResult
|
53
|
+
attr_reader :errors, :warnings, :markdowns, :messages
|
54
|
+
|
55
|
+
def initialize(errors: [], warnings: [], markdowns: [], messages: [])
|
56
|
+
@errors = errors
|
57
|
+
@warnings = warnings
|
58
|
+
@markdowns = markdowns
|
59
|
+
@messages = messages
|
60
|
+
end
|
61
|
+
|
62
|
+
private_class_method :new
|
63
|
+
|
64
|
+
def self.empty
|
65
|
+
new
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.error(error)
|
69
|
+
new(errors: [error])
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.warning(warning)
|
73
|
+
new(warnings: [warning])
|
74
|
+
end
|
75
|
+
|
76
|
+
def error(error)
|
77
|
+
errors << error
|
78
|
+
end
|
79
|
+
|
80
|
+
def warning(warning)
|
81
|
+
warnings << warning
|
82
|
+
end
|
83
|
+
|
84
|
+
def markdown(markdown)
|
85
|
+
markdowns << markdown
|
86
|
+
end
|
87
|
+
|
88
|
+
def message(message)
|
89
|
+
messages << message
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# rubocop:disable Style/SignalException
|
94
|
+
def check!
|
95
|
+
if git.modified_files.include?("CHANGELOG.md")
|
96
|
+
fail modified_text
|
97
|
+
end
|
98
|
+
|
99
|
+
if exist?
|
100
|
+
add_danger_messages(check_changelog_path)
|
101
|
+
elsif required?
|
102
|
+
required_texts.each { |_, text| fail(text) } # rubocop:disable Lint/UnreachableLoop
|
103
|
+
elsif optional?
|
104
|
+
message optional_text
|
105
|
+
end
|
106
|
+
|
107
|
+
check_changelog_commit_categories
|
108
|
+
end
|
109
|
+
|
110
|
+
# rubocop:enable Style/SignalException
|
111
|
+
|
112
|
+
# rubocop:disable Style/SignalException
|
113
|
+
def add_danger_messages(check_result)
|
114
|
+
check_result.errors.each { |error| fail(error) } # rubocop:disable Lint/UnreachableLoop
|
115
|
+
check_result.warnings.each { |warning| warn(warning) }
|
116
|
+
check_result.markdowns.each { |markdown_hash| markdown(**markdown_hash) }
|
117
|
+
check_result.messages.each { |text| message(text) }
|
118
|
+
end
|
119
|
+
|
120
|
+
# rubocop:enable Style/SignalException
|
121
|
+
|
122
|
+
def check_changelog_commit_categories
|
123
|
+
changelog_commits.each do |commit|
|
124
|
+
add_danger_messages(check_changelog_trailer(commit))
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def check_changelog_trailer(commit)
|
129
|
+
trailer = commit.message.match(CHANGELOG_TRAILER_REGEX)
|
130
|
+
name = trailer[:name]
|
131
|
+
category = trailer[:category]
|
132
|
+
|
133
|
+
unless name == "Changelog"
|
134
|
+
return ChangelogCheckResult.error("The changelog trailer for commit #{commit.sha} must be `Changelog` (starting with a capital C), not `#{name}`")
|
135
|
+
end
|
136
|
+
|
137
|
+
return ChangelogCheckResult.empty if self.class.categories.include?(category)
|
138
|
+
|
139
|
+
ChangelogCheckResult.error("Commit #{commit.sha} uses an invalid changelog category: #{category}")
|
140
|
+
end
|
141
|
+
|
142
|
+
def check_changelog_path
|
143
|
+
check_result = ChangelogCheckResult.empty
|
144
|
+
return check_result unless exist?
|
145
|
+
|
146
|
+
ee_changes = helper.changed_files(%r{\Aee/})
|
147
|
+
|
148
|
+
if ee_changes.any? && !ee_changelog? && !required?
|
149
|
+
check_result.warning("This MR changes code in `ee/`, but its Changelog commit is missing the [`EE: true` trailer](https://docs.gitlab.com/ee/development/changelog.html#gitlab-enterprise-changes). Consider adding it to your Changelog commits.")
|
150
|
+
end
|
151
|
+
|
152
|
+
if ee_changes.empty? && ee_changelog?
|
153
|
+
check_result.warning("This MR has a Changelog commit for EE, but no code changes in `ee/`. Consider removing the `EE: true` trailer from your commits.")
|
154
|
+
end
|
155
|
+
|
156
|
+
if ee_changes.any? && ee_changelog? && required_reasons.include?(:db_changes)
|
157
|
+
check_result.warning("This MR has a Changelog commit with the `EE: true` trailer, but there are database changes which [requires](https://docs.gitlab.com/ee/development/changelog.html#what-warrants-a-changelog-entry) the Changelog commit to not have the `EE: true` trailer. Consider removing the `EE: true` trailer from your commits.")
|
158
|
+
end
|
159
|
+
|
160
|
+
check_result
|
161
|
+
end
|
162
|
+
|
163
|
+
def required_reasons
|
164
|
+
[].tap do |reasons|
|
165
|
+
reasons << :db_changes if helper.changes.added.has_category?(:migration)
|
166
|
+
reasons << :feature_flag_removed if helper.changes.deleted.has_category?(:feature_flag)
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
def required?
|
171
|
+
required_reasons.any?
|
172
|
+
end
|
173
|
+
|
174
|
+
def optional?
|
175
|
+
categories_need_changelog? && mr_without_no_changelog_label?
|
176
|
+
end
|
177
|
+
|
178
|
+
def exist?
|
179
|
+
valid_changelog_commits.any?
|
180
|
+
end
|
181
|
+
|
182
|
+
def changelog_commits
|
183
|
+
git.commits.select do |commit|
|
184
|
+
commit.message.match?(CHANGELOG_TRAILER_REGEX)
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
def valid_changelog_commits
|
189
|
+
changelog_commits.select do |commit|
|
190
|
+
trailer = commit.message.match(CHANGELOG_TRAILER_REGEX)
|
191
|
+
|
192
|
+
self.class.categories.include?(trailer[:category])
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
def ee_changelog?
|
197
|
+
changelog_commits.any? do |commit|
|
198
|
+
commit.message.match?(CHANGELOG_EE_TRAILER_REGEX)
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
def modified_text
|
203
|
+
CHANGELOG_MODIFIED_URL_TEXT +
|
204
|
+
(helper.ci? ? format(OPTIONAL_CHANGELOG_MESSAGE[:ci]) : OPTIONAL_CHANGELOG_MESSAGE[:local])
|
205
|
+
end
|
206
|
+
|
207
|
+
def required_texts
|
208
|
+
required_reasons.each_with_object({}) do |required_reason, memo|
|
209
|
+
memo[required_reason] =
|
210
|
+
CHANGELOG_MISSING_URL_TEXT +
|
211
|
+
(helper.ci? ? format(REQUIRED_CHANGELOG_MESSAGE[:ci], reason: REQUIRED_CHANGELOG_REASONS.fetch(required_reason)) : REQUIRED_CHANGELOG_MESSAGE[:local])
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
def optional_text
|
216
|
+
CHANGELOG_MISSING_URL_TEXT +
|
217
|
+
(helper.ci? ? format(OPTIONAL_CHANGELOG_MESSAGE[:ci]) : OPTIONAL_CHANGELOG_MESSAGE[:local])
|
218
|
+
end
|
219
|
+
|
220
|
+
private
|
221
|
+
|
222
|
+
def read_file(path)
|
223
|
+
File.read(path)
|
224
|
+
end
|
225
|
+
|
226
|
+
def categories_need_changelog?
|
227
|
+
(helper.changes.categories - NO_CHANGELOG_CATEGORIES).any?
|
228
|
+
end
|
229
|
+
|
230
|
+
def mr_without_no_changelog_label?
|
231
|
+
(helper.mr_labels & NO_CHANGELOG_LABELS).empty?
|
232
|
+
end
|
233
|
+
end
|
234
|
+
end
|
@@ -120,13 +120,7 @@ module Danger
|
|
120
120
|
# +modified_files+ might contain paths that already have been renamed,
|
121
121
|
# so we need to remove them from the list.
|
122
122
|
def all_changed_files
|
123
|
-
|
124
|
-
.merge(added_files)
|
125
|
-
.merge(modified_files)
|
126
|
-
.merge(renamed_files.map { |x| x[:after] })
|
127
|
-
.subtract(renamed_files.map { |x| x[:before] })
|
128
|
-
.to_a
|
129
|
-
.sort
|
123
|
+
changes.files - changes.renamed_before.files
|
130
124
|
end
|
131
125
|
|
132
126
|
# @param filename [String] A file name for which we want the diff.
|
@@ -242,6 +236,20 @@ module Danger
|
|
242
236
|
CATEGORY_LABELS.fetch(category, "~#{category}")
|
243
237
|
end
|
244
238
|
|
239
|
+
# @return [String] +""+ when not in the CI context, and the MR Source Project ID as a string otherwise.
|
240
|
+
def mr_source_project_id
|
241
|
+
return "" unless ci?
|
242
|
+
|
243
|
+
gitlab_helper.mr_json["source_project_id"].to_s
|
244
|
+
end
|
245
|
+
|
246
|
+
# @return [String] +""+ when not in the CI context, and the MR Target Project ID as a string otherwise.
|
247
|
+
def mr_target_project_id
|
248
|
+
return "" unless ci?
|
249
|
+
|
250
|
+
gitlab_helper.mr_json["target_project_id"].to_s
|
251
|
+
end
|
252
|
+
|
245
253
|
# @return [String] +""+ when not in the CI context, and the MR IID as a string otherwise.
|
246
254
|
def mr_iid
|
247
255
|
return "" unless ci?
|
@@ -274,7 +282,7 @@ module Danger
|
|
274
282
|
def mr_labels
|
275
283
|
return [] unless ci?
|
276
284
|
|
277
|
-
gitlab_helper.mr_labels
|
285
|
+
(gitlab_helper.mr_labels + labels_to_add.to_a).uniq
|
278
286
|
end
|
279
287
|
|
280
288
|
# @return [String] +`git rev-parse --abbrev-ref HEAD`+ when not in the CI context, and the MR source branch otherwise.
|
@@ -330,11 +338,13 @@ module Danger
|
|
330
338
|
/\A\d+-\d+-stable-ee/i.match?(mr_target_branch)
|
331
339
|
end
|
332
340
|
|
333
|
-
# Whether a MR has
|
341
|
+
# Whether a MR has a scoped label with the given scope set or not.
|
342
|
+
#
|
343
|
+
# @param scope [String] The scope for which to look for labels, e.g. +type+ would look for any +type::*+ label.
|
334
344
|
#
|
335
345
|
# @return [Boolean]
|
336
|
-
def
|
337
|
-
mr_labels.any? { |label| label.start_with?("
|
346
|
+
def has_scoped_label_with_scope?(scope)
|
347
|
+
mr_labels.any? { |label| label.start_with?("#{scope}::") }
|
338
348
|
end
|
339
349
|
|
340
350
|
# @return [Boolean] whether a MR has any CI-related changes (i.e. +".gitlab-ci.yml"+ or +".gitlab/ci/*"+) or not.
|
@@ -393,6 +403,17 @@ module Danger
|
|
393
403
|
mr_labels.find { |label| label.start_with?("group::") }
|
394
404
|
end
|
395
405
|
|
406
|
+
# Accessor for storing labels to add so that other rules can check if labels will be added after Danger
|
407
|
+
# has evaluated all the rules.
|
408
|
+
# For instance, a rule might require a specific label to be set, but another rule could add this label
|
409
|
+
# itself. Without this method, the first rule wouldn't know that the label would be applied and would ask
|
410
|
+
# for it anyway.
|
411
|
+
#
|
412
|
+
# @return [Set<String>] the list of labels that Danger will add
|
413
|
+
def labels_to_add
|
414
|
+
@labels_to_add ||= Set.new
|
415
|
+
end
|
416
|
+
|
396
417
|
private
|
397
418
|
|
398
419
|
# @return [Danger::RequestSources::GitLab, nil] the +gitlab+ helper, or +nil+ when it's not available.
|
@@ -22,7 +22,7 @@ module Danger
|
|
22
22
|
#
|
23
23
|
# @return [Gitlab::Dangerfiles::Teammate]
|
24
24
|
def team_mr_author
|
25
|
-
company_members.find { |person| person.username == helper.mr_author }
|
25
|
+
@team_mr_author ||= company_members.find { |person| person.username == helper.mr_author }
|
26
26
|
end
|
27
27
|
|
28
28
|
# Assigns GitLab team members to be reviewer and maintainer
|
@@ -36,6 +36,7 @@ module Danger
|
|
36
36
|
def spin(project = nil, categories = [nil], timezone_experiment: false)
|
37
37
|
project = (project || helper.config.project_name).downcase
|
38
38
|
categories = categories.map { |category| category&.downcase }
|
39
|
+
categories.reject! { |category| integrations_reject_category?(category, project) }
|
39
40
|
|
40
41
|
spins = categories.sort_by(&:to_s).map do |category|
|
41
42
|
including_timezone = INCLUDE_TIMEZONE_FOR_CATEGORY.fetch(category, timezone_experiment)
|
@@ -106,6 +107,14 @@ module Danger
|
|
106
107
|
person.username == helper.mr_author
|
107
108
|
end
|
108
109
|
|
110
|
+
# @param [String] category name
|
111
|
+
# @return [Boolean]
|
112
|
+
def integrations_reject_category?(category, project)
|
113
|
+
# Reject integrations categories if the MR author has reviewing abilities for the category.
|
114
|
+
team_mr_author&.integrations_be?(project, category, helper.mr_labels) ||
|
115
|
+
team_mr_author&.integrations_fe?(project, category, helper.mr_labels)
|
116
|
+
end
|
117
|
+
|
109
118
|
def new_random(seed)
|
110
119
|
Random.new(Digest::MD5.hexdigest(seed).to_i(16))
|
111
120
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# This rule is the last one since we want to add all the labels to add at once,
|
2
|
+
# so we let other rules adding to `helper.labels_to_add` before actually adding them via the API here.
|
3
|
+
|
4
|
+
# Don't try to post anything locally.
|
5
|
+
return unless helper.ci?
|
6
|
+
|
7
|
+
def post_labels(labels)
|
8
|
+
gitlab.api.update_merge_request(helper.mr_target_project_id,
|
9
|
+
helper.mr_iid,
|
10
|
+
add_labels: labels.join(","))
|
11
|
+
rescue Gitlab::Error::Forbidden
|
12
|
+
warn("This Merge Request needs to be labelled with #{helper.labels_list(labels)}. Please request a reviewer or maintainer to add them.")
|
13
|
+
end
|
14
|
+
|
15
|
+
post_labels(helper.labels_to_add) if helper.labels_to_add.any?
|
16
|
+
|
17
|
+
anything_to_post = status_report.values.any?(&:any?)
|
18
|
+
|
19
|
+
if anything_to_post
|
20
|
+
markdown("**If needed, you can retry the [`danger-review` job](#{ENV["CI_JOB_URL"]}) that generated this comment.**")
|
21
|
+
end
|
@@ -53,60 +53,16 @@ RSpec.shared_context "with dangerfile" do
|
|
53
53
|
let(:renamed_files) { [{ before: renamed_before_file, after: renamed_after_file }] }
|
54
54
|
let(:change_class) { Gitlab::Dangerfiles::Change }
|
55
55
|
let(:changes_class) { Gitlab::Dangerfiles::Changes }
|
56
|
+
let(:ee_change) { nil }
|
56
57
|
let(:changes) { changes_class.new([]) }
|
57
58
|
let(:mr_title) { "Fake Title" }
|
58
59
|
let(:mr_labels) { [] }
|
59
|
-
let(:mr_changes_from_api) do
|
60
|
-
{
|
61
|
-
"changes" => [
|
62
|
-
{
|
63
|
-
"old_path" => "added-from-api",
|
64
|
-
"new_path" => "added-from-api",
|
65
|
-
"a_mode" => "100644",
|
66
|
-
"b_mode" => "100644",
|
67
|
-
"new_file" => true,
|
68
|
-
"renamed_file" => false,
|
69
|
-
"deleted_file" => false,
|
70
|
-
"diff" => "@@ -49,6 +49,14 @@\n- vendor/ruby/\n policy: pull\n \n+.danger-review-cache:\n",
|
71
|
-
},
|
72
|
-
{
|
73
|
-
"old_path" => "modified-from-api",
|
74
|
-
"new_path" => "modified-from-api",
|
75
|
-
"a_mode" => "100644",
|
76
|
-
"b_mode" => "100644",
|
77
|
-
"new_file" => false,
|
78
|
-
"renamed_file" => false,
|
79
|
-
"deleted_file" => false,
|
80
|
-
"diff" => "@@ -49,6 +49,14 @@\n- vendor/ruby/\n policy: pull\n \n+.danger-review-cache:\n",
|
81
|
-
},
|
82
|
-
{
|
83
|
-
"old_path" => "renamed_before-from-api",
|
84
|
-
"new_path" => "renamed_after-from-api",
|
85
|
-
"a_mode" => "100644",
|
86
|
-
"b_mode" => "100644",
|
87
|
-
"new_file" => false,
|
88
|
-
"renamed_file" => true,
|
89
|
-
"deleted_file" => false,
|
90
|
-
"diff" => "@@ -49,6 +49,14 @@\n- vendor/ruby/\n policy: pull\n \n+.danger-review-cache:\n",
|
91
|
-
},
|
92
|
-
{
|
93
|
-
"old_path" => "deleted-from-api",
|
94
|
-
"new_path" => "deleted-from-api",
|
95
|
-
"a_mode" => "100644",
|
96
|
-
"b_mode" => "100644",
|
97
|
-
"new_file" => false,
|
98
|
-
"renamed_file" => false,
|
99
|
-
"deleted_file" => true,
|
100
|
-
"diff" => "@@ -49,6 +49,14 @@\n- vendor/ruby/\n policy: pull\n \n+.danger-review-cache:\n",
|
101
|
-
},
|
102
|
-
],
|
103
|
-
}
|
104
|
-
end
|
105
60
|
|
106
61
|
let(:fake_git) { double("fake-git", added_files: added_files, modified_files: modified_files, deleted_files: deleted_files, renamed_files: renamed_files) }
|
107
62
|
let(:fake_helper) { double("fake-helper", changes: changes, added_files: added_files, modified_files: modified_files, deleted_files: deleted_files, renamed_files: renamed_files, mr_iid: 1234, mr_title: mr_title, mr_labels: mr_labels) }
|
108
63
|
|
109
64
|
before do
|
110
65
|
allow(dangerfile).to receive(:git).and_return(fake_git)
|
66
|
+
allow(dangerfile.helper).to receive(:changes).and_return(changes)
|
111
67
|
end
|
112
68
|
end
|
data/lib/gitlab/dangerfiles.rb
CHANGED
@@ -9,11 +9,14 @@ module Gitlab
|
|
9
9
|
end
|
10
10
|
end
|
11
11
|
LOCAL_RULES = %w[
|
12
|
+
changelog
|
12
13
|
changes_size
|
13
14
|
commit_messages
|
14
15
|
].freeze
|
15
16
|
CI_ONLY_RULES = %w[
|
16
17
|
simple_roulette
|
18
|
+
type_label
|
19
|
+
z_add_labels
|
17
20
|
].freeze
|
18
21
|
|
19
22
|
# Utility method to construct a [Gitlab::Dangerfiles::Engine] instance,
|
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: 2.
|
4
|
+
version: 2.9.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- GitLab
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-02-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: danger-gitlab
|
@@ -149,11 +149,15 @@ files:
|
|
149
149
|
- fixtures/emojis/aliases.json
|
150
150
|
- fixtures/emojis/digests.json
|
151
151
|
- gitlab-dangerfiles.gemspec
|
152
|
+
- lib/danger/plugins/changelog.rb
|
152
153
|
- lib/danger/plugins/internal/helper.rb
|
153
154
|
- lib/danger/plugins/roulette.rb
|
155
|
+
- lib/danger/rules/changelog/Dangerfile
|
154
156
|
- lib/danger/rules/changes_size/Dangerfile
|
155
157
|
- lib/danger/rules/commit_messages/Dangerfile
|
156
158
|
- lib/danger/rules/simple_roulette/Dangerfile
|
159
|
+
- lib/danger/rules/type_label/Dangerfile
|
160
|
+
- lib/danger/rules/z_add_labels/Dangerfile
|
157
161
|
- lib/gitlab-dangerfiles.rb
|
158
162
|
- lib/gitlab/Dangerfile
|
159
163
|
- lib/gitlab/dangerfiles.rb
|
@@ -170,14 +174,14 @@ files:
|
|
170
174
|
- lib/gitlab/dangerfiles/weightage.rb
|
171
175
|
- lib/gitlab/dangerfiles/weightage/maintainers.rb
|
172
176
|
- lib/gitlab/dangerfiles/weightage/reviewers.rb
|
173
|
-
homepage: https://gitlab.com/gitlab-org/gitlab-dangerfiles
|
177
|
+
homepage: https://gitlab.com/gitlab-org/ruby/gems/gitlab-dangerfiles
|
174
178
|
licenses:
|
175
179
|
- MIT
|
176
180
|
metadata:
|
177
181
|
allowed_push_host: https://rubygems.org
|
178
|
-
homepage_uri: https://gitlab.com/gitlab-org/gitlab-dangerfiles
|
179
|
-
source_code_uri: https://gitlab.com/gitlab-org/gitlab-dangerfiles
|
180
|
-
changelog_uri: https://gitlab.com/gitlab-org/gitlab-dangerfiles/-/releases
|
182
|
+
homepage_uri: https://gitlab.com/gitlab-org/ruby/gems/gitlab-dangerfiles
|
183
|
+
source_code_uri: https://gitlab.com/gitlab-org/ruby/gems/gitlab-dangerfiles
|
184
|
+
changelog_uri: https://gitlab.com/gitlab-org/ruby/gems/gitlab-dangerfiles/-/releases
|
181
185
|
post_install_message:
|
182
186
|
rdoc_options: []
|
183
187
|
require_paths:
|