Pick reviewers based on branch name
Change reviewer roulette to always pick the same reviewers for the same branch name. We do this by: 1. Making the branch name 'canonical' across CE and EE by stripping a leading 'ce-' or 'ee-' and a trailing '-ce' or '-ee'. If people are following our branch naming guidelines, this should give the same branch name in both repos. 2. Converting the branch name to a stable integer by taking the integer form of its MD5. 3. Passing that integer as a seed to Ruby's `Random` class, which 'may be used to ensure repeatable sequences of pseudo-random numbers between different runs of the program' (from the Ruby documentation). The upshot is that the same branch name (in CE and EE) should always pick the same reviewers, and those should be evenly distributed across the set of possible reviewers due to the use of MD5.
This commit is contained in:
parent
575ec3af13
commit
28531ab436
1 changed files with 14 additions and 4 deletions
|
@ -1,5 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'digest/md5'
|
||||||
|
|
||||||
MESSAGE = <<MARKDOWN
|
MESSAGE = <<MARKDOWN
|
||||||
## Reviewer roulette
|
## Reviewer roulette
|
||||||
|
|
||||||
|
@ -29,7 +31,9 @@ Please consider creating a merge request to
|
||||||
for them.
|
for them.
|
||||||
MARKDOWN
|
MARKDOWN
|
||||||
|
|
||||||
def spin(team, project, category)
|
def spin(team, project, category, branch_name)
|
||||||
|
rng = Random.new(Digest::MD5.hexdigest(branch_name).to_i(16))
|
||||||
|
|
||||||
reviewers = team.select { |member| member.reviewer?(project, category) }
|
reviewers = team.select { |member| member.reviewer?(project, category) }
|
||||||
traintainers = team.select { |member| member.traintainer?(project, category) }
|
traintainers = team.select { |member| member.traintainer?(project, category) }
|
||||||
maintainers = team.select { |member| member.maintainer?(project, category) }
|
maintainers = team.select { |member| member.maintainer?(project, category) }
|
||||||
|
@ -41,8 +45,8 @@ def spin(team, project, category)
|
||||||
# https://gitlab.com/gitlab-org/gitlab-ce/issues/57653
|
# https://gitlab.com/gitlab-org/gitlab-ce/issues/57653
|
||||||
|
|
||||||
# Make traintainers have triple the chance to be picked as a reviewer
|
# Make traintainers have triple the chance to be picked as a reviewer
|
||||||
reviewer = (reviewers + traintainers + traintainers).sample
|
reviewer = (reviewers + traintainers + traintainers).sample(random: rng)
|
||||||
maintainer = maintainers.sample
|
maintainer = maintainers.sample(random: rng)
|
||||||
|
|
||||||
"| #{helper.label_for_category(category)} | #{reviewer&.markdown_name} | #{maintainer&.markdown_name} |"
|
"| #{helper.label_for_category(category)} | #{reviewer&.markdown_name} | #{maintainer&.markdown_name} |"
|
||||||
end
|
end
|
||||||
|
@ -68,6 +72,12 @@ categories = changes.keys - [:unknown]
|
||||||
# CSS Clean up MRs are reviewed using a slightly different process, so we
|
# CSS Clean up MRs are reviewed using a slightly different process, so we
|
||||||
# disable the review roulette for such MRs.
|
# disable the review roulette for such MRs.
|
||||||
if changes.any? && !gitlab.mr_labels.include?('single codebase') && !gitlab.mr_labels.include?('CSS cleanup')
|
if changes.any? && !gitlab.mr_labels.include?('single codebase') && !gitlab.mr_labels.include?('CSS cleanup')
|
||||||
|
# Strip leading and trailing CE/EE markers
|
||||||
|
canonical_branch_name = gitlab
|
||||||
|
.mr_json['source_branch']
|
||||||
|
.gsub(/^[ce]e-/, '')
|
||||||
|
.gsub(/-[ce]e$/, '')
|
||||||
|
|
||||||
team =
|
team =
|
||||||
begin
|
begin
|
||||||
helper.project_team
|
helper.project_team
|
||||||
|
@ -82,7 +92,7 @@ if changes.any? && !gitlab.mr_labels.include?('single codebase') && !gitlab.mr_l
|
||||||
project = helper.project_name
|
project = helper.project_name
|
||||||
unknown = changes.fetch(:unknown, [])
|
unknown = changes.fetch(:unknown, [])
|
||||||
|
|
||||||
rows = categories.map { |category| spin(team, project, category) }
|
rows = categories.map { |category| spin(team, project, category, canonical_branch_name) }
|
||||||
|
|
||||||
markdown(MESSAGE)
|
markdown(MESSAGE)
|
||||||
markdown(CATEGORY_TABLE_HEADER + rows.join("\n")) unless rows.empty?
|
markdown(CATEGORY_TABLE_HEADER + rows.join("\n")) unless rows.empty?
|
||||||
|
|
Loading…
Reference in a new issue