diff --git a/docs/configuration.md b/docs/configuration.md index 345ca761d434e16c5a683e79ce2a7e9bd3aa248d..f0c978a5e3ecb3f1aa328936beecf45a7a2bf194 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -56,25 +56,26 @@ $ node renovate --help Options: - -h, --help output usage information - --enabled [boolean] Enable or disable renovate - --onboarding [boolean] Require a Configuration PR first - --platform <string> Platform type of repository - --endpoint <string> Custom endpoint to use - --token <string> Repository Auth Token - --package-files <list> Package file paths - --dep-types <list> Dependency types - --ignore-deps <list> Dependencies to ignore - --ignore-future [boolean] Ignore versions tagged as "future" - --ignore-unstable [boolean] Ignore versions with unstable semver - --respect-latest [boolean] Ignore versions newer than npm "latest" version - --recreate-closed [boolean] Recreate PRs even if same ones were closed previously - --rebase-stale-prs [boolean] Rebase stale PRs (GitHub only) - --labels <list> Labels to add to Pull Request - --assignees <list> Assignees for Pull Request - --reviewers <list> Requested reviewers for Pull Requests (GitHub only) - --pin-versions [boolean] Convert ranged versions in package.json to pinned versions - --log-level <string> Logging level + -h, --help output usage information + --enabled [boolean] Enable or disable renovate + --onboarding [boolean] Require a Configuration PR first + --platform <string> Platform type of repository + --endpoint <string> Custom endpoint to use + --token <string> Repository Auth Token + --package-files <list> Package file paths + --dep-types <list> Dependency types + --ignore-deps <list> Dependencies to ignore + --ignore-future [boolean] Ignore versions tagged as "future" + --ignore-unstable [boolean] Ignore versions with unstable semver + --respect-latest [boolean] Ignore versions newer than npm "latest" version + --recreate-closed [boolean] Recreate PRs even if same ones were closed previously + --rebase-stale-prs [boolean] Rebase stale PRs (GitHub only) + --maintain-yarn-lock [boolean] Keep yarn.lock updated in base branch (no monorepo support) + --labels <list> Labels to add to Pull Request + --assignees <list> Assignees for Pull Request + --reviewers <list> Requested reviewers for Pull Requests (GitHub only) + --pin-versions [boolean] Convert ranged versions in package.json to pinned versions + --log-level <string> Logging level Examples: @@ -124,6 +125,11 @@ Obviously, you can't set repository or package file location with this method. | `commitMessage` | Commit message template | string | `"Update dependency {{depName}} to version {{newVersion}}"` | | | | `prTitle` | Pull Request title template | string | `"{{#if isPin}}Pin{{else}}Update{{/if}} dependency {{depName}} to version {{#if isRange}}{{newVersion}}{{else}}{{#if isMajor}}{{newVersionMajor}}.x{{else}}{{newVersion}}{{/if}}{{/if}}"` | | | | `prBody` | Pull Request body template | string | `"This Pull Request updates dependency {{depName}} from version `{{currentVersion}}` to `{{newVersion}}`\n\n{{changelog}}"` | | | +| `maintainYarnLock` | Keep yarn.lock updated in base branch (no monorepo support) | boolean | `false` | `RENOVATE_MAINTAIN_YARN_LOCK` | `--maintain-yarn-lock` | +| `yarnMaintenanceBranchName` | Branch name template when maintaining yarn.lock | string | `"renovate/yarn-lock"` | | | +| `yarnMaintenanceCommitMessage` | Commit message template when maintaining yarn.lock | string | `"Renovate yarn.lock file"` | | | +| `yarnMaintenancePrTitle` | Pull Request title template when maintaining yarn.lock | string | `"Renovate yarn.lock file"` | | | +| `yarnMaintenancePrBody` | Pull Request body template when maintaining yarn.lock | string | `"This PR regenerates yarn.lock files based on the existing `package.json` files."` | | | | `labels` | Labels to add to Pull Request | list | `[]` | `RENOVATE_LABELS` | `--labels` | | `assignees` | Assignees for Pull Request | list | `[]` | `RENOVATE_ASSIGNEES` | `--assignees` | | `reviewers` | Requested reviewers for Pull Requests (GitHub only) | list | `[]` | `RENOVATE_REVIEWERS` | `--reviewers` | diff --git a/lib/config/definitions.js b/lib/config/definitions.js index 331e946b1e1bc6f5c8e271d70ee7daf65cac7a63..9a18d5b2e22d9709d6d25254361e7d4cef95d383 100644 --- a/lib/config/definitions.js +++ b/lib/config/definitions.js @@ -115,6 +115,45 @@ const options = [ cli: false, env: false, }, + // Yarn Lock Maintenance + { + name: 'maintainYarnLock', + description: 'Keep yarn.lock updated in base branch (no monorepo support)', + type: 'boolean', + default: false, + }, + { + name: 'yarnMaintenanceBranchName', + description: 'Branch name template when maintaining yarn.lock', + type: 'string', + default: 'renovate/yarn-lock', + cli: false, + env: false, + }, + { + name: 'yarnMaintenanceCommitMessage', + description: 'Commit message template when maintaining yarn.lock', + type: 'string', + default: 'Renovate yarn.lock file', + cli: false, + env: false, + }, + { + name: 'yarnMaintenancePrTitle', + description: 'Pull Request title template when maintaining yarn.lock', + type: 'string', + default: 'Renovate yarn.lock file', + cli: false, + env: false, + }, + { + name: 'yarnMaintenancePrBody', + description: 'Pull Request body template when maintaining yarn.lock', + type: 'string', + default: 'This PR regenerates yarn.lock files based on the existing `package.json` files.', + cli: false, + env: false, + }, // Pull Request options { name: 'labels', diff --git a/lib/helpers/yarn.js b/lib/helpers/yarn.js index bab38413696e46edeb8b2dabfea608bd30b5e8a5..2163a50ee0aafbb7d8f0df0aef1a77eab159b712 100644 --- a/lib/helpers/yarn.js +++ b/lib/helpers/yarn.js @@ -20,7 +20,10 @@ async function generateLockFile(newPackageJson, npmrcContent, yarnrcContent) { if (yarnrcContent) { fs.writeFileSync(path.join(tmpDir.name, '.yarnrc'), yarnrcContent); } - cp.spawnSync('yarn', ['install'], { cwd: tmpDir.name, shell: true }); + logger.debug('Spawning yarn install'); + const result = cp.spawnSync('yarn', ['install'], { cwd: tmpDir.name, shell: true }); + logger.debug(String(result.stdout)); + logger.debug(String(result.stderr)); yarnLock = fs.readFileSync(path.join(tmpDir.name, 'yarn.lock')); } catch (error) { throw error; diff --git a/lib/worker.js b/lib/worker.js index e85a361d31033d6be7697ca887d41e8a3a4776b9..a68720fac22014ee12490144add5daf8ac2b4869 100644 --- a/lib/worker.js +++ b/lib/worker.js @@ -1,4 +1,5 @@ const logger = require('winston'); +const path = require('path'); const stringify = require('json-stringify-pretty-compact'); const githubApi = require('./api/github'); const gitlabApi = require('./api/gitlab'); @@ -54,10 +55,38 @@ async function processPackageFile(repoName, packageFile, packageConfig) { // Find all upgrades for remaining dependencies const upgrades = await findUpgrades(dependencies, config); // Process all upgrades sequentially + if (config.maintainYarnLock) { + await maintainYarnLock(config); + } await processUpgradesSequentially(config, upgrades); logger.info(`${repoName} ${packageFile} done`); } +async function maintainYarnLock(inputConfig) { + const packageContent = await inputConfig.api.getFileContent(inputConfig.packageFile); + const yarnLockFileName = path.join(path.dirname(inputConfig.packageFile), 'yarn.lock'); + logger.debug(`Checking for ${yarnLockFileName}`); + const existingYarnLock = await inputConfig.api.getFileContent(yarnLockFileName); + if (!existingYarnLock) { + return; + } + logger.debug('Found existing yarn.lock file'); + const newYarnLock = await branchWorker.getYarnLockFile(packageContent, inputConfig); + if (existingYarnLock === newYarnLock.contents) { + logger.debug('Yarn lock file does not need updating'); + return; + } + logger.debug('Yarn lock needs updating'); + // API will know whether to create new branch or not + const params = Object.assign({}, inputConfig); + const commitMessage = handlebars.compile(params.yarnMaintenanceCommitMessage)(params); + params.branchName = params.yarnMaintenanceBranchName; + params.prTitle = params.yarnMaintenancePrTitle; + params.prBody = params.yarnMaintenancePrBody; + await inputConfig.api.commitFilesToBranch(params.branchName, [newYarnLock], commitMessage); + prWorker.ensurePr(params); +} + async function findUpgrades(dependencies, inputConfig) { const allUpgrades = []; // findDepUpgrades can add more than one upgrade to allUpgrades diff --git a/readme.md b/readme.md index 0bef48a9c7a96cefa139b6263a28b77016594668..0e9f9568d91ea022548bcea6a40f0476de4702f8 100644 --- a/readme.md +++ b/readme.md @@ -38,25 +38,26 @@ $ node renovate --help Options: - -h, --help output usage information - --enabled [boolean] Enable or disable renovate - --onboarding [boolean] Require a Configuration PR first - --platform <string> Platform type of repository - --endpoint <string> Custom endpoint to use - --token <string> Repository Auth Token - --package-files <list> Package file paths - --dep-types <list> Dependency types - --ignore-deps <list> Dependencies to ignore - --ignore-future [boolean] Ignore versions tagged as "future" - --ignore-unstable [boolean] Ignore versions with unstable semver - --respect-latest [boolean] Ignore versions newer than npm "latest" version - --recreate-closed [boolean] Recreate PRs even if same ones were closed previously - --rebase-stale-prs [boolean] Rebase stale PRs (GitHub only) - --labels <list> Labels to add to Pull Request - --assignees <list> Assignees for Pull Request - --reviewers <list> Requested reviewers for Pull Requests (GitHub only) - --pin-versions [boolean] Convert ranged versions in package.json to pinned versions - --log-level <string> Logging level + -h, --help output usage information + --enabled [boolean] Enable or disable renovate + --onboarding [boolean] Require a Configuration PR first + --platform <string> Platform type of repository + --endpoint <string> Custom endpoint to use + --token <string> Repository Auth Token + --package-files <list> Package file paths + --dep-types <list> Dependency types + --ignore-deps <list> Dependencies to ignore + --ignore-future [boolean] Ignore versions tagged as "future" + --ignore-unstable [boolean] Ignore versions with unstable semver + --respect-latest [boolean] Ignore versions newer than npm "latest" version + --recreate-closed [boolean] Recreate PRs even if same ones were closed previously + --rebase-stale-prs [boolean] Rebase stale PRs (GitHub only) + --maintain-yarn-lock [boolean] Keep yarn.lock updated in base branch (no monorepo support) + --labels <list> Labels to add to Pull Request + --assignees <list> Assignees for Pull Request + --reviewers <list> Requested reviewers for Pull Requests (GitHub only) + --pin-versions [boolean] Convert ranged versions in package.json to pinned versions + --log-level <string> Logging level Examples: