Skip to content
Snippets Groups Projects
Commit 6b67ffa5 authored by Steven Hargrove's avatar Steven Hargrove Committed by Rhys Arkins
Browse files

fix: enforce valid git branch names (#1725)

Adds proper enforcement of branch name rules.

Fixes #1724
parent 9ab4e55b
No related branches found
No related tags found
No related merge requests found
const handlebars = require('handlebars'); const handlebars = require('handlebars');
const slugify = require('slugify');
const cleanGitRef = require('clean-git-ref').clean;
const { generateBranchConfig } = require('./generate'); const { generateBranchConfig } = require('./generate');
/**
* Clean git branch name
*
* Remove what clean-git-ref fails to:
* - leading dot/leading dot after slash
* - trailing dot
* - whitespace
*/
function cleanBranchName(branchName) {
return cleanGitRef(branchName)
.replace(/^\.|\.$/, '') // leading or trailing dot
.replace(/\/\./g, '/') // leading dot after slash
.replace(/\s/g, ''); // whitespace
}
function branchifyUpgrades(config) { function branchifyUpgrades(config) {
logger.debug('branchifyUpgrades'); logger.debug('branchifyUpgrades');
logger.trace({ config }); logger.trace({ config });
...@@ -23,12 +40,10 @@ function branchifyUpgrades(config) { ...@@ -23,12 +40,10 @@ function branchifyUpgrades(config) {
logger.debug( logger.debug(
`Dependency ${upgrade.depName} is part of group ${upgrade.groupName}` `Dependency ${upgrade.depName} is part of group ${upgrade.groupName}`
); );
upgrade.groupSlug =
upgrade.groupSlug || upgrade.groupSlug = slugify(upgrade.groupSlug || upgrade.groupName, {
upgrade.groupName lower: true,
.toString() });
.toLowerCase()
.replace(/[^a-z0-9+]+/g, '-');
upgrade.branchName = handlebars.compile(upgrade.group.branchName)( upgrade.branchName = handlebars.compile(upgrade.group.branchName)(
upgrade upgrade
); );
...@@ -37,7 +52,10 @@ function branchifyUpgrades(config) { ...@@ -37,7 +52,10 @@ function branchifyUpgrades(config) {
} }
// Compile extra times in case of nested handlebars templates // Compile extra times in case of nested handlebars templates
upgrade.branchName = handlebars.compile(upgrade.branchName)(upgrade); upgrade.branchName = handlebars.compile(upgrade.branchName)(upgrade);
upgrade.branchName = handlebars.compile(upgrade.branchName)(upgrade); upgrade.branchName = cleanBranchName(
handlebars.compile(upgrade.branchName)(upgrade)
);
branchUpgrades[upgrade.branchName] = branchUpgrades[upgrade.branchName] =
branchUpgrades[upgrade.branchName] || []; branchUpgrades[upgrade.branchName] || [];
branchUpgrades[upgrade.branchName] = [upgrade].concat( branchUpgrades[upgrade.branchName] = [upgrade].concat(
......
...@@ -48,6 +48,7 @@ ...@@ -48,6 +48,7 @@
"chalk": "2.3.2", "chalk": "2.3.2",
"changelog": "1.4.2", "changelog": "1.4.2",
"child-process-promise": "2.2.1", "child-process-promise": "2.2.1",
"clean-git-ref": "1.0.3",
"commander": "2.15.1", "commander": "2.15.1",
"compare-versions": "3.1.0", "compare-versions": "3.1.0",
"conventional-commits-detector": "0.1.1", "conventional-commits-detector": "0.1.1",
...@@ -82,6 +83,7 @@ ...@@ -82,6 +83,7 @@
"semver-stable": "2.0.4", "semver-stable": "2.0.4",
"semver-utils": "1.1.1", "semver-utils": "1.1.1",
"showdown": "1.8.6", "showdown": "1.8.6",
"slugify": "1.2.9",
"tmp-promise": "1.0.4", "tmp-promise": "1.0.4",
"traverse": "0.6.6", "traverse": "0.6.6",
"upath": "1.0.4", "upath": "1.0.4",
......
...@@ -133,5 +133,73 @@ describe('workers/repository/updates/branchify', () => { ...@@ -133,5 +133,73 @@ describe('workers/repository/updates/branchify', () => {
expect(res.errors).toHaveLength(1); expect(res.errors).toHaveLength(1);
expect(res.warnings).toHaveLength(1); expect(res.warnings).toHaveLength(1);
}); });
it('enforces valid git branch name', async () => {
const fixtures = [
{
upgrade: {
groupName: '/My Group/',
group: { branchName: 'renovate/{{groupSlug}}' },
},
expectedBranchName: 'renovate/my-group',
},
{
upgrade: {
groupName: 'invalid branch name.lock',
group: { branchName: 'renovate/{{groupSlug}}' },
},
expectedBranchName: 'renovate/invalid-branch-name',
},
{
upgrade: {
groupName: '.a-bad- name:@.lock',
group: { branchName: 'renovate/{{groupSlug}}' },
},
expectedBranchName: 'renovate/a-bad-name-@',
},
{
upgrade: { branchName: 'renovate/bad-branch-name1..' },
expectedBranchName: 'renovate/bad-branch-name1',
},
{
upgrade: { branchName: 'renovate/~bad-branch-name2' },
expectedBranchName: 'renovate/-bad-branch-name2',
},
{
upgrade: { branchName: 'renovate/bad-branch-^-name3' },
expectedBranchName: 'renovate/bad-branch---name3',
},
{
upgrade: { branchName: 'renovate/bad-branch-name : 4' },
expectedBranchName: 'renovate/bad-branch-name--4',
},
{
upgrade: { branchName: 'renovate/bad-branch-name5/' },
expectedBranchName: 'renovate/bad-branch-name5',
},
{
upgrade: { branchName: '.bad-branch-name6' },
expectedBranchName: 'bad-branch-name6',
},
{
upgrade: { branchName: 'renovate/.bad-branch-name7' },
expectedBranchName: 'renovate/bad-branch-name7',
},
{
upgrade: { branchName: 'renovate/.bad-branch-name8' },
expectedBranchName: 'renovate/bad-branch-name8',
},
{
upgrade: { branchName: 'renovate/bad-branch-name9.' },
expectedBranchName: 'renovate/bad-branch-name9',
},
];
config.upgrades = fixtures.map(({ upgrade }) => upgrade);
(await branchifyUpgrades(config)).branches.forEach(
({ branchName }, index) => {
expect(branchName).toBe(fixtures[index].expectedBranchName);
}
);
});
}); });
}); });
...@@ -947,6 +947,10 @@ class-utils@^0.3.5: ...@@ -947,6 +947,10 @@ class-utils@^0.3.5:
isobject "^3.0.0" isobject "^3.0.0"
static-extend "^0.1.1" static-extend "^0.1.1"
clean-git-ref@1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/clean-git-ref/-/clean-git-ref-1.0.3.tgz#5325dc839eab01c974ae0e97f5734782750f88ec"
clean-stack@^1.0.0: clean-stack@^1.0.0:
version "1.3.0" version "1.3.0"
resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-1.3.0.tgz#9e821501ae979986c46b1d66d2d432db2fd4ae31" resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-1.3.0.tgz#9e821501ae979986c46b1d66d2d432db2fd4ae31"
...@@ -5731,6 +5735,10 @@ slide@^1.1.3, slide@^1.1.5, slide@^1.1.6, slide@~1.1.3, slide@~1.1.6: ...@@ -5731,6 +5735,10 @@ slide@^1.1.3, slide@^1.1.5, slide@^1.1.6, slide@~1.1.3, slide@~1.1.6:
version "1.1.6" version "1.1.6"
resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707"
slugify@1.2.9:
version "1.2.9"
resolved "https://registry.yarnpkg.com/slugify/-/slugify-1.2.9.tgz#c3d518f5136b3c69345d5d0bbbcde7412b5694aa"
smart-buffer@^1.0.13: smart-buffer@^1.0.13:
version "1.1.15" version "1.1.15"
resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-1.1.15.tgz#7f114b5b65fab3e2a35aa775bb12f0d1c649bf16" resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-1.1.15.tgz#7f114b5b65fab3e2a35aa775bb12f0d1c649bf16"
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment