From 67a8fe519d59c7a2919b5e1340e16d1566341272 Mon Sep 17 00:00:00 2001 From: jparnone <joseph.arnone@gmail.com> Date: Wed, 26 Aug 2020 09:00:45 -0400 Subject: [PATCH] feat(config): Added option "onboardingCommitMessage" (#6997) Co-authored-by: Rhys Arkins <rhys@arkins.net> --- docs/usage/self-hosted-configuration.md | 4 + lib/config/common.ts | 2 + lib/config/definitions.ts | 9 ++ .../onboarding/branch/create.spec.ts | 98 +++++++++++++++++++ .../repository/onboarding/branch/create.ts | 30 ++++-- lib/workers/repository/updates/generate.ts | 4 +- .../repository/util/commit-message.spec.ts | 40 ++++++++ lib/workers/repository/util/commit-message.ts | 11 +++ 8 files changed, 188 insertions(+), 10 deletions(-) create mode 100644 lib/workers/repository/onboarding/branch/create.spec.ts create mode 100644 lib/workers/repository/util/commit-message.spec.ts create mode 100644 lib/workers/repository/util/commit-message.ts diff --git a/docs/usage/self-hosted-configuration.md b/docs/usage/self-hosted-configuration.md index 3a1f3ba379..5d9d208e8c 100644 --- a/docs/usage/self-hosted-configuration.md +++ b/docs/usage/self-hosted-configuration.md @@ -110,6 +110,10 @@ Set this to `false` if (a) you configure Renovate entirely on the bot side (i.e. Note that this setting is independent of `branchPrefix`. For example, if you configure `branchPrefix` to be `renovate-` then you'd still have the onboarding PR created with branch `renovate/configure` until you configure `onboardingBranch=renovate-configure` or similar. If you have an existing Renovate installation and you change `onboardingBranch` then it's possible that you'll get onboarding PRs for repositories that had previously closed the onboarding PR unmerged. +## onboardingCommitMessage + +Note that if `commitMessagePrefix` or `semanticCommits` values are defined then they will be prepended to the commit message using the same logic that is used for adding them to non-onboarding commit messages. + ## onboardingConfig ## onboardingPrTitle diff --git a/lib/config/common.ts b/lib/config/common.ts index f09944becb..8bce196e2b 100644 --- a/lib/config/common.ts +++ b/lib/config/common.ts @@ -23,6 +23,7 @@ export interface RenovateSharedConfig { branchName?: string; manager?: string; commitMessage?: string; + commitMessagePrefix?: string; draftPR?: boolean; enabled?: boolean; enabledManagers?: string[]; @@ -86,6 +87,7 @@ export interface RenovateAdminConfig { onboarding?: boolean; onboardingBranch?: string; + onboardingCommitMessage?: string; onboardingPrTitle?: string; onboardingConfig?: RenovateSharedConfig; diff --git a/lib/config/definitions.ts b/lib/config/definitions.ts index 6a90038328..c16b0d498c 100644 --- a/lib/config/definitions.ts +++ b/lib/config/definitions.ts @@ -140,6 +140,15 @@ const options: RenovateOptions[] = [ admin: true, cli: false, }, + { + name: 'onboardingCommitMessage', + description: + 'Change this value in order to override the default onboarding commit message.', + type: 'string', + default: null, + admin: true, + cli: false, + }, { name: 'onboardingPrTitle', description: diff --git a/lib/workers/repository/onboarding/branch/create.spec.ts b/lib/workers/repository/onboarding/branch/create.spec.ts new file mode 100644 index 0000000000..282a88965b --- /dev/null +++ b/lib/workers/repository/onboarding/branch/create.spec.ts @@ -0,0 +1,98 @@ +import { RenovateConfig, getConfig } from '../../../../../test/util'; +import { commitFiles } from '../../../../util/git'; +import { COMMIT_MESSAGE_PREFIX_SEPARATOR } from '../../util/commit-message'; +import { createOnboardingBranch } from './create'; + +jest.mock('../../../../util/git'); +jest.mock('./config', () => ({ + getOnboardingConfig: () => + JSON.stringify({ + foo: 'bar', + }), +})); + +const buildExpectedCommitFilesArgument = (message: string) => ({ + branchName: 'renovate/configure', + files: [ + { + name: 'renovate.json', + contents: '{"foo":"bar"}', + }, + ], + message, +}); + +describe('workers/repository/onboarding/branch', () => { + let config: RenovateConfig; + beforeEach(() => { + jest.clearAllMocks(); + config = getConfig(); + }); + describe('createOnboardingBranch', () => { + it('applies the default commit message', async () => { + await createOnboardingBranch(config); + expect(commitFiles).toHaveBeenCalledWith( + buildExpectedCommitFilesArgument('Add renovate.json') + ); + }); + it('applies supplied commit message', async () => { + const message = + 'We can Renovate if we want to, we can leave PRs in decline'; + config.onboardingCommitMessage = message; + await createOnboardingBranch(config); + expect(commitFiles).toHaveBeenCalledWith( + buildExpectedCommitFilesArgument(`${message}`) + ); + }); + describe('applies the commitMessagePrefix value', () => { + it('to the default commit message', async () => { + const prefix = 'RENOV-123'; + config.commitMessagePrefix = prefix; + await createOnboardingBranch(config); + expect(commitFiles).toHaveBeenCalledWith( + buildExpectedCommitFilesArgument( + `${prefix}${COMMIT_MESSAGE_PREFIX_SEPARATOR} add renovate.json` + ) + ); + }); + it('to the supplied commit message', async () => { + const prefix = 'RENOV-123'; + const message = + "Cause your deps need an update and if they dont update, well they're no deps of mine"; + config.commitMessagePrefix = prefix; + config.onboardingCommitMessage = message; + await createOnboardingBranch(config); + expect(commitFiles).toHaveBeenCalledWith( + buildExpectedCommitFilesArgument( + `${prefix}${COMMIT_MESSAGE_PREFIX_SEPARATOR} ${message}` + ) + ); + }); + }); + describe('applies semanticCommit prefix', () => { + it('to the default commit message', async () => { + const prefix = 'chore(deps)'; + config.semanticCommits = true; + await createOnboardingBranch(config); + expect(commitFiles).toHaveBeenCalledWith( + buildExpectedCommitFilesArgument( + `${prefix}${COMMIT_MESSAGE_PREFIX_SEPARATOR} add renovate.json` + ) + ); + }); + it('to the supplied commit message', async () => { + 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.onboardingCommitMessage = message; + await createOnboardingBranch(config); + expect(commitFiles).toHaveBeenCalledWith( + buildExpectedCommitFilesArgument( + `${prefix}${COMMIT_MESSAGE_PREFIX_SEPARATOR} ${message}` + ) + ); + }); + }); + }); +}); diff --git a/lib/workers/repository/onboarding/branch/create.ts b/lib/workers/repository/onboarding/branch/create.ts index 615e332457..1777fc57a1 100644 --- a/lib/workers/repository/onboarding/branch/create.ts +++ b/lib/workers/repository/onboarding/branch/create.ts @@ -2,6 +2,7 @@ import { RenovateConfig } from '../../../../config'; import { configFileNames } from '../../../../config/app-strings'; import { logger } from '../../../../logger'; import { commitFiles } from '../../../../util/git'; +import { formatCommitMessagePrefix } from '../../util/commit-message'; import { getOnboardingConfig } from './config'; const defaultConfigFile = configFileNames[0]; @@ -12,18 +13,31 @@ export function createOnboardingBranch( logger.debug('createOnboardingBranch()'); const contents = getOnboardingConfig(config); logger.debug('Creating onboarding branch'); - let commitMessage; - // istanbul ignore if - if (config.semanticCommits) { - commitMessage = config.semanticCommitType; + + let commitMessagePrefix = ''; + if (config.commitMessagePrefix) { + commitMessagePrefix = config.commitMessagePrefix; + } else if (config.semanticCommits) { + commitMessagePrefix = config.semanticCommitType; if (config.semanticCommitScope) { - commitMessage += `(${config.semanticCommitScope})`; + commitMessagePrefix += `(${config.semanticCommitScope})`; } - commitMessage += ': '; - commitMessage += 'add ' + defaultConfigFile; + } + if (commitMessagePrefix) { + commitMessagePrefix = formatCommitMessagePrefix(commitMessagePrefix); + } + + let onboardingCommitMessage: string; + if (config.onboardingCommitMessage) { + onboardingCommitMessage = config.onboardingCommitMessage; } else { - commitMessage = 'Add ' + defaultConfigFile; + onboardingCommitMessage = `${ + commitMessagePrefix ? 'add' : 'Add' + } ${defaultConfigFile}`; } + + const commitMessage = `${commitMessagePrefix} ${onboardingCommitMessage}`.trim(); + // istanbul ignore if if (config.dryRun) { logger.info('DRY-RUN: Would commit files to onboarding branch'); diff --git a/lib/workers/repository/updates/generate.ts b/lib/workers/repository/updates/generate.ts index c3c6526793..e115b0a194 100644 --- a/lib/workers/repository/updates/generate.ts +++ b/lib/workers/repository/updates/generate.ts @@ -7,6 +7,7 @@ import { logger } from '../../../logger'; import { sanitize } from '../../../util/sanitize'; import * as template from '../../../util/template'; import { BranchConfig, BranchUpgradeConfig } from '../../common'; +import { formatCommitMessagePrefix } from '../util/commit-message'; function isTypesGroup(branchUpgrades: any[]): boolean { return ( @@ -181,8 +182,7 @@ export function generateBranchConfig( upgrade )})`; } - upgrade.commitMessagePrefix = semanticPrefix; - upgrade.commitMessagePrefix += semanticPrefix.endsWith(':') ? ' ' : ': '; + upgrade.commitMessagePrefix = formatCommitMessagePrefix(semanticPrefix); upgrade.toLowerCase = // eslint-disable-next-line @typescript-eslint/prefer-regexp-exec upgrade.semanticCommitType.match(/[A-Z]/) === null && diff --git a/lib/workers/repository/util/commit-message.spec.ts b/lib/workers/repository/util/commit-message.spec.ts new file mode 100644 index 0000000000..2e04be8f6a --- /dev/null +++ b/lib/workers/repository/util/commit-message.spec.ts @@ -0,0 +1,40 @@ +import { + COMMIT_MESSAGE_PREFIX_SEPARATOR, + formatCommitMessagePrefix, +} from './commit-message'; + +describe('workers/repository/util/commit-message', () => { + describe('COMMIT_MESSAGE_PREFIX_END_CHARACTER', () => { + it('is a colon character', () => { + expect(COMMIT_MESSAGE_PREFIX_SEPARATOR).toBe(':'); + }); + }); + describe('formatCommitMessagePrefix', () => { + it.each([ + [ + 'adds a separator', + 'does not end', + 'RENOV-123', + `RENOV-123${COMMIT_MESSAGE_PREFIX_SEPARATOR}`, + ], + [ + 'does nothing', + 'ends', + `RENOV-123${COMMIT_MESSAGE_PREFIX_SEPARATOR}`, + `RENOV-123${COMMIT_MESSAGE_PREFIX_SEPARATOR}`, + ], + ])( + '%s when the prefix %s with a separator', + ( + expectedAction: string, + endingState: string, + commitMessagePrefix: string, + expectedPrefix: string + ) => { + expect(formatCommitMessagePrefix(commitMessagePrefix)).toBe( + expectedPrefix + ); + } + ); + }); +}); diff --git a/lib/workers/repository/util/commit-message.ts b/lib/workers/repository/util/commit-message.ts new file mode 100644 index 0000000000..014eadda43 --- /dev/null +++ b/lib/workers/repository/util/commit-message.ts @@ -0,0 +1,11 @@ +export const COMMIT_MESSAGE_PREFIX_SEPARATOR = ':'; + +export const formatCommitMessagePrefix = ( + commitMessagePrefix: string +): string => { + return `${commitMessagePrefix}${ + commitMessagePrefix.endsWith(COMMIT_MESSAGE_PREFIX_SEPARATOR) + ? '' + : COMMIT_MESSAGE_PREFIX_SEPARATOR + }`; +}; -- GitLab