From 7c772bebf6ddcfcad5fe8e50d961511f04d938ec Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9my=20Coutable?= <remy@rymai.me>
Date: Mon, 25 Oct 2021 15:44:29 +0200
Subject: [PATCH] danger: Don't warn for missing labels while adding some
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Rémy Coutable <remy@rymai.me>
---
 Dangerfile                                 | 10 +++++++++-
 danger/database/Dangerfile                 |  4 +---
 danger/feature_flag/Dangerfile             |  4 +---
 danger/product_intelligence/Dangerfile     |  8 +++-----
 danger/specialization_labels/Dangerfile    |  6 +-----
 danger/{metadata => z_metadata}/Dangerfile |  2 +-
 doc/development/dangerbot.md               | 17 +++++++++++++++++
 tooling/danger/project_helper.rb           |  6 +++++-
 8 files changed, 38 insertions(+), 19 deletions(-)
 rename danger/{metadata => z_metadata}/Dangerfile (94%)

diff --git a/Dangerfile b/Dangerfile
index 37a45674e1685..ab96c43c4e55d 100644
--- a/Dangerfile
+++ b/Dangerfile
@@ -17,6 +17,14 @@ end
 
 anything_to_post = status_report.values.any? { |data| data.any? }
 
-if helper.ci? && anything_to_post
+return unless helper.ci?
+
+if project_helper.labels_to_add.any?
+  gitlab.api.update_merge_request(gitlab.mr_json['project_id'],
+                                  gitlab.mr_json['iid'],
+                                  add_labels: project_helper.labels_to_add.join(','))
+end
+
+if anything_to_post
   markdown("**If needed, you can retry the [`danger-review` job](#{ENV['CI_JOB_URL']}) that generated this comment.**")
 end
diff --git a/danger/database/Dangerfile b/danger/database/Dangerfile
index 693c03b9daddd..70adbb4c13990 100644
--- a/danger/database/Dangerfile
+++ b/danger/database/Dangerfile
@@ -66,8 +66,6 @@ if gitlab.mr_labels.include?('database') || db_paths_to_review.any?
   end
 
   unless helper.has_database_scoped_labels?
-    gitlab.api.update_merge_request(gitlab.mr_json['project_id'],
-                                    gitlab.mr_json['iid'],
-                                    add_labels: 'database::review pending')
+    project_helper.labels_to_add << 'database::review pending'
   end
 end
diff --git a/danger/feature_flag/Dangerfile b/danger/feature_flag/Dangerfile
index 9b67590f1172a..d6c1c53cddcb0 100644
--- a/danger/feature_flag/Dangerfile
+++ b/danger/feature_flag/Dangerfile
@@ -58,9 +58,7 @@ def message_for_feature_flag_with_group!(feature_flag:, mr_group_label:)
   return if feature_flag.group_match_mr_label?(mr_group_label)
 
   if mr_group_label.nil?
-    gitlab.api.update_merge_request(gitlab.mr_json['project_id'],
-                                    gitlab.mr_json['iid'],
-                                    add_labels: feature_flag.group)
+    project_helper.labels_to_add << feature_flag.group
   else
     fail %(`group` is set to ~"#{feature_flag.group}" in #{gitlab.html_link(feature_flag.path)}, which does not match ~"#{mr_group_label}" set on the MR!)
   end
diff --git a/danger/product_intelligence/Dangerfile b/danger/product_intelligence/Dangerfile
index dda3fbfc58905..eedb9b89d2254 100644
--- a/danger/product_intelligence/Dangerfile
+++ b/danger/product_intelligence/Dangerfile
@@ -13,12 +13,10 @@ MSG
 
 # exit if not matching files or if no product intelligence labels
 product_intelligence_paths_to_review = project_helper.changes_by_category[:product_intelligence]
-labels = product_intelligence.missing_labels
+labels_to_add = product_intelligence.missing_labels
 
-return if product_intelligence_paths_to_review.empty? || labels.empty?
+return if product_intelligence_paths_to_review.empty? || labels_to_add.empty?
 
 warn format(CHANGED_FILES_MESSAGE, changed_files: helper.markdown_list(product_intelligence_paths_to_review))
 
-gitlab.api.update_merge_request(gitlab.mr_json['project_id'],
-                                    gitlab.mr_json['iid'],
-                                    add_labels: labels)
+project_helper.labels_to_add.concat(labels_to_add)
diff --git a/danger/specialization_labels/Dangerfile b/danger/specialization_labels/Dangerfile
index e42e17762e468..ec79611d93d8b 100644
--- a/danger/specialization_labels/Dangerfile
+++ b/danger/specialization_labels/Dangerfile
@@ -19,8 +19,4 @@ labels_to_add = project_helper.changes_by_category.each_with_object([]) do |(cat
   memo << label if label && !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
+project_helper.labels_to_add.concat(labels_to_add) if labels_to_add.any?
diff --git a/danger/metadata/Dangerfile b/danger/z_metadata/Dangerfile
similarity index 94%
rename from danger/metadata/Dangerfile
rename to danger/z_metadata/Dangerfile
index 537f55ed649ce..0a70554486f77 100644
--- a/danger/metadata/Dangerfile
+++ b/danger/z_metadata/Dangerfile
@@ -18,7 +18,7 @@ if gitlab.mr_body.size < 5
   fail "Please provide a proper merge request description."
 end
 
-if (TYPE_LABELS & gitlab.mr_labels).empty?
+if (TYPE_LABELS & (gitlab.mr_labels + project_helper.labels_to_add)).empty?
   warn 'Please add a [merge request type](https://about.gitlab.com/handbook/engineering/metrics/#work-type-classification) to this merge request.'
 end
 
diff --git a/doc/development/dangerbot.md b/doc/development/dangerbot.md
index aca37e2182a65..829f6af76be3a 100644
--- a/doc/development/dangerbot.md
+++ b/doc/development/dangerbot.md
@@ -118,6 +118,23 @@ However, you can speed these cycles up somewhat by emptying the
 `.gitlab/ci/rails.gitlab-ci.yml` file in your merge request. Just don't forget
 to revert the change before merging!
 
+#### Adding labels via Danger
+
+NOTE:
+This is currently applicable to the [`gitlab-org/gitlab`](https://gitlab.com/gitlab-org/gitlab)
+project only.
+
+Danger is often used to improve MR hygiene by adding labels. Instead of calling the
+API directly in your `Dangerfile`, add the labels to the `project_helper.labels_to_add` array.
+The main `Dangerfile` will then take care of adding the labels to the MR with a single API call.
+
+#### Shared rules and plugins
+
+If the rule or plugin you implement can be useful for other projects, think about
+upstreaming them to the [`gitlab-org/gitlab-dangerfiles`](https://gitlab.com/gitlab-org/gitlab-dangerfiles) project.
+
+#### Enable Danger on a project
+
 To enable the Dangerfile on another existing GitLab project, run the following
 extra steps:
 
diff --git a/tooling/danger/project_helper.rb b/tooling/danger/project_helper.rb
index 1eac7380b3460..329599f338105 100644
--- a/tooling/danger/project_helper.rb
+++ b/tooling/danger/project_helper.rb
@@ -22,12 +22,12 @@ module ProjectHelper
         ce_ee_vue_templates
         ci_templates
         datateam
-        metadata
         feature_flag
         roulette
         sidekiq_queues
         specialization_labels
         specs
+        z_metadata
       ].freeze
 
       MESSAGE_PREFIX = '==>'
@@ -189,6 +189,10 @@ def file_lines(filename)
         read_file(filename).lines(chomp: true)
       end
 
+      def labels_to_add
+        @labels_to_add ||= []
+      end
+
       private
 
       def read_file(filename)
-- 
GitLab