From 65c3992ec592e235dd1343295b683c50f36c9de7 Mon Sep 17 00:00:00 2001
From: Rhys Arkins <rhys@arkins.net>
Date: Mon, 26 Apr 2021 07:00:26 +0200
Subject: [PATCH] fix: create PR if stale branch can't automerge (#9723)

---
 lib/workers/branch/automerge.ts  |  3 ++-
 lib/workers/branch/index.spec.ts | 25 +++++++++++++++++++++++++
 lib/workers/branch/index.ts      | 10 ++++++++++
 3 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/lib/workers/branch/automerge.ts b/lib/workers/branch/automerge.ts
index 674953beee..765d0c2b01 100644
--- a/lib/workers/branch/automerge.ts
+++ b/lib/workers/branch/automerge.ts
@@ -11,6 +11,7 @@ export type AutomergeResult =
   | 'branch status error'
   | 'failed'
   | 'no automerge'
+  | 'stale'
   | 'not ready';
 
 export async function tryBranchAutomerge(
@@ -48,7 +49,7 @@ export async function tryBranchAutomerge(
         err.message.includes('Not possible to fast-forward')
       ) {
         logger.warn({ err }, 'Branch is not up to date - cannot automerge');
-        return 'not ready';
+        return 'stale';
       }
       if (err.message.includes('Protected branch')) {
         if (err.message.includes('status check')) {
diff --git a/lib/workers/branch/index.spec.ts b/lib/workers/branch/index.spec.ts
index 097e78b549..fadb85c91c 100644
--- a/lib/workers/branch/index.spec.ts
+++ b/lib/workers/branch/index.spec.ts
@@ -448,6 +448,31 @@ describe(getName(__filename), () => {
       expect(platform.ensureCommentRemoval).toHaveBeenCalledTimes(0);
       expect(prAutomerge.checkAutoMerge).toHaveBeenCalledTimes(1);
     });
+    it('ensures PR when impossible to automerge', async () => {
+      getUpdated.getUpdatedPackageFiles.mockResolvedValueOnce({
+        updatedPackageFiles: [{}],
+      } as PackageFilesResult);
+      npmPostExtract.getAdditionalFiles.mockResolvedValueOnce({
+        artifactErrors: [],
+        updatedArtifacts: [{}],
+      } as WriteExistingFilesResult);
+      git.branchExists.mockReturnValue(true);
+      automerge.tryBranchAutomerge.mockResolvedValueOnce('stale');
+      prWorker.ensurePr.mockResolvedValueOnce({
+        prResult: PrResult.Created,
+        pr: {},
+      } as EnsurePrResult);
+      prAutomerge.checkAutoMerge.mockResolvedValueOnce({ automerged: false });
+      commit.commitFilesToBranch.mockResolvedValueOnce(null);
+      await branchWorker.processBranch({
+        ...config,
+        automerge: true,
+        rebaseWhen: 'conflicted',
+      });
+      expect(prWorker.ensurePr).toHaveBeenCalledTimes(1);
+      expect(platform.ensureCommentRemoval).toHaveBeenCalledTimes(0);
+      expect(prAutomerge.checkAutoMerge).toHaveBeenCalledTimes(1);
+    });
     it('ensures PR and adds lock file error comment if no releaseTimestamp', async () => {
       getUpdated.getUpdatedPackageFiles.mockResolvedValueOnce({
         updatedPackageFiles: [{}],
diff --git a/lib/workers/branch/index.ts b/lib/workers/branch/index.ts
index d5359e2028..8bbc0160d8 100644
--- a/lib/workers/branch/index.ts
+++ b/lib/workers/branch/index.ts
@@ -380,6 +380,16 @@ export async function processBranch(
         logger.debug('Branch is automerged - returning');
         return { branchExists: false, result: BranchResult.Automerged };
       }
+      if (
+        mergeStatus === 'stale' &&
+        ['conflicted', 'never'].includes(config.rebaseWhen)
+      ) {
+        logger.warn(
+          'Branch cannot automerge because it is stale and rebaseWhen setting disallows rebasing - raising a PR instead'
+        );
+        config.forcePr = true;
+        config.branchAutomergeFailureMessage = mergeStatus;
+      }
       if (
         mergeStatus === 'automerge aborted - PR exists' ||
         mergeStatus === 'branch status error' ||
-- 
GitLab