diff --git a/lib/config/migration.spec.ts b/lib/config/migration.spec.ts
index 8f4a4202ac53d75cddb46208bca36cd4745f5fe5..ea60ebd9c099cc684d70ed5ff6d37cab32314afc 100644
--- a/lib/config/migration.spec.ts
+++ b/lib/config/migration.spec.ts
@@ -452,35 +452,6 @@ describe('config/migration', () => {
       });
       expect(isMigrated).toBeTrue();
     });
-    it('it migrates semanticCommits', () => {
-      let config: TestRenovateConfig;
-      let res: MigratedConfig;
-
-      config = { semanticCommits: true as never };
-      res = configMigration.migrateConfig(config);
-      expect(res.isMigrated).toBeTrue();
-      expect(res.migratedConfig).toMatchObject({ semanticCommits: 'enabled' });
-
-      config = { semanticCommits: false as never };
-      res = configMigration.migrateConfig(config);
-      expect(res.isMigrated).toBeTrue();
-      expect(res.migratedConfig).toMatchObject({ semanticCommits: 'disabled' });
-
-      config = { semanticCommits: null as never };
-      res = configMigration.migrateConfig(config);
-      expect(res.isMigrated).toBeTrue();
-      expect(res.migratedConfig).toMatchObject({ semanticCommits: 'auto' });
-
-      config = { semanticCommits: 'enabled' };
-      res = configMigration.migrateConfig(config);
-      expect(res.isMigrated).toBeFalse();
-      expect(res.migratedConfig).toMatchObject({ semanticCommits: 'enabled' });
-
-      config = { semanticCommits: 'disabled' };
-      res = configMigration.migrateConfig(config);
-      expect(res.isMigrated).toBeFalse();
-      expect(res.migratedConfig).toMatchObject({ semanticCommits: 'disabled' });
-    });
 
     it('it migrates preset strings to array', () => {
       let config: TestRenovateConfig;
diff --git a/lib/config/migration.ts b/lib/config/migration.ts
index b0af7ad93f3b01381a52458693a1b2897c6b5543..bd7f996119bcd8302bd449be0fcd0bd2e1b968fd 100644
--- a/lib/config/migration.ts
+++ b/lib/config/migration.ts
@@ -68,19 +68,6 @@ export function migrateConfig(
           migratedConfig[newKey] = true;
         }
         delete migratedConfig[key];
-      } else if (key === 'semanticCommits') {
-        if (val === true) {
-          migratedConfig.semanticCommits = 'enabled';
-        } else if (val === false) {
-          migratedConfig.semanticCommits = 'disabled';
-        } else if (val !== 'enabled' && val !== 'disabled') {
-          migratedConfig.semanticCommits = 'auto';
-        }
-      } else if (key === 'enabledManagers' && is.array(val)) {
-        // Replace yarn with npm, since yarn actually uses npm as package manager
-        migratedConfig.enabledManagers = migratedConfig.enabledManagers.map(
-          (element) => (element === 'yarn' ? 'npm' : element)
-        );
       } else if (parentKey === 'hostRules' && key === 'platform') {
         migratedConfig.hostType = val;
         delete migratedConfig.platform;
@@ -150,13 +137,6 @@ export function migrateConfig(
         delete depTypePackageRule.packageRules;
         migratedConfig.packageRules.push(depTypePackageRule);
         delete migratedConfig[key];
-      } else if (key === 'pinVersions') {
-        delete migratedConfig.pinVersions;
-        if (val === true) {
-          migratedConfig.rangeStrategy = 'pin';
-        } else if (val === false) {
-          migratedConfig.rangeStrategy = 'replace';
-        }
       } else if (is.string(val) && val.includes('{{baseDir}}')) {
         migratedConfig[key] = val.replace(
           regEx(/{{baseDir}}/g),
@@ -169,24 +149,6 @@ export function migrateConfig(
         );
       } else if (key === 'gitFs') {
         delete migratedConfig.gitFs;
-      } else if (key === 'rebaseStalePrs') {
-        delete migratedConfig.rebaseStalePrs;
-        if (!migratedConfig.rebaseWhen) {
-          if (val === null) {
-            migratedConfig.rebaseWhen = 'auto';
-          }
-          if (val === true) {
-            migratedConfig.rebaseWhen = 'behind-base-branch';
-          }
-          if (val === false) {
-            migratedConfig.rebaseWhen = 'conflicted';
-          }
-        }
-      } else if (key === 'rebaseConflictedPrs') {
-        delete migratedConfig.rebaseConflictedPrs;
-        if (val === false) {
-          migratedConfig.rebaseWhen = 'never';
-        }
       } else if (key === 'ignoreNpmrcFile') {
         delete migratedConfig.ignoreNpmrcFile;
         if (!is.string(migratedConfig.npmrc)) {
diff --git a/lib/config/migrations/custom/enabled-managers-migration.spec.ts b/lib/config/migrations/custom/enabled-managers-migration.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b9cdf711a78946027a77b94ec29c55126b239e4b
--- /dev/null
+++ b/lib/config/migrations/custom/enabled-managers-migration.spec.ts
@@ -0,0 +1,14 @@
+import { EnabledManagersMigration } from './enabled-managers-migration';
+
+describe('config/migrations/custom/enabled-managers-migration', () => {
+  it('should replace yarn with npm', () => {
+    expect(EnabledManagersMigration).toMigrate(
+      {
+        enabledManagers: ['test1', 'yarn', 'test2'],
+      },
+      {
+        enabledManagers: ['test1', 'npm', 'test2'],
+      }
+    );
+  });
+});
diff --git a/lib/config/migrations/custom/enabled-managers-migration.ts b/lib/config/migrations/custom/enabled-managers-migration.ts
new file mode 100644
index 0000000000000000000000000000000000000000..0841b68e07140cbbce6a428fc9d27acbb0f55c4d
--- /dev/null
+++ b/lib/config/migrations/custom/enabled-managers-migration.ts
@@ -0,0 +1,15 @@
+import is from '@sindresorhus/is';
+import { AbstractMigration } from '../base/abstract-migration';
+
+export class EnabledManagersMigration extends AbstractMigration {
+  readonly propertyName = 'enabledManagers';
+
+  override run(value: string[]): void {
+    if (is.array(value)) {
+      const newValue = value.map((manager) =>
+        manager === 'yarn' ? 'npm' : manager
+      );
+      this.rewrite(newValue);
+    }
+  }
+}
diff --git a/lib/config/migrations/custom/pin-versions-migration.spec.ts b/lib/config/migrations/custom/pin-versions-migration.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c3f339a853c1a16a8aacc5c4591af3921dfcf9f9
--- /dev/null
+++ b/lib/config/migrations/custom/pin-versions-migration.spec.ts
@@ -0,0 +1,25 @@
+import { PinVersionsMigration } from './pin-versions-migration';
+
+describe('config/migrations/custom/pin-versions-migration', () => {
+  it('should migrate true', () => {
+    expect(PinVersionsMigration).toMigrate(
+      {
+        pinVersions: true,
+      },
+      {
+        rangeStrategy: 'pin',
+      }
+    );
+  });
+
+  it('should migrate false', () => {
+    expect(PinVersionsMigration).toMigrate(
+      {
+        pinVersions: false,
+      },
+      {
+        rangeStrategy: 'replace',
+      }
+    );
+  });
+});
diff --git a/lib/config/migrations/custom/pin-versions-migration.ts b/lib/config/migrations/custom/pin-versions-migration.ts
new file mode 100644
index 0000000000000000000000000000000000000000..1e6bf5e2621a6bc964119c4bf743e0c163c916d9
--- /dev/null
+++ b/lib/config/migrations/custom/pin-versions-migration.ts
@@ -0,0 +1,13 @@
+import is from '@sindresorhus/is';
+import { AbstractMigration } from '../base/abstract-migration';
+
+export class PinVersionsMigration extends AbstractMigration {
+  override readonly deprecated = true;
+  readonly propertyName = 'pinVersions';
+
+  override run(value): void {
+    if (is.boolean(value)) {
+      this.setSafely('rangeStrategy', value ? 'pin' : 'replace');
+    }
+  }
+}
diff --git a/lib/config/migrations/custom/rebase-conflicted-prs-migration.spec.ts b/lib/config/migrations/custom/rebase-conflicted-prs-migration.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..a237f6feaf58583412d5bc86e32aa33dd319a139
--- /dev/null
+++ b/lib/config/migrations/custom/rebase-conflicted-prs-migration.spec.ts
@@ -0,0 +1,14 @@
+import { RebaseConflictedPrs } from './rebase-conflicted-prs-migration';
+
+describe('config/migrations/custom/rebase-conflicted-prs-migration', () => {
+  it('should migrate false', () => {
+    expect(RebaseConflictedPrs).toMigrate(
+      {
+        rebaseConflictedPrs: false,
+      },
+      {
+        rebaseWhen: 'never',
+      }
+    );
+  });
+});
diff --git a/lib/config/migrations/custom/rebase-conflicted-prs-migration.ts b/lib/config/migrations/custom/rebase-conflicted-prs-migration.ts
new file mode 100644
index 0000000000000000000000000000000000000000..388d8d7dd1f5e1e2ee44a0903f910781329862bf
--- /dev/null
+++ b/lib/config/migrations/custom/rebase-conflicted-prs-migration.ts
@@ -0,0 +1,12 @@
+import { AbstractMigration } from '../base/abstract-migration';
+
+export class RebaseConflictedPrs extends AbstractMigration {
+  override readonly deprecated = true;
+  readonly propertyName = 'rebaseConflictedPrs';
+
+  override run(value): void {
+    if (value === false) {
+      this.setSafely('rebaseWhen', 'never');
+    }
+  }
+}
diff --git a/lib/config/migrations/custom/rebase-stale-prs-migration.spec.ts b/lib/config/migrations/custom/rebase-stale-prs-migration.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..ab2c0772d9e798bd4205f0f546bfb132b81c9706
--- /dev/null
+++ b/lib/config/migrations/custom/rebase-stale-prs-migration.spec.ts
@@ -0,0 +1,36 @@
+import { RebaseStalePrsMigration } from './rebase-stale-prs-migration';
+
+describe('config/migrations/custom/rebase-stale-prs-migration', () => {
+  it('should migrate true', () => {
+    expect(RebaseStalePrsMigration).toMigrate(
+      {
+        rebaseStalePrs: true,
+      },
+      {
+        rebaseWhen: 'behind-base-branch',
+      }
+    );
+  });
+
+  it('should migrate false', () => {
+    expect(RebaseStalePrsMigration).toMigrate(
+      {
+        rebaseStalePrs: false,
+      },
+      {
+        rebaseWhen: 'conflicted',
+      }
+    );
+  });
+
+  it('should migrate null', () => {
+    expect(RebaseStalePrsMigration).toMigrate(
+      {
+        rebaseStalePrs: null,
+      },
+      {
+        rebaseWhen: 'auto',
+      }
+    );
+  });
+});
diff --git a/lib/config/migrations/custom/rebase-stale-prs-migration.ts b/lib/config/migrations/custom/rebase-stale-prs-migration.ts
new file mode 100644
index 0000000000000000000000000000000000000000..27e68d382d83351ac1b983980f16b575df996de4
--- /dev/null
+++ b/lib/config/migrations/custom/rebase-stale-prs-migration.ts
@@ -0,0 +1,24 @@
+import is from '@sindresorhus/is';
+import { AbstractMigration } from '../base/abstract-migration';
+
+export class RebaseStalePrsMigration extends AbstractMigration {
+  override readonly deprecated = true;
+  readonly propertyName = 'rebaseStalePrs';
+
+  override run(value): void {
+    const rebaseConflictedPrs = this.get('rebaseConflictedPrs');
+
+    if (rebaseConflictedPrs !== false) {
+      if (is.boolean(value)) {
+        this.setSafely(
+          'rebaseWhen',
+          value ? 'behind-base-branch' : 'conflicted'
+        );
+      }
+
+      if (is.null_(value)) {
+        this.setSafely('rebaseWhen', 'auto');
+      }
+    }
+  }
+}
diff --git a/lib/config/migrations/custom/semantic-commits-migration.spec.ts b/lib/config/migrations/custom/semantic-commits-migration.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..89de9d07f483bafba604b2d19ac8ed5ecdb6583f
--- /dev/null
+++ b/lib/config/migrations/custom/semantic-commits-migration.spec.ts
@@ -0,0 +1,59 @@
+import { SemanticCommitsMigration } from './semantic-commits-migration';
+
+describe('config/migrations/custom/semantic-commits-migration', () => {
+  it('should migrate true to "enabled"', () => {
+    expect(SemanticCommitsMigration).toMigrate(
+      {
+        semanticCommits: true,
+      } as any,
+      { semanticCommits: 'enabled' }
+    );
+  });
+
+  it('should migrate false to "disabled"', () => {
+    expect(SemanticCommitsMigration).toMigrate(
+      {
+        semanticCommits: false,
+      } as any,
+      { semanticCommits: 'disabled' }
+    );
+  });
+
+  it('should migrate null to "auto"', () => {
+    expect(SemanticCommitsMigration).toMigrate(
+      {
+        semanticCommits: null,
+      } as any,
+      { semanticCommits: 'auto' }
+    );
+  });
+
+  it('should migrate random string to "auto"', () => {
+    expect(SemanticCommitsMigration).toMigrate(
+      {
+        semanticCommits: 'test',
+      } as any,
+      { semanticCommits: 'auto' }
+    );
+  });
+
+  it('should not migrate valid enabled config', () => {
+    expect(SemanticCommitsMigration).toMigrate(
+      {
+        semanticCommits: 'enabled',
+      } as any,
+      { semanticCommits: 'enabled' },
+      false
+    );
+  });
+
+  it('should not migrate valid disabled config', () => {
+    expect(SemanticCommitsMigration).toMigrate(
+      {
+        semanticCommits: 'disabled',
+      } as any,
+      { semanticCommits: 'disabled' },
+      false
+    );
+  });
+});
diff --git a/lib/config/migrations/custom/semantic-commits-migration.ts b/lib/config/migrations/custom/semantic-commits-migration.ts
new file mode 100644
index 0000000000000000000000000000000000000000..6deab7ad75d811cf73c9ba899945ca0fd448a982
--- /dev/null
+++ b/lib/config/migrations/custom/semantic-commits-migration.ts
@@ -0,0 +1,14 @@
+import is from '@sindresorhus/is';
+import { AbstractMigration } from '../base/abstract-migration';
+
+export class SemanticCommitsMigration extends AbstractMigration {
+  readonly propertyName = 'semanticCommits';
+
+  override run(value): void {
+    if (is.boolean(value)) {
+      this.rewrite(value ? 'enabled' : 'disabled');
+    } else if (value !== 'enabled' && value !== 'disabled') {
+      this.rewrite('auto');
+    }
+  }
+}
diff --git a/lib/config/migrations/migrations-service.ts b/lib/config/migrations/migrations-service.ts
index f4abee1004966931822410e6c54f1b0753ff0e10..5286e417e5671a1a81e39c404e6ce9e88bd4568f 100644
--- a/lib/config/migrations/migrations-service.ts
+++ b/lib/config/migrations/migrations-service.ts
@@ -3,9 +3,14 @@ import type { RenovateConfig } from '../types';
 import { RemovePropertyMigration } from './base/remove-property-migration';
 import { RenamePropertyMigration } from './base/rename-property-migration';
 import { BinarySourceMigration } from './custom/binary-source-migration';
+import { EnabledManagersMigration } from './custom/enabled-managers-migration';
 import { GoModTidyMigration } from './custom/go-mod-tidy-migration';
 import { IgnoreNodeModulesMigration } from './custom/ignore-node-modules-migration';
+import { PinVersionsMigration } from './custom/pin-versions-migration';
+import { RebaseConflictedPrs } from './custom/rebase-conflicted-prs-migration';
+import { RebaseStalePrsMigration } from './custom/rebase-stale-prs-migration';
 import { RequiredStatusChecksMigration } from './custom/required-status-checks-migration';
+import { SemanticCommitsMigration } from './custom/semantic-commits-migration';
 import { TrustLevelMigration } from './custom/trust-level-migration';
 import type { Migration, MigrationConstructor } from './types';
 
@@ -37,9 +42,14 @@ export class MigrationsService {
 
   static readonly customMigrations: ReadonlyArray<MigrationConstructor> = [
     BinarySourceMigration,
+    EnabledManagersMigration,
     GoModTidyMigration,
     IgnoreNodeModulesMigration,
+    PinVersionsMigration,
+    RebaseConflictedPrs,
+    RebaseStalePrsMigration,
     RequiredStatusChecksMigration,
+    SemanticCommitsMigration,
     TrustLevelMigration,
   ];