diff --git a/lib/config/definitions.js b/lib/config/definitions.js index 7183c2d03bbedd1b0ab7bc9f69b0b32e655eb2da..8ea4a24c37ba3ffa1cde738e0226bbd2bd5bffad 100644 --- a/lib/config/definitions.js +++ b/lib/config/definitions.js @@ -547,8 +547,8 @@ const options = [ stage: 'package', type: 'json', default: { - branchName: - '{{{branchPrefix}}}{{{depNameSanitized}}}-{{{newVersionMajor}}}.{{{newVersionMinor}}}.x', + branchTopic: + '{{{depNameSanitized}}}-{{{newVersionMajor}}}.{{{newVersionMinor}}}.x', }, cli: false, mergeable: true, @@ -563,9 +563,9 @@ const options = [ recreateClosed: true, rebaseStalePrs: true, groupName: 'Pin Dependencies', + commitMessageAction: 'Pin', group: { - commitMessage: 'Pin Dependencies', - prTitle: '{{{groupName}}}', + commitMessageTopic: 'dependencies', }, }, cli: false, @@ -681,14 +681,29 @@ const options = [ name: 'branchName', description: 'Branch name template', type: 'string', - default: template('branchName'), + default: '{{{branchPrefix}}}{{{managerBranchPrefix}}}{{{branchTopic}}}', + cli: false, + }, + { + name: 'managerBranchPrefix', + description: 'Branch manager prefix', + type: 'string', + default: '', + cli: false, + }, + { + name: 'branchTopic', + description: 'Branch topic', + type: 'string', + default: '{{{depNameSanitized}}}-{{{newVersionMajor}}}.x', cli: false, }, { name: 'commitMessage', - description: 'Commit message template', + description: 'Message to use for commit messages and pull request titles', type: 'string', - default: template('commitMessage'), + default: + '{{commitMessagePrefix}} {{commitMessageAction}} {{commitMessageTopic}} {{commitMessageExtra}} {{commitMessageSuffix}}', cli: false, }, { @@ -698,11 +713,42 @@ const options = [ type: 'string', cli: false, }, + { + name: 'commitMessagePrefix', + description: + 'Prefix to add to start of commit messages and PR titles. Uses a semantic prefix if semanticCommits enabled', + type: 'string', + cli: false, + }, + { + name: 'commitMessageAction', + description: 'Action verb to use in commit messages and PR titles', + type: 'string', + default: 'Update', + cli: false, + }, + { + name: 'commitMessageTopic', + description: 'The upgrade topic/noun used in commit messages and PR titles', + type: 'string', + default: 'dependency {{depName}}', + cli: false, + }, + { + name: 'commitMessageExtra', + description: + 'Extra description used after the commit message topic - typically the version', + type: 'string', + default: + 'to {{#unless isRange}}v{{/unless}}{{#if isMajor}}{{newVersionMajor}}{{else}}{{newVersion}}{{/if}}', + cli: false, + }, { name: 'prTitle', - description: 'Pull Request title template', + description: + 'Pull Request title template (deprecated). Now uses commitMessage.', type: 'string', - default: template('prTitle'), + default: null, cli: false, }, { @@ -730,9 +776,9 @@ const options = [ enabled: false, recreateClosed: true, rebaseStalePrs: true, - branchName: template('branchName', 'lock-file-maintenance'), - commitMessage: template('commitMessage', 'lock-file-maintenance'), - prTitle: template('prTitle', 'lock-file-maintenance'), + branchTopic: 'lock-file-maintenance', + commitMessageAction: 'Refresh', + commitMessageTopic: 'lock file versions', prBody: template('prBody', 'lock-file-maintenance'), schedule: ['before 5am on monday'], groupName: null, @@ -767,9 +813,8 @@ const options = [ description: 'Config if groupName is enabled', type: 'json', default: { - branchName: template('branchName', 'group'), - commitMessage: template('commitMessage', 'group'), - prTitle: template('prTitle', 'group'), + branchTopic: '{{groupSlug}}', + commitMessageTopic: '{{groupName}}', prBody: template('prBody', 'group'), }, cli: false, @@ -833,6 +878,9 @@ const options = [ default: { groupName: 'Node.js', lazyGrouping: false, + group: { + commitMessageTopic: 'Node.js', + }, }, mergeable: true, cli: false, @@ -861,29 +909,32 @@ const options = [ stage: 'repository', type: 'json', default: { - branchName: template('branchName', 'docker'), - commitMessage: template('commitMessage', 'docker'), - prTitle: template('prTitle', 'docker'), + managerBranchPrefix: 'docker-', + commitMessageTopic: '{{depName}} Docker tag', prBody: template('prBody', 'docker'), major: { enabled: false }, digest: { - branchName: template('branchName', 'docker-digest'), - commitMessage: template('commitMessage', 'docker-digest'), + branchTopic: '{{{depNameSanitized}}}-{{{currentTag}}}', + commitMessageExtra: 'to {{newDigestShort}}', prBody: template('prBody', 'docker-digest'), - prTitle: template('prTitle', 'docker-digest'), + commitMessageTopic: '{{depName}}:{{currentTag}} Docker digest', + group: { + prBody: template('prBody', 'docker-digest-group'), + commitMessageTopic: '{{groupName}}', + }, }, pin: { - branchName: template('branchName', 'docker-pin'), - prTitle: template('prTitle', 'docker-pin'), + commitMessageExtra: '', prBody: template('prBody', 'docker-pin'), - groupName: 'Pin Docker Digests', + groupName: 'Docker digests', group: { - prTitle: template('prTitle', 'docker-pin-group'), prBody: template('prBody', 'docker-pin-group'), + commitMessageTopic: '{{groupName}}', + branchTopic: 'digests-pin', }, }, group: { - prTitle: template('prTitle', 'docker-group'), + commitMessageTopic: '{{groupName}} Docker tags', prBody: template('prBody', 'docker-group'), }, }, diff --git a/lib/config/templates/default/branch-name.hbs b/lib/config/templates/default/branch-name.hbs deleted file mode 100644 index 438c0092208c1170bce39b2fcdd5d2215b65838e..0000000000000000000000000000000000000000 --- a/lib/config/templates/default/branch-name.hbs +++ /dev/null @@ -1 +0,0 @@ -{{{branchPrefix}}}{{{depNameSanitized}}}-{{{newVersionMajor}}}.x diff --git a/lib/config/templates/default/pr-title.hbs b/lib/config/templates/default/pr-title.hbs deleted file mode 100644 index 540afe2a3e4f65687d50a1ed386416a58c618a4e..0000000000000000000000000000000000000000 --- a/lib/config/templates/default/pr-title.hbs +++ /dev/null @@ -1 +0,0 @@ -{{#if isPin}}Pin{{else}}{{#if isRollback}}Roll back{{else}}Update{{/if}}{{/if}} dependency {{{depName}}} to {{#if isRange}}{{{newVersion}}}{{else}}{{#if isMajor}}v{{{newVersionMajor}}}{{else}}v{{{newVersion}}}{{/if}}{{/if}} diff --git a/lib/config/templates/docker-digest-group/pr-body.hbs b/lib/config/templates/docker-digest-group/pr-body.hbs new file mode 100644 index 0000000000000000000000000000000000000000..7e2c8cdf6809bafe9e954a21cc2ecf338b57c2ac --- /dev/null +++ b/lib/config/templates/docker-digest-group/pr-body.hbs @@ -0,0 +1,37 @@ +This Pull Request updates Dockerfiles to the latest image digests. For details on Renovate's Docker support, please visit https://renovateapp.com/docs/language-support/docker + +{{#if schedule}} +**Note**: This PR was created on a configured schedule ("{{{schedule}}}"{{#if timezone}} in timezone `{{{timezone}}}`{{/if}}) and will not receive updates outside those times. +{{/if}} + +{{#each upgrades as |upgrade|}} +- {{#if repositoryUrl}}[{{upgrade.depName}}]({{upgrade.repositoryUrl}}){{else}}`{{{depName}}}`{{/if}}: `{{upgrade.newDigest}}` +{{/each}} + +**Important**: Renovate will wait until you have merged this Pin request before creating PRs for any *upgrades*. If you do not wish to pin anything, please update your config accordingly instead of leaving this PR open. + +{{#if hasErrors}} + +--- + +# Errors + +Renovate encountered some errors when processing your repository, so you are being notified here even if they do not directly apply to this PR. + +{{#each errors as |error|}} +- `{{error.depName}}`: {{error.message}} +{{/each}} +{{/if}} + +{{#if hasWarnings}} + +--- + +# Warnings + +Please make sure the following warnings are safe to ignore: + +{{#each warnings as |warning|}} +- `{{warning.depName}}`: {{warning.message}} +{{/each}} +{{/if}} diff --git a/lib/config/templates/docker-digest/branch-name.hbs b/lib/config/templates/docker-digest/branch-name.hbs deleted file mode 100644 index 06de4198bc0df91a9c4cf3d0089a42cab443930c..0000000000000000000000000000000000000000 --- a/lib/config/templates/docker-digest/branch-name.hbs +++ /dev/null @@ -1 +0,0 @@ -{{{branchPrefix}}}docker-{{{depNameSanitized}}}-{{{currentTag}}} diff --git a/lib/config/templates/docker-digest/commit-message.hbs b/lib/config/templates/docker-digest/commit-message.hbs deleted file mode 100644 index 27a48b56432afd3061b16871453e2c321291c057..0000000000000000000000000000000000000000 --- a/lib/config/templates/docker-digest/commit-message.hbs +++ /dev/null @@ -1 +0,0 @@ -Update {{{depName}}}:{{{currentTag}}} digest diff --git a/lib/config/templates/docker-digest/pr-title.hbs b/lib/config/templates/docker-digest/pr-title.hbs deleted file mode 100644 index a1f68f7e628e5c8cfd6af0cc50511c2537b1eb02..0000000000000000000000000000000000000000 --- a/lib/config/templates/docker-digest/pr-title.hbs +++ /dev/null @@ -1 +0,0 @@ -Update {{{depName}}} Docker image {{{currentTag}}} digest ({{{newDigestShort}}}) diff --git a/lib/config/templates/docker-group/pr-title.hbs b/lib/config/templates/docker-group/pr-title.hbs deleted file mode 100644 index aaebe61c28ddafd97aafa8933423ccaacbbd80bb..0000000000000000000000000000000000000000 --- a/lib/config/templates/docker-group/pr-title.hbs +++ /dev/null @@ -1 +0,0 @@ -Update Docker {{{groupName}}} digests diff --git a/lib/config/templates/docker-pin-group/pr-title.hbs b/lib/config/templates/docker-pin-group/pr-title.hbs deleted file mode 100644 index 719292a0f94f5ec7b406ad8335aa2f6d1e3324bd..0000000000000000000000000000000000000000 --- a/lib/config/templates/docker-pin-group/pr-title.hbs +++ /dev/null @@ -1 +0,0 @@ -Pin Docker digests diff --git a/lib/config/templates/docker-pin/branch-name.hbs b/lib/config/templates/docker-pin/branch-name.hbs deleted file mode 100644 index 48b92818bb5cf52b5ed6eca1d0d68755b45c29f1..0000000000000000000000000000000000000000 --- a/lib/config/templates/docker-pin/branch-name.hbs +++ /dev/null @@ -1 +0,0 @@ -{{{branchPrefix}}}docker-pin-{{{depNameSanitized}}}-{{{currentTag}}} diff --git a/lib/config/templates/docker-pin/pr-title.hbs b/lib/config/templates/docker-pin/pr-title.hbs deleted file mode 100644 index c6edcdec1d30d431f09932cde617eabdfe9d99ed..0000000000000000000000000000000000000000 --- a/lib/config/templates/docker-pin/pr-title.hbs +++ /dev/null @@ -1 +0,0 @@ -Pin Docker {{{depName}}}:{{{currentTag}}} image digest diff --git a/lib/config/templates/docker/branch-name.hbs b/lib/config/templates/docker/branch-name.hbs deleted file mode 100644 index a0e81a09ba4586f0fb83c3917613394653e7c3dc..0000000000000000000000000000000000000000 --- a/lib/config/templates/docker/branch-name.hbs +++ /dev/null @@ -1 +0,0 @@ -{{{branchPrefix}}}docker-{{{depNameSanitized}}}-{{{newVersionMajor}}}.x diff --git a/lib/config/templates/docker/commit-message.hbs b/lib/config/templates/docker/commit-message.hbs deleted file mode 100644 index 01b064eaa1b44f16e6df32cf02c0af8dcf782a1d..0000000000000000000000000000000000000000 --- a/lib/config/templates/docker/commit-message.hbs +++ /dev/null @@ -1 +0,0 @@ -Update {{{depName}}} to tag {{{newTag}}} diff --git a/lib/config/templates/docker/pr-title.hbs b/lib/config/templates/docker/pr-title.hbs deleted file mode 100644 index addd9cef9aa7f2fc6cd80eab0f367f99ef7f67ff..0000000000000000000000000000000000000000 --- a/lib/config/templates/docker/pr-title.hbs +++ /dev/null @@ -1 +0,0 @@ -Update {{{depName}}} Docker tag to {{#if isMajor}}v{{{newVersionMajor}}}{{else}}v{{{newTag}}}{{/if}} diff --git a/lib/config/templates/group/branch-name.hbs b/lib/config/templates/group/branch-name.hbs deleted file mode 100644 index 30d001b693b9dfd57876e44db8b77862eb0d456c..0000000000000000000000000000000000000000 --- a/lib/config/templates/group/branch-name.hbs +++ /dev/null @@ -1 +0,0 @@ -{{{branchPrefix}}}{{groupSlug}} diff --git a/lib/config/templates/group/commit-message.hbs b/lib/config/templates/group/commit-message.hbs deleted file mode 100644 index 16e6b7d8b97e42a914aa1b963c51790b7969a52d..0000000000000000000000000000000000000000 --- a/lib/config/templates/group/commit-message.hbs +++ /dev/null @@ -1 +0,0 @@ -Update {{{groupName}}} packages diff --git a/lib/config/templates/group/pr-title.hbs b/lib/config/templates/group/pr-title.hbs deleted file mode 100644 index 30c85d545a74de627cb269f52f8f84294d0163d3..0000000000000000000000000000000000000000 --- a/lib/config/templates/group/pr-title.hbs +++ /dev/null @@ -1 +0,0 @@ -Update {{{groupName}}} packages{{#if singleVersion}} to {{#unless isRange}}v{{/unless}}{{{singleVersion}}}{{/if}} diff --git a/lib/config/templates/lock-file-maintenance/branch-name.hbs b/lib/config/templates/lock-file-maintenance/branch-name.hbs deleted file mode 100644 index 4f4502faebb87292e66fa111833419d5843eb425..0000000000000000000000000000000000000000 --- a/lib/config/templates/lock-file-maintenance/branch-name.hbs +++ /dev/null @@ -1 +0,0 @@ -{{{branchPrefix}}}lock-file-maintenance diff --git a/lib/config/templates/lock-file-maintenance/commit-message.hbs b/lib/config/templates/lock-file-maintenance/commit-message.hbs deleted file mode 100644 index 4637bf90cd7b3c25dbed1169f4ea7ba03bce5636..0000000000000000000000000000000000000000 --- a/lib/config/templates/lock-file-maintenance/commit-message.hbs +++ /dev/null @@ -1 +0,0 @@ -Update lock file diff --git a/lib/config/templates/lock-file-maintenance/pr-title.hbs b/lib/config/templates/lock-file-maintenance/pr-title.hbs deleted file mode 100644 index c5d18441be75eb7ac8e107b1fa2a2e994ca1ee8a..0000000000000000000000000000000000000000 --- a/lib/config/templates/lock-file-maintenance/pr-title.hbs +++ /dev/null @@ -1 +0,0 @@ -Lock file maintenance diff --git a/lib/config/templates/node/branch-name.hbs b/lib/config/templates/node/branch-name.hbs deleted file mode 100644 index cadb37ed119d168dbcf680636b69d10171bd34b4..0000000000000000000000000000000000000000 --- a/lib/config/templates/node/branch-name.hbs +++ /dev/null @@ -1 +0,0 @@ -{{{branchPrefix}}}nodejs diff --git a/lib/config/validation.js b/lib/config/validation.js index 456c23d91c75325179dfb3570fdb5d22a5331b9d..3b7d31db5dec109b5cbfba964a2345e0f6d9ad59 100644 --- a/lib/config/validation.js +++ b/lib/config/validation.js @@ -23,6 +23,15 @@ async function validateConfig(config, isPreset, parentPath) { let errors = []; let warnings = []; + function getDeprecationMessage(option) { + const deprecatedOptions = { + branchName: `Direct editing of branchName is now deprecated. Please edit branchPrefix, managerBranchPrefix, or branchTopic instead`, + commitMessage: `Direct editing of commitMessage is now deprecated. Please edit commitMessage's subcomponents instead.`, + prTitle: `Direct editing of prTitle is now deprecated. Please edit commitMessage subcomponents instead as they will be passed through to prTitle.`, + }; + return deprecatedOptions[option]; + } + function isIgnored(key) { const ignoredNodes = [ 'prBanner', @@ -54,6 +63,12 @@ async function validateConfig(config, isPreset, parentPath) { !isIgnored(key) && // We need to ignore some reserved keys !isAFunction(val) // Ignore all functions ) { + if (getDeprecationMessage(key)) { + warnings.push({ + depName: 'Deprecation Warning', + message: getDeprecationMessage(key), + }); + } if (!optionTypes[key]) { errors.push({ depName: 'Configuration Error', diff --git a/lib/manager/npm/versions.js b/lib/manager/npm/versions.js index 36abd86d73a624eba5fd52d2117274148de719ae..a6c32a4b20bc60d3f12726a5b8fda33467ed6a85 100644 --- a/lib/manager/npm/versions.js +++ b/lib/manager/npm/versions.js @@ -118,6 +118,7 @@ function determineUpgrades(npmDep, config) { newVersion: rollbackVersion, newVersionMajor: getMajor(rollbackVersion), semanticCommitType: 'fix', + commitMessageAction: 'Roll back', branchName: '{{{branchPrefix}}}rollback-{{{depNameSanitized}}}-{{{newVersionMajor}}}.x', }; diff --git a/lib/workers/branch/commit.js b/lib/workers/branch/commit.js index 135b5b6ba1731310838bbd60a7ff6a6b9e4b2569..f0dc4941b6f5256068c16f44e902e94c492c2b4e 100644 --- a/lib/workers/branch/commit.js +++ b/lib/workers/branch/commit.js @@ -1,5 +1,3 @@ -const handlebars = require('handlebars'); - module.exports = { commitFilesToBranch, }; @@ -10,28 +8,12 @@ async function commitFilesToBranch(config) { ); if (updatedFiles && updatedFiles.length) { logger.debug(`${updatedFiles.length} file(s) to commit`); - let commitMessage = handlebars.compile(config.commitMessage)(config); - if (config.semanticCommits) { - const splitMessage = commitMessage.split('\n'); - splitMessage[0] = splitMessage[0].toLowerCase(); - let semanticPrefix = config.semanticCommitType; - if (config.semanticCommitScope) { - semanticPrefix += `(${handlebars.compile(config.semanticCommitScope)( - config - )})`; - } - commitMessage = `${semanticPrefix}: ${splitMessage.join('\n')}`; - } - if (config.commitBody) { - commitMessage = `${commitMessage}\n\n${handlebars.compile( - config.commitBody - )(config)}`; - } + // API will know whether to create new branch or not await platform.commitFilesToBranch( config.branchName, updatedFiles, - commitMessage, + config.commitMessage, config.parentBranch || config.baseBranch || undefined, config.gitAuthor, config.gitPrivateKey diff --git a/lib/workers/repository/updates/branchify.js b/lib/workers/repository/updates/branchify.js index 07e03980f413fac2f0b8b9d8c7f22fe45577a119..cc1a5102ee631877ce2c8be99e26f250efde331e 100644 --- a/lib/workers/repository/updates/branchify.js +++ b/lib/workers/repository/updates/branchify.js @@ -40,13 +40,13 @@ function branchifyUpgrades(config) { logger.debug( `Dependency ${upgrade.depName} is part of group ${upgrade.groupName}` ); - upgrade.groupSlug = slugify(upgrade.groupSlug || upgrade.groupName, { lower: true, }); - upgrade.branchName = handlebars.compile(upgrade.group.branchName)( - upgrade - ); + upgrade.branchTopic = upgrade.group.branchTopic || upgrade.branchTopic; + upgrade.branchName = handlebars.compile( + upgrade.group.branchName || upgrade.branchName + )(upgrade); } else { upgrade.branchName = handlebars.compile(upgrade.branchName)(upgrade); } diff --git a/lib/workers/repository/updates/generate.js b/lib/workers/repository/updates/generate.js index 8f94aae503fea3c42e5db0cae6bf3d3cbc646899..1b1f14607ac6fa752ce5ff9e7d9c538483449b61 100644 --- a/lib/workers/repository/updates/generate.js +++ b/lib/workers/repository/updates/generate.js @@ -1,4 +1,6 @@ const handlebars = require('handlebars'); +const semver = require('semver'); +const { mergeChildConfig } = require('../../../config'); function generateBranchConfig(branchUpgrades) { logger.debug(`generateBranchConfig()`); @@ -27,39 +29,76 @@ function generateBranchConfig(branchUpgrades) { const useGroupSettings = hasGroupName && groupEligible; logger.debug(`useGroupSettings: ${useGroupSettings}`); for (const branchUpgrade of branchUpgrades) { - const upgrade = { ...branchUpgrade }; + let upgrade = { ...branchUpgrade }; if (useGroupSettings) { // Now overwrite original config with group config - Object.assign(upgrade, upgrade.group); + upgrade = mergeChildConfig(upgrade, upgrade.group); } else { delete upgrade.groupName; } // Delete group config regardless of whether it was applied delete upgrade.group; delete upgrade.lazyGrouping; - if (newVersion.length === 1) { - [upgrade.singleVersion] = newVersion; - } else { + if (newVersion.length > 1) { + delete upgrade.commitMessageExtra; upgrade.recreateClosed = true; + } else if (semver.valid(newVersion[0])) { + upgrade.isRange = false; } // Use templates to generate strings logger.debug( { branchName: upgrade.branchName, prTitle: upgrade.prTitle }, 'Compiling prTitle' ); - upgrade.prTitle += - upgrade.baseBranches && upgrade.baseBranches.length > 1 - ? ' ({{baseBranch}})' - : ''; - upgrade.prTitle = handlebars.compile(upgrade.prTitle)(upgrade); - if (upgrade.semanticCommits) { + upgrade.branchName = handlebars.compile(upgrade.branchName)(upgrade); + if (upgrade.semanticCommits && !upgrade.commitMessagePrefix) { logger.debug('Upgrade has semantic commits enabled'); let semanticPrefix = upgrade.semanticCommitType; if (upgrade.semanticCommitScope) { - semanticPrefix += `(${upgrade.semanticCommitScope})`; + semanticPrefix += `(${handlebars.compile(upgrade.semanticCommitScope)( + upgrade + )})`; } - upgrade.prTitle = `${semanticPrefix}: ${upgrade.prTitle.toLowerCase()}`; + upgrade.commitMessagePrefix = `${semanticPrefix}: `; + upgrade.toLowerCase = true; + } + // Compile a few times in case there are nested templates + upgrade.commitMessage = handlebars.compile(upgrade.commitMessage || '')( + upgrade + ); + upgrade.commitMessage = handlebars.compile(upgrade.commitMessage)(upgrade); + upgrade.commitMessage = handlebars.compile(upgrade.commitMessage)(upgrade); + upgrade.commitMessage = upgrade.commitMessage.trim(); // Trim exterior whitespace + upgrade.commitMessage = upgrade.commitMessage.replace(/\s+/g, ' '); // Trim extra whitespace inside string + if (upgrade.toLowerCase) { + // We only need to lowercvase the first line + const splitMessage = upgrade.commitMessage.split('\n'); + splitMessage[0] = splitMessage[0].toLowerCase(); + upgrade.commitMessage = splitMessage.join('\n'); + } + if (upgrade.commitBody) { + upgrade.commitMessage = `${upgrade.commitMessage}\n\n${handlebars.compile( + upgrade.commitBody + )(upgrade)}`; } + if (upgrade.prTitle) { + upgrade.prTitle = handlebars.compile(upgrade.prTitle)(upgrade); + upgrade.prTitle = handlebars.compile(upgrade.prTitle)(upgrade); + upgrade.prTitle = handlebars + .compile(upgrade.prTitle)(upgrade) + .trim() + .replace(/\s+/g, ' '); + if (upgrade.toLowerCase) { + upgrade.prTitle = upgrade.prTitle.toLowerCase(); + } + } else { + [upgrade.prTitle] = upgrade.commitMessage.split('\n'); + } + upgrade.prTitle += + upgrade.baseBranches && upgrade.baseBranches.length > 1 + ? ' ({{baseBranch}})' + : ''; + // Compile again to allow for nested handlebars templates upgrade.prTitle = handlebars.compile(upgrade.prTitle)(upgrade); logger.debug(`${upgrade.branchName}, ${upgrade.prTitle}`); diff --git a/test/config/__snapshots__/index.spec.js.snap b/test/config/__snapshots__/index.spec.js.snap index 0234866bd5d4c6934b4e920781ad1b43e39748de..ababe95b4bfde1413a58b836a7351cf89e70d446 100644 --- a/test/config/__snapshots__/index.spec.js.snap +++ b/test/config/__snapshots__/index.spec.js.snap @@ -16,12 +16,17 @@ Object { "automergeType": "pr", "baseBranches": Array [], "bazel": Object {}, - "branchName": "{{{branchPrefix}}}{{{depNameSanitized}}}-{{{newVersionMajor}}}.x", + "branchName": "{{{branchPrefix}}}{{{managerBranchPrefix}}}{{{branchTopic}}}", "branchPrefix": "renovate/", + "branchTopic": "{{{depNameSanitized}}}-{{{newVersionMajor}}}.x", "bumpVersion": null, "circleci": Object {}, "commitBody": null, - "commitMessage": "Update dependency {{{depName}}} to {{#unless isRange}}v{{/unless}}{{{newVersion}}}", + "commitMessage": "{{commitMessagePrefix}} {{commitMessageAction}} {{commitMessageTopic}} {{commitMessageExtra}} {{commitMessageSuffix}}", + "commitMessageAction": "Update", + "commitMessageExtra": "to {{#unless isRange}}v{{/unless}}{{#if isMajor}}{{newVersionMajor}}{{else}}{{newVersion}}{{/if}}", + "commitMessagePrefix": null, + "commitMessageTopic": "dependency {{depName}}", "copyLocalLibs": false, "depTypeList": Array [], "dependencies": Object {}, @@ -33,33 +38,36 @@ Object { "devDependencies": Object {}, "digest": Object {}, "docker": Object { - "branchName": "{{{branchPrefix}}}docker-{{{depNameSanitized}}}-{{{newVersionMajor}}}.x", - "commitMessage": "Update {{{depName}}} to tag {{{newTag}}}", + "commitMessageTopic": "{{depName}} Docker tag", "digest": Object { - "branchName": "{{{branchPrefix}}}docker-{{{depNameSanitized}}}-{{{currentTag}}}", - "commitMessage": "Update {{{depName}}}:{{{currentTag}}} digest", + "branchTopic": "{{{depNameSanitized}}}-{{{currentTag}}}", + "commitMessageExtra": "to {{newDigestShort}}", + "commitMessageTopic": "{{depName}}:{{currentTag}} Docker digest", + "group": Object { + "commitMessageTopic": "{{groupName}}", + "prBody": "This Pull Request updates Dockerfiles to the latest image digests. For details on Renovate's Docker support, please visit https://renovateapp.com/docs/language-support/docker\\n\\n{{#if schedule}}\\n**Note**: This PR was created on a configured schedule (\\"{{{schedule}}}\\"{{#if timezone}} in timezone \`{{{timezone}}}\`{{/if}}) and will not receive updates outside those times.\\n{{/if}}\\n\\n{{#each upgrades as |upgrade|}}\\n- {{#if repositoryUrl}}[{{upgrade.depName}}]({{upgrade.repositoryUrl}}){{else}}\`{{{depName}}}\`{{/if}}: \`{{upgrade.newDigest}}\`\\n{{/each}}\\n\\n**Important**: Renovate will wait until you have merged this Pin request before creating PRs for any *upgrades*. If you do not wish to pin anything, please update your config accordingly instead of leaving this PR open.\\n\\n{{#if hasErrors}}\\n\\n---\\n\\n# Errors\\n\\nRenovate encountered some errors when processing your repository, so you are being notified here even if they do not directly apply to this PR.\\n\\n{{#each errors as |error|}}\\n- \`{{error.depName}}\`: {{error.message}}\\n{{/each}}\\n{{/if}}\\n\\n{{#if hasWarnings}}\\n\\n---\\n\\n# Warnings\\n\\nPlease make sure the following warnings are safe to ignore:\\n\\n{{#each warnings as |warning|}}\\n- \`{{warning.depName}}\`: {{warning.message}}\\n{{/each}}\\n{{/if}}", + }, "prBody": "This Pull Request updates Docker base image \`{{{depName}}}:{{{currentTag}}}\` to the latest digest (\`{{{newDigest}}}\`). For details on Renovate's Docker support, please visit https://renovateapp.com/docs/language-support/docker\\n\\n{{#if schedule}}\\n**Note**: This PR was created on a configured schedule (\\"{{{schedule}}}\\"{{#if timezone}} in timezone \`{{{timezone}}}\`{{/if}}) and will not receive updates outside those times.\\n{{/if}}\\n\\n{{#if hasErrors}}\\n\\n---\\n\\n# Errors\\n\\nRenovate encountered some errors when processing your repository, so you are being notified here even if they do not directly apply to this PR.\\n\\n{{#each errors as |error|}}\\n- \`{{error.depName}}\`: {{error.message}}\\n{{/each}}\\n{{/if}}\\n\\n{{#if hasWarnings}}\\n\\n---\\n\\n# Warnings\\n\\nPlease make sure the following warnings are safe to ignore:\\n\\n{{#each warnings as |warning|}}\\n- \`{{warning.depName}}\`: {{warning.message}}\\n{{/each}}\\n{{/if}}", - "prTitle": "Update {{{depName}}} Docker image {{{currentTag}}} digest ({{{newDigestShort}}})", }, "group": Object { + "commitMessageTopic": "{{groupName}} Docker tags", "prBody": "This Pull Request updates Dockerfiles to use image digests.\\n\\n{{#if schedule}}\\n**Note**: This PR was created on a configured schedule (\\"{{{schedule}}}\\"{{#if timezone}} in timezone \`{{{timezone}}}\`{{/if}}) and will not receive updates outside those times.\\n{{/if}}\\n\\n{{#each upgrades as |upgrade|}}\\n- {{#if repositoryUrl}}[{{upgrade.depName}}]({{upgrade.repositoryUrl}}){{else}}\`{{{depName}}}\`{{/if}}: \`{{upgrade.newDigest}}\`\\n{{/each}}\\n\\n{{#if hasErrors}}\\n\\n---\\n\\n# Errors\\n\\nRenovate encountered some errors when processing your repository, so you are being notified here even if they do not directly apply to this PR.\\n\\n{{#each errors as |error|}}\\n- \`{{error.depName}}\`: {{error.message}}\\n{{/each}}\\n{{/if}}\\n\\n{{#if hasWarnings}}\\n\\n---\\n\\n# Warnings\\n\\nPlease make sure the following warnings are safe to ignore:\\n\\n{{#each warnings as |warning|}}\\n- \`{{warning.depName}}\`: {{warning.message}}\\n{{/each}}\\n{{/if}}", - "prTitle": "Update Docker {{{groupName}}} digests", }, "major": Object { "enabled": false, }, + "managerBranchPrefix": "docker-", "pin": Object { - "branchName": "{{{branchPrefix}}}docker-pin-{{{depNameSanitized}}}-{{{currentTag}}}", + "commitMessageExtra": "", "group": Object { + "branchTopic": "digests-pin", + "commitMessageTopic": "{{groupName}}", "prBody": "This Pull Request pins Dockerfiles to use image digests. For details on Renovate's Docker support, please visit https://renovateapp.com/docs/language-support/docker\\n\\n{{#if schedule}}\\n**Note**: This PR was created on a configured schedule (\\"{{{schedule}}}\\"{{#if timezone}} in timezone \`{{{timezone}}}\`{{/if}}) and will not receive updates outside those times.\\n{{/if}}\\n\\n{{#each upgrades as |upgrade|}}\\n- {{#if repositoryUrl}}[{{upgrade.depName}}]({{upgrade.repositoryUrl}}){{else}}\`{{{depName}}}\`{{/if}}: \`{{upgrade.newDigest}}\`\\n{{/each}}\\n\\n**Important**: Renovate will wait until you have merged this Pin request before creating PRs for any *upgrades*. If you do not wish to pin anything, please update your config accordingly instead of leaving this PR open.\\n\\n{{#if hasErrors}}\\n\\n---\\n\\n# Errors\\n\\nRenovate encountered some errors when processing your repository, so you are being notified here even if they do not directly apply to this PR.\\n\\n{{#each errors as |error|}}\\n- \`{{error.depName}}\`: {{error.message}}\\n{{/each}}\\n{{/if}}\\n\\n{{#if hasWarnings}}\\n\\n---\\n\\n# Warnings\\n\\nPlease make sure the following warnings are safe to ignore:\\n\\n{{#each warnings as |warning|}}\\n- \`{{warning.depName}}\`: {{warning.message}}\\n{{/each}}\\n{{/if}}", - "prTitle": "Pin Docker digests", }, - "groupName": "Pin Docker Digests", + "groupName": "Docker digests", "prBody": "This Pull Request pins Docker base image \`{{{depName}}}:{{{currentTag}}}\` to use a digest (\`{{{newDigest}}}\`).\\nThis digest will then be kept updated via Pull Requests whenever the image is updated on the Docker registry. For details on Renovate's Docker support, please visit https://renovateapp.com/docs/language-support/docker\\n\\n{{#if schedule}}\\n**Note**: This PR was created on a configured schedule (\\"{{{schedule}}}\\"{{#if timezone}} in timezone \`{{{timezone}}}\`{{/if}}) and will not receive updates outside those times.\\n{{/if}}\\n\\n**Important**: Renovate will wait until you have merged this Pin request before creating PRs for any *upgrades*. If you do not wish to pin anything, please update your config accordingly instead of leaving this PR open.\\n\\n{{#if hasErrors}}\\n\\n---\\n\\n# Errors\\n\\nRenovate encountered some errors when processing your repository, so you are being notified here even if they do not directly apply to this PR.\\n\\n{{#each errors as |error|}}\\n- \`{{error.depName}}\`: {{error.message}}\\n{{/each}}\\n{{/if}}\\n\\n{{#if hasWarnings}}\\n\\n---\\n\\n# Warnings\\n\\nPlease make sure the following warnings are safe to ignore:\\n\\n{{#each warnings as |warning|}}\\n- \`{{warning.depName}}\`: {{warning.message}}\\n{{/each}}\\n{{/if}}", - "prTitle": "Pin Docker {{{depName}}}:{{{currentTag}}} image digest", }, "prBody": "This Pull Request updates Docker base image \`{{{depName}}}\` from tag \`{{{currentTag}}}\` to new tag \`{{{newTag}}}\`. For details on Renovate's Docker support, please visit https://renovateapp.com/docs/language-support/docker\\n\\n{{#if schedule}}\\n**Note**: This PR was created on a configured schedule (\\"{{{schedule}}}\\"{{#if timezone}} in timezone \`{{{timezone}}}\`{{/if}}) and will not receive updates outside those times.\\n{{/if}}\\n\\n{{#if hasErrors}}\\n\\n---\\n\\n# Errors\\n\\nRenovate encountered some errors when processing your repository, so you are being notified here even if they do not directly apply to this PR.\\n\\n{{#each errors as |error|}}\\n- \`{{error.depName}}\`: {{error.message}}\\n{{/each}}\\n{{/if}}\\n\\n{{#if hasWarnings}}\\n\\n---\\n\\n# Warnings\\n\\nPlease make sure the following warnings are safe to ignore:\\n\\n{{#each warnings as |warning|}}\\n- \`{{warning.depName}}\`: {{warning.message}}\\n{{/each}}\\n{{/if}}", - "prTitle": "Update {{{depName}}} Docker tag to {{#if isMajor}}v{{{newVersionMajor}}}{{else}}v{{{newTag}}}{{/if}}", }, "docker-compose": Object {}, "enabled": true, @@ -84,10 +92,9 @@ Object { "gitAuthor": null, "gitPrivateKey": null, "group": Object { - "branchName": "{{{branchPrefix}}}{{groupSlug}}", - "commitMessage": "Update {{{groupName}}} packages", + "branchTopic": "{{groupSlug}}", + "commitMessageTopic": "{{groupName}}", "prBody": "This Pull Request renovates the package group \\"{{{groupName}}}\\".\\n\\n{{#if schedule}}\\n**Note**: This PR was created on a configured schedule (\\"{{{schedule}}}\\"{{#if timezone}} in timezone \`{{{timezone}}}\`{{/if}}) and will not receive updates outside those times.\\n{{/if}}\\n\\n{{#each upgrades as |upgrade|}}\\n- {{#if repositoryUrl}}[{{{upgrade.depName}}}]({{upgrade.repositoryUrl}}){{else}}\`{{{depName}}}\`{{/if}} (\`{{{depType}}}\`): from \`{{{upgrade.currentVersion}}}\` to \`{{{upgrade.newVersion}}}\`\\n{{/each}}\\n\\n{{#if hasReleaseNotes}}\\n# Release Notes\\n{{#each upgrades as |upgrade|}}\\n{{#if upgrade.hasReleaseNotes}}\\n<details>\\n<summary>{{upgrade.githubName}}</summary>\\n\\n{{#each upgrade.releases as |release|}}\\n{{#if release.releaseNotes}}\\n### [\`v{{{release.version}}}\`]({{{release.releaseNotes.url}}})\\n\\n{{{release.releaseNotes.body}}}\\n\\n---\\n\\n{{/if}}\\n{{/each}}\\n\\n</details>\\n{{/if}}\\n{{/each}}\\n{{/if}}\\n\\n{{#if hasCommits}}\\n# Commits\\n\\n{{#each upgrades as |upgrade|}}\\n{{#if upgrade.releases.length}}\\n<details>\\n<summary>{{upgrade.githubName}}</summary>\\n{{#each upgrade.releases as |release|}}\\n{{#if release.hasCommits}}\\n\\n#### v{{{release.version}}}\\n{{#each release.commits as |commit|}}\\n- [\`{{commit.shortSha}}\`]({{commit.url}}){{commit.message}}\\n{{/each}}\\n{{/if}}\\n{{/each}}\\n\\n</details>\\n\\n{{/if}}\\n{{/each}}\\n{{/if}}\\n\\n{{#if isPin}}\\n**Important**: Renovate will wait until you have merged this Pin request before creating PRs for any *upgrades*. If you do not wish to pin anything, please update your config accordingly instead of leaving this PR open.\\n{{/if}}\\n\\n{{#if hasErrors}}\\n\\n---\\n\\n# Errors\\n\\nRenovate encountered some errors when processing your repository, so you are being notified here even if they do not directly apply to this PR.\\n\\n{{#each errors as |error|}}\\n- \`{{error.depName}}\`: {{error.message}}\\n{{/each}}\\n{{/if}}\\n\\n{{#if hasWarnings}}\\n\\n---\\n\\n# Warnings\\n\\nPlease make sure the following warnings are safe to ignore:\\n\\n{{#each warnings as |warning|}}\\n- \`{{warning.depName}}\`: {{warning.message}}\\n{{/each}}\\n{{/if}}", - "prTitle": "Update {{{groupName}}} packages{{#if singleVersion}} to {{#unless isRange}}v{{/unless}}{{{singleVersion}}}{{/if}}", }, "groupName": null, "groupSlug": null, @@ -101,12 +108,12 @@ Object { "labels": Array [], "lazyGrouping": true, "lockFileMaintenance": Object { - "branchName": "{{{branchPrefix}}}lock-file-maintenance", - "commitMessage": "Update lock file", + "branchTopic": "lock-file-maintenance", + "commitMessageAction": "Refresh", + "commitMessageTopic": "lock file versions", "enabled": false, "groupName": null, "prBody": "This Pull Request updates \`package.json\` lock files to use the latest dependency versions.\\n\\n{{#if schedule}}\\n**Note**: This PR was created on a configured schedule (\\"{{{schedule}}}\\"{{#if timezone}} in timezone \`{{{timezone}}}\`{{/if}}) and will not receive updates outside those times.\\n{{/if}}\\n\\n{{#if hasErrors}}\\n\\n---\\n\\n# Errors\\n\\nRenovate encountered some errors when processing your repository, so you are being notified here even if they do not directly apply to this PR.\\n\\n{{#each errors as |error|}}\\n- \`{{error.depName}}\`: {{error.message}}\\n{{/each}}\\n{{/if}}\\n\\n{{#if hasWarnings}}\\n\\n---\\n\\n# Warnings\\n\\nPlease make sure the following warnings are safe to ignore:\\n\\n{{#each warnings as |warning|}}\\n- \`{{warning.depName}}\`: {{warning.message}}\\n{{/each}}\\n{{/if}}", - "prTitle": "Lock file maintenance", "rebaseStalePrs": true, "recreateClosed": true, "schedule": Array [ @@ -115,11 +122,15 @@ Object { }, "logLevel": "error", "major": Object {}, + "managerBranchPrefix": "", "meteor": Object {}, "minor": Object {}, "mirrorMode": false, "multipleMajorPrs": false, "node": Object { + "group": Object { + "commitMessageTopic": "Node.js", + }, "groupName": "Node.js", "lazyGrouping": false, }, @@ -136,7 +147,7 @@ Object { "packageRules": Array [], "patch": Object { "automerge": true, - "branchName": "{{{branchPrefix}}}{{{depNameSanitized}}}-{{{newVersionMajor}}}.{{{newVersionMinor}}}.x", + "branchTopic": "{{{depNameSanitized}}}-{{{newVersionMajor}}}.{{{newVersionMinor}}}.x", }, "pathRules": Array [], "paths": Array [], @@ -144,9 +155,9 @@ Object { "enabled": false, }, "pin": Object { + "commitMessageAction": "Pin", "group": Object { - "commitMessage": "Pin Dependencies", - "prTitle": "{{{groupName}}}", + "commitMessageTopic": "dependencies", }, "groupName": "Pin Dependencies", "rebaseStalePrs": true, @@ -162,7 +173,7 @@ Object { "prFooter": "This PR has been generated by [Renovate Bot](https://renovateapp.com).", "prHourlyLimit": 10, "prNotPendingHours": 25, - "prTitle": "{{#if isPin}}Pin{{else}}{{#if isRollback}}Roll back{{else}}Update{{/if}}{{/if}} dependency {{{depName}}} to {{#if isRange}}{{{newVersion}}}{{else}}{{#if isMajor}}v{{{newVersionMajor}}}{{else}}v{{{newVersion}}}{{/if}}{{/if}}", + "prTitle": null, "privateKey": null, "rebaseStalePrs": null, "recreateClosed": false, @@ -224,12 +235,12 @@ Array [ exports[`config/index mergeChildConfig(parentConfig, childConfig) merges 1`] = ` Object { - "branchName": "{{{branchPrefix}}}lock-file-maintenance", - "commitMessage": "Update lock file", + "branchTopic": "lock-file-maintenance", + "commitMessageAction": "Refresh", + "commitMessageTopic": "lock file versions", "enabled": false, "groupName": null, "prBody": "This Pull Request updates \`package.json\` lock files to use the latest dependency versions.\\n\\n{{#if schedule}}\\n**Note**: This PR was created on a configured schedule (\\"{{{schedule}}}\\"{{#if timezone}} in timezone \`{{{timezone}}}\`{{/if}}) and will not receive updates outside those times.\\n{{/if}}\\n\\n{{#if hasErrors}}\\n\\n---\\n\\n# Errors\\n\\nRenovate encountered some errors when processing your repository, so you are being notified here even if they do not directly apply to this PR.\\n\\n{{#each errors as |error|}}\\n- \`{{error.depName}}\`: {{error.message}}\\n{{/each}}\\n{{/if}}\\n\\n{{#if hasWarnings}}\\n\\n---\\n\\n# Warnings\\n\\nPlease make sure the following warnings are safe to ignore:\\n\\n{{#each warnings as |warning|}}\\n- \`{{warning.depName}}\`: {{warning.message}}\\n{{/each}}\\n{{/if}}", - "prTitle": "Lock file maintenance", "rebaseStalePrs": true, "recreateClosed": true, "schedule": Array [ diff --git a/test/config/__snapshots__/validation.spec.js.snap b/test/config/__snapshots__/validation.spec.js.snap index 7ac7a5b8f5f86ea9305e9bf1f7d3af35e5e492ce..ec7d7a889a0c65479bf7ff469752d4739b490902 100644 --- a/test/config/__snapshots__/validation.spec.js.snap +++ b/test/config/__snapshots__/validation.spec.js.snap @@ -59,6 +59,15 @@ Array [ exports[`config/validation validateConfig(config) ignore packageRule nesting validation for presets 1`] = `Array []`; +exports[`config/validation validateConfig(config) returns deprecation warnings 1`] = ` +Array [ + Object { + "depName": "Deprecation Warning", + "message": "Direct editing of prTitle is now deprecated. Please edit commitMessage subcomponents instead as they will be passed through to prTitle.", + }, +] +`; + exports[`config/validation validateConfig(config) returns nested errors 1`] = ` Array [ Object { diff --git a/test/config/validation.spec.js b/test/config/validation.spec.js index 883bcdf618a37f6f2a5e49c9a0d0cd1291c53f11..136f1ed8d58bbeeb2be0a21ed2d6e46b35295fcc 100644 --- a/test/config/validation.spec.js +++ b/test/config/validation.spec.js @@ -2,6 +2,14 @@ const configValidation = require('../../lib/config/validation.js'); describe('config/validation', () => { describe('validateConfig(config)', () => { + it('returns deprecation warnings', async () => { + const config = { + prTitle: 'something', + }; + const { warnings } = await configValidation.validateConfig(config); + expect(warnings).toHaveLength(1); + expect(warnings).toMatchSnapshot(); + }); it('returns nested errors', async () => { const config = { foo: 1, diff --git a/test/manager/npm/__snapshots__/versions.spec.js.snap b/test/manager/npm/__snapshots__/versions.spec.js.snap index ef2d8ea89f544a0e457acdeb4a050e2231d1569b..1a36cb0652d153fe768285c7dc13097c2f18e7a4 100644 --- a/test/manager/npm/__snapshots__/versions.spec.js.snap +++ b/test/manager/npm/__snapshots__/versions.spec.js.snap @@ -385,6 +385,7 @@ Array [ exports[`manager/npm/versions .determineUpgrades(npmDep, config) should downgrade from missing versions 1`] = ` Object { "branchName": "{{{branchPrefix}}}rollback-{{{depNameSanitized}}}-{{{newVersionMajor}}}.x", + "commitMessageAction": "Roll back", "isRollback": true, "newVersion": "1.16.0", "newVersionMajor": 1, diff --git a/test/workers/branch/__snapshots__/commit.spec.js.snap b/test/workers/branch/__snapshots__/commit.spec.js.snap index cb12267eed42c8bf2114412c1c1b9ab9aefc3552..52f0f758a5f499584846bec6c6f2ccf4e7fcab44 100644 --- a/test/workers/branch/__snapshots__/commit.spec.js.snap +++ b/test/workers/branch/__snapshots__/commit.spec.js.snap @@ -1,43 +1,5 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`workers/branch/automerge commitFilesToBranch adds commit message body 1`] = ` -Array [ - Array [ - "renovate/some-branch", - Array [ - Object { - "contents": "some contents", - "name": "package.json", - }, - ], - "some commit message - -[skip-ci]", - undefined, - null, - null, - ], -] -`; - -exports[`workers/branch/automerge commitFilesToBranch applies semantic prefix 1`] = ` -Array [ - Array [ - "renovate/some-branch", - Array [ - Object { - "contents": "some contents", - "name": "package.json", - }, - ], - "a(b): some commit message", - undefined, - null, - null, - ], -] -`; - exports[`workers/branch/automerge commitFilesToBranch commits files 1`] = ` Array [ Array [ diff --git a/test/workers/branch/commit.spec.js b/test/workers/branch/commit.spec.js index 85791623752ad8a93dc7ae7f54f4656f153765a2..f1455a57ae37fd6243bec1c23b0f2ec82aaa923d 100644 --- a/test/workers/branch/commit.spec.js +++ b/test/workers/branch/commit.spec.js @@ -30,38 +30,5 @@ describe('workers/branch/automerge', () => { expect(platform.commitFilesToBranch.mock.calls.length).toBe(1); expect(platform.commitFilesToBranch.mock.calls).toMatchSnapshot(); }); - it('applies semantic prefix', async () => { - config.updatedPackageFiles.push({ - name: 'package.json', - contents: 'some contents', - }); - config.semanticCommits = true; - await commitFilesToBranch(config); - expect(platform.commitFilesToBranch.mock.calls.length).toBe(1); - expect(platform.commitFilesToBranch.mock.calls).toMatchSnapshot(); - }); - it('lowercases only the first line when applying semantic prefix', async () => { - config.updatedPackageFiles.push({ - name: 'package.json', - contents: 'some contents', - }); - config.commitMessage = 'Foo\n\nBar'; - config.semanticCommits = true; - await commitFilesToBranch(config); - expect(platform.commitFilesToBranch.mock.calls.length).toBe(1); - expect(platform.commitFilesToBranch.mock.calls[0][2]).toEqual( - 'a(b): foo\n\nBar' - ); - }); - it('adds commit message body', async () => { - config.updatedPackageFiles.push({ - name: 'package.json', - contents: 'some contents', - }); - config.commitBody = '[skip-ci]'; - await commitFilesToBranch(config); - expect(platform.commitFilesToBranch.mock.calls.length).toBe(1); - expect(platform.commitFilesToBranch.mock.calls).toMatchSnapshot(); - }); }); }); diff --git a/test/workers/repository/updates/__snapshots__/generate.spec.js.snap b/test/workers/repository/updates/__snapshots__/generate.spec.js.snap new file mode 100644 index 0000000000000000000000000000000000000000..f631d86e7f6c1701b65c53061dc15bf9bb1aeb94 --- /dev/null +++ b/test/workers/repository/updates/__snapshots__/generate.spec.js.snap @@ -0,0 +1,9 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`workers/repository/updates/generate generateBranchConfig() adds commit message body 1`] = ` +"Update dependency some-dep to v1.2.0 + +[skip-ci]" +`; + +exports[`workers/repository/updates/generate generateBranchConfig() supports manual prTitle 1`] = `"upgrade some-dep"`; diff --git a/test/workers/repository/updates/generate.spec.js b/test/workers/repository/updates/generate.spec.js index a4dd11bc64d8c2544d77147b5baeffac85c20a0e..bc778190941e270adf12f3cbe2ace89656c5532e 100644 --- a/test/workers/repository/updates/generate.spec.js +++ b/test/workers/repository/updates/generate.spec.js @@ -1,3 +1,5 @@ +const defaultConfig = require('../../../../lib/config/defaults').getConfig(); + beforeEach(() => { jest.resetAllMocks(); }); @@ -102,7 +104,6 @@ describe('workers/repository/updates/generate', () => { ]; const res = generateBranchConfig(branch); expect(res.foo).toBe(2); - expect(res.singleVersion).toBeDefined(); expect(res.groupName).toBeDefined(); }); it('groups multiple upgrades different version', () => { @@ -141,14 +142,13 @@ describe('workers/repository/updates/generate', () => { it('uses semantic commits', () => { const branch = [ { + ...defaultConfig, depName: 'some-dep', - groupName: 'some-group', - branchName: 'some-branch', - prTitle: 'some-title', semanticCommits: true, semanticCommitType: 'chore', semanticCommitScope: 'package', lazyGrouping: true, + newVersion: '1.2.0', foo: 1, group: { foo: 2, @@ -156,7 +156,34 @@ describe('workers/repository/updates/generate', () => { }, ]; const res = generateBranchConfig(branch); - expect(res.prTitle).toEqual('chore(package): some-title'); + expect(res.prTitle).toEqual( + 'chore(package): update dependency some-dep to v1.2.0' + ); + }); + it('adds commit message body', () => { + const branch = [ + { + ...defaultConfig, + depName: 'some-dep', + commitBody: '[skip-ci]', + newVersion: '1.2.0', + }, + ]; + const res = generateBranchConfig(branch); + expect(res.commitMessage).toMatchSnapshot(); + expect(res.commitMessage.includes('\n')).toBe(true); + }); + it('supports manual prTitle', () => { + const branch = [ + { + ...defaultConfig, + depName: 'some-dep', + prTitle: 'Upgrade {{depName}}', + toLowerCase: true, + }, + ]; + const res = generateBranchConfig(branch); + expect(res.prTitle).toMatchSnapshot(); }); it('handles @types specially', () => { const branch = [ diff --git a/website/docs/_posts/2017-10-05-configuration-options.md b/website/docs/_posts/2017-10-05-configuration-options.md index 78c8e87051500ac4225e358cf7876d9c225cec6b..b355815162748ef1a45f7e3ab0b8f4bd96ed66df 100644 --- a/website/docs/_posts/2017-10-05-configuration-options.md +++ b/website/docs/_posts/2017-10-05-configuration-options.md @@ -138,6 +138,17 @@ Prefix to be used for all branch names You can modify this field if you want to change the prefix used. For example if you want branches to be like `deps/eslint-4.x` instead of `renovate/eslint-4.x` then you set `branchPrefix` = `deps/`. Or if you wish to avoid forward slashes in branch names then you could use `renovate_` instead, for example. +## branchTopic + +The main name/text that Renovate should use when creating a branch on your repository. + +| name | value | +| ------- | -------------------------------------------------------------------- | +| type | string | +| default | {{{depNameSanitized}}}-{{{newVersionMajor}}}.{{{newVersionMinor}}}.x | + +This field is combined with `branchPrefix` and `managerBranchPrefix` to form the full `branchName`. `branchName` uniqueness is important for dependency update grouping or non-grouping so be cautious about ever editing this field manually. + ## bumpVersion Bump the version in the package.json being updated @@ -178,15 +189,59 @@ For example, To add `[skip ci]` to every commit you could configure: Commit message template -| name | value | -| ------- | ---------------------------------------------------------------------------------------------- | -| type | handlebars template | -| default | {% raw %}{{semanticPrefix}}Update dependency {{depName}} to version {{newVersion}}{% endraw %} | +| name | value | +| ------- | ------------------------------------------------------------------------------------------------------------------------------------------ | +| type | handlebars template | +| default | {% raw %}{{commitMessagePrefix}} {{commitMessageAction}} {{commitMessageTopic}} {{commitMessageExtra}} {{commitMessageSuffix}}{% endraw %} | The commit message is less important than branchName so you may override it if you wish. Example commit message: "chore(deps): Update dependency eslint to version 4.0.1" +## commitMessageAction + +Action verb to use in commit messages and PR titles. + +| name | value | +| ------- | ------ | +| type | string | +| default | Update | + +This is used to alter `commitMessage` and `prTitle` without needing to copy/paste the whole string. Actions may be like 'Update', 'Pin', 'Roll back', 'Refresh', etc. + +## commitMessageExtra + +Extra description used after the commit message topic - typically the version. + +| name | value | +| ------- | ---------------------------------------------------------------------------------------------------------------------- | +| type | string | +| default | {% raw %}to {{#unless isRange}}v{{/unless}}{{#if isMajor}}{{newVersionMajor}}{{else}}{{newVersion}}{{/if}}{% endraw %} | + +This is used to alter `commitMessage` and `prTitle` without needing to copy/paste the whole string. The "extra" is usually an identifier of the new version, e.g. "to v1.3.2" or "to tag 9.2". + +## commitMessagePrefix + +Prefix to add to start of commit messages and PR titles. Uses a semantic prefix if semanticCommits enabled. + +| name | value | +| ------- | ------ | +| type | string | +| default | '' | + +This is used to alter `commitMessage` and `prTitle` without needing to copy/paste the whole string. The "prefix" is usually an automatically applied semantic commit prefix, however it can also be statically configured. + +## commitMessageTopic + +The upgrade topic/noun used in commit messages and PR titles. + +| name | value | +| ------- | ---------------------- | +| type | string | +| default | dependency {{depName}} | + +This is used to alter `commitMessage` and `prTitle` without needing to copy/paste the whole string. The "topic" is usually refers to the dependency being updated, e.g. "dependency react". + ## copyLocalLibs | name | value | @@ -550,6 +605,17 @@ Configuration specific for major dependency updates. Add to this object if you wish to define rules that apply only to major updates. +## managerBranchPrefix + +Prefix to be added after `branchPrefix` for distinguishing between branches for different branches. + +| name | value | +| ------- | ------ | +| type | string | +| default | '' | + +This value defaults to empty string, as historically no prefix was necessary for when Renovate was JS-only. Now - for example - we use `docker-` for Docker branches, so they may look like `renovate/docker-ubuntu-16.x`. + ## meteor Configuration specific for meteor updates. diff --git a/website/docs/_posts/2018-04-09-configuration-templates.md b/website/docs/_posts/2018-04-09-configuration-templates.md new file mode 100644 index 0000000000000000000000000000000000000000..fb5a18570bf78e2ce099b2b8d556c074f9905840 --- /dev/null +++ b/website/docs/_posts/2018-04-09-configuration-templates.md @@ -0,0 +1,51 @@ +--- +date: 2018-04-09 +title: Config Template Editing +categories: + - deep-dives +description: How to edit Renovate's config templates +type: Document +order: 30 +--- + +Tnis document describes how you can edit the branch names, commit messages, or PR titles and content. + +## Branch Name + +The branch name is very important for Renovate because it helps determine "grouping" of updates, and also makes it efficient when an existing PR needs to be updated with a newer version. Also, if you change branchPrefix and have some upgrades "ignored" (closed without merging) then you may see duplicate PRs opened with your new branch name. + +`branchName` has a default value of `{{{branchPrefix}}}{{{managerBranchPrefix}}}{{{branchTopic}}}`. + +The most common type of branch name you will see looks like this: `renovate/react-16.x`. In this example, the `branchPrefix` is the default `renovate/`, `managerBranchPrefix` is empty, and `branchTopic` is `react-16.x`. + +Most people can leave `branchPrefix` as `renovate/` however if you prefer to have no forward slashes then you might pick `renovate-` instead. Please note that the onboarding PR is fixed to use `renovate/configure` however. + +`managerBranchPrefix` is optional and by default is empty for all JavaScript dependencies. We use `docker-` for all Docker updates, so you might see branches like `renovate/docker-ubuntu-16.x`. + +`branchTopic` depends on the package manager and upgrade type, so you will see a lot of variety. It is also the one you might be most likely to want to change, but be careful and consider posting your config to https://github.com/renovateapp/config-help first. + +## Commit Message + +Renovate is designed to have just a single commit per branch, for merging convenience. As such, that commitMessage should reflect the contents of the branch and usually be the same as the PR Title. + +`commitMessage` has a default value of `{{commitMessagePrefix}} {{commitMessageAction}} {{commitMessageTopic}} {{commitMessageExtra}} {{commitMessageSuffix}}`, with the intention that you only edit some of those subcomponents. + +`commitMessagePrefix` is usually not necessary to configure directly, and is used by Renovate if it needs to add a prefix due to Semantic Commit conventions. Do not touch it unless you know what you're doing. + +`commitMessageAction` is usually just 1 word, e.g. 'Update', 'Pin', 'Refresh', etc. It's usually also not necessary to edit, although maybe you prefer 'Upgrade' instead of 'Update'? + +`commitMessageTopic` is usually 2-3 words aimed to identify _what_ is being updated. e.g. it might be `dependency react` or `Docker image ubuntu`. You may want to edit this, but if you think your idea/requirement is a good one then maybe you can propose it to the project or publish it as a preset config for others with similar requirements. + +`commitMessageExtra` usually refers to the version being updated to. e.g. `to v16` for a major upgrade, or `to v16.0.3` for a patch update. It may also be empty in some cases, e.g. if the action/topic is `Pin Docker digests`. + +`commitMessageSuffix` defaults to empty and is there for flexibility and future use. Maybe for `major` updates you always want the PR to end with `(MAJOR)`, for instance. + +`commitBody` is used if you wish to add multi-line commit messages, such as for the `Signed-off-by` fields, or adding `[skip-ci]`, etc. It is appended to the generated `commitMessage`, separated by a newline. + +## PR Title + +Because commit messages should usually match with the PR title, the PR title template now defaults to `null` and inherits whatever is configured for `commitMessage`. If you have a requirement where `prTitle` should be different from `commitMessage`, then please raise a feature request for discussion. + +## PR Body + +The PR Body is currently a little difficult to edit because of its size, however it should soon be redesigned like the other templates to allow more easier editing without needing to copy/paste the whole template.