From 6ea48d19e3d6e348fdeef447e812367f93de8328 Mon Sep 17 00:00:00 2001
From: Parvesh Chaudhary <parveshchaudhary111@gmail.com>
Date: Sat, 23 Apr 2022 15:18:23 +0530
Subject: [PATCH] feat: pruneBranchAfterAutomerge (#15126)

---
 docs/usage/configuration-options.md                |  5 +++++
 lib/config/options/index.ts                        |  6 ++++++
 lib/config/types.ts                                |  1 +
 lib/workers/repository/update/pr/automerge.spec.ts | 11 +++++++++++
 lib/workers/repository/update/pr/automerge.ts      |  5 +++++
 5 files changed, 28 insertions(+)

diff --git a/docs/usage/configuration-options.md b/docs/usage/configuration-options.md
index 2284f7b682..2155e6dd28 100644
--- a/docs/usage/configuration-options.md
+++ b/docs/usage/configuration-options.md
@@ -2080,6 +2080,11 @@ Here's an example of how you would define PR priority so that devDependencies ar
 
 The PR title is important for some of Renovate's matching algorithms (e.g. determining whether to recreate a PR or not) so ideally don't modify it much.
 
+## pruneBranchAfterAutomerge
+
+By default Renovate deletes, or "prunes", the branch after automerging.
+Set `pruneBranchAfterAutomerge` to `false` to keep the branch after automerging.
+
 ## pruneStaleBranches
 
 Configure to `false` to disable deleting orphan branches and autoclosing PRs.
diff --git a/lib/config/options/index.ts b/lib/config/options/index.ts
index 757ad222ec..09b01bdec9 100644
--- a/lib/config/options/index.ts
+++ b/lib/config/options/index.ts
@@ -1499,6 +1499,12 @@ const options: RenovateOptions[] = [
     env: false,
     supportedPlatforms: ['github'],
   },
+  {
+    name: 'pruneBranchAfterAutomerge',
+    description: 'Set to `true` to enable branch pruning after automerging.',
+    type: 'boolean',
+    default: true,
+  },
   // Default templates
   {
     name: 'branchName',
diff --git a/lib/config/types.ts b/lib/config/types.ts
index 3191acdd83..bd1dfa9efd 100644
--- a/lib/config/types.ts
+++ b/lib/config/types.ts
@@ -23,6 +23,7 @@ export interface RenovateSharedConfig {
   $schema?: string;
   automerge?: boolean;
   automergeStrategy?: MergeStrategy;
+  pruneBranchAfterAutomerge?: boolean;
   branchPrefix?: string;
   branchName?: string;
   manager?: string;
diff --git a/lib/workers/repository/update/pr/automerge.spec.ts b/lib/workers/repository/update/pr/automerge.spec.ts
index b5160535a3..adf095f1a2 100644
--- a/lib/workers/repository/update/pr/automerge.spec.ts
+++ b/lib/workers/repository/update/pr/automerge.spec.ts
@@ -28,6 +28,7 @@ describe('workers/repository/update/pr/automerge', () => {
 
     it('should automerge if enabled and pr is mergeable', async () => {
       config.automerge = true;
+      config.pruneBranchAfterAutomerge = true;
       platform.getBranchStatus.mockResolvedValueOnce(BranchStatus.green);
       platform.mergePr.mockResolvedValueOnce(true);
       const res = await prAutomerge.checkAutoMerge(pr, config);
@@ -72,6 +73,16 @@ describe('workers/repository/update/pr/automerge', () => {
       expect(platform.ensureComment).toHaveBeenCalledTimes(1);
     });
 
+    it('should skip branch deletion after automerge if prune is disabled', async () => {
+      config.automerge = true;
+      config.pruneBranchAfterAutomerge = false;
+      platform.getBranchStatus.mockResolvedValueOnce(BranchStatus.green);
+      platform.mergePr.mockResolvedValueOnce(true);
+      const res = await prAutomerge.checkAutoMerge(pr, config);
+      expect(res).toEqual({ automerged: true, branchRemoved: false });
+      expect(platform.mergePr).toHaveBeenCalledTimes(1);
+    });
+
     it('should not automerge if enabled and pr is mergeable but cannot rebase', async () => {
       config.automerge = true;
       platform.getBranchStatus.mockResolvedValueOnce(BranchStatus.green);
diff --git a/lib/workers/repository/update/pr/automerge.ts b/lib/workers/repository/update/pr/automerge.ts
index 001a433c09..d26a635cf7 100644
--- a/lib/workers/repository/update/pr/automerge.ts
+++ b/lib/workers/repository/update/pr/automerge.ts
@@ -39,6 +39,7 @@ export async function checkAutoMerge(
     branchName,
     automergeType,
     automergeStrategy,
+    pruneBranchAfterAutomerge,
     automergeComment,
     ignoreTests,
     rebaseRequested,
@@ -129,6 +130,10 @@ export async function checkAutoMerge(
   });
   if (res) {
     logger.info({ pr: pr.number, prTitle: pr.title }, 'PR automerged');
+    if (!pruneBranchAfterAutomerge) {
+      logger.info('Skipping pruning of merged branch');
+      return { automerged: true, branchRemoved: false };
+    }
     let branchRemoved = false;
     try {
       await deleteBranch(branchName);
-- 
GitLab