From 693f58e17821f7d2ba509cb8b3e14005b1c29336 Mon Sep 17 00:00:00 2001
From: Fernando Mora <moberstr@gmail.com>
Date: Thu, 3 Dec 2020 15:20:09 +0100
Subject: [PATCH] feat(config): Add mergeable `addLabels` option (#7869)

Co-authored-by: Rhys Arkins <rhys@arkins.net>
Co-authored-by: HonkingGoose <34918129+HonkingGoose@users.noreply.github.com>
Co-authored-by: Michael Kriese <michael.kriese@visualon.de>
---
 docs/usage/configuration-options.md | 30 +++++++++++++++++++++++++++++
 lib/config/common.ts                |  1 +
 lib/config/definitions.ts           |  7 +++++++
 lib/workers/pr/index.spec.ts        | 10 ++++++++++
 lib/workers/pr/index.ts             |  2 +-
 5 files changed, 49 insertions(+), 1 deletion(-)

diff --git a/docs/usage/configuration-options.md b/docs/usage/configuration-options.md
index e7e5d06277..5f39f4e75d 100644
--- a/docs/usage/configuration-options.md
+++ b/docs/usage/configuration-options.md
@@ -27,6 +27,36 @@ Also, be sure to check out Renovate's [shareable config presets](/config-presets
 
 If you have any questions about the below config options, or would like to get help/feedback about a config, please post it as an issue in [renovatebot/config-help](https://github.com/renovatebot/config-help) where we will do our best to answer your question.
 
+## addLabels
+
+The `labels` field is non-mergeable, meaning that any config setting a list of PR labels will replace any existing list.
+If you want to append labels for matched rules, then define an `addLabels` array with one (or more) label strings.
+All matched `addLabels` strings will be attached to the PR.
+
+Consider this example:
+
+```json
+{
+  "labels": ["dependencies"],
+  "packageRules": [
+    {
+      "packagePatterns": ["eslint"],
+      "labels": ["linting"]
+    },
+    {
+      "depTypeList": ["optionalDependencies"],
+      "addLabels": ["optional"]
+    }
+  ]
+}
+```
+
+With the above config:
+
+- Optional dependencies will have the labels `dependencies` and `optional`
+- ESLint dependencies will have the label `linting`
+- All other dependencies will have the label `dependencies`
+
 ## additionalBranchPrefix
 
 This value defaults to an empty string, and is typically not necessary.
diff --git a/lib/config/common.ts b/lib/config/common.ts
index 26f9205669..3db93010aa 100644
--- a/lib/config/common.ts
+++ b/lib/config/common.ts
@@ -37,6 +37,7 @@ export interface RenovateSharedConfig {
   ignoreDeps?: string[];
   ignorePaths?: string[];
   labels?: string[];
+  addLabels?: string[];
   managers?: string | string[];
   dependencyDashboardApproval?: boolean;
   npmrc?: string;
diff --git a/lib/config/definitions.ts b/lib/config/definitions.ts
index e8c22bb2a1..a2085e088e 100644
--- a/lib/config/definitions.ts
+++ b/lib/config/definitions.ts
@@ -1409,9 +1409,16 @@ const options: RenovateOptions[] = [
   // Pull Request options
   {
     name: 'labels',
+    description: 'Labels to set in Pull Request',
+    type: 'array',
+    subType: 'string',
+  },
+  {
+    name: 'addLabels',
     description: 'Labels to add to Pull Request',
     type: 'array',
     subType: 'string',
+    mergeable: true,
   },
   {
     name: 'assignees',
diff --git a/lib/workers/pr/index.spec.ts b/lib/workers/pr/index.spec.ts
index f2c2290ab0..59ee12f457 100644
--- a/lib/workers/pr/index.spec.ts
+++ b/lib/workers/pr/index.spec.ts
@@ -643,5 +643,15 @@ describe('workers/pr', () => {
         gitLabAutomerge: true,
       });
     });
+
+    it('should create a PR with set of labels and mergeable addLabels', async () => {
+      config.labels = ['deps', 'renovate'];
+      config.addLabels = ['deps', 'js'];
+      const { prResult } = await prWorker.ensurePr(config);
+      expect(prResult).toEqual(PrResult.Created);
+      expect(platform.createPr.mock.calls[0][0]).toMatchObject({
+        labels: ['deps', 'renovate', 'js'],
+      });
+    });
   });
 });
diff --git a/lib/workers/pr/index.ts b/lib/workers/pr/index.ts
index 40a3cac686..56e3489598 100644
--- a/lib/workers/pr/index.ts
+++ b/lib/workers/pr/index.ts
@@ -384,7 +384,7 @@ export async function ensurePr(
           targetBranch: config.baseBranch,
           prTitle,
           prBody,
-          labels: config.labels,
+          labels: [...new Set([...config.labels, ...config.addLabels])],
           platformOptions: getPlatformPrOptions(config),
           draftPR: config.draftPR,
         });
-- 
GitLab