aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--docs/usage/configuration-options.md6
-rw-r--r--lib/config/options/index.ts6
-rw-r--r--lib/config/types.ts1
-rw-r--r--lib/workers/repository/updates/branch-name.spec.ts46
-rw-r--r--lib/workers/repository/updates/branch-name.ts25
5 files changed, 80 insertions, 4 deletions
diff --git a/docs/usage/configuration-options.md b/docs/usage/configuration-options.md
index 01e974dd7c0..4b904edbef5 100644
--- a/docs/usage/configuration-options.md
+++ b/docs/usage/configuration-options.md
@@ -287,6 +287,12 @@ If you truly need to configure this then it probably means either:
- You are hopefully mistaken, and there's a better approach you should use, so open a new "config help" discussion at the [Renovate discussions tab](https://github.com/renovatebot/renovate/discussions) or
- You have a use case we didn't expect and we should have a feature request from you to add it to the project
+## branchNameStrict
+
+By default, Renovate does not use strict-mode when slugifying the branch name. This means that certain special characters such as `.` may end up within the branch name.
+
+By setting this configuration to `true`, all special characters will be removed from the branch name, resulting in a branch name consisting exclusively of alphabetic characters separated by `-`.
+
## branchPrefix
You can modify this field if you want to change the prefix used.
diff --git a/lib/config/options/index.ts b/lib/config/options/index.ts
index 66a5b943950..c7911955152 100644
--- a/lib/config/options/index.ts
+++ b/lib/config/options/index.ts
@@ -2352,6 +2352,12 @@ const options: RenovateOptions[] = [
default: false,
supportedPlatforms: ['github'],
},
+ {
+ name: 'branchNameStrict',
+ description: `Whether to be strict about the use of special characters within the branch name.`,
+ type: 'boolean',
+ default: false,
+ },
];
export function getOptions(): RenovateOptions[] {
diff --git a/lib/config/types.ts b/lib/config/types.ts
index f9f53cae4c6..4e11fa6e81d 100644
--- a/lib/config/types.ts
+++ b/lib/config/types.ts
@@ -28,6 +28,7 @@ export interface RenovateSharedConfig {
branchPrefix?: string;
branchPrefixOld?: string;
branchName?: string;
+ branchNameStrict?: boolean;
manager?: string | null;
commitMessage?: string;
commitMessagePrefix?: string;
diff --git a/lib/workers/repository/updates/branch-name.spec.ts b/lib/workers/repository/updates/branch-name.spec.ts
index 93ff3a94ee5..07c368946e8 100644
--- a/lib/workers/repository/updates/branch-name.spec.ts
+++ b/lib/workers/repository/updates/branch-name.spec.ts
@@ -146,6 +146,22 @@ describe('workers/repository/updates/branch-name', () => {
expect(upgrade.branchName).toBe('renovate/jest-42.x');
});
+ it('realistic defaults with strict branch name enabled', () => {
+ const upgrade: RenovateConfig = {
+ branchNameStrict: true,
+ branchName:
+ '{{{branchPrefix}}}{{{additionalBranchPrefix}}}{{{branchTopic}}}',
+ branchTopic:
+ '{{{depNameSanitized}}}-{{{newMajor}}}{{#if isPatch}}.{{{newMinor}}}{{/if}}.x{{#if isLockfileUpdate}}-lockfile{{/if}}',
+ branchPrefix: 'renovate/',
+ depNameSanitized: 'jest',
+ newMajor: '42',
+ group: {},
+ };
+ generateBranchName(upgrade);
+ expect(upgrade.branchName).toBe('renovate/jest-42-x');
+ });
+
it('hashedBranchLength hashing', () => {
const upgrade: RenovateConfig = {
branchName:
@@ -293,5 +309,35 @@ describe('workers/repository/updates/branch-name', () => {
expect(fixture.upgrade.branchName).toEqual(fixture.expectedBranchName);
});
});
+
+ it('strict branch name enabled group', () => {
+ const upgrade: RenovateConfig = {
+ branchNameStrict: true,
+ groupName: 'some group name `~#$%^&*()-_=+[]{}|;,./<>? .version',
+ group: {
+ branchName: '{{groupSlug}}-{{branchTopic}}',
+ branchTopic: 'grouptopic',
+ },
+ };
+ generateBranchName(upgrade);
+ expect(upgrade.branchName).toBe(
+ 'some-group-name-dollarpercentand-or-lessgreater-version-grouptopic'
+ );
+ });
+
+ it('strict branch name disabled', () => {
+ const upgrade: RenovateConfig = {
+ branchNameStrict: false,
+ groupName: '[some] group name.#$%version',
+ group: {
+ branchName: '{{groupSlug}}-{{branchTopic}}',
+ branchTopic: 'grouptopic',
+ },
+ };
+ generateBranchName(upgrade);
+ expect(upgrade.branchName).toBe(
+ 'some-group-name.dollarpercentversion-grouptopic'
+ );
+ });
});
});
diff --git a/lib/workers/repository/updates/branch-name.ts b/lib/workers/repository/updates/branch-name.ts
index da71eae75a1..b88ec208b3d 100644
--- a/lib/workers/repository/updates/branch-name.ts
+++ b/lib/workers/repository/updates/branch-name.ts
@@ -10,6 +10,9 @@ import * as template from '../../../util/template';
const MIN_HASH_LENGTH = 6;
const RE_MULTIPLE_DASH = regEx(/--+/g);
+
+const RE_SPECIAL_CHARS_STRICT = regEx(/[`~!@#$%^&*()_=+[\]\\|{};':",.<>?]/g);
+
/**
* Clean git branch name
*
@@ -17,15 +20,26 @@ const RE_MULTIPLE_DASH = regEx(/--+/g);
* - leading dot/leading dot after slash
* - trailing dot
* - whitespace
+ * - special characters
+ * - leading or trailing dashes
* - chained dashes(breaks markdown comments) are replaced by single dash
*/
-function cleanBranchName(branchName: string): string {
+function cleanBranchName(
+ branchName: string,
+ branchNameStrict?: boolean
+): string {
+ let cleanedBranchName = branchName;
+
+ if (branchNameStrict) {
+ cleanedBranchName = cleanedBranchName.replace(RE_SPECIAL_CHARS_STRICT, '-'); // massage out all special characters that slip through slugify
+ }
+
return cleanGitRef
- .clean(branchName)
+ .clean(cleanedBranchName)
.replace(regEx(/^\.|\.$/), '') // leading or trailing dot
.replace(regEx(/\/\./g), '/') // leading dot after slash
.replace(regEx(/\s/g), '') // whitespace
- .replace(regEx(/[[\]?:\\^~]/g), '-') // massage out all these characters: : ? [ \ ^ ~
+ .replace(regEx(/[[\]?:\\^~]/g), '-') // massage out all these characters: [ ] ? : \ ^ ~
.replace(regEx(/(^|\/)-+/g), '$1') // leading dashes
.replace(regEx(/-+(\/|$)/g), '$1') // trailing dashes
.replace(RE_MULTIPLE_DASH, '-'); // chained dashes
@@ -94,5 +108,8 @@ export function generateBranchName(update: RenovateConfig): void {
update.branchName = template.compile(update.branchName, update);
}
- update.branchName = cleanBranchName(update.branchName);
+ update.branchName = cleanBranchName(
+ update.branchName,
+ update.branchNameStrict
+ );
}