Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'lib/gitlab/danger/roulette.rb')
-rw-r--r--lib/gitlab/danger/roulette.rb67
1 files changed, 67 insertions, 0 deletions
diff --git a/lib/gitlab/danger/roulette.rb b/lib/gitlab/danger/roulette.rb
index dbf42912882..9f7980dc20a 100644
--- a/lib/gitlab/danger/roulette.rb
+++ b/lib/gitlab/danger/roulette.rb
@@ -6,6 +6,46 @@ module Gitlab
module Danger
module Roulette
ROULETTE_DATA_URL = 'https://about.gitlab.com/roulette.json'
+ OPTIONAL_CATEGORIES = [:qa, :test].freeze
+
+ Spin = Struct.new(:category, :reviewer, :maintainer, :optional_role)
+
+ # Assigns GitLab team members to be reviewer and maintainer
+ # for each change category that a Merge Request contains.
+ #
+ # @return [Array<Spin>]
+ def spin(project, categories, branch_name)
+ team =
+ begin
+ project_team(project)
+ rescue => err
+ warn("Reviewer roulette failed to load team data: #{err.message}")
+ []
+ end
+
+ canonical_branch_name = canonical_branch_name(branch_name)
+
+ spin_per_category = categories.each_with_object({}) do |category, memo|
+ memo[category] = spin_for_category(team, project, category, canonical_branch_name)
+ end
+
+ spin_per_category.map do |category, spin|
+ case category
+ when :test
+ if spin.reviewer.nil?
+ # Fetch an already picked backend reviewer, or pick one otherwise
+ spin.reviewer = spin_per_category[:backend]&.reviewer || spin_for_category(team, project, :backend, canonical_branch_name).reviewer
+ end
+ when :engineering_productivity
+ if spin.maintainer.nil?
+ # Fetch an already picked backend maintainer, or pick one otherwise
+ spin.maintainer = spin_per_category[:backend]&.maintainer || spin_for_category(team, project, :backend, canonical_branch_name).maintainer
+ end
+ end
+
+ spin
+ end
+ end
# Looks up the current list of GitLab team members and parses it into a
# useful form
@@ -58,6 +98,33 @@ module Gitlab
def mr_author?(person)
person.username == gitlab.mr_author
end
+
+ def spin_role_for_category(team, role, project, category)
+ team.select do |member|
+ member.public_send("#{role}?", project, category, gitlab.mr_labels) # rubocop:disable GitlabSecurity/PublicSend
+ end
+ end
+
+ def spin_for_category(team, project, category, branch_name)
+ reviewers, traintainers, maintainers =
+ %i[reviewer traintainer maintainer].map do |role|
+ spin_role_for_category(team, role, project, category)
+ end
+
+ # TODO: take CODEOWNERS into account?
+ # https://gitlab.com/gitlab-org/gitlab/issues/26723
+
+ # Make traintainers have triple the chance to be picked as a reviewer
+ random = new_random(branch_name)
+ reviewer = spin_for_person(reviewers + traintainers + traintainers, random: random)
+ maintainer = spin_for_person(maintainers, random: random)
+
+ Spin.new(category, reviewer, maintainer).tap do |spin|
+ if OPTIONAL_CATEGORIES.include?(category)
+ spin.optional_role = :maintainer
+ end
+ end
+ end
end
end
end