gitlab-reviewers 1.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 +7 -0
- data/.gitignore +8 -0
- data/Gemfile +4 -0
- data/Rakefile +2 -0
- data/danger/plugins/helper.rb +9 -0
- data/danger/plugins/roulette.rb +9 -0
- data/gitlab-reviewers.gemspec +29 -0
- data/lib/gitlab_roulette/danger/helper.rb +130 -0
- data/lib/gitlab_roulette/danger/request_helper.rb +23 -0
- data/lib/gitlab_roulette/danger/roulette.rb +80 -0
- data/lib/gitlab_roulette/danger/teammate.rb +75 -0
- data/lib/gitlab_roulette/gitlab_danger.rb +53 -0
- data/lib/gitlab_roulette/version.rb +3 -0
- data/lib/gitlab_roulette.rb +15 -0
- metadata +126 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 965fa0c3349af7a6b822b4b136c691b023ac400fe363efaa2dbc7cd403c74f38
|
4
|
+
data.tar.gz: 1095ff6b2dca3be16c3bfdbd0eab613bf7f40cdb36a01621ea74c25d98a33c6a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: bfe1a35bed9c8d397c974ead3bf8fd9c547a49b97076cc0ed89592282e87e21e41c0d399d6388f26a804182d7effb053d4e661e0da23c4c9a14b07c29eb9553d
|
7
|
+
data.tar.gz: bc1e1ebc02564472d82942c28065cca6dcc47e9f0ac4445227fa050ce4d1a85aa86263c4a586b8532ef3ad3b421a539b89d2513446f73e9bbbc6b59baba47f49
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
lib = File.expand_path("lib", __dir__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require "gitlab_roulette/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "gitlab-reviewers"
|
7
|
+
spec.version = GitlabRoulette::VERSION
|
8
|
+
spec.authors = ["LuizaLabs"]
|
9
|
+
|
10
|
+
spec.summary = %q{GitlabRoulette adds a reviewer roulette to your self hosted Gitlab repository}
|
11
|
+
spec.description = %q{GitlabRoulette choose reviewer and a maintainer for your merge request automatically}
|
12
|
+
|
13
|
+
spec.metadata["allowed_push_host"] = "https://rubygems.org"
|
14
|
+
|
15
|
+
# Specify which files should be added to the gem when it is released.
|
16
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
17
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
18
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
19
|
+
end
|
20
|
+
spec.bindir = "exe"
|
21
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
22
|
+
spec.require_paths = ["lib"]
|
23
|
+
|
24
|
+
spec.add_development_dependency "bundler", "~> 2.0"
|
25
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
26
|
+
spec.add_development_dependency "danger-gitlab", "~> 7.0.0"
|
27
|
+
spec.add_development_dependency "danger", "~> 6.1.0"
|
28
|
+
spec.add_development_dependency "faraday", "~> 0.17.1"
|
29
|
+
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'teammate'
|
4
|
+
|
5
|
+
module Gitlab
|
6
|
+
module Danger
|
7
|
+
module Helper
|
8
|
+
|
9
|
+
# Returns a list of all files that have been added, modified or renamed.
|
10
|
+
# `git.modified_files` might contain paths that already have been renamed,
|
11
|
+
# so we need to remove them from the list.
|
12
|
+
#
|
13
|
+
# Considering these changes:
|
14
|
+
#
|
15
|
+
# - A new_file.rb
|
16
|
+
# - D deleted_file.rb
|
17
|
+
# - M modified_file.rb
|
18
|
+
# - R renamed_file_before.rb -> renamed_file_after.rb
|
19
|
+
#
|
20
|
+
# it will return
|
21
|
+
# ```
|
22
|
+
# [ 'new_file.rb', 'modified_file.rb', 'renamed_file_after.rb' ]
|
23
|
+
# ```
|
24
|
+
#
|
25
|
+
# @return [Array<String>]
|
26
|
+
def all_changed_files
|
27
|
+
Set.new
|
28
|
+
.merge(git.added_files.to_a)
|
29
|
+
.merge(git.modified_files.to_a)
|
30
|
+
.merge(git.renamed_files.map { |x| x[:after] })
|
31
|
+
.subtract(git.renamed_files.map { |x| x[:before] })
|
32
|
+
.to_a
|
33
|
+
.sort
|
34
|
+
end
|
35
|
+
|
36
|
+
def categories
|
37
|
+
@categories ||=
|
38
|
+
begin
|
39
|
+
url = "#{ENV['CI_API_V4_URL']}/projects/#{ENV['CI_PROJECT_ID']}/variables/GITLAB_ROULETTE_CATEGORIES"
|
40
|
+
response = Faraday.get(url) do |req|
|
41
|
+
req.headers['Content-Type'] = 'application/json'
|
42
|
+
req.headers['PRIVATE-TOKEN'] = ENV['DANGER_GITLAB_API_TOKEN']
|
43
|
+
end
|
44
|
+
|
45
|
+
result = JSON.parse(response.body)
|
46
|
+
JSON.parse(result['value'])
|
47
|
+
rescue => err
|
48
|
+
puts "Failed to fetch categories from #{url}"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def gitlab_helper
|
53
|
+
# Unfortunately the following does not work:
|
54
|
+
# - respond_to?(:gitlab)
|
55
|
+
# - respond_to?(:gitlab, true)
|
56
|
+
gitlab
|
57
|
+
rescue NoMethodError
|
58
|
+
nil
|
59
|
+
end
|
60
|
+
|
61
|
+
def project_name
|
62
|
+
ENV["CI_PROJECT_NAME"]
|
63
|
+
end
|
64
|
+
|
65
|
+
def markdown_list(items)
|
66
|
+
list = items.map { |item| "* `#{item}`" }.join("\n")
|
67
|
+
|
68
|
+
if items.size > 10
|
69
|
+
"\n<details>\n\n#{list}\n\n</details>\n"
|
70
|
+
else
|
71
|
+
list
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# @return [Hash<String,Array<String>>]
|
76
|
+
def changes_by_category
|
77
|
+
all_changed_files.each_with_object(Hash.new { |h, k| h[k] = [] }) do |file, hash|
|
78
|
+
hash[category_for_file(file)] << file
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# Determines the category a file
|
83
|
+
# @return[Symbol]
|
84
|
+
def category_for_file(file)
|
85
|
+
category, _ = categories.find { |category, regex_list|
|
86
|
+
regex_list.any? { |regex_string| /#{regex_string}/.match?(file) }
|
87
|
+
}
|
88
|
+
result = category || "unknown"
|
89
|
+
result.to_sym
|
90
|
+
end
|
91
|
+
|
92
|
+
# Returns the GFM for a category label, making its best guess if it's not
|
93
|
+
# a category we know about.
|
94
|
+
#
|
95
|
+
# @return[String]
|
96
|
+
def label_for_category(category)
|
97
|
+
CATEGORY_LABELS.fetch(category, "~#{category}")
|
98
|
+
end
|
99
|
+
|
100
|
+
CATEGORY_LABELS = {
|
101
|
+
developer: "Random Developer",
|
102
|
+
ecomm: '~"Ecomm"',
|
103
|
+
tools: '~"Tools and MiniApps"',
|
104
|
+
checkout: '~"Checkout"',
|
105
|
+
navigation: '~"Navigation"',
|
106
|
+
mpay: '~"Magalu Pay"',
|
107
|
+
}.freeze
|
108
|
+
|
109
|
+
def new_teammates(usernames)
|
110
|
+
usernames.map { |u| Gitlab::Danger::Teammate.new('username' => u) }
|
111
|
+
end
|
112
|
+
|
113
|
+
def missing_database_labels(current_mr_labels)
|
114
|
+
labels = if has_database_scoped_labels?(current_mr_labels)
|
115
|
+
['database']
|
116
|
+
else
|
117
|
+
['database', 'database::review pending']
|
118
|
+
end
|
119
|
+
|
120
|
+
labels - current_mr_labels
|
121
|
+
end
|
122
|
+
|
123
|
+
private
|
124
|
+
|
125
|
+
def has_database_scoped_labels?(current_mr_labels)
|
126
|
+
current_mr_labels.any? { |label| label.start_with?('database::') }
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'net/http'
|
4
|
+
require 'json'
|
5
|
+
|
6
|
+
module Gitlab
|
7
|
+
module Danger
|
8
|
+
module RequestHelper
|
9
|
+
HTTPError = Class.new(RuntimeError)
|
10
|
+
|
11
|
+
# @param [String] url
|
12
|
+
def self.http_get_json(url)
|
13
|
+
rsp = Net::HTTP.get_response(URI.parse(url))
|
14
|
+
|
15
|
+
unless rsp.is_a?(Net::HTTPOK)
|
16
|
+
raise HTTPError, "Failed to read #{url}: #{rsp.code} #{rsp.message}"
|
17
|
+
end
|
18
|
+
|
19
|
+
JSON.parse(rsp.body)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'teammate'
|
4
|
+
require 'faraday'
|
5
|
+
|
6
|
+
module Gitlab
|
7
|
+
module Danger
|
8
|
+
module Roulette
|
9
|
+
ROULETTE_DATA_URL = ENV["GITLAB_ROULETTE_URL"]
|
10
|
+
|
11
|
+
# Looks up the current list of GitLab team members and parses it into a
|
12
|
+
# useful form
|
13
|
+
#
|
14
|
+
# @return [Array<Teammate>]
|
15
|
+
def team
|
16
|
+
@team ||= developers.sort_by { |dev| dev['reviews'] }.map { |hash| ::Gitlab::Danger::Teammate.new(hash) }
|
17
|
+
end
|
18
|
+
|
19
|
+
def developers
|
20
|
+
@developers ||=
|
21
|
+
begin
|
22
|
+
url = "#{ENV['CI_API_V4_URL']}/projects/#{ENV['CI_PROJECT_ID']}/variables/GITLAB_ROULETTE_DATA"
|
23
|
+
response = Faraday.get(url) do |req|
|
24
|
+
req.headers['Content-Type'] = 'application/json'
|
25
|
+
req.headers['PRIVATE-TOKEN'] = ENV['DANGER_GITLAB_API_TOKEN']
|
26
|
+
end
|
27
|
+
|
28
|
+
result = JSON.parse(response.body)
|
29
|
+
JSON.parse(result['value'])
|
30
|
+
rescue => err
|
31
|
+
puts "Failed to fetch developer from #{url}"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def update_reviews_count(developers_to_increment_reviews)
|
36
|
+
begin
|
37
|
+
developers.each do |dev|
|
38
|
+
username = dev["username"]
|
39
|
+
dev["reviews"] += 1 if developers_to_increment_reviews.include?(username)
|
40
|
+
end
|
41
|
+
url = "#{ENV['CI_API_V4_URL']}/projects/#{ENV['CI_PROJECT_ID']}/variables/GITLAB_ROULETTE_DATA"
|
42
|
+
response = Faraday.put(url) do |req|
|
43
|
+
req.headers['Content-Type'] = 'application/json'
|
44
|
+
req.headers['PRIVATE-TOKEN'] = ENV['DANGER_GITLAB_API_TOKEN']
|
45
|
+
req.params['value'] = JSON.pretty_generate(developers)
|
46
|
+
end
|
47
|
+
rescue => err
|
48
|
+
puts "Failed to update developer from #{url}"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# Like +team+, but only returns teammates in the current project, based on
|
53
|
+
# project_name.
|
54
|
+
#
|
55
|
+
# @return [Array<Teammate>]
|
56
|
+
def project_team(project_name)
|
57
|
+
team.select { |member| member.in_project?(project_name) }
|
58
|
+
end
|
59
|
+
|
60
|
+
# @param [Array<Teammate>] people
|
61
|
+
def spin_for_person(people, excludes)
|
62
|
+
people.select { |member| !excludes.include?(member.user_name) }.find(&method(:valid_person?))
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
# @param [Teammate] person
|
68
|
+
# @return [Boolean]
|
69
|
+
def valid_person?(person)
|
70
|
+
!mr_author?(person) && person.available?
|
71
|
+
end
|
72
|
+
|
73
|
+
# @param [Teammate] person
|
74
|
+
# @return [Boolean]
|
75
|
+
def mr_author?(person)
|
76
|
+
person.username == gitlab.mr_author
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'cgi'
|
4
|
+
|
5
|
+
module Gitlab
|
6
|
+
module Danger
|
7
|
+
class Teammate
|
8
|
+
attr_reader :name, :username, :role, :projects
|
9
|
+
|
10
|
+
def initialize(options = {})
|
11
|
+
@username = options['username']
|
12
|
+
@name = options['name'] || @username
|
13
|
+
@role = options['role']
|
14
|
+
@projects = options['projects']
|
15
|
+
end
|
16
|
+
|
17
|
+
def user_name
|
18
|
+
username
|
19
|
+
end
|
20
|
+
|
21
|
+
def markdown_name
|
22
|
+
"[#{name}](#{gitlab_host}/#{username}) (@#{username})"
|
23
|
+
end
|
24
|
+
|
25
|
+
def in_project?(name)
|
26
|
+
projects&.has_key?(name)
|
27
|
+
end
|
28
|
+
|
29
|
+
# Traintainers also count as reviewers
|
30
|
+
def reviewer?(project, category, labels)
|
31
|
+
has_capability?(project, category, :reviewer, labels) ||
|
32
|
+
traintainer?(project, category, labels)
|
33
|
+
end
|
34
|
+
|
35
|
+
def traintainer?(project, category, labels)
|
36
|
+
has_capability?(project, category, :trainee_maintainer, labels)
|
37
|
+
end
|
38
|
+
|
39
|
+
# Traintainers also count as maintainer
|
40
|
+
def maintainer?(project, category, labels)
|
41
|
+
has_capability?(project, category, :maintainer, labels) ||
|
42
|
+
traintainer?(project, category, labels)
|
43
|
+
end
|
44
|
+
|
45
|
+
# @return [Boolean]
|
46
|
+
def available?
|
47
|
+
has_capacity?
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def gitlab_host
|
53
|
+
@gitlab_host ||= ENV["GITLAB_HOST"]
|
54
|
+
end
|
55
|
+
|
56
|
+
# @return [Boolean]
|
57
|
+
def has_capacity?
|
58
|
+
true
|
59
|
+
end
|
60
|
+
|
61
|
+
def has_capability?(project, category, kind, labels)
|
62
|
+
case category
|
63
|
+
when :developer
|
64
|
+
role[/Developer/] && capabilities(project).any? { |capability| capability.include?("#{kind}") && capability.include?("ecomm") }
|
65
|
+
else
|
66
|
+
capabilities(project).any? { |capability| capability.include?("#{kind}") && capability.include?("#{category}") }
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def capabilities(project)
|
71
|
+
Array(projects.fetch(project, []))
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class GitlabDanger
|
4
|
+
LOCAL_RULES ||= %w[
|
5
|
+
changes_size
|
6
|
+
gemfile
|
7
|
+
documentation
|
8
|
+
frozen_string
|
9
|
+
duplicate_yarn_dependencies
|
10
|
+
prettier
|
11
|
+
eslint
|
12
|
+
database
|
13
|
+
commit_messages
|
14
|
+
].freeze
|
15
|
+
|
16
|
+
CI_ONLY_RULES ||= %w[
|
17
|
+
metadata
|
18
|
+
changelog
|
19
|
+
specs
|
20
|
+
roulette
|
21
|
+
single_codebase
|
22
|
+
gitlab_ui_wg
|
23
|
+
ce_ee_vue_templates
|
24
|
+
].freeze
|
25
|
+
|
26
|
+
MESSAGE_PREFIX = '==>'.freeze
|
27
|
+
|
28
|
+
attr_reader :gitlab_danger_helper
|
29
|
+
|
30
|
+
def initialize(gitlab_danger_helper)
|
31
|
+
@gitlab_danger_helper = gitlab_danger_helper
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.local_warning_message
|
35
|
+
"#{MESSAGE_PREFIX} Only the following Danger rules can be run locally: #{LOCAL_RULES.join(', ')}"
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.success_message
|
39
|
+
"#{MESSAGE_PREFIX} No Danger rule violations!"
|
40
|
+
end
|
41
|
+
|
42
|
+
def rule_names
|
43
|
+
ci? ? LOCAL_RULES | CI_ONLY_RULES : LOCAL_RULES
|
44
|
+
end
|
45
|
+
|
46
|
+
def html_link(str)
|
47
|
+
self.ci? ? gitlab_danger_helper.html_link(str) : str
|
48
|
+
end
|
49
|
+
|
50
|
+
def ci?
|
51
|
+
!gitlab_danger_helper.nil?
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require "gitlab_roulette/version"
|
2
|
+
require "faraday"
|
3
|
+
require "ostruct"
|
4
|
+
require "json"
|
5
|
+
|
6
|
+
require "danger"
|
7
|
+
|
8
|
+
require "gitlab_roulette/danger/helper"
|
9
|
+
require "gitlab_roulette/danger/request_helper"
|
10
|
+
require "gitlab_roulette/danger/roulette"
|
11
|
+
require "gitlab_roulette/danger/teammate"
|
12
|
+
|
13
|
+
module GitlabRoulette
|
14
|
+
class Error < StandardError; end
|
15
|
+
end
|
metadata
ADDED
@@ -0,0 +1,126 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: gitlab-reviewers
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- LuizaLabs
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2023-09-04 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: danger-gitlab
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 7.0.0
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 7.0.0
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: danger
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 6.1.0
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 6.1.0
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: faraday
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 0.17.1
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 0.17.1
|
83
|
+
description: GitlabRoulette choose reviewer and a maintainer for your merge request
|
84
|
+
automatically
|
85
|
+
email:
|
86
|
+
executables: []
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- ".gitignore"
|
91
|
+
- Gemfile
|
92
|
+
- Rakefile
|
93
|
+
- danger/plugins/helper.rb
|
94
|
+
- danger/plugins/roulette.rb
|
95
|
+
- gitlab-reviewers.gemspec
|
96
|
+
- lib/gitlab_roulette.rb
|
97
|
+
- lib/gitlab_roulette/danger/helper.rb
|
98
|
+
- lib/gitlab_roulette/danger/request_helper.rb
|
99
|
+
- lib/gitlab_roulette/danger/roulette.rb
|
100
|
+
- lib/gitlab_roulette/danger/teammate.rb
|
101
|
+
- lib/gitlab_roulette/gitlab_danger.rb
|
102
|
+
- lib/gitlab_roulette/version.rb
|
103
|
+
homepage:
|
104
|
+
licenses: []
|
105
|
+
metadata:
|
106
|
+
allowed_push_host: https://rubygems.org
|
107
|
+
post_install_message:
|
108
|
+
rdoc_options: []
|
109
|
+
require_paths:
|
110
|
+
- lib
|
111
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
112
|
+
requirements:
|
113
|
+
- - ">="
|
114
|
+
- !ruby/object:Gem::Version
|
115
|
+
version: '0'
|
116
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
117
|
+
requirements:
|
118
|
+
- - ">="
|
119
|
+
- !ruby/object:Gem::Version
|
120
|
+
version: '0'
|
121
|
+
requirements: []
|
122
|
+
rubygems_version: 3.1.6
|
123
|
+
signing_key:
|
124
|
+
specification_version: 4
|
125
|
+
summary: GitlabRoulette adds a reviewer roulette to your self hosted Gitlab repository
|
126
|
+
test_files: []
|