From 08549e270d749401fa66f332262d5245ea000bfd Mon Sep 17 00:00:00 2001
From: Aleksandr Mezin <aleksandr.mezin@webpros.com>
Date: Thu, 25 Jul 2024 19:09:12 +0300
Subject: [PATCH] feat(templates): allow `upgrades` in `commitMessage` and
 `prTitle` (#29955)

Co-authored-by: Rhys Arkins <rhys@arkins.net>
---
 .../__snapshots__/generate.spec.ts.snap       |  10 --
 .../repository/updates/generate.spec.ts       | 112 +++++++++++++++++-
 lib/workers/repository/updates/generate.ts    |   8 +-
 3 files changed, 114 insertions(+), 16 deletions(-)

diff --git a/lib/workers/repository/updates/__snapshots__/generate.spec.ts.snap b/lib/workers/repository/updates/__snapshots__/generate.spec.ts.snap
index 1271188a38..2bf6c1fbc2 100644
--- a/lib/workers/repository/updates/__snapshots__/generate.spec.ts.snap
+++ b/lib/workers/repository/updates/__snapshots__/generate.spec.ts.snap
@@ -29,7 +29,6 @@ exports[`workers/repository/updates/generate generateBranchConfig() handles @typ
   "upgrades": [
     {
       "branchName": "some-branch",
-      "commitMessage": "",
       "depName": "some-dep",
       "depTypes": undefined,
       "displayFrom": "",
@@ -48,7 +47,6 @@ exports[`workers/repository/updates/generate generateBranchConfig() handles @typ
     {
       "branchName": "some-branch",
       "commitBodyTable": true,
-      "commitMessage": "",
       "datasource": "npm",
       "depName": "some-dep",
       "depTypes": undefined,
@@ -67,7 +65,6 @@ exports[`workers/repository/updates/generate generateBranchConfig() handles @typ
     },
     {
       "branchName": "some-branch",
-      "commitMessage": "",
       "depName": "@types/some-dep",
       "depTypes": undefined,
       "displayFrom": "",
@@ -116,7 +113,6 @@ exports[`workers/repository/updates/generate generateBranchConfig() handles @typ
     {
       "branchName": "some-branch",
       "commitBodyTable": true,
-      "commitMessage": "",
       "datasource": "npm",
       "depName": "some-dep",
       "depTypes": undefined,
@@ -133,7 +129,6 @@ exports[`workers/repository/updates/generate generateBranchConfig() handles @typ
     {
       "branchName": "some-branch",
       "commitBodyTable": true,
-      "commitMessage": "",
       "datasource": "npm",
       "depName": "some-dep",
       "depTypes": undefined,
@@ -150,7 +145,6 @@ exports[`workers/repository/updates/generate generateBranchConfig() handles @typ
     {
       "branchName": "some-branch",
       "commitBodyTable": true,
-      "commitMessage": "",
       "currentValue": "0.5.7",
       "currentVersion": "0.5.7",
       "datasource": "npm",
@@ -196,7 +190,6 @@ exports[`workers/repository/updates/generate generateBranchConfig() handles lock
   "upgrades": [
     {
       "branchName": "some-branch",
-      "commitMessage": "",
       "depTypes": undefined,
       "displayFrom": "",
       "displayPending": "",
@@ -242,7 +235,6 @@ exports[`workers/repository/updates/generate generateBranchConfig() handles lock
   "upgrades": [
     {
       "branchName": "some-branch",
-      "commitMessage": "",
       "currentValue": "^1.0.0",
       "currentVersion": "1.0.0",
       "depTypes": undefined,
@@ -263,5 +255,3 @@ exports[`workers/repository/updates/generate generateBranchConfig() handles lock
   ],
 }
 `;
-
-exports[`workers/repository/updates/generate generateBranchConfig() handles upgrades: some-title (patch) 1`] = `"some-title (patch)"`;
diff --git a/lib/workers/repository/updates/generate.spec.ts b/lib/workers/repository/updates/generate.spec.ts
index f84c767c7b..3332212e32 100644
--- a/lib/workers/repository/updates/generate.spec.ts
+++ b/lib/workers/repository/updates/generate.spec.ts
@@ -1058,7 +1058,7 @@ describe('workers/repository/updates/generate', () => {
     });
 
     it('handles upgrades', () => {
-      const branch = [
+      const baseBranchesUpdates = [
         {
           manager: 'some-manager',
           depName: 'some-dep',
@@ -1066,8 +1066,14 @@ describe('workers/repository/updates/generate', () => {
           prTitle: 'some-title',
           newValue: '0.6.0',
           hasBaseBranches: true,
+          baseBranch: 'base-branch',
           fileReplacePosition: 5,
         },
+      ];
+      expect(generateBranchConfig(baseBranchesUpdates)).toMatchObject({
+        prTitle: 'some-title (base-branch)',
+      });
+      const separateMinorUpdates = [
         {
           ...requiredDefaultOptions,
           manager: 'some-manager',
@@ -1080,6 +1086,11 @@ describe('workers/repository/updates/generate', () => {
           updateType: 'minor' as UpdateType,
           fileReplacePosition: 1,
         },
+      ];
+      expect(generateBranchConfig(separateMinorUpdates)).toMatchObject({
+        prTitle: 'some-title (minor)',
+      });
+      const separateMajorUpdates = [
         {
           ...requiredDefaultOptions,
           manager: 'some-manager',
@@ -1092,6 +1103,11 @@ describe('workers/repository/updates/generate', () => {
           updateType: 'major' as UpdateType,
           fileReplacePosition: 2,
         },
+      ];
+      expect(generateBranchConfig(separateMajorUpdates)).toMatchObject({
+        prTitle: 'some-title (major)',
+      });
+      const separatePatchUpdates = [
         {
           ...requiredDefaultOptions,
           manager: 'some-manager',
@@ -1105,9 +1121,19 @@ describe('workers/repository/updates/generate', () => {
           updateType: 'patch' as UpdateType,
           fileReplacePosition: 0,
         },
+      ];
+      expect(generateBranchConfig(separatePatchUpdates)).toMatchObject({
+        prTitle: 'some-title (patch)',
+      });
+      const branch = [
+        ...baseBranchesUpdates,
+        ...separateMinorUpdates,
+        ...separateMajorUpdates,
+        ...separatePatchUpdates,
       ] satisfies BranchUpgradeConfig[];
-      const res = generateBranchConfig(branch);
-      expect(res.prTitle).toMatchSnapshot('some-title (patch)');
+      expect(generateBranchConfig(branch)).toMatchObject({
+        prTitle: 'some-title (patch)',
+      });
     });
 
     it('combines prBodyColumns', () => {
@@ -1497,5 +1523,85 @@ describe('workers/repository/updates/generate', () => {
         expect(upgrade.depTypes).toEqual(res.depTypes);
       }
     });
+
+    it('allows upgrades in commitMessage', () => {
+      const branch = [
+        {
+          ...requiredDefaultOptions,
+          manager: 'some-manager',
+          branchName: 'dep1',
+          depName: 'dep1',
+          commitMessagePrefix:
+            '{{#each upgrades}}{{{prBodyDefinitions.Issue}}} {{/each}}',
+          newVersion: '1.2.0',
+          newValue: '1.2.0',
+          updateType: 'minor' as UpdateType,
+          fileReplacePosition: 1,
+          prBodyDefinitions: {
+            Issue: 'I1',
+          },
+        },
+      ] satisfies BranchUpgradeConfig[];
+
+      expect(generateBranchConfig(branch)).toMatchObject({
+        commitMessage: 'I1 Update dependency dep1 to 1.2.0',
+        prTitle: 'I1 Update dependency dep1 to 1.2.0',
+      });
+    });
+
+    it('allows upgrades in commitMessage (group)', () => {
+      const commonOptions = {
+        ...requiredDefaultOptions,
+        manager: 'some-manager',
+        branchName: 'deps',
+        groupName: 'deps',
+        group: {
+          commitMessageTopic: '{{{groupName}}}',
+          commitMessagePrefix:
+            '{{#each upgrades}}{{{prBodyDefinitions.Issue}}} {{/each}}',
+        },
+      };
+
+      const branch = [
+        {
+          ...commonOptions,
+          depName: 'dep1',
+          newVersion: '1.2.0',
+          newValue: '1.2.0',
+          updateType: 'minor' as UpdateType,
+          fileReplacePosition: 1,
+          prBodyDefinitions: {
+            Issue: 'I1',
+          },
+        },
+        {
+          ...commonOptions,
+          depName: 'dep2',
+          newVersion: '1.0.0',
+          newValue: '1.0.0',
+          updateType: 'major' as UpdateType,
+          fileReplacePosition: 2,
+          prBodyDefinitions: {
+            Issue: 'I2',
+          },
+        },
+        {
+          ...commonOptions,
+          depName: 'dep3',
+          newVersion: '1.2.3',
+          newValue: '1.2.3',
+          updateType: 'patch' as UpdateType,
+          fileReplacePosition: 0,
+          prBodyDefinitions: {
+            Issue: 'I3',
+          },
+        },
+      ] satisfies BranchUpgradeConfig[];
+      const res = generateBranchConfig(branch);
+      expect(res).toMatchObject({
+        commitMessage: 'I3 I2 I1 Update deps',
+        prTitle: 'I3 I2 I1 Update deps',
+      });
+    });
   });
 });
diff --git a/lib/workers/repository/updates/generate.ts b/lib/workers/repository/updates/generate.ts
index 2072995ccf..234e20e40a 100644
--- a/lib/workers/repository/updates/generate.ts
+++ b/lib/workers/repository/updates/generate.ts
@@ -302,9 +302,6 @@ export function generateBranchConfig(
     } else if (semver.valid(toVersions[0])) {
       upgrade.isRange = false;
     }
-    // Use templates to generate strings
-    const commitMessage = compileCommitMessage(upgrade);
-    compilePrTitle(upgrade, commitMessage);
     config.upgrades.push(upgrade);
     if (upgrade.releaseTimestamp) {
       if (releaseTimestamp!) {
@@ -357,6 +354,11 @@ export function generateBranchConfig(
     ...config.upgrades[0],
     releaseTimestamp: releaseTimestamp!,
   }; // TODO: fixme (#9666)
+
+  // Use templates to generate strings
+  const commitMessage = compileCommitMessage(config);
+  compilePrTitle(config, commitMessage);
+
   config.dependencyDashboardApproval = config.upgrades.some(
     (upgrade) => upgrade.dependencyDashboardApproval,
   );
-- 
GitLab