From 8c68b463ac07ee4bb8cd84541b574965029b6c86 Mon Sep 17 00:00:00 2001 From: Adam Setch Date: Tue, 16 Aug 2022 08:22:34 -0400 Subject: [PATCH 01/10] update clean branch name comments --- lib/workers/repository/updates/branch-name.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/workers/repository/updates/branch-name.ts b/lib/workers/repository/updates/branch-name.ts index da71eae75a1d90..a4299dafd6fdde 100644 --- a/lib/workers/repository/updates/branch-name.ts +++ b/lib/workers/repository/updates/branch-name.ts @@ -17,6 +17,8 @@ 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 { @@ -25,7 +27,7 @@ function cleanBranchName(branchName: string): string { .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 From 893af3c54203f49e498dfd8712c6920f1584f5d4 Mon Sep 17 00:00:00 2001 From: Adam Setch Date: Tue, 16 Aug 2022 14:28:07 -0400 Subject: [PATCH 02/10] set slugify to strict Removes any special characters from branch names --- lib/workers/repository/updates/branch-name.spec.ts | 4 ++-- lib/workers/repository/updates/branch-name.ts | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/workers/repository/updates/branch-name.spec.ts b/lib/workers/repository/updates/branch-name.spec.ts index 93ff3a94ee596c..128b63b5fe37de 100644 --- a/lib/workers/repository/updates/branch-name.spec.ts +++ b/lib/workers/repository/updates/branch-name.spec.ts @@ -230,14 +230,14 @@ describe('workers/repository/updates/branch-name', () => { groupName: 'invalid branch name.lock', group: { branchName: 'renovate/{{groupSlug}}' }, }, - expectedBranchName: 'renovate/invalid-branch-name', + expectedBranchName: 'renovate/invalid-branch-namelock', }, { upgrade: { groupName: '.a-bad- name:@.lock', group: { branchName: 'renovate/{{groupSlug}}' }, }, - expectedBranchName: 'renovate/a-bad-name-@', + expectedBranchName: 'renovate/a-bad-namelock', }, { upgrade: { branchName: 'renovate/bad-branch-name1..' }, diff --git a/lib/workers/repository/updates/branch-name.ts b/lib/workers/repository/updates/branch-name.ts index a4299dafd6fdde..e3f727c9982c5d 100644 --- a/lib/workers/repository/updates/branch-name.ts +++ b/lib/workers/repository/updates/branch-name.ts @@ -43,6 +43,7 @@ export function generateBranchName(update: RenovateConfig): void { ); update.groupSlug = slugify(update.groupSlug ?? update.groupName, { lower: true, + strict: true, }); if (update.updateType === 'major' && update.separateMajorMinor) { if (update.separateMultipleMajor) { From 97a8b39aef297da05310efc6c01fbb9dbd3b9ad4 Mon Sep 17 00:00:00 2001 From: Adam Setch Date: Wed, 17 Aug 2022 15:24:17 -0400 Subject: [PATCH 03/10] add strictBranchSlugify configuration option to toggle branch name sluggify strictness --- docs/usage/configuration-options.md | 4 +++ lib/config/options/index.ts | 6 ++++ lib/config/types.ts | 1 + .../repository/updates/branch-name.spec.ts | 34 +++++++++++++++++-- lib/workers/repository/updates/branch-name.ts | 2 +- 5 files changed, 44 insertions(+), 3 deletions(-) diff --git a/docs/usage/configuration-options.md b/docs/usage/configuration-options.md index 0c00279e4b93f4..88a439f7bacb43 100644 --- a/docs/usage/configuration-options.md +++ b/docs/usage/configuration-options.md @@ -2911,3 +2911,7 @@ To disable the vulnerability alerts feature, set `enabled=false` in a `vulnerabi } } ``` + +## strictBranchSlugify + +By default, Renovate does not use strict-mode when slugifying the branch name. To enforce strict-mode and prevent any special characters within the branch name, set this to `true` diff --git a/lib/config/options/index.ts b/lib/config/options/index.ts index 4a0439c8530f3f..8597b1df7aa78b 100644 --- a/lib/config/options/index.ts +++ b/lib/config/options/index.ts @@ -2342,6 +2342,12 @@ const options: RenovateOptions[] = [ default: false, supportedPlatforms: ['github'], }, + { + name: 'strictBranchSlugify', + description: `Whether to be strict about the use of special characters in the branch name.`, + type: 'boolean', + default: false, + }, ]; export function getOptions(): RenovateOptions[] { diff --git a/lib/config/types.ts b/lib/config/types.ts index f9f53cae4c6533..ac855d7b0fb1df 100644 --- a/lib/config/types.ts +++ b/lib/config/types.ts @@ -69,6 +69,7 @@ export interface RenovateSharedConfig { semanticCommits?: 'auto' | 'enabled' | 'disabled'; semanticCommitScope?: string | null; semanticCommitType?: string; + strictBranchSlugify?: boolean; suppressNotifications?: string[]; timezone?: string; unicodeEmoji?: boolean; diff --git a/lib/workers/repository/updates/branch-name.spec.ts b/lib/workers/repository/updates/branch-name.spec.ts index 128b63b5fe37de..e4c8db8de98a5b 100644 --- a/lib/workers/repository/updates/branch-name.spec.ts +++ b/lib/workers/repository/updates/branch-name.spec.ts @@ -230,14 +230,14 @@ describe('workers/repository/updates/branch-name', () => { groupName: 'invalid branch name.lock', group: { branchName: 'renovate/{{groupSlug}}' }, }, - expectedBranchName: 'renovate/invalid-branch-namelock', + expectedBranchName: 'renovate/invalid-branch-name', }, { upgrade: { groupName: '.a-bad- name:@.lock', group: { branchName: 'renovate/{{groupSlug}}' }, }, - expectedBranchName: 'renovate/a-bad-namelock', + expectedBranchName: 'renovate/a-bad-name-@', }, { upgrade: { branchName: 'renovate/bad-branch-name1..' }, @@ -293,5 +293,35 @@ describe('workers/repository/updates/branch-name', () => { expect(fixture.upgrade.branchName).toEqual(fixture.expectedBranchName); }); }); + + it('strict branch slugify enabled', () => { + const upgrade: RenovateConfig = { + strictBranchSlugify: true, + groupName: '[some] group name.#$%version', + group: { + branchName: '{{groupSlug}}-{{branchTopic}}', + branchTopic: 'grouptopic', + }, + }; + generateBranchName(upgrade); + expect(upgrade.branchName).toBe( + 'some-group-namedollarpercentversion-grouptopic' + ); + }); + + it('strict branch slugify disabled', () => { + const upgrade: RenovateConfig = { + strictBranchSlugify: 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 e3f727c9982c5d..1660cd30258ea4 100644 --- a/lib/workers/repository/updates/branch-name.ts +++ b/lib/workers/repository/updates/branch-name.ts @@ -43,7 +43,7 @@ export function generateBranchName(update: RenovateConfig): void { ); update.groupSlug = slugify(update.groupSlug ?? update.groupName, { lower: true, - strict: true, + strict: update.strictBranchSlugify, }); if (update.updateType === 'major' && update.separateMajorMinor) { if (update.separateMultipleMajor) { From d922244586dfd5d9114833239fe6ed9709828d7f Mon Sep 17 00:00:00 2001 From: Adam Setch Date: Wed, 17 Aug 2022 15:32:05 -0400 Subject: [PATCH 04/10] Update docs/usage/configuration-options.md Co-authored-by: Rhys Arkins --- docs/usage/configuration-options.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/usage/configuration-options.md b/docs/usage/configuration-options.md index 88a439f7bacb43..452bd00ed5d01f 100644 --- a/docs/usage/configuration-options.md +++ b/docs/usage/configuration-options.md @@ -2914,4 +2914,5 @@ To disable the vulnerability alerts feature, set `enabled=false` in a `vulnerabi ## strictBranchSlugify -By default, Renovate does not use strict-mode when slugifying the branch name. To enforce strict-mode and prevent any special characters within the branch name, set this to `true` +By default, Renovate does not use strict-mode when slugifying the branch name. +To enforce strict-mode and prevent any special characters within the branch name, set this to `true`. From 51dd8771b3674d20c881610646ddf71def0b1029 Mon Sep 17 00:00:00 2001 From: Adam Setch Date: Wed, 17 Aug 2022 16:17:34 -0400 Subject: [PATCH 05/10] fix alphabetic ordering --- docs/usage/configuration-options.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/usage/configuration-options.md b/docs/usage/configuration-options.md index 452bd00ed5d01f..8099170685de24 100644 --- a/docs/usage/configuration-options.md +++ b/docs/usage/configuration-options.md @@ -2774,6 +2774,11 @@ You can set your own label name with the `"stopUpdatingLabel"` field: } ``` +## strictBranchSlugify + +By default, Renovate does not use strict-mode when slugifying the branch name. +To enforce strict-mode and prevent any special characters within the branch name, set this to `true`. + ## suppressNotifications Use this field to suppress various types of warnings and other notifications from Renovate. @@ -2911,8 +2916,3 @@ To disable the vulnerability alerts feature, set `enabled=false` in a `vulnerabi } } ``` - -## strictBranchSlugify - -By default, Renovate does not use strict-mode when slugifying the branch name. -To enforce strict-mode and prevent any special characters within the branch name, set this to `true`. From d1d4d7aa958383ab8faaaada990dae5500ddf705 Mon Sep 17 00:00:00 2001 From: Adam Setch Date: Wed, 17 Aug 2022 21:30:17 -0400 Subject: [PATCH 06/10] docs: improve documentation about what is and is not strict mode --- docs/usage/configuration-options.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/usage/configuration-options.md b/docs/usage/configuration-options.md index 8099170685de24..2425ea3e04117f 100644 --- a/docs/usage/configuration-options.md +++ b/docs/usage/configuration-options.md @@ -2776,8 +2776,9 @@ You can set your own label name with the `"stopUpdatingLabel"` field: ## strictBranchSlugify -By default, Renovate does not use strict-mode when slugifying the branch name. -To enforce strict-mode and prevent any special characters within the branch name, set this to `true`. +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 consistingly exclusively of alphabetic characters seperated by `-`. ## suppressNotifications From 4097dbd159d2ee654e8edeb0f1b3dad630c3bdbd Mon Sep 17 00:00:00 2001 From: Adam Setch Date: Thu, 18 Aug 2022 00:04:20 -0400 Subject: [PATCH 07/10] refactor branchNameStrict rename new configuration to branchNameStrict so that it matches existing branch* and branchName* options pivot to regex vs using slugify strict mode additional tests --- docs/usage/configuration-options.md | 12 ++++---- lib/config/types.ts | 2 +- .../repository/updates/branch-name.spec.ts | 28 +++++++++++++++---- lib/workers/repository/updates/branch-name.ts | 8 +++++- 4 files changed, 36 insertions(+), 14 deletions(-) diff --git a/docs/usage/configuration-options.md b/docs/usage/configuration-options.md index 2425ea3e04117f..251544a805cc1f 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. @@ -2774,12 +2780,6 @@ You can set your own label name with the `"stopUpdatingLabel"` field: } ``` -## strictBranchSlugify - -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 consistingly exclusively of alphabetic characters seperated by `-`. - ## suppressNotifications Use this field to suppress various types of warnings and other notifications from Renovate. diff --git a/lib/config/types.ts b/lib/config/types.ts index ac855d7b0fb1df..4e11fa6e81d24a 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; @@ -69,7 +70,6 @@ export interface RenovateSharedConfig { semanticCommits?: 'auto' | 'enabled' | 'disabled'; semanticCommitScope?: string | null; semanticCommitType?: string; - strictBranchSlugify?: boolean; suppressNotifications?: string[]; timezone?: string; unicodeEmoji?: boolean; diff --git a/lib/workers/repository/updates/branch-name.spec.ts b/lib/workers/repository/updates/branch-name.spec.ts index e4c8db8de98a5b..07c368946e8afc 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: @@ -294,10 +310,10 @@ describe('workers/repository/updates/branch-name', () => { }); }); - it('strict branch slugify enabled', () => { + it('strict branch name enabled group', () => { const upgrade: RenovateConfig = { - strictBranchSlugify: true, - groupName: '[some] group name.#$%version', + branchNameStrict: true, + groupName: 'some group name `~#$%^&*()-_=+[]{}|;,./<>? .version', group: { branchName: '{{groupSlug}}-{{branchTopic}}', branchTopic: 'grouptopic', @@ -305,13 +321,13 @@ describe('workers/repository/updates/branch-name', () => { }; generateBranchName(upgrade); expect(upgrade.branchName).toBe( - 'some-group-namedollarpercentversion-grouptopic' + 'some-group-name-dollarpercentand-or-lessgreater-version-grouptopic' ); }); - it('strict branch slugify disabled', () => { + it('strict branch name disabled', () => { const upgrade: RenovateConfig = { - strictBranchSlugify: false, + branchNameStrict: false, groupName: '[some] group name.#$%version', group: { branchName: '{{groupSlug}}-{{branchTopic}}', diff --git a/lib/workers/repository/updates/branch-name.ts b/lib/workers/repository/updates/branch-name.ts index 1660cd30258ea4..5ceedb3d6077ba 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 * @@ -43,7 +46,6 @@ export function generateBranchName(update: RenovateConfig): void { ); update.groupSlug = slugify(update.groupSlug ?? update.groupName, { lower: true, - strict: update.strictBranchSlugify, }); if (update.updateType === 'major' && update.separateMajorMinor) { if (update.separateMultipleMajor) { @@ -97,5 +99,9 @@ export function generateBranchName(update: RenovateConfig): void { update.branchName = template.compile(update.branchName, update); } + if (update.branchNameStrict) { + update.branchName = update.branchName.replace(RE_SPECIAL_CHARS_STRICT, '-'); // massage out all these special characters that slip through slugify + } + update.branchName = cleanBranchName(update.branchName); } From ab616e07ad1b02545bac9e946879e23eeddd2016 Mon Sep 17 00:00:00 2001 From: Adam Setch Date: Thu, 18 Aug 2022 00:13:17 -0400 Subject: [PATCH 08/10] consolidate regex into cleanBranchName function --- lib/workers/repository/updates/branch-name.ts | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/lib/workers/repository/updates/branch-name.ts b/lib/workers/repository/updates/branch-name.ts index 5ceedb3d6077ba..5095dd8eff5742 100644 --- a/lib/workers/repository/updates/branch-name.ts +++ b/lib/workers/repository/updates/branch-name.ts @@ -24,9 +24,18 @@ const RE_SPECIAL_CHARS_STRICT = regEx(/[`~!@#$%^&*()_=+[\]\\|{};':",.<>?]/g); * - 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 @@ -99,9 +108,8 @@ export function generateBranchName(update: RenovateConfig): void { update.branchName = template.compile(update.branchName, update); } - if (update.branchNameStrict) { - update.branchName = update.branchName.replace(RE_SPECIAL_CHARS_STRICT, '-'); // massage out all these special characters that slip through slugify - } - - update.branchName = cleanBranchName(update.branchName); + update.branchName = cleanBranchName( + update.branchName, + update.branchNameStrict + ); } From f0fd8dec41efc526f0e187b369885a18ee6ab935 Mon Sep 17 00:00:00 2001 From: Adam Setch Date: Thu, 18 Aug 2022 00:16:25 -0400 Subject: [PATCH 09/10] fix undefined usecase --- lib/workers/repository/updates/branch-name.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/workers/repository/updates/branch-name.ts b/lib/workers/repository/updates/branch-name.ts index 5095dd8eff5742..b88ec208b3d8e5 100644 --- a/lib/workers/repository/updates/branch-name.ts +++ b/lib/workers/repository/updates/branch-name.ts @@ -26,7 +26,7 @@ const RE_SPECIAL_CHARS_STRICT = regEx(/[`~!@#$%^&*()_=+[\]\\|{};':",.<>?]/g); */ function cleanBranchName( branchName: string, - branchNameStrict: boolean + branchNameStrict?: boolean ): string { let cleanedBranchName = branchName; From 6f4d85b74c0765c3e043aef52403150e5cff8f3d Mon Sep 17 00:00:00 2001 From: Adam Setch Date: Thu, 18 Aug 2022 00:19:06 -0400 Subject: [PATCH 10/10] fix rename of config --- lib/config/options/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/config/options/index.ts b/lib/config/options/index.ts index 6e2edd4019503c..c7911955152ee1 100644 --- a/lib/config/options/index.ts +++ b/lib/config/options/index.ts @@ -2353,8 +2353,8 @@ const options: RenovateOptions[] = [ supportedPlatforms: ['github'], }, { - name: 'strictBranchSlugify', - description: `Whether to be strict about the use of special characters in the branch name.`, + name: 'branchNameStrict', + description: `Whether to be strict about the use of special characters within the branch name.`, type: 'boolean', default: false, },