From a1de1740f53d6c4cefdb2e768f10ac4fe5cd9aa9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9my=20Coutable?= <remy@rymai.me>
Date: Thu, 3 Sep 2020 17:26:35 +0000
Subject: [PATCH] Danger: Automatically add specialization labels based on
 changes
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

I realized since we already detect the category of changes, we can
easily apply the relevant "specialization" labels based on that.

Signed-off-by: Rémy Coutable <remy@rymai.me>
---
 danger/database/Dangerfile              |  8 +++-----
 danger/documentation/Dangerfile         |  6 ------
 danger/specialization_labels/Dangerfile | 25 +++++++++++++++++++++++++
 lib/gitlab/danger/helper.rb             | 12 ------------
 lib/gitlab_danger.rb                    |  1 +
 spec/lib/gitlab/danger/helper_spec.rb   | 16 ----------------
 6 files changed, 29 insertions(+), 39 deletions(-)
 create mode 100644 danger/specialization_labels/Dangerfile

diff --git a/danger/database/Dangerfile b/danger/database/Dangerfile
index 41ca2aa19780..ca4b151faf97 100644
--- a/danger/database/Dangerfile
+++ b/danger/database/Dangerfile
@@ -59,11 +59,9 @@ if gitlab.mr_labels.include?('database') || db_paths_to_review.any?
   markdown(DB_MESSAGE)
   markdown(DB_FILES_MESSAGE + helper.markdown_list(db_paths_to_review)) if db_paths_to_review.any?
 
-  database_labels = helper.missing_database_labels(gitlab.mr_labels)
-
-  if database_labels.any?
+  unless has_database_scoped_labels?(gitlab.mr_labels)
     gitlab.api.update_merge_request(gitlab.mr_json['project_id'],
-                                        gitlab.mr_json['iid'],
-                                        labels: (gitlab.mr_labels + database_labels).join(','))
+                                    gitlab.mr_json['iid'],
+                                    add_labels: 'database::review pending')
   end
 end
diff --git a/danger/documentation/Dangerfile b/danger/documentation/Dangerfile
index 1dd6d4849683..16d22969fbd9 100644
--- a/danger/documentation/Dangerfile
+++ b/danger/documentation/Dangerfile
@@ -25,9 +25,3 @@ markdown(<<~MARKDOWN)
   - [Technical Writers assignments](https://about.gitlab.com/handbook/engineering/technical-writing/#designated-technical-writers) for the appropriate technical writer for this review.
   - [Documentation workflows](https://docs.gitlab.com/ee/development/documentation/workflow.html) for information on when to assign a merge request for review.
 MARKDOWN
-
-unless gitlab.mr_labels.include?('documentation')
-  gitlab.api.update_merge_request(gitlab.mr_json['project_id'],
-                                  gitlab.mr_json['iid'],
-                                  labels: (gitlab.mr_labels + ['documentation']).join(','))
-end
diff --git a/danger/specialization_labels/Dangerfile b/danger/specialization_labels/Dangerfile
new file mode 100644
index 000000000000..b12771b98070
--- /dev/null
+++ b/danger/specialization_labels/Dangerfile
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+gitlab_danger = GitlabDanger.new(helper.gitlab_helper)
+
+return unless gitlab_danger.ci?
+
+SPECIALIZATIONS = {
+  database: 'database',
+  backend: 'backend',
+  frontend: 'frontend',
+  docs: 'documentation',
+  qa: 'QA',
+  engineering_productivity: 'Engineering Productivity'
+}.freeze
+
+labels_to_add = helper.changes_by_category.each_with_object([]) do |(category, _changes), memo|
+  label = SPECIALIZATIONS.fetch(category, category.to_s)
+  memo << label unless gitlab.mr_labels.include?(label)
+end
+
+if labels_to_add.any?
+  gitlab.api.update_merge_request(gitlab.mr_json['project_id'],
+                                  gitlab.mr_json['iid'],
+                                  add_labels: labels_to_add.join(','))
+end
diff --git a/lib/gitlab/danger/helper.rb b/lib/gitlab/danger/helper.rb
index 9ba5df89a35e..878f11eb9cec 100644
--- a/lib/gitlab/danger/helper.rb
+++ b/lib/gitlab/danger/helper.rb
@@ -206,16 +206,6 @@ def new_teammates(usernames)
         usernames.map { |u| Gitlab::Danger::Teammate.new('username' => u) }
       end
 
-      def missing_database_labels(current_mr_labels)
-        labels = if has_database_scoped_labels?(current_mr_labels)
-                   ['database']
-                 else
-                   ['database', 'database::review pending']
-                 end
-
-        labels - current_mr_labels
-      end
-
       def sanitize_mr_title(title)
         title.gsub(DRAFT_REGEX, '').gsub(/`/, '\\\`')
       end
@@ -259,8 +249,6 @@ def changed_files(regex)
         all_changed_files.grep(regex)
       end
 
-      private
-
       def has_database_scoped_labels?(current_mr_labels)
         current_mr_labels.any? { |label| label.start_with?('database::') }
       end
diff --git a/lib/gitlab_danger.rb b/lib/gitlab_danger.rb
index a98ac9200da9..5537bd81f10e 100644
--- a/lib/gitlab_danger.rb
+++ b/lib/gitlab_danger.rb
@@ -22,6 +22,7 @@ class GitlabDanger
     roulette
     ce_ee_vue_templates
     sidekiq_queues
+    specialization_labels
   ].freeze
 
   MESSAGE_PREFIX = '==>'.freeze
diff --git a/spec/lib/gitlab/danger/helper_spec.rb b/spec/lib/gitlab/danger/helper_spec.rb
index e5018e46634a..0e66bf8691e4 100644
--- a/spec/lib/gitlab/danger/helper_spec.rb
+++ b/spec/lib/gitlab/danger/helper_spec.rb
@@ -371,22 +371,6 @@
     end
   end
 
-  describe '#missing_database_labels' do
-    subject { helper.missing_database_labels(current_mr_labels) }
-
-    context 'when current merge request has ~database::review pending' do
-      let(:current_mr_labels) { ['database::review pending', 'feature'] }
-
-      it { is_expected.to match_array(['database']) }
-    end
-
-    context 'when current merge request does not have ~database::review pending' do
-      let(:current_mr_labels) { ['feature'] }
-
-      it { is_expected.to match_array(['database', 'database::review pending']) }
-    end
-  end
-
   describe '#sanitize_mr_title' do
     where(:mr_title, :expected_mr_title) do
       'My MR title'      | 'My MR title'
-- 
GitLab