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.rb85
1 files changed, 52 insertions, 33 deletions
diff --git a/lib/gitlab/danger/roulette.rb b/lib/gitlab/danger/roulette.rb
index ed4af3f4a43..2e6181d1cab 100644
--- a/lib/gitlab/danger/roulette.rb
+++ b/lib/gitlab/danger/roulette.rb
@@ -1,6 +1,7 @@
# frozen_string_literal: true
require_relative 'teammate'
+require_relative 'request_helper'
module Gitlab
module Danger
@@ -12,45 +13,49 @@ module Gitlab
database: false
}.freeze
- Spin = Struct.new(:category, :reviewer, :maintainer, :optional_role)
+ Spin = Struct.new(:category, :reviewer, :maintainer, :optional_role, :timezone_experiment)
+
+ def team_mr_author
+ team.find { |person| person.username == mr_author_username }
+ end
# 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, timezone_experiment: false)
- 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|
+ def spin(project, categories, timezone_experiment: false)
+ spins = categories.map do |category|
including_timezone = INCLUDE_TIMEZONE_FOR_CATEGORY.fetch(category, timezone_experiment)
- memo[category] = spin_for_category(team, project, category, canonical_branch_name, timezone_experiment: including_timezone)
+ spin_for_category(project, category, timezone_experiment: including_timezone)
end
- spin_per_category.map do |category, spin|
- case category
+ backend_spin = spins.find { |spin| spin.category == :backend }
+
+ spins.each do |spin|
+ including_timezone = INCLUDE_TIMEZONE_FOR_CATEGORY.fetch(spin.category, timezone_experiment)
+ case spin.category
+ when :qa
+ # MR includes QA changes, but also other changes, and author isn't an SET
+ if categories.size > 1 && !team_mr_author&.reviewer?(project, spin.category, [])
+ spin.optional_role = :maintainer
+ end
when :test
+ spin.optional_role = :maintainer
+
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
+ spin.reviewer = backend_spin&.reviewer || spin_for_category(project, :backend, timezone_experiment: including_timezone).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
+ spin.maintainer = backend_spin&.maintainer || spin_for_category(project, :backend, timezone_experiment: including_timezone).maintainer
end
end
-
- spin
end
+
+ spins
end
# Looks up the current list of GitLab team members and parses it into a
@@ -73,14 +78,9 @@ module Gitlab
# @return [Array<Teammate>]
def project_team(project_name)
team.select { |member| member.in_project?(project_name) }
- end
-
- def canonical_branch_name(branch_name)
- branch_name.gsub(/^[ce]e-|-[ce]e$/, '')
- end
-
- def new_random(seed)
- Random.new(Digest::MD5.hexdigest(seed).to_i(16))
+ rescue => err
+ warn("Reviewer roulette failed to load team data: #{err.message}")
+ []
end
# Known issue: If someone is rejected due to OOO, and then becomes not OOO, the
@@ -113,16 +113,35 @@ module Gitlab
# @param [Teammate] person
# @return [Boolean]
def mr_author?(person)
- person.username == gitlab.mr_author
+ person.username == mr_author_username
+ end
+
+ def mr_author_username
+ helper.gitlab_helper&.mr_author || `whoami`
+ end
+
+ def mr_source_branch
+ return `git rev-parse --abbrev-ref HEAD` unless helper.gitlab_helper&.mr_json
+
+ helper.gitlab_helper.mr_json['source_branch']
+ end
+
+ def mr_labels
+ helper.gitlab_helper&.mr_labels || []
+ end
+
+ def new_random(seed)
+ Random.new(Digest::MD5.hexdigest(seed).to_i(16))
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
+ member.public_send("#{role}?", project, category, mr_labels) # rubocop:disable GitlabSecurity/PublicSend
end
end
- def spin_for_category(team, project, category, branch_name, timezone_experiment: false)
+ def spin_for_category(project, category, timezone_experiment: false)
+ team = project_team(project)
reviewers, traintainers, maintainers =
%i[reviewer traintainer maintainer].map do |role|
spin_role_for_category(team, role, project, category)
@@ -132,11 +151,11 @@ module Gitlab
# 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)
+ random = new_random(mr_source_branch)
reviewer = spin_for_person(reviewers + traintainers + traintainers, random: random, timezone_experiment: timezone_experiment)
maintainer = spin_for_person(maintainers, random: random, timezone_experiment: timezone_experiment)
- Spin.new(category, reviewer, maintainer)
+ Spin.new(category, reviewer, maintainer, false, timezone_experiment)
end
end
end