diff --git a/lib/workers/repository/onboarding/pr/index.ts b/lib/workers/repository/onboarding/pr/index.ts
index 8efa0695c2e871f623d73899cc126151283f7b82..e0423a12b65c573406ecba885a60270dc9661d2d 100644
--- a/lib/workers/repository/onboarding/pr/index.ts
+++ b/lib/workers/repository/onboarding/pr/index.ts
@@ -12,11 +12,8 @@ import {
 } from '../../../../util/git';
 import * as template from '../../../../util/template';
 import type { BranchConfig } from '../../../types';
-import {
-  addAssigneesReviewers,
-  getPlatformPrOptions,
-  prepareLabels,
-} from '../../update/pr';
+import { addAssigneesReviewers, getPlatformPrOptions } from '../../update/pr';
+import { prepareLabels } from '../../update/pr/labels';
 import { getBaseBranchDesc } from './base-branch';
 import { getConfigDesc } from './config-description';
 import { getDepWarnings, getErrors, getWarnings } from './errors-warnings';
diff --git a/lib/workers/repository/update/pr/automerge.spec.ts b/lib/workers/repository/update/pr/automerge.spec.ts
index adf095f1a2fb064d156da5002c29648f486a09df..81521555314acdc3d804ac711a15c736c2526cc3 100644
--- a/lib/workers/repository/update/pr/automerge.spec.ts
+++ b/lib/workers/repository/update/pr/automerge.spec.ts
@@ -26,6 +26,11 @@ describe('workers/repository/update/pr/automerge', () => {
       jest.clearAllMocks();
     });
 
+    it('should not automerge if not configured', async () => {
+      await prAutomerge.checkAutoMerge(pr, config);
+      expect(platform.mergePr).toHaveBeenCalledTimes(0);
+    });
+
     it('should automerge if enabled and pr is mergeable', async () => {
       config.automerge = true;
       config.pruneBranchAfterAutomerge = true;
diff --git a/lib/workers/repository/update/pr/index.spec.ts b/lib/workers/repository/update/pr/index.spec.ts
index ab25a757b12da1d1757b0311537ffc597d473314..d6dbf7d49f90648d118113dbabbccf11d655a593 100644
--- a/lib/workers/repository/update/pr/index.spec.ts
+++ b/lib/workers/repository/update/pr/index.spec.ts
@@ -10,7 +10,6 @@ import type { Pr } from '../../../../modules/platform';
 import { BranchStatus } from '../../../../types';
 import * as _limits from '../../../global/limits';
 import type { BranchConfig } from '../../../types';
-import * as prAutomerge from './automerge';
 import * as _changelogHelper from './changelog';
 import type { ChangeLogResult } from './changelog';
 import * as codeOwners from './code-owners';
@@ -116,85 +115,6 @@ function isResultWithoutPr(
 }
 
 describe('workers/repository/update/pr/index', () => {
-  describe('checkAutoMerge(pr, config)', () => {
-    let config: BranchConfig;
-    let pr: Pr;
-
-    beforeEach(() => {
-      config = partial<BranchConfig>({
-        ...getConfig(),
-      });
-      pr = partial<Pr>({});
-    });
-
-    afterEach(() => {
-      jest.clearAllMocks();
-    });
-
-    it('should not automerge if not configured', async () => {
-      await prAutomerge.checkAutoMerge(pr, config);
-      expect(platform.mergePr).toHaveBeenCalledTimes(0);
-    });
-
-    it('should automerge if enabled and pr is mergeable', async () => {
-      config.automerge = true;
-      platform.getBranchStatus.mockResolvedValueOnce(BranchStatus.green);
-      platform.mergePr.mockResolvedValueOnce(true);
-      await prAutomerge.checkAutoMerge(pr, config);
-      expect(platform.mergePr).toHaveBeenCalledTimes(1);
-    });
-
-    it('should automerge comment', async () => {
-      config.automerge = true;
-      config.automergeType = 'pr-comment';
-      config.automergeComment = '!merge';
-      platform.getBranchStatus.mockResolvedValueOnce(BranchStatus.green);
-      await prAutomerge.checkAutoMerge(pr, config);
-      expect(platform.ensureCommentRemoval).toHaveBeenCalledTimes(0);
-      expect(platform.ensureComment).toHaveBeenCalledTimes(1);
-    });
-
-    it('should remove previous automerge comment when rebasing', async () => {
-      config.automerge = true;
-      config.automergeType = 'pr-comment';
-      config.automergeComment = '!merge';
-      config.rebaseRequested = true;
-      platform.getBranchStatus.mockResolvedValueOnce(BranchStatus.green);
-      await prAutomerge.checkAutoMerge(pr, config);
-      expect(platform.ensureCommentRemoval).toHaveBeenCalledTimes(1);
-      expect(platform.ensureComment).toHaveBeenCalledTimes(1);
-    });
-
-    it('should not automerge if enabled and pr is mergeable but cannot rebase', async () => {
-      config.automerge = true;
-      platform.getBranchStatus.mockResolvedValueOnce(BranchStatus.green);
-      git.isBranchModified.mockResolvedValueOnce(true);
-      await prAutomerge.checkAutoMerge(pr, config);
-      expect(platform.mergePr).toHaveBeenCalledTimes(0);
-    });
-
-    it('should not automerge if enabled and pr is mergeable but branch status is not success', async () => {
-      config.automerge = true;
-      platform.getBranchStatus.mockResolvedValueOnce(BranchStatus.yellow);
-      await prAutomerge.checkAutoMerge(pr, config);
-      expect(platform.mergePr).toHaveBeenCalledTimes(0);
-    });
-
-    it('should not automerge if enabled and pr is mergeable but unstable', async () => {
-      config.automerge = true;
-      pr.cannotMergeReason = 'some reason';
-      await prAutomerge.checkAutoMerge(pr, config);
-      expect(platform.mergePr).toHaveBeenCalledTimes(0);
-    });
-
-    it('should not automerge if enabled and pr is unmergeable', async () => {
-      config.automerge = true;
-      git.isBranchConflicted.mockResolvedValueOnce(true);
-      await prAutomerge.checkAutoMerge(pr, config);
-      expect(platform.mergePr).toHaveBeenCalledTimes(0);
-    });
-  });
-
   describe('ensurePr', () => {
     let config: BranchConfig;
     // TODO fix type
@@ -871,81 +791,4 @@ describe('workers/repository/update/pr/index', () => {
       });
     });
   });
-
-  describe('prepareLabels(config)', () => {
-    it('returns empty array if no labels are configured', () => {
-      const result = prWorker.prepareLabels({});
-      expect(result).toBeArrayOfSize(0);
-    });
-
-    it('only labels', () => {
-      const result = prWorker.prepareLabels({ labels: ['labelA', 'labelB'] });
-      expect(result).toBeArrayOfSize(2);
-      expect(result).toEqual(['labelA', 'labelB']);
-    });
-
-    it('only addLabels', () => {
-      const result = prWorker.prepareLabels({
-        addLabels: ['labelA', 'labelB'],
-      });
-      expect(result).toBeArrayOfSize(2);
-      expect(result).toEqual(['labelA', 'labelB']);
-    });
-
-    it('merge labels and addLabels', () => {
-      const result = prWorker.prepareLabels({
-        labels: ['labelA', 'labelB'],
-        addLabels: ['labelC'],
-      });
-      expect(result).toBeArrayOfSize(3);
-      expect(result).toEqual(['labelA', 'labelB', 'labelC']);
-    });
-
-    it('deduplicate merged labels and addLabels', () => {
-      const result = prWorker.prepareLabels({
-        labels: ['labelA', 'labelB'],
-        addLabels: ['labelB', 'labelC'],
-      });
-      expect(result).toBeArrayOfSize(3);
-      expect(result).toEqual(['labelA', 'labelB', 'labelC']);
-    });
-
-    it('empty labels ignored', () => {
-      const result = prWorker.prepareLabels({
-        labels: ['labelA', ''],
-        addLabels: [' ', 'labelB'],
-      });
-      expect(result).toBeArrayOfSize(2);
-      expect(result).toEqual(['labelA', 'labelB']);
-    });
-
-    it('null labels ignored', () => {
-      const result = prWorker.prepareLabels({
-        labels: ['labelA', null],
-        // an empty space between two commas in an array is categorized as a null value
-        // eslint-disable-next-line no-sparse-arrays
-        addLabels: ['labelB', '', undefined, , ,],
-      });
-      expect(result).toBeArrayOfSize(2);
-      expect(result).toEqual(['labelA', 'labelB']);
-    });
-
-    it('template labels', () => {
-      const result = prWorker.prepareLabels({
-        labels: ['datasource-{{{datasource}}}'],
-        datasource: 'npm',
-      });
-      expect(result).toBeArrayOfSize(1);
-      expect(result).toEqual(['datasource-npm']);
-    });
-
-    it('template labels with empty datasource', () => {
-      const result = prWorker.prepareLabels({
-        labels: ['{{{datasource}}}', ' {{{datasource}}} '],
-        datasource: null,
-      });
-      expect(result).toBeArrayOfSize(0);
-      expect(result).toEqual([]);
-    });
-  });
 });
diff --git a/lib/workers/repository/update/pr/index.ts b/lib/workers/repository/update/pr/index.ts
index ad81190bc2a3a2f6bee3645ba7d89e2da4da8eab..e44e576a975eb149bef4c53d215d760de5b092a4 100644
--- a/lib/workers/repository/update/pr/index.ts
+++ b/lib/workers/repository/update/pr/index.ts
@@ -1,4 +1,3 @@
-import is from '@sindresorhus/is';
 import { GlobalConfig } from '../../../../config/global';
 import type { RenovateConfig } from '../../../../config/types';
 import {
@@ -15,7 +14,6 @@ import { sampleSize } from '../../../../util';
 import { stripEmojis } from '../../../../util/emoji';
 import { deleteBranch, getBranchLastCommitTime } from '../../../../util/git';
 import { regEx } from '../../../../util/regex';
-import * as template from '../../../../util/template';
 import { Limit, incLimitedValue, isLimitReached } from '../../../global/limits';
 import type {
   BranchConfig,
@@ -26,6 +24,7 @@ import { resolveBranchStatus } from '../branch/status-checks';
 import { getPrBody } from './body';
 import { ChangeLogError } from './changelog/types';
 import { codeOwnersForPr } from './code-owners';
+import { prepareLabels } from './labels';
 
 function noWhitespaceOrHeadings(input: string): string {
   return input.replace(regEx(/\r?\n|\r|\s|#/g), '');
@@ -59,15 +58,6 @@ function prepareAssigneesReviewers(
   return filterUnavailableUsers(config, normalizedUsernames);
 }
 
-export function prepareLabels(config: RenovateConfig): string[] {
-  const labels = config.labels ?? [];
-  const addLabels = config.addLabels ?? [];
-  return [...new Set([...labels, ...addLabels])]
-    .filter(is.nonEmptyStringAndNotWhitespace)
-    .map((label) => template.compile(label, config))
-    .filter(is.nonEmptyStringAndNotWhitespace);
-}
-
 export async function addAssigneesReviewers(
   config: RenovateConfig,
   pr: Pr
diff --git a/lib/workers/repository/update/pr/labels.spec.ts b/lib/workers/repository/update/pr/labels.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..60f5f8d315f419c2c3ff4c01995bdb3566eb0760
--- /dev/null
+++ b/lib/workers/repository/update/pr/labels.spec.ts
@@ -0,0 +1,80 @@
+import { prepareLabels } from './labels';
+
+describe('workers/repository/update/pr/labels', () => {
+  describe('prepareLabels(config)', () => {
+    it('returns empty array if no labels are configured', () => {
+      const result = prepareLabels({});
+      expect(result).toBeArrayOfSize(0);
+    });
+
+    it('only labels', () => {
+      const result = prepareLabels({ labels: ['labelA', 'labelB'] });
+      expect(result).toBeArrayOfSize(2);
+      expect(result).toEqual(['labelA', 'labelB']);
+    });
+
+    it('only addLabels', () => {
+      const result = prepareLabels({
+        addLabels: ['labelA', 'labelB'],
+      });
+      expect(result).toBeArrayOfSize(2);
+      expect(result).toEqual(['labelA', 'labelB']);
+    });
+
+    it('merge labels and addLabels', () => {
+      const result = prepareLabels({
+        labels: ['labelA', 'labelB'],
+        addLabels: ['labelC'],
+      });
+      expect(result).toBeArrayOfSize(3);
+      expect(result).toEqual(['labelA', 'labelB', 'labelC']);
+    });
+
+    it('deduplicate merged labels and addLabels', () => {
+      const result = prepareLabels({
+        labels: ['labelA', 'labelB'],
+        addLabels: ['labelB', 'labelC'],
+      });
+      expect(result).toBeArrayOfSize(3);
+      expect(result).toEqual(['labelA', 'labelB', 'labelC']);
+    });
+
+    it('empty labels ignored', () => {
+      const result = prepareLabels({
+        labels: ['labelA', ''],
+        addLabels: [' ', 'labelB'],
+      });
+      expect(result).toBeArrayOfSize(2);
+      expect(result).toEqual(['labelA', 'labelB']);
+    });
+
+    it('null labels ignored', () => {
+      const result = prepareLabels({
+        labels: ['labelA', null],
+        // an empty space between two commas in an array is categorized as a null value
+        // eslint-disable-next-line no-sparse-arrays
+        addLabels: ['labelB', '', undefined, , ,],
+      });
+      expect(result).toBeArrayOfSize(2);
+      expect(result).toEqual(['labelA', 'labelB']);
+    });
+
+    it('template labels', () => {
+      const result = prepareLabels({
+        labels: ['datasource-{{{datasource}}}'],
+        datasource: 'npm',
+      });
+      expect(result).toBeArrayOfSize(1);
+      expect(result).toEqual(['datasource-npm']);
+    });
+
+    it('template labels with empty datasource', () => {
+      const result = prepareLabels({
+        labels: ['{{{datasource}}}', ' {{{datasource}}} '],
+        datasource: null,
+      });
+      expect(result).toBeArrayOfSize(0);
+      expect(result).toEqual([]);
+    });
+  });
+});
diff --git a/lib/workers/repository/update/pr/labels.ts b/lib/workers/repository/update/pr/labels.ts
new file mode 100644
index 0000000000000000000000000000000000000000..df04f8012593467243fa14a4ca57db717d16649e
--- /dev/null
+++ b/lib/workers/repository/update/pr/labels.ts
@@ -0,0 +1,12 @@
+import is from '@sindresorhus/is';
+import type { RenovateConfig } from '../../../../config/types';
+import * as template from '../../../../util/template';
+
+export function prepareLabels(config: RenovateConfig): string[] {
+  const labels = config.labels ?? [];
+  const addLabels = config.addLabels ?? [];
+  return [...new Set([...labels, ...addLabels])]
+    .filter(is.nonEmptyStringAndNotWhitespace)
+    .map((label) => template.compile(label, config))
+    .filter(is.nonEmptyStringAndNotWhitespace);
+}