From ef41262f17f125f618a442846b4f554255b54a76 Mon Sep 17 00:00:00 2001
From: Brad Jorsch <anomiex@users.noreply.github.com>
Date: Mon, 13 Jun 2022 10:19:44 -0400
Subject: [PATCH] fix: resolve repoConfig.packageRules.extends with repo config
 (#14978)

---
 lib/config/options/index.ts                   |  3 +-
 lib/workers/repository/init/merge.spec.ts     | 31 ++++++++++++++-----
 lib/workers/repository/init/merge.ts          |  1 +
 .../onboarding/branch/index.spec.ts           | 15 +++++----
 4 files changed, 34 insertions(+), 16 deletions(-)

diff --git a/lib/config/options/index.ts b/lib/config/options/index.ts
index bc84a2a66b..9b1692ed1f 100644
--- a/lib/config/options/index.ts
+++ b/lib/config/options/index.ts
@@ -152,8 +152,7 @@ const options: RenovateOptions[] = [
   },
   {
     name: 'extends',
-    description:
-      'Configuration presets to use or extend. Note: This config option does not work if you use a `config.js` file.',
+    description: 'Configuration presets to use or extend.',
     stage: 'package',
     type: 'array',
     subType: 'string',
diff --git a/lib/workers/repository/init/merge.spec.ts b/lib/workers/repository/init/merge.spec.ts
index d0f7aa03d4..c82dd31040 100644
--- a/lib/workers/repository/init/merge.spec.ts
+++ b/lib/workers/repository/init/merge.spec.ts
@@ -199,16 +199,31 @@ describe('workers/repository/init/merge', () => {
     it('migrates nested config', async () => {
       git.getFileList.mockResolvedValue(['renovate.json']);
       fs.readLocalFile.mockResolvedValue('{}');
-      migrateAndValidate.migrateAndValidate.mockResolvedValue({
-        warnings: [],
-        errors: [],
-      });
-      migrate.migrateConfig.mockReturnValueOnce({
+      migrateAndValidate.migrateAndValidate.mockImplementation((_, c) => {
+        // We shouldn't see packageRules here (avoids #14827).
+        // (someday the validation should probably be reworked to know about `sourceUrl` from the repo config, but that day isn't today)
+        expect(c).not.toHaveProperty('packageRules');
+        return Promise.resolve({
+          ...c,
+          warnings: [],
+          errors: [],
+        });
+      });
+      migrate.migrateConfig.mockImplementation((c) => ({
         isMigrated: true,
-        migratedConfig: {},
+        migratedConfig: c,
+      }));
+      config.extends = [':automergeAll'];
+      config.packageRules = [{ extends: ['monorepo:react'] }];
+      const ret = await mergeRenovateConfig(config);
+      expect(ret).toMatchObject({
+        automerge: true,
+        packageRules: [
+          {
+            matchSourceUrlPrefixes: ['https://github.com/facebook/react'],
+          },
+        ],
       });
-      config.extends = [':automergeDisabled'];
-      expect(await mergeRenovateConfig(config)).toBeDefined();
     });
 
     it('continues if no errors', async () => {
diff --git a/lib/workers/repository/init/merge.ts b/lib/workers/repository/init/merge.ts
index 1ead00699e..4ad24befac 100644
--- a/lib/workers/repository/init/merge.ts
+++ b/lib/workers/repository/init/merge.ts
@@ -249,6 +249,7 @@ export async function mergeRenovateConfig(
     delete resolvedConfig.hostRules;
   }
   returnConfig = mergeChildConfig(returnConfig, resolvedConfig);
+  returnConfig = await presets.resolveConfigPresets(returnConfig, config);
   returnConfig.renovateJsonPresent = true;
   // istanbul ignore if
   if (returnConfig.ignorePaths?.length) {
diff --git a/lib/workers/repository/onboarding/branch/index.spec.ts b/lib/workers/repository/onboarding/branch/index.spec.ts
index ea25b06f2a..98a55a94d0 100644
--- a/lib/workers/repository/onboarding/branch/index.spec.ts
+++ b/lib/workers/repository/onboarding/branch/index.spec.ts
@@ -96,13 +96,16 @@ describe('workers/repository/onboarding/branch/index', () => {
       git.getFileList.mockResolvedValue(['package.json']);
       fs.readLocalFile.mockResolvedValue('{}');
       await checkOnboardingBranch(config);
+      const expectConfig = {
+        ...config,
+        onboardingBranch: 'test',
+        renovateJsonPresent: true,
+        warnings: [],
+      };
+      delete expectConfig.extends;
+      delete expectConfig.ignorePresets;
       expect(configModule.getOnboardingConfigContents).toHaveBeenCalledWith(
-        {
-          ...config,
-          onboardingBranch: 'test',
-          renovateJsonPresent: true,
-          warnings: [],
-        },
+        expectConfig,
         configFileNames[0]
       );
       const file = git.commitFiles.mock.calls[0][0].files[0] as FileAddition;
-- 
GitLab