diff --git a/lib/workers/repository/index.js b/lib/workers/repository/index.js index 43c1cda55f21a813bde1d494397eb9e5056a5ae1..f16d281a372e634c077f88c68bea4a63a4bf8998 100644 --- a/lib/workers/repository/index.js +++ b/lib/workers/repository/index.js @@ -10,6 +10,7 @@ const upgrades = require('./upgrades'); const cleanup = require('./cleanup'); const { checkMonorepos } = require('../../manager/npm/monorepos'); +const { ensureOnboardingPr } = require('./onboarding/pr'); module.exports = { pinDependenciesFirst, @@ -142,7 +143,7 @@ async function renovateRepository(repoConfig, token) { 'Finished updating branches' ); } else { - await onboarding.ensurePr(config, branchUpgrades); + await ensureOnboardingPr({ ...config, branches: branchUpgrades }); logger.info('"Configure Renovate" PR needs to be closed first'); branchList = [`${config.branchPrefix}configure`]; } diff --git a/lib/workers/repository/onboarding.js b/lib/workers/repository/onboarding.js index 24703e45f0d3be8b7e9ea54bd0bf976ccd0df304..4f18caf37ae7f655b2ace85560b68c5e1c59b228 100644 --- a/lib/workers/repository/onboarding.js +++ b/lib/workers/repository/onboarding.js @@ -1,11 +1,8 @@ const apis = require('./apis'); const manager = require('../../manager'); -const onboardPrTitle = 'Configure Renovate'; - module.exports = { createOnboardingBranch, - ensurePr, getOnboardingStatus, }; @@ -34,174 +31,6 @@ async function createOnboardingBranch(inputConfig) { return config; } -async function ensurePr(config, branchUpgrades) { - const { logger, errors, warnings } = config; - const description = config.description || []; - if (config.assignees && config.assignees.length) { - const assignees = config.assignees.map( - assignee => (assignee[0] === '@' ? assignee : `@${assignee}`) - ); - description.push(`Assign PRs to ${assignees.join(' and ')}`); - } - if (config.labels && config.labels.length) { - let desc = 'Apply label'; - if (config.labels.length > 1) { - desc += 's'; - } - desc += ` ${config.labels - .map(label => `<code>${label}</code>`) - .join(' and ')} to PRs`; - description.push(desc); - } - if (config.schedule && config.schedule.length) { - description.push(`Run Renovate on following schedule: ${config.schedule}`); - } - let prBody = `Welcome to [Renovate](https://renovateapp.com)! - -This is an onboarding PR to help you understand and configure Renovate before any regular Pull Requests begin. Once you close this Pull Request, Renovate will begin keeping your dependencies up-to-date via automated Pull Requests. - -If you have any questions, try reading our [Getting Started Configuring Renovate](https://renovateapp.com/docs/getting-started/configure-renovate) page first, or feel free to ask the app author @rarkins a question in a comment below. - ---- - -{{BASEBRANCHDESCRIPTION}}{{PRDESCRIPTION}} - -Sometimes you may see multiple options for the same dependency (e.g. pinning in one branch and upgrading in another). This is expected and allows you the flexibility to choose which to merge first. Once you merge any PR, others will be updated or removed the next time Renovate runs. - -Would you like to change the way Renovate is upgrading your dependencies? Simply edit the \`renovate.json\` in this branch and this Pull Request description will be updated the next time Renovate runs. - -Our [Configuration Docs](https://renovateapp.com/docs/) should be helpful if you wish to modify any behaviour. - ---- - -#### Don't want a \`renovate.json\` file? - -You are not required to *merge* this Pull Request - Renovate will begin even if this "Configure Renovate" PR is closed *unmerged* and without a \`renovate.json\` file. However, it's recommended that you add configuration to your repository to ensure behaviour matches what you see described here. - -Alternatively, you can add the same configuration settings into a "renovate" section of your \`package.json\` file(s) in this branch and delete the \`renovate.json\` from this PR. If you make these configuration changes in this branch then the results will be described in this PR after the next time Renovate runs. - -#### Want to start over? - -If you'd like Renovate to recreate this "Configure Renovate" PR from scratch - for example if your base branch has had substantial changes - then you need to: - -1. (IMPORTANT) Rename this PR to something else, e.g. "Configure Renovate - old" -2. Close the PR and delete the branch - -If later on you ever wish to reconfigure Renovate then you can use this same trick of renaming the PR, but you'll also need to delete any \`renovate.json\` file too. You should then get a new "Configure Renovate" PR like this. -`; - if (warnings.length) { - let prWarnings = `---\n\n### Warnings (${warnings.length})\n\n`; - prWarnings += `Please correct - or verify that you can safely ignore - these warnings before you merge this PR. -`; - warnings.forEach(warning => { - prWarnings += `- \`${warning.depName}\`: ${warning.message}\n`; - }); - prWarnings += '\n---'; - prBody = prBody.replace('---', prWarnings); - } - if (errors.length) { - let prErrors = `---\n\n### Errors (${errors.length})\n\n`; - prErrors += `Renovate has raised errors when processing this repository that you should fix before merging or closing this PR. - -Please make any fixes in _this branch_. -`; - errors.forEach(error => { - prErrors += `- \`${error.depName}\`: ${error.message}\n`; - }); - prErrors += - '\nFeel free to raise create a [GitHub Issue](https:/github.com/singapore/renovate/issues) to ask any questions.'; - prErrors += '\n\n---'; - prBody = prBody.replace('---', prErrors); - } - if (description.length) { - let configDesc = `---\n\n## Configuration Summary\n\nBased on the currently configured presets, Renovate will:\n<ul>\n`; - configDesc += - ' <li>Start dependency updates once this Configure Renovate PR is merged or closed</li>\n'; - description.forEach(desc => { - configDesc += ` <li>${desc}</li>\n`; - }); - configDesc += '\n</ul>\n\n---'; - prBody = prBody.replace('---', configDesc); - } - - // Describe base branch only if it's configured - let baseBranchDesc = ''; - if ( - config.contentBaseBranch && - config.contentBaseBranch !== `${config.branchPrefix}configure` - ) { - baseBranchDesc = `You have configured renovate to use branch \`${config.contentBaseBranch}\` as base branch.\n\n`; - } - prBody = prBody.replace('{{BASEBRANCHDESCRIPTION}}', baseBranchDesc); - - let prDesc = ` -With your current configuration, renovate will initially create the following Pull Requests: - -| Pull Requests (${branchUpgrades.length}) | -| ------ | -`; - branchUpgrades.forEach(branch => { - const prTitleRe = /@([a-z]+\/[a-z]+)/; - prDesc += `| **${branch.prTitle.replace(prTitleRe, '@​$1')}**<ul>`; - if (branch.schedule && branch.schedule.length) { - prDesc += `<li>Schedule: ${JSON.stringify(branch.schedule)}</li>`; - } - prDesc += `<li>Branch name: \`${branch.branchName}\`</li>`; - branch.upgrades.forEach(upgrade => { - if (upgrade.type === 'lockFileMaintenance') { - prDesc += - '<li>Regenerates lock file to use latest dependency versions</li>'; - } else { - if (upgrade.isPin) { - prDesc += '<li>Pins '; - } else { - prDesc += '<li>Upgrades '; - } - if (upgrade.repositoryUrl) { - prDesc += `[${upgrade.depName}](${upgrade.repositoryUrl})`; - } else { - prDesc += upgrade.depName.replace(prTitleRe, '@​$1'); - } - prDesc += ` in \`${upgrade.depType}\` `; - if (!upgrade.isPin) { - prDesc += `from \`${upgrade.currentVersion}\` `; - } - prDesc += `to \`${upgrade.newVersion}\``; - prDesc += '</li>'; - } - }); - prDesc += '</ul> |\n'; - }); - if (branchUpgrades.length === 0) { - // Overwrite empty content - prDesc = - 'It looks like your repository dependencies are already up-to-date and no initial Pull Requests will be necessary.'; - } - prBody = prBody.replace('{{PRDESCRIPTION}}', prDesc); - // Check if existing PR exists - const onboardBranchName = `${config.branchPrefix}configure`; - const existingPr = await config.api.getBranchPr(onboardBranchName); - if (existingPr) { - // Check if existing PR needs updating - if (existingPr.title === onboardPrTitle && existingPr.body === prBody) { - logger.info(`${existingPr.displayNumber} does not need updating`); - return; - } - // PR must need updating - await config.api.updatePr(existingPr.number, onboardPrTitle, prBody); - logger.info(`Updated ${existingPr.displayNumber}`); - return; - } - const pr = await config.api.createPr( - onboardBranchName, - onboardPrTitle, - prBody, - [], // labels - true - ); - logger.debug(`Created ${pr.displayNumber} for configuration`); -} - async function getOnboardingStatus(inputConfig) { let config = { ...inputConfig }; const { logger } = config; diff --git a/lib/workers/repository/onboarding/pr/base-branch.js b/lib/workers/repository/onboarding/pr/base-branch.js new file mode 100644 index 0000000000000000000000000000000000000000..f4b376197f9f9b222a296a8f25abcc2f50233eee --- /dev/null +++ b/lib/workers/repository/onboarding/pr/base-branch.js @@ -0,0 +1,10 @@ +function getBaseBranchDesc(config) { + // Describe base branch only if it's configured + return config.baseBranch + ? `You have configured renovate to use branch \`${config.baseBranch}\` as base branch.\n\n` + : ''; +} + +module.exports = { + getBaseBranchDesc, +}; diff --git a/lib/workers/repository/onboarding/pr/config-description.js b/lib/workers/repository/onboarding/pr/config-description.js new file mode 100644 index 0000000000000000000000000000000000000000..e12788e55d43ac985f4f0d4fb127b956654f431d --- /dev/null +++ b/lib/workers/repository/onboarding/pr/config-description.js @@ -0,0 +1,83 @@ +function getAssigneesDesc(config) { + const { logger } = config; + logger.debug('getAssigneesDesc()'); + logger.trace({ config }); + if (!(config.assignees && config.assignees.length)) { + logger.debug('No assignees configuration'); + return []; + } + logger.debug('Found assignees config'); + let desc = `Assign PRs to `; + desc += config.assignees + .map(assignee => (assignee[0] === '@' ? assignee : `@${assignee}`)) + .join(' and '); + return [desc]; +} + +function getLabelsDesc(config) { + const { logger } = config; + logger.debug('getLabelsDesc()'); + logger.trace({ config }); + if (!(config.labels && config.labels.length)) { + logger.debug('No labels configuration'); + return []; + } + let desc = 'Apply label'; + if (config.labels.length > 1) { + desc += 's'; + } + desc += ` ${config.labels.map(label => `\`${label}\``).join(' and ')} to PRs`; + return [desc]; +} + +function getScheduleDesc(config) { + const { logger } = config; + logger.debug('getScheduleDesc()'); + logger.trace({ config }); + if (!(config.schedule && config.schedule.length)) { + logger.debug('No schedule'); + return []; + } + const desc = `Run Renovate on following schedule: ${config.schedule}`; + return [desc]; +} + +function getDescriptionArray(config) { + const { logger } = config; + logger.debug('getDescriptionArray()'); + logger.trace({ config }); + return (config.description || []) + .concat(getAssigneesDesc(config)) + .concat(getLabelsDesc(config)) + .concat(getScheduleDesc(config)); +} + +function getConfigDesc(config) { + const { logger } = config; + logger.debug('getConfigDesc()'); + logger.trace({ config }); + const descriptionArr = getDescriptionArray(config); + if (!descriptionArr.length) { + logger.debug('No config description found'); + return ''; + } + logger.debug({ length: descriptionArr.length }, 'Found description array'); + let desc = `\n## Configuration Summary\n\nBased on the currently configured presets, Renovate will:\n\n`; + desc += + ' - Start dependency updates once this Configure Renovate PR is merged or closed\n'; + descriptionArr.forEach(d => { + desc += ` - ${d}\n`; + }); + desc += '\n'; + desc += `Would you like to change the way Renovate is upgrading your dependencies?`; + desc += ` Simply edit the \`renovate.json\` in this branch and this Pull Request description will be updated the next time Renovate runs. `; + desc += '\n\n---\n'; + return desc; +} + +module.exports = { + getAssigneesDesc, + getLabelsDesc, + getScheduleDesc, + getConfigDesc, +}; diff --git a/lib/workers/repository/onboarding/pr/errors-warnings.js b/lib/workers/repository/onboarding/pr/errors-warnings.js new file mode 100644 index 0000000000000000000000000000000000000000..1ef29911f6c6121a03238082980faf75ffa4a4d9 --- /dev/null +++ b/lib/workers/repository/onboarding/pr/errors-warnings.js @@ -0,0 +1,31 @@ +function getWarnings(config) { + if (!config.warnings.length) { + return ''; + } + let warningText = `\n### Warnings (${config.warnings.length})\n\n`; + warningText += `Please correct - or verify that you can safely ignore - these warnings before you merge this PR.\n\n`; + config.warnings.forEach(w => { + warningText += `- \`${w.depName}\`: ${w.message}\n`; + }); + warningText += '\n---\n'; + return warningText; +} + +function getErrors(config) { + let errorText = ''; + if (!config.errors.length) { + return ''; + } + errorText = `\n### Errors (${config.errors.length})\n\n`; + errorText += `Renovate has found errors that you should fix (in this branch) before finishing this PR.\n\n`; + config.errors.forEach(e => { + errorText += `- \`${e.depName}\`: ${e.message}\n`; + }); + errorText += '\n---\n'; + return errorText; +} + +module.exports = { + getWarnings, + getErrors, +}; diff --git a/lib/workers/repository/onboarding/pr/index.js b/lib/workers/repository/onboarding/pr/index.js new file mode 100644 index 0000000000000000000000000000000000000000..f89aebd74f08fa0853c54df68042048d4c210db2 --- /dev/null +++ b/lib/workers/repository/onboarding/pr/index.js @@ -0,0 +1,79 @@ +const { getConfigDesc } = require('./config-description'); +const { getErrors, getWarnings } = require('./errors-warnings'); +const { getBaseBranchDesc } = require('./base-branch'); +const { getPrList } = require('./pr-list'); + +const prTemplate = `Welcome to [Renovate](https://renovateapp.com)! + +This is an onboarding PR to help you understand and configure Renovate before any regular Pull Requests begin. Once you close this Pull Request, Renovate will begin keeping your dependencies up-to-date via automated Pull Requests. + +If you have any questions, try reading our [Configuring Renovate](https://renovateapp.com/docs/getting-started/configure-renovate) help page first, or feel free to ask the app author @rarkins a question in a comment below. + +--- +{{CONFIG}} +{{WARNINGS}} +{{ERRORS}} +{{BASEBRANCH}} +{{PRLIST}} + +--- + +#### Don't want a \`renovate.json\` file? + +Renovate will begin once this "Configure Renovate" PR is merged *or* closed, but it's recommended that you add the \`renovate.json\` to your repository to ensure behaviour matches what you see described here. Alternatively, you can add the same configuration settings into a "renovate" section of your \`package.json\` file(s) in this branch and delete the \`renovate.json\` from this PR. + +#### Want to start over? + +If you'd like Renovate to recreate this "Configure Renovate" PR from scratch - for example if your base branch has had substantial changes - then you need to: + +1. (IMPORTANT) Rename this PR to something else, e.g. "Configure Renovate - old" +2. Close the PR and delete the branch + +If later on you ever wish to reconfigure Renovate then you can use this same trick of renaming the PR, but you'll also need to delete any \`renovate.json\` file too. You should then get a new "Configure Renovate" PR like this. +`; + +async function ensureOnboardingPr(config) { + const { logger } = config; + logger.debug('ensureOnboardingPr()'); + logger.trace({ config }); + const onboardingBranch = `${config.branchPrefix}configure`; + const onboardingPrTitle = 'Configure Renovate'; + logger.debug('Filling in onboarding PR template'); + let prBody = prTemplate; + prBody = prBody.replace('{{CONFIG}}\n', getConfigDesc(config)); + prBody = prBody.replace('{{WARNINGS}}\n', getWarnings(config)); + prBody = prBody.replace('{{ERRORS}}\n', getErrors(config)); + prBody = prBody.replace('{{BASEBRANCH}}\n', getBaseBranchDesc(config)); + prBody = prBody.replace('{{PRLIST}}\n', getPrList(config)); + logger.trace('prBody:\n' + prBody); + + // Check if existing PR exists + const existingPr = await config.api.getBranchPr( + `${config.branchPrefix}configure` + ); + if (existingPr) { + // Check if existing PR needs updating + if (existingPr.title === onboardingPrTitle && existingPr.body === prBody) { + logger.info(`${existingPr.displayNumber} does not need updating`); + return; + } + // PR must need updating + await config.api.updatePr(existingPr.number, onboardingPrTitle, prBody); + logger.info(`Updated ${existingPr.displayNumber}`); + return; + } + const labels = []; + const useDefaultBranch = true; + const pr = await config.api.createPr( + onboardingBranch, + onboardingPrTitle, + prBody, + labels, + useDefaultBranch + ); + logger.info({ pr: pr.displayNumber }, 'Created onboarding PR'); +} + +module.exports = { + ensureOnboardingPr, +}; diff --git a/lib/workers/repository/onboarding/pr/pr-list.js b/lib/workers/repository/onboarding/pr/pr-list.js new file mode 100644 index 0000000000000000000000000000000000000000..8ad0fe8dc55cf5e6ad09bf2fc8b24dea0750192b --- /dev/null +++ b/lib/workers/repository/onboarding/pr/pr-list.js @@ -0,0 +1,51 @@ +function getPrList(config) { + const { branches, logger } = config; + logger.debug('getPrList()'); + logger.trace({ config }); + let prDesc = `\n### What to Expect\n\n`; + if (!branches.length) { + return `${prDesc}It looks like your repository dependencies are already up-to-date and no Pull Requests will be necessary right away.\n`; + } + prDesc += `With your current configuration, Renovate will create ${branches.length} Pull Request`; + prDesc += branches.length > 1 ? `s:\n\n` : `:\n\n`; + + for (const [index, branch] of branches.entries()) { + const prTitleRe = /@([a-z]+\/[a-z]+)/; + prDesc += `${index + 1}. **${branch.prTitle.replace( + prTitleRe, + '@​$1' + )}**\n\n`; + if (branch.schedule && branch.schedule.length) { + prDesc += ` - Schedule: ${JSON.stringify(branch.schedule)}\n`; + } + prDesc += ` - Branch name: \`${branch.branchName}\`\n`; + for (const upgrade of branch.upgrades) { + if (upgrade.type === 'lockFileMaintenance') { + prDesc += ' - Regenerates lock file to use latest dependency versions'; + } else { + if (upgrade.isPin) { + prDesc += ' - Pins '; + } else { + prDesc += ' - Upgrades '; + } + if (upgrade.repositoryUrl) { + prDesc += `[${upgrade.depName}](${upgrade.repositoryUrl})`; + } else { + prDesc += upgrade.depName.replace(prTitleRe, '@​$1'); + } + prDesc += ` in \`${upgrade.depType}\` `; + if (!upgrade.isPin) { + prDesc += `from \`${upgrade.currentVersion}\` `; + } + prDesc += `to \`${upgrade.newVersion}\``; + prDesc += '\n'; + } + } + prDesc += '\n\n'; + } + return prDesc; +} + +module.exports = { + getPrList, +}; diff --git a/test/.eslintrc.js b/test/.eslintrc.js index ebd8e158a3aa415bdb698d46c34c84c7fada738f..017c81540fd43417548069c72a5b48dce84d6ecb 100644 --- a/test/.eslintrc.js +++ b/test/.eslintrc.js @@ -3,6 +3,7 @@ module.exports = { jest: true, }, rules: { + 'prefer-destructuring': 0, 'prefer-promise-reject-errors': 0, 'import/no-extraneous-dependencies': 0, 'global-require': 0, diff --git a/test/workers/repository/__snapshots__/onboarding.spec.js.snap b/test/workers/repository/__snapshots__/onboarding.spec.js.snap index f91b67f9e771ae6df5a2dbe8e3c4cd65700d6865..a4a877009340171ac7620d996cd3cd2b86a0ea4b 100644 --- a/test/workers/repository/__snapshots__/onboarding.spec.js.snap +++ b/test/workers/repository/__snapshots__/onboarding.spec.js.snap @@ -1,380 +1,5 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`lib/workers/repository/onboarding ensurePr(config, branchUpgrades) creates complex pr 1`] = ` -Array [ - Array [ - "renovate/configure", - "Configure Renovate", - "Welcome to [Renovate](https://renovateapp.com)! - -This is an onboarding PR to help you understand and configure Renovate before any regular Pull Requests begin. Once you close this Pull Request, Renovate will begin keeping your dependencies up-to-date via automated Pull Requests. - -If you have any questions, try reading our [Getting Started Configuring Renovate](https://renovateapp.com/docs/getting-started/configure-renovate) page first, or feel free to ask the app author @rarkins a question in a comment below. - ---- - - -With your current configuration, renovate will initially create the following Pull Requests: - -| Pull Requests (2) | -| ------ | -| **Pin a**<ul><li>Branch name: \`branch-a\`</li><li>Pins [a](https://a) in \`undefined\` to \`1.1.0\`</li></ul> | -| **Upgrade b**<ul><li>Schedule: \\"on monday\\"</li><li>Branch name: \`branch-b\`</li><li>Upgrades b in \`undefined\` from \`1.0.0\` to \`2.0.0\`</li></ul> | - - -Sometimes you may see multiple options for the same dependency (e.g. pinning in one branch and upgrading in another). This is expected and allows you the flexibility to choose which to merge first. Once you merge any PR, others will be updated or removed the next time Renovate runs. - -Would you like to change the way Renovate is upgrading your dependencies? Simply edit the \`renovate.json\` in this branch and this Pull Request description will be updated the next time Renovate runs. - -Our [Configuration Docs](https://renovateapp.com/docs/) should be helpful if you wish to modify any behaviour. - ---- - -#### Don't want a \`renovate.json\` file? - -You are not required to *merge* this Pull Request - Renovate will begin even if this \\"Configure Renovate\\" PR is closed *unmerged* and without a \`renovate.json\` file. However, it's recommended that you add configuration to your repository to ensure behaviour matches what you see described here. - -Alternatively, you can add the same configuration settings into a \\"renovate\\" section of your \`package.json\` file(s) in this branch and delete the \`renovate.json\` from this PR. If you make these configuration changes in this branch then the results will be described in this PR after the next time Renovate runs. - -#### Want to start over? - -If you'd like Renovate to recreate this \\"Configure Renovate\\" PR from scratch - for example if your base branch has had substantial changes - then you need to: - -1. (IMPORTANT) Rename this PR to something else, e.g. \\"Configure Renovate - old\\" -2. Close the PR and delete the branch - -If later on you ever wish to reconfigure Renovate then you can use this same trick of renaming the PR, but you'll also need to delete any \`renovate.json\` file too. You should then get a new \\"Configure Renovate\\" PR like this. -", - Array [], - true, - ], -] -`; - -exports[`lib/workers/repository/onboarding ensurePr(config, branchUpgrades) creates pr 1`] = ` -Array [ - Array [ - "renovate/configure", - "Configure Renovate", - "Welcome to [Renovate](https://renovateapp.com)! - -This is an onboarding PR to help you understand and configure Renovate before any regular Pull Requests begin. Once you close this Pull Request, Renovate will begin keeping your dependencies up-to-date via automated Pull Requests. - -If you have any questions, try reading our [Getting Started Configuring Renovate](https://renovateapp.com/docs/getting-started/configure-renovate) page first, or feel free to ask the app author @rarkins a question in a comment below. - ---- - -You have configured renovate to use branch \`next\` as base branch. - -It looks like your repository dependencies are already up-to-date and no initial Pull Requests will be necessary. - -Sometimes you may see multiple options for the same dependency (e.g. pinning in one branch and upgrading in another). This is expected and allows you the flexibility to choose which to merge first. Once you merge any PR, others will be updated or removed the next time Renovate runs. - -Would you like to change the way Renovate is upgrading your dependencies? Simply edit the \`renovate.json\` in this branch and this Pull Request description will be updated the next time Renovate runs. - -Our [Configuration Docs](https://renovateapp.com/docs/) should be helpful if you wish to modify any behaviour. - ---- - -#### Don't want a \`renovate.json\` file? - -You are not required to *merge* this Pull Request - Renovate will begin even if this \\"Configure Renovate\\" PR is closed *unmerged* and without a \`renovate.json\` file. However, it's recommended that you add configuration to your repository to ensure behaviour matches what you see described here. - -Alternatively, you can add the same configuration settings into a \\"renovate\\" section of your \`package.json\` file(s) in this branch and delete the \`renovate.json\` from this PR. If you make these configuration changes in this branch then the results will be described in this PR after the next time Renovate runs. - -#### Want to start over? - -If you'd like Renovate to recreate this \\"Configure Renovate\\" PR from scratch - for example if your base branch has had substantial changes - then you need to: - -1. (IMPORTANT) Rename this PR to something else, e.g. \\"Configure Renovate - old\\" -2. Close the PR and delete the branch - -If later on you ever wish to reconfigure Renovate then you can use this same trick of renaming the PR, but you'll also need to delete any \`renovate.json\` file too. You should then get a new \\"Configure Renovate\\" PR like this. -", - Array [], - true, - ], -] -`; - -exports[`lib/workers/repository/onboarding ensurePr(config, branchUpgrades) creates pr with dynamic descriptions 1`] = ` -Array [ - "renovate/configure", - "Configure Renovate", - "Welcome to [Renovate](https://renovateapp.com)! - -This is an onboarding PR to help you understand and configure Renovate before any regular Pull Requests begin. Once you close this Pull Request, Renovate will begin keeping your dependencies up-to-date via automated Pull Requests. - -If you have any questions, try reading our [Getting Started Configuring Renovate](https://renovateapp.com/docs/getting-started/configure-renovate) page first, or feel free to ask the app author @rarkins a question in a comment below. - ---- - -## Configuration Summary - -Based on the currently configured presets, Renovate will: -<ul> - <li>Start dependency updates once this Configure Renovate PR is merged or closed</li> - <li>Assign PRs to @rarkins</li> - <li>Apply labels <code>renovate</code> and <code>upgrades</code> to PRs</li> - <li>Run Renovate on following schedule: before 5am</li> - -</ul> - ---- - -It looks like your repository dependencies are already up-to-date and no initial Pull Requests will be necessary. - -Sometimes you may see multiple options for the same dependency (e.g. pinning in one branch and upgrading in another). This is expected and allows you the flexibility to choose which to merge first. Once you merge any PR, others will be updated or removed the next time Renovate runs. - -Would you like to change the way Renovate is upgrading your dependencies? Simply edit the \`renovate.json\` in this branch and this Pull Request description will be updated the next time Renovate runs. - -Our [Configuration Docs](https://renovateapp.com/docs/) should be helpful if you wish to modify any behaviour. - ---- - -#### Don't want a \`renovate.json\` file? - -You are not required to *merge* this Pull Request - Renovate will begin even if this \\"Configure Renovate\\" PR is closed *unmerged* and without a \`renovate.json\` file. However, it's recommended that you add configuration to your repository to ensure behaviour matches what you see described here. - -Alternatively, you can add the same configuration settings into a \\"renovate\\" section of your \`package.json\` file(s) in this branch and delete the \`renovate.json\` from this PR. If you make these configuration changes in this branch then the results will be described in this PR after the next time Renovate runs. - -#### Want to start over? - -If you'd like Renovate to recreate this \\"Configure Renovate\\" PR from scratch - for example if your base branch has had substantial changes - then you need to: - -1. (IMPORTANT) Rename this PR to something else, e.g. \\"Configure Renovate - old\\" -2. Close the PR and delete the branch - -If later on you ever wish to reconfigure Renovate then you can use this same trick of renaming the PR, but you'll also need to delete any \`renovate.json\` file too. You should then get a new \\"Configure Renovate\\" PR like this. -", - Array [], - true, -] -`; - -exports[`lib/workers/repository/onboarding ensurePr(config, branchUpgrades) creates pr with preset descriptions 1`] = ` -Array [ - "renovate/configure", - "Configure Renovate", - "Welcome to [Renovate](https://renovateapp.com)! - -This is an onboarding PR to help you understand and configure Renovate before any regular Pull Requests begin. Once you close this Pull Request, Renovate will begin keeping your dependencies up-to-date via automated Pull Requests. - -If you have any questions, try reading our [Getting Started Configuring Renovate](https://renovateapp.com/docs/getting-started/configure-renovate) page first, or feel free to ask the app author @rarkins a question in a comment below. - ---- - -## Configuration Summary - -Based on the currently configured presets, Renovate will: -<ul> - <li>Start dependency updates once this Configure Renovate PR is merged or closed</li> - <li>Description 1</li> - <li>Description 2</li> - -</ul> - ---- - -It looks like your repository dependencies are already up-to-date and no initial Pull Requests will be necessary. - -Sometimes you may see multiple options for the same dependency (e.g. pinning in one branch and upgrading in another). This is expected and allows you the flexibility to choose which to merge first. Once you merge any PR, others will be updated or removed the next time Renovate runs. - -Would you like to change the way Renovate is upgrading your dependencies? Simply edit the \`renovate.json\` in this branch and this Pull Request description will be updated the next time Renovate runs. - -Our [Configuration Docs](https://renovateapp.com/docs/) should be helpful if you wish to modify any behaviour. - ---- - -#### Don't want a \`renovate.json\` file? - -You are not required to *merge* this Pull Request - Renovate will begin even if this \\"Configure Renovate\\" PR is closed *unmerged* and without a \`renovate.json\` file. However, it's recommended that you add configuration to your repository to ensure behaviour matches what you see described here. - -Alternatively, you can add the same configuration settings into a \\"renovate\\" section of your \`package.json\` file(s) in this branch and delete the \`renovate.json\` from this PR. If you make these configuration changes in this branch then the results will be described in this PR after the next time Renovate runs. - -#### Want to start over? - -If you'd like Renovate to recreate this \\"Configure Renovate\\" PR from scratch - for example if your base branch has had substantial changes - then you need to: - -1. (IMPORTANT) Rename this PR to something else, e.g. \\"Configure Renovate - old\\" -2. Close the PR and delete the branch - -If later on you ever wish to reconfigure Renovate then you can use this same trick of renaming the PR, but you'll also need to delete any \`renovate.json\` file too. You should then get a new \\"Configure Renovate\\" PR like this. -", - Array [], - true, -] -`; - -exports[`lib/workers/repository/onboarding ensurePr(config, branchUpgrades) creates shows warnings and errors 1`] = ` -Array [ - Array [ - "renovate/configure", - "Configure Renovate", - "Welcome to [Renovate](https://renovateapp.com)! - -This is an onboarding PR to help you understand and configure Renovate before any regular Pull Requests begin. Once you close this Pull Request, Renovate will begin keeping your dependencies up-to-date via automated Pull Requests. - -If you have any questions, try reading our [Getting Started Configuring Renovate](https://renovateapp.com/docs/getting-started/configure-renovate) page first, or feel free to ask the app author @rarkins a question in a comment below. - ---- - -### Errors (1) - -Renovate has raised errors when processing this repository that you should fix before merging or closing this PR. - -Please make any fixes in _this branch_. -- \`a\`: uhoh a - -Feel free to raise create a [GitHub Issue](https:/github.com/singapore/renovate/issues) to ask any questions. - ---- - -### Warnings (1) - -Please correct - or verify that you can safely ignore - these warnings before you merge this PR. -- \`b\`: uhoh b - ---- - - -With your current configuration, renovate will initially create the following Pull Requests: - -| Pull Requests (2) | -| ------ | -| **Pin a**<ul><li>Branch name: \`branch-a\`</li><li>Pins [a](https://a) in \`undefined\` to \`1.1.0\`</li></ul> | -| **Upgrade b**<ul><li>Branch name: \`branch-b\`</li><li>Upgrades [b](https://b) in \`undefined\` from \`1.0.0\` to \`2.0.0\`</li></ul> | - - -Sometimes you may see multiple options for the same dependency (e.g. pinning in one branch and upgrading in another). This is expected and allows you the flexibility to choose which to merge first. Once you merge any PR, others will be updated or removed the next time Renovate runs. - -Would you like to change the way Renovate is upgrading your dependencies? Simply edit the \`renovate.json\` in this branch and this Pull Request description will be updated the next time Renovate runs. - -Our [Configuration Docs](https://renovateapp.com/docs/) should be helpful if you wish to modify any behaviour. - ---- - -#### Don't want a \`renovate.json\` file? - -You are not required to *merge* this Pull Request - Renovate will begin even if this \\"Configure Renovate\\" PR is closed *unmerged* and without a \`renovate.json\` file. However, it's recommended that you add configuration to your repository to ensure behaviour matches what you see described here. - -Alternatively, you can add the same configuration settings into a \\"renovate\\" section of your \`package.json\` file(s) in this branch and delete the \`renovate.json\` from this PR. If you make these configuration changes in this branch then the results will be described in this PR after the next time Renovate runs. - -#### Want to start over? - -If you'd like Renovate to recreate this \\"Configure Renovate\\" PR from scratch - for example if your base branch has had substantial changes - then you need to: - -1. (IMPORTANT) Rename this PR to something else, e.g. \\"Configure Renovate - old\\" -2. Close the PR and delete the branch - -If later on you ever wish to reconfigure Renovate then you can use this same trick of renaming the PR, but you'll also need to delete any \`renovate.json\` file too. You should then get a new \\"Configure Renovate\\" PR like this. -", - Array [], - true, - ], -] -`; - -exports[`lib/workers/repository/onboarding ensurePr(config, branchUpgrades) handles groups 1`] = ` -Array [ - Array [ - "renovate/configure", - "Configure Renovate", - "Welcome to [Renovate](https://renovateapp.com)! - -This is an onboarding PR to help you understand and configure Renovate before any regular Pull Requests begin. Once you close this Pull Request, Renovate will begin keeping your dependencies up-to-date via automated Pull Requests. - -If you have any questions, try reading our [Getting Started Configuring Renovate](https://renovateapp.com/docs/getting-started/configure-renovate) page first, or feel free to ask the app author @rarkins a question in a comment below. - ---- - - -With your current configuration, renovate will initially create the following Pull Requests: - -| Pull Requests (1) | -| ------ | -| **Pin a**<ul><li>Branch name: \`branch-a\`</li><li>Pins [a](https://a) in \`undefined\` to \`1.1.0\`</li><li>Upgrades [b](https://b) in \`undefined\` from \`1.0.0\` to \`2.0.0\`</li></ul> | - - -Sometimes you may see multiple options for the same dependency (e.g. pinning in one branch and upgrading in another). This is expected and allows you the flexibility to choose which to merge first. Once you merge any PR, others will be updated or removed the next time Renovate runs. - -Would you like to change the way Renovate is upgrading your dependencies? Simply edit the \`renovate.json\` in this branch and this Pull Request description will be updated the next time Renovate runs. - -Our [Configuration Docs](https://renovateapp.com/docs/) should be helpful if you wish to modify any behaviour. - ---- - -#### Don't want a \`renovate.json\` file? - -You are not required to *merge* this Pull Request - Renovate will begin even if this \\"Configure Renovate\\" PR is closed *unmerged* and without a \`renovate.json\` file. However, it's recommended that you add configuration to your repository to ensure behaviour matches what you see described here. - -Alternatively, you can add the same configuration settings into a \\"renovate\\" section of your \`package.json\` file(s) in this branch and delete the \`renovate.json\` from this PR. If you make these configuration changes in this branch then the results will be described in this PR after the next time Renovate runs. - -#### Want to start over? - -If you'd like Renovate to recreate this \\"Configure Renovate\\" PR from scratch - for example if your base branch has had substantial changes - then you need to: - -1. (IMPORTANT) Rename this PR to something else, e.g. \\"Configure Renovate - old\\" -2. Close the PR and delete the branch - -If later on you ever wish to reconfigure Renovate then you can use this same trick of renaming the PR, but you'll also need to delete any \`renovate.json\` file too. You should then get a new \\"Configure Renovate\\" PR like this. -", - Array [], - true, - ], -] -`; - -exports[`lib/workers/repository/onboarding ensurePr(config, branchUpgrades) maintains yarn.lock 1`] = ` -Array [ - Array [ - "renovate/configure", - "Configure Renovate", - "Welcome to [Renovate](https://renovateapp.com)! - -This is an onboarding PR to help you understand and configure Renovate before any regular Pull Requests begin. Once you close this Pull Request, Renovate will begin keeping your dependencies up-to-date via automated Pull Requests. - -If you have any questions, try reading our [Getting Started Configuring Renovate](https://renovateapp.com/docs/getting-started/configure-renovate) page first, or feel free to ask the app author @rarkins a question in a comment below. - ---- - - -With your current configuration, renovate will initially create the following Pull Requests: - -| Pull Requests (1) | -| ------ | -| **Lock File Maintenance**<ul><li>Schedule: \\"before 5am on monday\\"</li><li>Branch name: \`renovate/lock-files\`</li><li>Regenerates lock file to use latest dependency versions</li></ul> | - - -Sometimes you may see multiple options for the same dependency (e.g. pinning in one branch and upgrading in another). This is expected and allows you the flexibility to choose which to merge first. Once you merge any PR, others will be updated or removed the next time Renovate runs. - -Would you like to change the way Renovate is upgrading your dependencies? Simply edit the \`renovate.json\` in this branch and this Pull Request description will be updated the next time Renovate runs. - -Our [Configuration Docs](https://renovateapp.com/docs/) should be helpful if you wish to modify any behaviour. - ---- - -#### Don't want a \`renovate.json\` file? - -You are not required to *merge* this Pull Request - Renovate will begin even if this \\"Configure Renovate\\" PR is closed *unmerged* and without a \`renovate.json\` file. However, it's recommended that you add configuration to your repository to ensure behaviour matches what you see described here. - -Alternatively, you can add the same configuration settings into a \\"renovate\\" section of your \`package.json\` file(s) in this branch and delete the \`renovate.json\` from this PR. If you make these configuration changes in this branch then the results will be described in this PR after the next time Renovate runs. - -#### Want to start over? - -If you'd like Renovate to recreate this \\"Configure Renovate\\" PR from scratch - for example if your base branch has had substantial changes - then you need to: - -1. (IMPORTANT) Rename this PR to something else, e.g. \\"Configure Renovate - old\\" -2. Close the PR and delete the branch - -If later on you ever wish to reconfigure Renovate then you can use this same trick of renaming the PR, but you'll also need to delete any \`renovate.json\` file too. You should then get a new \\"Configure Renovate\\" PR like this. -", - Array [], - true, - ], -] -`; - exports[`lib/workers/repository/onboarding getOnboardingStatus(config) commits files and returns false if no pr 1`] = ` Array [ "renovate/configure", diff --git a/test/workers/repository/index.spec.js b/test/workers/repository/index.spec.js index e5cdff6bb40f151b823e818cd171ccf21ac48893..bc0100dff661f43e20806b0f57095b46a111055a 100644 --- a/test/workers/repository/index.spec.js +++ b/test/workers/repository/index.spec.js @@ -7,6 +7,9 @@ const onboarding = require('../../../lib/workers/repository/onboarding'); const upgrades = require('../../../lib/workers/repository/upgrades'); const logger = require('../../_fixtures/logger'); +const onboardingPr = require('../../../lib/workers/repository/onboarding/pr'); + +jest.mock('../../../lib/workers/repository/onboarding/pr'); describe('workers/repository', () => { describe('pinDependenciesFirst', () => { @@ -50,7 +53,6 @@ describe('workers/repository', () => { apis.resolvePackageFiles = jest.fn(input => input); apis.checkMonorepos = jest.fn(input => input); onboarding.getOnboardingStatus = jest.fn(input => input); - onboarding.ensurePr = jest.fn(); upgrades.determineRepoUpgrades = jest.fn(() => []); upgrades.branchifyUpgrades = jest.fn(() => ({ branchUpgrades: {} })); branchWorker.processBranch = jest.fn(() => 'done'); @@ -119,7 +121,7 @@ describe('workers/repository', () => { await repositoryWorker.renovateRepository(config); expect(onboarding.getOnboardingStatus.mock.calls.length).toBe(1); expect(branchWorker.processBranch.mock.calls.length).toBe(0); - expect(onboarding.ensurePr.mock.calls.length).toBe(1); + expect(onboardingPr.ensureOnboardingPr.mock.calls.length).toBe(1); expect(config.logger.error.mock.calls.length).toBe(0); }); it('uses onboarding custom baseBranch', async () => { @@ -137,7 +139,7 @@ describe('workers/repository', () => { await repositoryWorker.renovateRepository(config); expect(onboarding.getOnboardingStatus.mock.calls.length).toBe(1); expect(branchWorker.processBranch.mock.calls.length).toBe(0); - expect(onboarding.ensurePr.mock.calls.length).toBe(1); + expect(onboardingPr.ensureOnboardingPr.mock.calls.length).toBe(1); expect(config.logger.error.mock.calls.length).toBe(0); }); it('errors onboarding custom baseBranch', async () => { @@ -157,7 +159,7 @@ describe('workers/repository', () => { await repositoryWorker.renovateRepository(config); expect(onboarding.getOnboardingStatus.mock.calls.length).toBe(1); expect(branchWorker.processBranch.mock.calls.length).toBe(0); - expect(onboarding.ensurePr.mock.calls.length).toBe(1); + expect(onboardingPr.ensureOnboardingPr.mock.calls.length).toBe(1); expect(config.logger.error.mock.calls.length).toBe(0); }); it('calls branchWorker', async () => { diff --git a/test/workers/repository/onboarding.spec.js b/test/workers/repository/onboarding.spec.js index 739219251e1524d17114930adaf4cc6dc6720e3b..d3f610634a33188c48c2f657564ff0a386ba8408 100644 --- a/test/workers/repository/onboarding.spec.js +++ b/test/workers/repository/onboarding.spec.js @@ -4,194 +4,6 @@ const logger = require('../../_fixtures/logger'); const defaultConfig = require('../../../lib/config/defaults').getConfig(); describe('lib/workers/repository/onboarding', () => { - describe('ensurePr(config, branchUpgrades)', () => { - let config; - let branchUpgrades; - beforeEach(() => { - config = { - branchPrefix: 'renovate/', - errors: [], - warnings: [], - api: { - createPr: jest.fn(() => ({ displayNumber: 1 })), - getBranchPr: jest.fn(), - updatePr: jest.fn(), - }, - logger, - }; - branchUpgrades = []; - }); - it('creates pr', async () => { - config.contentBaseBranch = 'next'; - await onboarding.ensurePr(config, branchUpgrades); - expect(config.api.createPr.mock.calls.length).toBe(1); - expect(config.api.updatePr.mock.calls.length).toBe(0); - expect(config.api.createPr.mock.calls).toMatchSnapshot(); - }); - it('creates pr with preset descriptions', async () => { - config.description = ['Description 1', 'Description 2']; - await onboarding.ensurePr(config, branchUpgrades); - expect(config.api.createPr.mock.calls.length).toBe(1); - expect(config.api.updatePr.mock.calls.length).toBe(0); - expect( - config.api.createPr.mock.calls[0][2].indexOf('## Configuration Summary') - ).not.toBe(-1); - expect(config.api.createPr.mock.calls[0]).toMatchSnapshot(); - }); - it('creates pr with dynamic descriptions', async () => { - config.labels = ['renovate', 'upgrades']; - config.assignees = ['rarkins']; - config.schedule = ['before 5am']; - await onboarding.ensurePr(config, branchUpgrades); - expect(config.api.createPr.mock.calls.length).toBe(1); - expect(config.api.updatePr.mock.calls.length).toBe(0); - expect( - config.api.createPr.mock.calls[0][2].indexOf('## Configuration Summary') - ).not.toBe(-1); - expect(config.api.createPr.mock.calls[0]).toMatchSnapshot(); - }); - it('updates pr', async () => { - config.api.getBranchPr.mockReturnValueOnce({}); - await onboarding.ensurePr(config, branchUpgrades); - expect(config.api.createPr.mock.calls.length).toBe(0); - expect(config.api.updatePr.mock.calls.length).toBe(1); - }); - it('does not update pr', async () => { - // prettier-ignore - const existingPrBody = "Welcome to [Renovate](https://renovateapp.com)!\n\nThis is an onboarding PR to help you understand and configure Renovate before any regular Pull Requests begin. Once you close this Pull Request, Renovate will begin keeping your dependencies up-to-date via automated Pull Requests.\n\nIf you have any questions, try reading our [Getting Started Configuring Renovate](https://renovateapp.com/docs/getting-started/configure-renovate) page first, or feel free to ask the app author @rarkins a question in a comment below.\n\n---\n\nIt looks like your repository dependencies are already up-to-date and no initial Pull Requests will be necessary.\n\nSometimes you may see multiple options for the same dependency (e.g. pinning in one branch and upgrading in another). This is expected and allows you the flexibility to choose which to merge first. Once you merge any PR, others will be updated or removed the next time Renovate runs.\n\nWould you like to change the way Renovate is upgrading your dependencies? Simply edit the `renovate.json` in this branch and this Pull Request description will be updated the next time Renovate runs.\n\nOur [Configuration Docs](https://renovateapp.com/docs/) should be helpful if you wish to modify any behaviour.\n\n---\n\n#### Don't want a `renovate.json` file?\n\nYou are not required to *merge* this Pull Request - Renovate will begin even if this \"Configure Renovate\" PR is closed *unmerged* and without a `renovate.json` file. However, it's recommended that you add configuration to your repository to ensure behaviour matches what you see described here.\n\nAlternatively, you can add the same configuration settings into a \"renovate\" section of your `package.json` file(s) in this branch and delete the `renovate.json` from this PR. If you make these configuration changes in this branch then the results will be described in this PR after the next time Renovate runs.\n\n#### Want to start over?\n\nIf you'd like Renovate to recreate this \"Configure Renovate\" PR from scratch - for example if your base branch has had substantial changes - then you need to:\n\n1. (IMPORTANT) Rename this PR to something else, e.g. \"Configure Renovate - old\"\n2. Close the PR and delete the branch\n\nIf later on you ever wish to reconfigure Renovate then you can use this same trick of renaming the PR, but you'll also need to delete any `renovate.json` file too. You should then get a new \"Configure Renovate\" PR like this.\n"; - config.api.getBranchPr.mockReturnValueOnce({ - title: 'Configure Renovate', - body: existingPrBody, - }); - await onboarding.ensurePr(config, branchUpgrades); - expect(config.api.createPr.mock.calls.length).toBe(0); - expect(config.api.updatePr.mock.calls.length).toBe(0); - }); - it('creates complex pr', async () => { - branchUpgrades = [ - { - branchName: 'branch-a', - prTitle: 'Pin a', - upgrades: [ - { - isPin: true, - depName: 'a', - repositoryUrl: 'https://a', - currentVersion: '^1.0.0', - newVersion: '1.1.0', - }, - ], - }, - { - branchName: 'branch-b', - prTitle: 'Upgrade b', - schedule: 'on monday', - upgrades: [ - { - depName: 'b', - currentVersion: '1.0.0', - newVersion: '2.0.0', - }, - ], - }, - ]; - await onboarding.ensurePr(config, branchUpgrades); - expect(config.api.createPr.mock.calls.length).toBe(1); - expect(config.api.updatePr.mock.calls.length).toBe(0); - expect(config.api.createPr.mock.calls).toMatchSnapshot(); - }); - it('maintains yarn.lock', async () => { - branchUpgrades = [ - { - branchName: 'renovate/lock-files', - prTitle: 'Lock File Maintenance', - schedule: 'before 5am on monday', - upgrades: [ - { - type: 'lockFileMaintenance', - }, - ], - }, - ]; - await onboarding.ensurePr(config, branchUpgrades); - expect(config.api.createPr.mock.calls.length).toBe(1); - expect(config.api.updatePr.mock.calls.length).toBe(0); - expect(config.api.createPr.mock.calls).toMatchSnapshot(); - }); - it('handles groups', async () => { - branchUpgrades = [ - { - branchName: 'branch-a', - prTitle: 'Pin a', - groupName: 'some-group', - upgrades: [ - { - isPin: true, - depName: 'a', - repositoryUrl: 'https://a', - currentVersion: '^1.0.0', - newVersion: '1.1.0', - }, - { - depName: 'b', - repositoryUrl: 'https://b', - currentVersion: '1.0.0', - newVersion: '2.0.0', - }, - ], - }, - ]; - await onboarding.ensurePr(config, branchUpgrades); - expect(config.api.createPr.mock.calls.length).toBe(1); - expect(config.api.updatePr.mock.calls.length).toBe(0); - expect(config.api.createPr.mock.calls).toMatchSnapshot(); - }); - it('creates shows warnings and errors', async () => { - branchUpgrades = [ - { - branchName: 'branch-a', - prTitle: 'Pin a', - upgrades: [ - { - isPin: true, - depName: 'a', - repositoryUrl: 'https://a', - currentVersion: '^1.0.0', - newVersion: '1.1.0', - }, - ], - }, - { - branchName: 'branch-b', - prTitle: 'Upgrade b', - upgrades: [ - { - depName: 'b', - repositoryUrl: 'https://b', - currentVersion: '1.0.0', - newVersion: '2.0.0', - }, - ], - }, - ]; - config.errors = [ - { - depName: 'a', - message: 'uhoh a', - }, - ]; - config.warnings = [ - { - depName: 'b', - message: 'uhoh b', - }, - ]; - await onboarding.ensurePr(config, branchUpgrades); - expect(config.api.createPr.mock.calls.length).toBe(1); - expect(config.api.updatePr.mock.calls.length).toBe(0); - expect(config.api.createPr.mock.calls).toMatchSnapshot(); - }); - }); describe('getOnboardingStatus(config)', () => { let config; beforeEach(() => { diff --git a/test/workers/repository/onboarding/pr/__snapshots__/config-description.spec.js.snap b/test/workers/repository/onboarding/pr/__snapshots__/config-description.spec.js.snap new file mode 100644 index 0000000000000000000000000000000000000000..1f2f712fd7b4b8b6c967bcbeb71f971200881304 --- /dev/null +++ b/test/workers/repository/onboarding/pr/__snapshots__/config-description.spec.js.snap @@ -0,0 +1,37 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`workers/repository/onboarding/pr/config-description getConfigDesc() assignees, labels and schedule 1`] = ` +" +## Configuration Summary + +Based on the currently configured presets, Renovate will: + + - Start dependency updates once this Configure Renovate PR is merged or closed + - Assign PRs to @someone and @someone-else + - Apply labels \`renovate\` and \`deps\` to PRs + - Run Renovate on following schedule: before 5am + +Would you like to change the way Renovate is upgrading your dependencies? Simply edit the \`renovate.json\` in this branch and this Pull Request description will be updated the next time Renovate runs. + +--- +" +`; + +exports[`workers/repository/onboarding/pr/config-description getConfigDesc() returns a list 1`] = ` +" +## Configuration Summary + +Based on the currently configured presets, Renovate will: + + - Start dependency updates once this Configure Renovate PR is merged or closed + - description 1 + - description two + - something else + +Would you like to change the way Renovate is upgrading your dependencies? Simply edit the \`renovate.json\` in this branch and this Pull Request description will be updated the next time Renovate runs. + +--- +" +`; + +exports[`workers/repository/onboarding/pr/config-description getConfigDesc() returns empty 1`] = `""`; diff --git a/test/workers/repository/onboarding/pr/__snapshots__/errors-warnings.spec.js.snap b/test/workers/repository/onboarding/pr/__snapshots__/errors-warnings.spec.js.snap new file mode 100644 index 0000000000000000000000000000000000000000..df58d70e944c8cedf8932c4f634c2e5f153310fb --- /dev/null +++ b/test/workers/repository/onboarding/pr/__snapshots__/errors-warnings.spec.js.snap @@ -0,0 +1,25 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`workers/repository/onboarding/pr/errors-warnings getErrors() returns error text 1`] = ` +" +### Errors (1) + +Renovate has found errors that you should fix (in this branch) before finishing this PR. + +- \`renovate.json\`: Failed to parse + +--- +" +`; + +exports[`workers/repository/onboarding/pr/errors-warnings getWarnings() returns warning text 1`] = ` +" +### Warnings (1) + +Please correct - or verify that you can safely ignore - these warnings before you merge this PR. + +- \`foo\`: Failed to look up dependency + +--- +" +`; diff --git a/test/workers/repository/onboarding/pr/__snapshots__/pr-list.spec.js.snap b/test/workers/repository/onboarding/pr/__snapshots__/pr-list.spec.js.snap new file mode 100644 index 0000000000000000000000000000000000000000..d7559ff1f528179c99797dba743cd93babfae6de --- /dev/null +++ b/test/workers/repository/onboarding/pr/__snapshots__/pr-list.spec.js.snap @@ -0,0 +1,38 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`workers/repository/onboarding/pr/pr-list getPrList() handles multiple 1`] = ` +" +### What to Expect + +With your current configuration, Renovate will create 2 Pull Requests: + +1. **Pin dependencies** + + - Branch name: \`renovate/pin-dependencies\` + - Pins [a](https://a) in \`devDependencies\` to \`1.1.0\` + - Pins b in \`devDependencies\` to \`1.5.3\` + + +2. **Update a to v2** + + - Branch name: \`renovate/a-2.x\` + - Upgrades [a](https://a) in \`devDependencies\` from \`^1.0.0\` to \`2.0.1\` + + +" +`; + +exports[`workers/repository/onboarding/pr/pr-list getPrList() has special lock file maintenance description 1`] = ` +" +### What to Expect + +With your current configuration, Renovate will create 1 Pull Request: + +1. **Lock file maintenance** + + - Schedule: [\\"before 5am\\"] + - Branch name: \`renovate/lock-file-maintenance\` + - Regenerates lock file to use latest dependency versions + +" +`; diff --git a/test/workers/repository/onboarding/pr/config-description.spec.js b/test/workers/repository/onboarding/pr/config-description.spec.js new file mode 100644 index 0000000000000000000000000000000000000000..074a9f8e89b2c4ba0a87e01eb72afd15966e7f13 --- /dev/null +++ b/test/workers/repository/onboarding/pr/config-description.spec.js @@ -0,0 +1,40 @@ +const logger = require('../../../../_fixtures/logger'); +const defaultConfig = require('../../../../../lib/config/defaults').getConfig(); + +const { + getConfigDesc, +} = require('../../../../../lib/workers/repository/onboarding/pr/config-description'); + +describe('workers/repository/onboarding/pr/config-description', () => { + describe('getConfigDesc()', () => { + let config; + beforeEach(() => { + jest.resetAllMocks(); + config = { + ...defaultConfig, + logger, + }; + }); + it('returns empty', async () => { + delete config.description; + const res = getConfigDesc(config); + expect(res).toMatchSnapshot(); + }); + it('returns a list', () => { + config.description = [ + 'description 1', + 'description two', + 'something else', + ]; + const res = getConfigDesc(config); + expect(res).toMatchSnapshot(); + }); + it('assignees, labels and schedule', () => { + config.assignees = ['someone', '@someone-else']; + config.labels = ['renovate', 'deps']; + config.schedule = ['before 5am']; + const res = getConfigDesc(config); + expect(res).toMatchSnapshot(); + }); + }); +}); diff --git a/test/workers/repository/onboarding/pr/errors-warnings.spec.js b/test/workers/repository/onboarding/pr/errors-warnings.spec.js new file mode 100644 index 0000000000000000000000000000000000000000..2c29778268a5b6360799381a5204f855b15a3b51 --- /dev/null +++ b/test/workers/repository/onboarding/pr/errors-warnings.spec.js @@ -0,0 +1,50 @@ +const logger = require('../../../../_fixtures/logger'); +const defaultConfig = require('../../../../../lib/config/defaults').getConfig(); + +const { + getWarnings, + getErrors, +} = require('../../../../../lib/workers/repository/onboarding/pr/errors-warnings'); + +describe('workers/repository/onboarding/pr/errors-warnings', () => { + describe('getWarnings()', () => { + let config; + beforeEach(() => { + jest.resetAllMocks(); + config = { + ...defaultConfig, + logger, + }; + }); + it('returns warning text', async () => { + config.warnings = [ + { + depName: 'foo', + message: 'Failed to look up dependency', + }, + ]; + const res = getWarnings(config); + expect(res).toMatchSnapshot(); + }); + }); + describe('getErrors()', () => { + let config; + beforeEach(() => { + jest.resetAllMocks(); + config = { + ...defaultConfig, + logger, + }; + }); + it('returns error text', async () => { + config.errors = [ + { + depName: 'renovate.json', + message: 'Failed to parse', + }, + ]; + const res = getErrors(config); + expect(res).toMatchSnapshot(); + }); + }); +}); diff --git a/test/workers/repository/onboarding/pr/index.spec.js b/test/workers/repository/onboarding/pr/index.spec.js new file mode 100644 index 0000000000000000000000000000000000000000..d44adf6b0ac6464df7bc06dd0390625310e5d385 --- /dev/null +++ b/test/workers/repository/onboarding/pr/index.spec.js @@ -0,0 +1,53 @@ +const logger = require('../../../../_fixtures/logger'); +const defaultConfig = require('../../../../../lib/config/defaults').getConfig(); + +const { + ensureOnboardingPr, +} = require('../../../../../lib/workers/repository/onboarding/pr'); + +describe('workers/repository/onboarding/pr', () => { + describe('ensureOnboardingPr()', () => { + let config; + beforeEach(() => { + jest.resetAllMocks(); + config = { + ...defaultConfig, + logger, + api: { + createPr: jest.fn(() => ({})), + getBranchPr: jest.fn(), + updatePr: jest.fn(), + }, + errors: [], + warnings: [], + description: [], + branches: [], + }; + }); + let createPrBody; + it('creates PR', async () => { + await ensureOnboardingPr(config); + expect(config.api.createPr.mock.calls).toHaveLength(1); + createPrBody = config.api.createPr.mock.calls[0][2]; + }); + it('returns if PR does not need updating', async () => { + config.api.getBranchPr.mockReturnValue({ + title: 'Configure Renovate', + body: createPrBody, + }); + await ensureOnboardingPr(config); + expect(config.api.createPr.mock.calls).toHaveLength(0); + expect(config.api.updatePr.mock.calls).toHaveLength(0); + }); + it('updates PR', async () => { + config.baseBranch = 'some-branch'; + config.api.getBranchPr.mockReturnValue({ + title: 'Configure Renovate', + body: createPrBody, + }); + await ensureOnboardingPr(config); + expect(config.api.createPr.mock.calls).toHaveLength(0); + expect(config.api.updatePr.mock.calls).toHaveLength(1); + }); + }); +}); diff --git a/test/workers/repository/onboarding/pr/pr-list.spec.js b/test/workers/repository/onboarding/pr/pr-list.spec.js new file mode 100644 index 0000000000000000000000000000000000000000..369fece57d57e596cdd0fda21f8ca40d477d9a91 --- /dev/null +++ b/test/workers/repository/onboarding/pr/pr-list.spec.js @@ -0,0 +1,73 @@ +const logger = require('../../../../_fixtures/logger'); +const defaultConfig = require('../../../../../lib/config/defaults').getConfig(); + +const { + getPrList, +} = require('../../../../../lib/workers/repository/onboarding/pr/pr-list'); + +describe('workers/repository/onboarding/pr/pr-list', () => { + describe('getPrList()', () => { + let config; + beforeEach(() => { + jest.resetAllMocks(); + config = { + ...defaultConfig, + logger, + }; + }); + it('has special lock file maintenance description', async () => { + config.branches = [ + { + prTitle: 'Lock file maintenance', + schedule: ['before 5am'], + branchName: 'renovate/lock-file-maintenance', + upgrades: [ + { + type: 'lockFileMaintenance', + }, + ], + }, + ]; + const res = getPrList(config); + expect(res).toMatchSnapshot(); + }); + it('handles multiple', async () => { + config.branches = [ + { + prTitle: 'Pin dependencies', + branchName: 'renovate/pin-dependencies', + upgrades: [ + { + isPin: true, + repositoryUrl: 'https://a', + depName: 'a', + depType: 'devDependencies', + newVersion: '1.1.0', + }, + { + isPin: true, + depName: 'b', + depType: 'devDependencies', + newVersion: '1.5.3', + }, + ], + }, + { + prTitle: 'Update a to v2', + branchName: 'renovate/a-2.x', + upgrades: [ + { + repositoryUrl: 'https://a', + depName: 'a', + currentVersion: '^1.0.0', + depType: 'devDependencies', + newVersion: '2.0.1', + }, + ], + }, + ]; + const res = getPrList(config); + expect(res).toMatchSnapshot(); + }); + }); +});