gitlab-dangerfiles 2.4.0 → 2.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 635a5f7c76e99281a75a956cc045c25b11e0ba243dca544dfeff4c53c6665826
4
- data.tar.gz: baf2cd3b0d5bc499f980ac031c816dbdfe656e099af9db4520ad0a282788b1c8
3
+ metadata.gz: 5d547fabe6901fa966c63b46205d60383a37876720750d659b1efc911f5ff5a9
4
+ data.tar.gz: c2acf1003771ac3e206388e51bd5c6c55df9aab6e554f122cdac7c55de446619
5
5
  SHA512:
6
- metadata.gz: 8db37fdb8728b021e63c60cf612255894d353224274010ae5ccaf7b110968c5735fbc8ec7bf936c320d6b1c0c5413ab5bd9eb925571035b824d06b6c95cd3a0f
7
- data.tar.gz: 1c3a3d119b6be0a19d2648740038d33e1dcba3ed0821dec6c4b4be988983a8d7a45818b33c3510168a924b47950151fc0906f10887f6ac1f21388fad62bd43cb
6
+ metadata.gz: 8e8ea522c518333c74741b7c7f1fa9647117a2c181c05c2c6603a72e3ea0bc635e56dff1f5b8f0369d840f9adb55341571863f898cbc67d523ca6dbef6bc8603
7
+ data.tar.gz: 4ef5aa8b96aa69a98daec6bdc2f721aed505dd96c52f931e427269bd8f789b987273cc3be364746bdd26c00154da8a974883ac503c35e0b6edb701990f7ea48d
@@ -0,0 +1 @@
1
+ * @gl-quality/eng-prod
@@ -0,0 +1,13 @@
1
+ ---
2
+ # Settings for generating changelogs using the GitLab API. See
3
+ # https://docs.gitlab.com/ee/api/repositories.html#generate-changelog-data for
4
+ # more information.
5
+ categories:
6
+ added: Added
7
+ fixed: Fixed
8
+ changed: Changed
9
+ deprecated: Deprecated
10
+ removed: Removed
11
+ security: Security
12
+ performance: Performance
13
+ other: Other
@@ -1,35 +1,12 @@
1
- <!-- Replace `v4.5.0` with the previous release here, and `e18d76b309e42888759c1effe96767f13e34ae55`
2
- with the latest commit from https://gitlab.com/gitlab-org/gitlab-dangerfiles/commits/master that will be included in the release. -->
3
- - Diff: https://gitlab.com/gitlab-org/gitlab-dangerfiles/compare/v4.5.0...e18d76b309e42888759c1effe96767f13e34ae55
4
-
5
- - Release notes:
6
-
7
- <!-- Keep the sections order but remove the empty sections -->
8
-
9
- ```markdown
10
- ### New features and features updates
11
-
12
- - !aaa <Title of the aaa MR>.
13
-
14
- ### Fixes
15
-
16
- - !bbb <Title of the bbb MR>.
17
-
18
- ### Doc changes
19
-
20
- - !ccc <Title of the ccc MR>.
21
-
22
- ### Other changes (tooling, technical debt)
23
-
24
- - !ddd <Title of the ddd MR>.
25
- ```
1
+ <!-- Replace `<NEW_VERSION>` with the previous release here, and `<COMMIT_UPDATING_VERSION>`
2
+ with the latest commit from this merge request. -->
3
+ - Diff: https://gitlab.com/gitlab-org/ruby/gems/gitlab-dangerfiles/compare/v<NEW_VERSION>...<COMMIT_UPDATING_VERSION>
26
4
 
27
5
  - Checklist before merging:
28
6
  - [ ] Diff link is up-to-date.
29
- - [ ] Based on the diff, `lib/gitlab/dangerfiles/version.rb` is updated, according to [SemVer](https://semver.org).
30
- - [ ] Release notes are accurate.
7
+ - [ ] Based on the diff, `version.rb` is updated, according to [SemVer](https://semver.org).
31
8
 
32
9
  - Checklist after merging:
33
- - [ ] [Update the release notes for the newly created tag](docs/release_process.md#how-to).
10
+ - [ ] Check that automatic release notes (generated following the same process as https://docs.gitlab.com/ee/development/changelog.html) are correct.
34
11
 
35
- /label ~"Engineering Productivity" ~"ep::workflow" ~"tooling::workflow" ~tooling ~"Danger bot"
12
+ /label ~"type::maintenance" ~"static code analysis"
data/.gitlab-ci.yml CHANGED
@@ -28,6 +28,12 @@ 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
+
31
37
  test:rspec:
32
38
  extends: .default
33
39
  stage: test
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,40 @@
1
+ ## Developer Certificate of Origin and License
2
+
3
+ By contributing to GitLab B.V., you accept and agree to the following terms and
4
+ conditions for your present and future contributions submitted to GitLab B.V.
5
+ Except for the license granted herein to GitLab B.V. and recipients of software
6
+ distributed by GitLab B.V., you reserve all right, title, and interest in and to
7
+ your Contributions.
8
+
9
+ All contributions are subject to the Developer Certificate of Origin and license set out at [docs.gitlab.com/ce/legal/developer_certificate_of_origin](https://docs.gitlab.com/ce/legal/developer_certificate_of_origin).
10
+
11
+ _This notice should stay as the first item in the CONTRIBUTING.md file._
12
+
13
+ ## Code of conduct
14
+
15
+ As contributors and maintainers of this project, we pledge to respect all people
16
+ who contribute through reporting issues, posting feature requests, updating
17
+ documentation, submitting pull requests or patches, and other activities.
18
+
19
+ We are committed to making participation in this project a harassment-free
20
+ experience for everyone, regardless of level of experience, gender, gender
21
+ identity and expression, sexual orientation, disability, personal appearance,
22
+ body size, race, ethnicity, age, or religion.
23
+
24
+ Examples of unacceptable behavior by participants include the use of sexual
25
+ language or imagery, derogatory comments or personal attacks, trolling, public
26
+ or private harassment, insults, or other unprofessional conduct.
27
+
28
+ Project maintainers have the right and responsibility to remove, edit, or reject
29
+ comments, commits, code, wiki edits, issues, and other contributions that are
30
+ not aligned to this Code of Conduct. Project maintainers who do not follow the
31
+ Code of Conduct may be removed from the project team.
32
+
33
+ This code of conduct applies both within project spaces and in public spaces
34
+ when an individual is representing the project or its community.
35
+
36
+ Instances of abusive, harassing, or otherwise unacceptable behavior can be
37
+ reported by emailing contact@gitlab.com.
38
+
39
+ This Code of Conduct is adapted from the [Contributor Covenant](https://contributor-covenant.org), version 1.1.0,
40
+ available at [https://contributor-covenant.org/version/1/1/0/](https://contributor-covenant.org/version/1/1/0/).
data/Dangerfile ADDED
@@ -0,0 +1,5 @@
1
+ require_relative "lib/gitlab-dangerfiles"
2
+
3
+ Gitlab::Dangerfiles.for_project(self) do |dangerfiles|
4
+ dangerfiles.import_defaults
5
+ end
data/Gemfile CHANGED
@@ -6,3 +6,7 @@ gemspec
6
6
  gem "rake", "~> 12.0"
7
7
  gem "guard-rspec"
8
8
  gem "yard"
9
+
10
+ group :test do
11
+ gem "pry-byebug", "~> 3.8", require: false
12
+ end
data/README.md CHANGED
@@ -26,22 +26,45 @@ $ gem install gitlab-dangerfiles
26
26
 
27
27
  ### Importing plugins and rules
28
28
 
29
- In your project's `Dangerfile`, add the following two line to import the plugins and rules from this gem:
29
+ In your project's `Dangerfile`, add the following to import the plugins and rules from this gem:
30
30
 
31
31
  ```ruby
32
32
  require 'gitlab-dangerfiles'
33
33
 
34
- # Get an instance of Gitlab::Dangerfiles
35
- gitlab_dangerfiles = Gitlab::Dangerfiles::Engine.new(self)
34
+ Gitlab::Dangerfiles.for_project(self) do |dangerfiles|
35
+ # Import all plugins from the gem
36
+ dangerfiles.import_plugins
36
37
 
37
- # Import all plugins from the gem
38
- gitlab_dangerfiles.import_plugins
38
+ # Import all rules from the gem
39
+ dangerfiles.import_dangerfiles
39
40
 
40
- # Import all rules from the gem
41
- gitlab_dangerfiles.import_dangerfiles
41
+ # Or import only a subset of rules
42
+ dangerfiles.import_dangerfiles(only: %w[changes_size])
42
43
 
43
- # Or import a subset of rules from the gem
44
- gitlab_dangerfiles.import_dangerfiles(rules: [:changes_size])
44
+ # Or import all rules except a subset of rules
45
+ dangerfiles.import_dangerfiles(except: %w[commit_messages])
46
+
47
+ # Or import only a subset of rules, except a subset of rules
48
+ dangerfiles.import_dangerfiles(only: %w[changes_size], except: %w[commit_messages])
49
+ end
50
+ ```
51
+
52
+ For simple projects such as libraries, you can use the convenience method `import_defaults`:
53
+
54
+ ```ruby
55
+ Gitlab::Dangerfiles.for_project(self) do |dangerfiles|
56
+ # Imports all plugins, rules and the default reviewer roulette
57
+ dangerfiles.import_defaults
58
+ end
59
+ ```
60
+
61
+ You may optionally pass a project name; by default, `ENV['CI_PROJECT_NAME']` will be used:
62
+
63
+ ```ruby
64
+ Gitlab::Dangerfiles.for_project(self, 'my-project') do |dangerfiles|
65
+ # Imports all plugins, rules and the default reviewer roulette
66
+ dangerfiles.import_defaults
67
+ end
45
68
  ```
46
69
 
47
70
  ### Plugins
@@ -53,6 +76,20 @@ Danger plugins are located under `lib/danger/plugins`.
53
76
 
54
77
  For the full documentation about the plugins, please see https://www.rubydoc.info/gems/gitlab-dangerfiles.
55
78
 
79
+ ### Configuration
80
+
81
+ Default configuration can be overriden in the form `helper.config.CONFIG_NAME = NEW_VALUE` (`CONFIG_NAME` being a value configuration key).
82
+
83
+ Alternatively, you can also get/set configuration on the engine directly via `Gitlab::Dangerfiles::Engine#config`.
84
+
85
+ #### Available general configurations
86
+
87
+ - `project_name`: The project name. Currently used by the Roulette plugin to fetch relevant
88
+ reviewers/maintainers based on the project name. Default to `ENV["CI_PROJECT_NAME"]`.
89
+ - `files_to_category`: A hash of the form `{ filename_regex => categories, [filename_regex, changes_regex] => categories }`.
90
+ `filename_regex` is the regex pattern to match file names. `changes_regex` is the regex pattern to
91
+ match changed lines in files that match `filename_regex`. Used in `helper.changes_by_category`, `helper.changes`, and `helper.categories_for_file`.
92
+
56
93
  ### Rules
57
94
 
58
95
  Danger rules are located under `lib/danger/rules`.
@@ -72,6 +109,44 @@ Danger rules are located under `lib/danger/rules`.
72
109
  - `max_commits_count`: The maximum number of allowed non-squashed/non-fixup commits for a given MR.
73
110
  A warning is triggered if the MR has more commits.
74
111
 
112
+ ### Reviewer Roulette
113
+
114
+ The library includes a simplified default reviewer roulette that you can use in your
115
+ project. To use it in your project, perform the following steps:
116
+
117
+ 1. If not yet done, create a `Dangerfile` at the top-level of your project. Refer to [Usage](#usage) to
118
+ see how to set it up.
119
+ 1. When using the default roulette, use `import_defaults` or import it manually when setting
120
+ up the gitlab-dangerfiles instance:
121
+ ```ruby
122
+ Gitlab::Dangerfiles.for_project(self) do |dangerfiles|
123
+ dangerfiles.import_dangerfiles(only: %w[simple_roulette])
124
+ end
125
+ ```
126
+
127
+ ### CI configuration
128
+
129
+ In order to run `danger` on GitLab CI, perform the following steps:
130
+
131
+ 1. If not yet done, create a `Dangerfile` at the top-level of your project. Refer to [Usage](#usage) to
132
+ see how to set it up.
133
+ 2. In `.gitlab-ci.yml`, include [CI configuration](https://gitlab.com/gitlab-org/quality/pipeline-common/-/blob/master/ci/danger-review.yml)
134
+ which defines `danger-review` [CI job](https://docs.gitlab.com/ee/ci/jobs/):
135
+
136
+ ```yaml
137
+ include:
138
+ - project: 'gitlab-org/quality/pipeline-common'
139
+ file:
140
+ - '/ci/danger-review.yml'
141
+ ```
142
+
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 `Maintainer`.
145
+ 4. Add a [CI/CD variable](https://docs.gitlab.com/ee/ci/variables/#add-a-cicd-variable-to-a-project)
146
+ `DANGER_GITLAB_API_TOKEN` (`Masked` but not `Protected`) and use Project access token as value.
147
+
148
+ See a [real world example](https://gitlab.com/gitlab-org/ruby/gems/gitlab-styles/-/merge_requests/105).
149
+
75
150
  ## Documentation
76
151
 
77
152
  Latest documentation can be found at <https://www.rubydoc.info/gems/gitlab-dangerfiles>.
@@ -3,10 +3,10 @@
3
3
  require "net/http"
4
4
  require "json"
5
5
 
6
- require_relative "../../gitlab/dangerfiles/changes"
7
- require_relative "../../gitlab/dangerfiles/config"
8
- require_relative "../../gitlab/dangerfiles/teammate"
9
- require_relative "../../gitlab/dangerfiles/title_linting"
6
+ require_relative "../../../gitlab/dangerfiles/changes"
7
+ require_relative "../../../gitlab/dangerfiles/config"
8
+ require_relative "../../../gitlab/dangerfiles/teammate"
9
+ require_relative "../../../gitlab/dangerfiles/title_linting"
10
10
 
11
11
  module Danger
12
12
  # Common helper functions for our danger scripts.
@@ -16,6 +16,7 @@ module Danger
16
16
  docs: "~documentation", # Docs are reviewed along DevOps stages, so don't need roulette for now.
17
17
  none: "",
18
18
  qa: "~QA",
19
+ ux: "~UX",
19
20
  test: "~test ~Quality for `spec/features/*`",
20
21
  # Deprecated as of 2.3.0 in favor of tooling
21
22
  engineering_productivity: '~"Engineering Productivity" for CI, Danger',
@@ -174,7 +175,7 @@ module Danger
174
175
  #
175
176
  # @return [{Symbol => Array<String>}] a hash of the type +{ category1: ["file1", "file2"], category2: ["file3", "file4"] }+
176
177
  # using filename regex (+filename_regex+) and specific change regex (+changes_regex+) from the given +categories+ hash.
177
- def changes_by_category(categories)
178
+ def changes_by_category(categories = [])
178
179
  all_changed_files.each_with_object(Hash.new { |h, k| h[k] = [] }) do |file, hash|
179
180
  categories_for_file(file, categories).each { |category| hash[category] << file }
180
181
  end
@@ -186,7 +187,7 @@ module Danger
186
187
  #
187
188
  # @return [Gitlab::Dangerfiles::Changes] a +Gitlab::Dangerfiles::Changes+ object that represents the changes of an MR
188
189
  # using filename regex (+filename_regex+) and specific change regex (+changes_regex+) from the given +categories+ hash.
189
- def changes(categories)
190
+ def changes(categories = [])
190
191
  Gitlab::Dangerfiles::Changes.new([]).tap do |changes|
191
192
  added_files.each do |file|
192
193
  categories_for_file(file, categories).each { |category| changes << Gitlab::Dangerfiles::Change.new(file, :added, category) }
@@ -211,14 +212,17 @@ module Danger
211
212
  end
212
213
 
213
214
  # @param filename [String] A file name.
214
- # @param categories [{Regexp => Array<Symbol>}, {Array<Regexp> => Array<Symbol>}] A hash of the form +{ filename_regex => categories, [filename_regex, changes_regex] => categories }+.
215
- # +filename_regex+ is the regex pattern to match file names. +changes_regex+ is the regex pattern to
216
- # match changed lines in files that match +filename_regex+
215
+ # @param files_to_category [{Regexp => Array<Symbol>}, {Array<Regexp> => Array<Symbol>}] A hash of the form +{ filename_regex => categories, [filename_regex, changes_regex] => categories }+.
216
+ # +filename_regex+ is the regex pattern to match file names. +changes_regex+ is the regex pattern to
217
+ # match changed lines in files that match +filename_regex+
217
218
  #
218
219
  # @return [Array<Symbol>] the categories a file is in, e.g., +[:frontend]+, +[:backend]+, or +%i[frontend tooling]+
219
220
  # using filename regex (+filename_regex+) and specific change regex (+changes_regex+) from the given +categories+ hash.
220
- def categories_for_file(filename, categories)
221
- _, categories = categories.find do |key, _|
221
+ def categories_for_file(filename, files_to_category = {})
222
+ files_to_category = Array(files_to_category).compact
223
+ files_to_category = helper.config.files_to_category if files_to_category.empty?
224
+
225
+ _, categories = files_to_category.find do |key, _|
222
226
  filename_regex, changes_regex = Array(key)
223
227
 
224
228
  found = filename_regex.match?(filename)
@@ -33,7 +33,10 @@ module Danger
33
33
  # @param timezone_experiment [Boolean] Whether to select reviewers based in timezone or not.
34
34
  #
35
35
  # @return [Array<Spin>]
36
- def spin(project, categories = [nil], timezone_experiment: false)
36
+ def spin(project = nil, categories = [nil], timezone_experiment: false)
37
+ project = (project || helper.config.project_name).downcase
38
+ categories = categories.map { |category| category&.downcase }
39
+
37
40
  spins = categories.sort_by(&:to_s).map do |category|
38
41
  including_timezone = INCLUDE_TIMEZONE_FOR_CATEGORY.fetch(category, timezone_experiment)
39
42
 
@@ -0,0 +1,96 @@
1
+ # frozen_string_literal: true
2
+
3
+ PROJECT_NAME = helper.config.project_name
4
+
5
+ MESSAGE = <<MARKDOWN
6
+ ## Reviewer roulette
7
+
8
+ Changes that require review have been detected! A merge request is normally
9
+ reviewed by both a reviewer and a maintainer in its primary category and by a
10
+ maintainer in all other categories.
11
+ MARKDOWN
12
+
13
+ TABLE_MARKDOWN = <<MARKDOWN
14
+
15
+ To spread load more evenly across eligible reviewers, Danger has picked a candidate for each
16
+ review slot. Feel free to
17
+ [override these selections](https://about.gitlab.com/handbook/engineering/projects/##{PROJECT_NAME})
18
+ if you think someone else would be better-suited
19
+ or use the [GitLab Review Workload Dashboard](https://gitlab-org.gitlab.io/gitlab-roulette/) to find other available reviewers.
20
+
21
+ To read more on how to use the reviewer roulette, please take a look at the
22
+ [Engineering workflow](https://about.gitlab.com/handbook/engineering/workflow/#basics)
23
+ and [code review guidelines](https://docs.gitlab.com/ee/development/code_review.html).
24
+ Please consider assigning a reviewer or maintainer who is a
25
+ [domain expert](https://about.gitlab.com/handbook/engineering/projects/#gitlab-development-kit) in the area of the merge request.
26
+
27
+ Once you've decided who will review this merge request, mention them as you
28
+ normally would! Danger does not automatically notify them for you.
29
+
30
+ MARKDOWN
31
+
32
+ TABLE_HEADER_WITH_CATEGORIES = <<MARKDOWN
33
+ | Category | Reviewer | Maintainer |
34
+ | -------- | -------- | ---------- |
35
+ MARKDOWN
36
+
37
+ TABLE_HEADER_WITHOUT_CATEGORIES = <<MARKDOWN
38
+ | Reviewer | Maintainer |
39
+ | -------- | ---------- |
40
+ MARKDOWN
41
+
42
+ OPTIONAL_REVIEW_TEMPLATE = '%{role} review is optional'
43
+ NOT_AVAILABLE_TEMPLATE = 'No %{role} available'
44
+
45
+ def note_for_spins_role(spins, role)
46
+ spins.each do |spin|
47
+ note = note_for_spin_role(spin, role)
48
+
49
+ return note if note
50
+ end
51
+
52
+ NOT_AVAILABLE_TEMPLATE % { role: role }
53
+ end
54
+
55
+ def note_for_spin_role(spin, role)
56
+ if spin.optional_role == role
57
+ return OPTIONAL_REVIEW_TEMPLATE % { role: role.capitalize }
58
+ end
59
+
60
+ spin.public_send(role)&.markdown_name(author: roulette.team_mr_author)
61
+ end
62
+
63
+ def markdown_row_for_spins(category = nil, spins_array)
64
+ reviewer_note = note_for_spins_role(spins_array, :reviewer)
65
+ maintainer_note = note_for_spins_role(spins_array, :maintainer)
66
+
67
+ row = "| #{reviewer_note} | #{maintainer_note} |"
68
+ row.prepend("| #{helper.label_for_category(category)} ") if categories_defined?
69
+
70
+ row
71
+ end
72
+
73
+ def categories_defined?
74
+ helper.config.files_to_category.any?
75
+ end
76
+
77
+ def categories(changes)
78
+ categories_defined? ? changes.keys : [nil]
79
+ end
80
+
81
+ def table_header
82
+ categories_defined? ? TABLE_HEADER_WITH_CATEGORIES : TABLE_HEADER_WITHOUT_CATEGORIES
83
+ end
84
+
85
+ changes = helper.changes_by_category
86
+
87
+ if changes.any?
88
+ random_roulette_spins = roulette.spin(nil, categories(changes))
89
+
90
+ rows = random_roulette_spins.map do |spin|
91
+ markdown_row_for_spins(spin.category, [spin])
92
+ end
93
+
94
+ markdown(MESSAGE)
95
+ markdown(TABLE_MARKDOWN + table_header + rows.join("\n")) unless rows.empty?
96
+ end
@@ -82,7 +82,7 @@ module Gitlab
82
82
  return false if subject.empty?
83
83
  return false if ("A".."Z").cover?(subject[0])
84
84
 
85
- first_char = subject.sub(/\A(\[.+\]|\w+:)\s/, "")[0]
85
+ first_char = subject.sub(/\A(\[[^\]]+\]|[^:\s]+:)\s/, "")[0]
86
86
  first_char_downcased = first_char.downcase
87
87
  return true unless ("a".."z").cover?(first_char_downcased)
88
88
 
@@ -3,6 +3,16 @@
3
3
  module Gitlab
4
4
  module Dangerfiles
5
5
  class Config
6
+ # @!attribute project_name
7
+ # @return [String] the project name. Currently used by the Roulette plugin to fetch relevant reviewers/maintainers based on the project name. Default to +ENV["CI_PROJECT_NAME"]+.
8
+ attr_accessor :project_name
9
+
10
+ # @!attribute files_to_category
11
+ # @return [{Regexp => Array<Symbol>}, {Array<Regexp> => Array<Symbol>}] A hash of the form +{ filename_regex => categories, [filename_regex, changes_regex] => categories }+.
12
+ # +filename_regex+ is the regex pattern to match file names. +changes_regex+ is the regex pattern to
13
+ # match changed lines in files that match +filename_regex+. Used in `helper.changes_by_category`, `helper.changes`, and `helper.categories_for_file`.
14
+ attr_accessor :files_to_category
15
+
6
16
  # @!attribute code_size_thresholds
7
17
  # @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
18
  attr_accessor :code_size_thresholds
@@ -15,6 +25,8 @@ module Gitlab
15
25
  DEFAULT_COMMIT_MESSAGES_MAX_COMMITS_COUNT = 10
16
26
 
17
27
  def initialize
28
+ @files_to_category = {}
29
+ @project_name = ENV["CI_PROJECT_NAME"]
18
30
  @code_size_thresholds = DEFAULT_CHANGES_SIZE_THRESHOLDS
19
31
  @max_commits_count = DEFAULT_COMMIT_MESSAGES_MAX_COMMITS_COUNT
20
32
  end
@@ -12,7 +12,7 @@ module Gitlab
12
12
  @name = options["name"]
13
13
  @markdown_name = options["markdown_name"]
14
14
  @role = options["role"]
15
- @projects = options["projects"]
15
+ @projects = process_projects(options["projects"])
16
16
  @available = options["available"]
17
17
  @hungry = options["hungry"]
18
18
  @reduced_capacity = options["reduced_capacity"]
@@ -79,6 +79,14 @@ module Gitlab
79
79
 
80
80
  private
81
81
 
82
+ def process_projects(projects)
83
+ return nil unless projects
84
+
85
+ projects.each_with_object({}) do |(project, capabilities), all|
86
+ all[project.downcase] = Array(capabilities).map(&:downcase)
87
+ end
88
+ end
89
+
82
90
  def utc_offset_text(author = nil)
83
91
  offset_text = if floored_offset_hours >= 0
84
92
  "UTC+#{floored_offset_hours}"
@@ -108,11 +116,10 @@ module Gitlab
108
116
 
109
117
  area && labels.any?("devops::#{area.downcase}") if kind == :reviewer
110
118
  when :tooling, :engineering_productivity # Deprecated as of 2.3.0 in favor of tooling
111
- return false unless role[/Engineering Productivity/]
112
- return true if kind == :reviewer
113
- return true if capabilities(project).include?("#{kind} engineering_productivity")
119
+ return true if capabilities(project).include?("#{kind} #{category}")
120
+ return false if kind == :maintainer
114
121
 
115
- capabilities(project).include?("#{kind} backend")
122
+ capabilities(project).include?("#{kind} backend") # fallback to backend reviewer
116
123
  when :integrations_be
117
124
  kind == :reviewer &&
118
125
  role.match?(/Backend Engineer.+Ecosystem:Integrations/)
@@ -1,5 +1,5 @@
1
1
  module Gitlab
2
2
  module Dangerfiles
3
- VERSION = "2.4.0"
3
+ VERSION = "2.7.0"
4
4
  end
5
5
  end
@@ -13,8 +13,24 @@ module Gitlab
13
13
  commit_messages
14
14
  ].freeze
15
15
  CI_ONLY_RULES = %w[
16
+ simple_roulette
16
17
  ].freeze
17
18
 
19
+ # Utility method to construct a [Gitlab::Dangerfiles::Engine] instance,
20
+ # which is yielded to the given block.
21
+ #
22
+ # @param dangerfile [Danger::Dangerfile] A +Danger::Dangerfile+ object.
23
+ # @param project_name An option string to set the project name. Defaults to +ENV['CI_PROJECT_NAME']+.
24
+ #
25
+ # @return [Gitlab::Dangerfiles::Engine]
26
+ def self.for_project(dangerfile, project_name = nil)
27
+ Engine.new(dangerfile).tap do |engine|
28
+ engine.config.project_name = project_name if project_name
29
+
30
+ yield engine
31
+ end
32
+ end
33
+
18
34
  # This class provides utility methods to import plugins and dangerfiles easily.
19
35
  class Engine
20
36
  # @param dangerfile [Danger::Dangerfile] A +Danger::Dangerfile+ object.
@@ -26,41 +42,75 @@ module Gitlab
26
42
  # @return [Gitlab::Dangerfiles::Engine]
27
43
  def initialize(dangerfile)
28
44
  @dangerfile = dangerfile
45
+
46
+ # Import internal plugins eagerly, since other functionality in this class may depend on them.
47
+ danger_plugin.import_plugin(File.expand_path("../danger/plugins/internal/*.rb", __dir__))
29
48
  end
30
49
 
31
50
  # Import all available plugins.
32
51
  #
33
52
  # @example
34
53
  # # In your main Dangerfile:
35
- # dangerfiles = Gitlab::Dangerfiles::Engine.new(self)
36
- #
37
- # # Import all plugins
38
- # dangerfiles.import_plugins
54
+ # Gitlab::Dangerfiles.for_project(self) do |dangerfiles|
55
+ # dangerfiles.import_plugins
56
+ # end
39
57
  def import_plugins
40
58
  danger_plugin.import_plugin(File.expand_path("../danger/plugins/*.rb", __dir__))
41
59
  end
42
60
 
43
61
  # Import available Dangerfiles.
44
62
  #
63
+ # @deprecated
45
64
  # @param rules [Symbol, Array<String>] Can be either +:all+ (default) to import all rules,
46
65
  # or an array of rules.
47
66
  # Available rules are: +changes_size+.
48
67
  #
49
- # @example
50
- # # In your main Dangerfile:
51
- # dangerfiles = Gitlab::Dangerfiles::Engine.new(self)
68
+ # @param only [Symbol, Array<String>] An array of rules to import (defaults to all rules).
69
+ # Available rules are: +changes_size+.
52
70
  #
53
- # # Import all rules
54
- # dangerfiles.import_dangerfiles
71
+ # @param except [Symbol, Array<String>] An array of rules to not import (defaults to []).
72
+ # Available rules are: +changes_size+.
55
73
  #
56
- # # Or import only a subset of rules
57
- # dangerfiles.import_dangerfiles(rules: %w[changes_size])
58
- def import_dangerfiles(rules: :all)
59
- filtered_rules(rules).each do |rule|
74
+ # @example
75
+ # # In your main Dangerfile:
76
+ # Gitlab::Dangerfiles.for_project(self) do |dangerfiles|
77
+ # # Import all rules
78
+ # dangerfiles.import_dangerfiles
79
+ # # Or import only a subset of rules
80
+ # dangerfiles.import_dangerfiles(only: %w[changes_size])
81
+ # # Or import all rules except a subset of rules
82
+ # dangerfiles.import_dangerfiles(except: %w[commit_messages])
83
+ # # Or import only a subset of rules, except a subset of rules
84
+ # dangerfiles.import_dangerfiles(only: %w[changes_size], except: %w[commit_messages])
85
+ # end
86
+ def import_dangerfiles(rules: nil, only: nil, except: [])
87
+ puts "The `:rules` parameter is deprecated in favor of `:only`." unless rules.nil?
88
+
89
+ only ||= EXISTING_RULES if rules == :all
90
+ only ||= rules || EXISTING_RULES
91
+
92
+ filtered_rules(only, except).each do |rule|
60
93
  danger_plugin.import_dangerfile(path: File.join(RULES_DIR, rule))
61
94
  end
62
95
  end
63
96
 
97
+ # Proxy method to +helper_plugin.config+.
98
+ def config
99
+ helper_plugin.config
100
+ end
101
+
102
+ # Imports all default plugins and rules.
103
+ #
104
+ # @example
105
+ # # In your main Dangerfile:
106
+ # Gitlab::Dangerfiles.for_project(self) do |dangerfiles|
107
+ # dangerfiles.import_defaults
108
+ # end
109
+ def import_defaults
110
+ import_plugins
111
+ import_dangerfiles
112
+ end
113
+
64
114
  private
65
115
 
66
116
  attr_reader :dangerfile
@@ -71,10 +121,8 @@ module Gitlab
71
121
  helper_plugin.ci? ? LOCAL_RULES | CI_ONLY_RULES : LOCAL_RULES
72
122
  end
73
123
 
74
- def filtered_rules(rules)
75
- rules = EXISTING_RULES if rules == :all
76
-
77
- Array(rules).map(&:to_s) & EXISTING_RULES & allowed_rules
124
+ def filtered_rules(only, except)
125
+ (Array(only).map(&:to_s) & EXISTING_RULES & allowed_rules) - except
78
126
  end
79
127
 
80
128
  def danger_plugin
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.0
4
+ version: 2.7.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-11-02 00:00:00.000000000 Z
11
+ date: 2021-12-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: danger-gitlab
@@ -131,10 +131,14 @@ extra_rdoc_files: []
131
131
  files:
132
132
  - ".gitignore"
133
133
  - ".gitlab-ci.yml"
134
+ - ".gitlab/CODEOWNERS"
135
+ - ".gitlab/changelog_config.yml"
134
136
  - ".gitlab/merge_request_templates/Release.md"
135
137
  - ".rspec"
136
138
  - ".yardopts"
137
139
  - CODE_OF_CONDUCT.md
140
+ - CONTRIBUTING.md
141
+ - Dangerfile
138
142
  - Gemfile
139
143
  - Guardfile
140
144
  - LICENSE.txt
@@ -145,10 +149,11 @@ files:
145
149
  - fixtures/emojis/aliases.json
146
150
  - fixtures/emojis/digests.json
147
151
  - gitlab-dangerfiles.gemspec
148
- - lib/danger/plugins/helper.rb
152
+ - lib/danger/plugins/internal/helper.rb
149
153
  - lib/danger/plugins/roulette.rb
150
154
  - lib/danger/rules/changes_size/Dangerfile
151
155
  - lib/danger/rules/commit_messages/Dangerfile
156
+ - lib/danger/rules/simple_roulette/Dangerfile
152
157
  - lib/gitlab-dangerfiles.rb
153
158
  - lib/gitlab/Dangerfile
154
159
  - lib/gitlab/dangerfiles.rb