diff --git a/lib/config/common.ts b/lib/config/common.ts index dd60f538c24fbe378211a6349cb483f9e758463c..4348a5d319680dd45b15ef1a9d628b6bf1548d31 100644 --- a/lib/config/common.ts +++ b/lib/config/common.ts @@ -52,7 +52,7 @@ export interface RenovateSharedConfig { repositoryCache?: RepositoryCacheConfig; requiredStatusChecks?: string[]; schedule?: string[]; - semanticCommits?: boolean; + semanticCommits?: 'auto' | 'enabled' | 'disabled'; semanticCommitScope?: string; semanticCommitType?: string; suppressNotifications?: string[]; diff --git a/lib/config/definitions.ts b/lib/config/definitions.ts index 6e0338c7a81f9e3137b193426d44f92a77482e8f..ed3cfe4617dc713b861c96be8b0f54c397701f71 100644 --- a/lib/config/definitions.ts +++ b/lib/config/definitions.ts @@ -1084,8 +1084,9 @@ const options: RenovateOptions[] = [ { name: 'semanticCommits', description: 'Enable semantic commit prefixes for commits and PR titles', - type: 'boolean', - default: null, + type: 'string', + allowedValues: ['auto', 'enabled', 'disabled'], + default: 'auto', }, { name: 'semanticCommitType', diff --git a/lib/config/migration.spec.ts b/lib/config/migration.spec.ts index b81057b142c8dd7c10edf13cd416606964529634..3ff1e01cef65ebb77fabbd4ebf6e28d7feb45d4f 100644 --- a/lib/config/migration.spec.ts +++ b/lib/config/migration.spec.ts @@ -1,6 +1,7 @@ import { PLATFORM_TYPE_GITHUB } from '../constants/platforms'; import { getConfig } from './defaults'; import * as configMigration from './migration'; +import { MigratedConfig } from './migration'; import { RenovateSharedConfig, RenovateConfig as _RenovateConfig } from '.'; const defaultConfig = getConfig(); @@ -129,7 +130,7 @@ describe('config/migration', () => { ], raiseDeprecationWarnings: false, }; - const parentConfig = { ...defaultConfig, semanticCommits: false }; + const parentConfig = { ...defaultConfig, semanticCommits: 'disabled' }; const { isMigrated, migratedConfig } = configMigration.migrateConfig( config, parentConfig @@ -269,7 +270,6 @@ describe('config/migration', () => { it('does not migrate config', () => { const config: RenovateConfig = { enabled: true, - semanticCommits: true, separateMinorPatch: true, }; const { isMigrated, migratedConfig } = configMigration.migrateConfig( @@ -403,5 +403,24 @@ describe('config/migration', () => { expect(migratedConfig).toMatchSnapshot(); expect(isMigrated).toBe(true); }); + it('it migrates semanticCommits', () => { + let config: RenovateConfig; + let res: MigratedConfig; + + config = { semanticCommits: true as never }; + res = configMigration.migrateConfig(config); + expect(res.isMigrated).toBe(true); + expect(res.migratedConfig).toMatchObject({ semanticCommits: 'enabled' }); + + config = { semanticCommits: false as never }; + res = configMigration.migrateConfig(config); + expect(res.isMigrated).toBe(true); + expect(res.migratedConfig).toMatchObject({ semanticCommits: 'disabled' }); + + config = { semanticCommits: null as never }; + res = configMigration.migrateConfig(config); + expect(res.isMigrated).toBe(true); + expect(res.migratedConfig).toMatchObject({ semanticCommits: 'auto' }); + }); }); }); diff --git a/lib/config/migration.ts b/lib/config/migration.ts index e1aa1ab235dfd1aba02bb38f2bc87ae609a34ed1..9791fff3229dfbb538668b37a4309954df5b0690 100644 --- a/lib/config/migration.ts +++ b/lib/config/migration.ts @@ -101,6 +101,15 @@ export function migrateConfig( migratedConfig.postUpdateOptions.push('gomodTidy'); } delete migratedConfig.gomodTidy; + } else if (key === 'semanticCommits') { + isMigrated = true; + if (val === true) { + migratedConfig.semanticCommits = 'enabled'; + } else if (val === false) { + migratedConfig.semanticCommits = 'disabled'; + } else { + migratedConfig.semanticCommits = 'auto'; + } } else if (parentKey === 'hostRules' && key === 'platform') { isMigrated = true; migratedConfig.hostType = val; diff --git a/lib/config/presets/__snapshots__/index.spec.ts.snap b/lib/config/presets/__snapshots__/index.spec.ts.snap index 2156450ef059c8dc713c2e3578c1949843a01b18..f96377310cc9c43debfecb29cdb9631707d4ee95 100644 --- a/lib/config/presets/__snapshots__/index.spec.ts.snap +++ b/lib/config/presets/__snapshots__/index.spec.ts.snap @@ -393,7 +393,7 @@ Object { "schedule": Array [ "before 8am", ], - "semanticCommits": true, + "semanticCommits": "enabled", "separateMajorMinor": true, "separateMinorPatch": false, "timezone": "Asia/Taipei", diff --git a/lib/config/presets/internal/default.ts b/lib/config/presets/internal/default.ts index f45ba82d608de502e378deebcb00515b2ce4079f..dbdc507686aaf8e22f26be410fe0d6aaf8ee55a1 100644 --- a/lib/config/presets/internal/default.ts +++ b/lib/config/presets/internal/default.ts @@ -510,11 +510,11 @@ export const presets: Record<string, Preset> = { }, semanticCommits: { description: 'Use semantic prefixes for commit messages and PR titles', - semanticCommits: true, + semanticCommits: 'enabled', }, semanticCommitsDisabled: { description: 'Disable semantic prefixes for commit messages and PR titles', - semanticCommits: false, + semanticCommits: 'disabled', }, disableLockFiles: { description: 'Disable lock file updates', diff --git a/lib/workers/branch/commit.spec.ts b/lib/workers/branch/commit.spec.ts index 65add63e6f921604314e17eecca44cd327325094..bd559cb48d44a73be3b6ae636481aa10992492e9 100644 --- a/lib/workers/branch/commit.spec.ts +++ b/lib/workers/branch/commit.spec.ts @@ -12,7 +12,7 @@ describe('workers/branch/automerge', () => { ...defaultConfig, branchName: 'renovate/some-branch', commitMessage: 'some commit message', - semanticCommits: false, + semanticCommits: 'disabled', semanticCommitType: 'a', semanticCommitScope: 'b', updatedPackageFiles: [], diff --git a/lib/workers/repository/init/config.ts b/lib/workers/repository/init/config.ts index 0422ae6acf3fa985360bc40e47033c4bffbf04fe..c59dfd80f201106d812469b1ea2ef3a8e4293d28 100644 --- a/lib/workers/repository/init/config.ts +++ b/lib/workers/repository/init/config.ts @@ -222,7 +222,8 @@ export async function getRepoConfig( config.baseBranch = config.defaultBranch; config = await checkOnboardingBranch(config); config = await mergeRenovateConfig(config); - config.semanticCommits = - config.semanticCommits ?? (await detectSemanticCommits()); + if (config.semanticCommits === 'auto') { + config.semanticCommits = await detectSemanticCommits(); + } return config; } diff --git a/lib/workers/repository/init/semantic.spec.ts b/lib/workers/repository/init/semantic.spec.ts index 433a21d5254c1aebcc990dea24244b9a5ff48a90..0a5b37fdd8e10286ba672a2813605065ce93dd81 100644 --- a/lib/workers/repository/init/semantic.spec.ts +++ b/lib/workers/repository/init/semantic.spec.ts @@ -17,13 +17,13 @@ describe('workers/repository/init/semantic', () => { config.semanticCommits = null; git.getCommitMessages.mockResolvedValue(['foo', 'bar']); const res = await detectSemanticCommits(); - expect(res).toBe(false); + expect(res).toBe('disabled'); }); it('detects true if known', async () => { config.semanticCommits = null; git.getCommitMessages.mockResolvedValue(['fix: foo', 'refactor: bar']); const res = await detectSemanticCommits(); - expect(res).toBe(true); + expect(res).toBe('enabled'); }); }); }); diff --git a/lib/workers/repository/init/semantic.ts b/lib/workers/repository/init/semantic.ts index f9b74b62fd4eb12a328d8530edfe90e75d454f2b..62816e63e563411d47a01ea6ae525534b4743f0b 100644 --- a/lib/workers/repository/init/semantic.ts +++ b/lib/workers/repository/init/semantic.ts @@ -2,7 +2,9 @@ import conventionalCommitsDetector from 'conventional-commits-detector'; import { logger } from '../../../logger'; import { getCommitMessages } from '../../../util/git'; -export async function detectSemanticCommits(): Promise<boolean> { +type DetectedSemanticCommit = 'enabled' | 'disabled'; + +export async function detectSemanticCommits(): Promise<DetectedSemanticCommit> { logger.debug('detectSemanticCommits()'); const commitMessages = await getCommitMessages(); logger.trace(`commitMessages=${JSON.stringify(commitMessages)}`); @@ -10,8 +12,8 @@ export async function detectSemanticCommits(): Promise<boolean> { logger.debug('Semantic commits detection: ' + type); if (type === 'angular') { logger.debug('angular semantic commits detected'); - return true; + return 'enabled'; } logger.debug('No semantic commits detected'); - return false; + return 'disabled'; } diff --git a/lib/workers/repository/onboarding/branch/create.spec.ts b/lib/workers/repository/onboarding/branch/create.spec.ts index 282a88965b1a0b9a1212159351d5307cd7c72820..410f42bcc43c87e6abc72fdb5549d23d23cc4427 100644 --- a/lib/workers/repository/onboarding/branch/create.spec.ts +++ b/lib/workers/repository/onboarding/branch/create.spec.ts @@ -72,7 +72,7 @@ describe('workers/repository/onboarding/branch', () => { describe('applies semanticCommit prefix', () => { it('to the default commit message', async () => { const prefix = 'chore(deps)'; - config.semanticCommits = true; + config.semanticCommits = 'enabled'; await createOnboardingBranch(config); expect(commitFiles).toHaveBeenCalledWith( buildExpectedCommitFilesArgument( @@ -84,7 +84,7 @@ describe('workers/repository/onboarding/branch', () => { const prefix = 'chore(deps)'; const message = 'I say, we can update when we want to, a commit they will never mind'; - config.semanticCommits = true; + config.semanticCommits = 'enabled'; config.onboardingCommitMessage = message; await createOnboardingBranch(config); expect(commitFiles).toHaveBeenCalledWith( diff --git a/lib/workers/repository/onboarding/branch/create.ts b/lib/workers/repository/onboarding/branch/create.ts index 1777fc57a1e4e251db3c9cd79281ef8176817e42..e1792c357be2e7a7b984e14667b912ce4a6cc35f 100644 --- a/lib/workers/repository/onboarding/branch/create.ts +++ b/lib/workers/repository/onboarding/branch/create.ts @@ -17,7 +17,7 @@ export function createOnboardingBranch( let commitMessagePrefix = ''; if (config.commitMessagePrefix) { commitMessagePrefix = config.commitMessagePrefix; - } else if (config.semanticCommits) { + } else if (config.semanticCommits === 'enabled') { commitMessagePrefix = config.semanticCommitType; if (config.semanticCommitScope) { commitMessagePrefix += `(${config.semanticCommitScope})`; diff --git a/lib/workers/repository/onboarding/branch/rebase.ts b/lib/workers/repository/onboarding/branch/rebase.ts index 73096472eef18980244d24bf781c64313c1729f8..57fb9d034b9a8c6abe6ad9738c548d736c026b94 100644 --- a/lib/workers/repository/onboarding/branch/rebase.ts +++ b/lib/workers/repository/onboarding/branch/rebase.ts @@ -14,7 +14,7 @@ const defaultConfigFile = configFileNames[0]; function getCommitMessage(config: RenovateConfig): string { let commitMessage: string; // istanbul ignore if - if (config.semanticCommits) { + if (config.semanticCommits === 'enabled') { commitMessage = config.semanticCommitType; if (config.semanticCommitScope) { commitMessage += `(${config.semanticCommitScope})`; diff --git a/lib/workers/repository/updates/generate.spec.ts b/lib/workers/repository/updates/generate.spec.ts index 79e81a8cbc6b7b02b4f160e394687ab5fd2cf2a9..4317e68d2db3221cd39bb1739be19cf6a3534a47 100644 --- a/lib/workers/repository/updates/generate.spec.ts +++ b/lib/workers/repository/updates/generate.spec.ts @@ -219,7 +219,7 @@ describe('workers/repository/updates/generate', () => { partial<BranchUpgradeConfig>({ ...defaultConfig, depName: 'some-dep', - semanticCommits: true, + semanticCommits: 'enabled', semanticCommitType: 'chore', semanticCommitScope: 'package', newValue: '1.2.0', @@ -243,7 +243,7 @@ describe('workers/repository/updates/generate', () => { depName: 'some-dep', packageFile: 'package.json', baseDir: '', - semanticCommits: true, + semanticCommits: 'enabled', semanticCommitType: 'chore', semanticCommitScope: '{{baseDir}}', newValue: '1.2.0', @@ -268,7 +268,7 @@ describe('workers/repository/updates/generate', () => { depName: 'some-dep', packageFile: 'foo/bar/package.json', parentDir: 'bar', - semanticCommits: true, + semanticCommits: 'enabled', semanticCommitType: 'chore', semanticCommitScope: '{{parentDir}}', newValue: '1.2.0', @@ -292,7 +292,7 @@ describe('workers/repository/updates/generate', () => { depName: 'some-dep', packageFile: 'foo/bar/package.json', baseDir: 'foo/bar', - semanticCommits: true, + semanticCommits: 'enabled', semanticCommitType: 'chore', semanticCommitScope: '{{baseDir}}', newValue: '1.2.0', diff --git a/lib/workers/repository/updates/generate.ts b/lib/workers/repository/updates/generate.ts index e115b0a19469f18ffd53823356b932cb1b576b67..a53c3a4909c279b990324a4717a3bc2fa53f468f 100644 --- a/lib/workers/repository/updates/generate.ts +++ b/lib/workers/repository/updates/generate.ts @@ -173,7 +173,7 @@ export function generateBranchConfig( upgrade.isRange = false; } // Use templates to generate strings - if (upgrade.semanticCommits && !upgrade.commitMessagePrefix) { + if (upgrade.semanticCommits === 'enabled' && !upgrade.commitMessagePrefix) { logger.trace('Upgrade has semantic commits enabled'); let semanticPrefix = upgrade.semanticCommitType; if (upgrade.semanticCommitScope) {