diff --git a/lib/config/definitions.js b/lib/config/definitions.js index ec5ad8b3d3e7a6bbe6afd11536dfaccb6be82636..f5705f514dc95580213869ece6429d24c32eebe1 100644 --- a/lib/config/definitions.js +++ b/lib/config/definitions.js @@ -62,6 +62,13 @@ const options = [ type: 'boolean', default: false, }, + { + name: 'binarySource', + description: 'Where to source binaries like `npm` and `yarn` from', + admin: true, + type: 'string', + default: 'bundled', + }, // Log options { name: 'logLevel', diff --git a/lib/manager/npm/post-update/index.js b/lib/manager/npm/post-update/index.js index 7cd2ec692d21400ccc1d0865e286c9f91d94fe8c..04dbf257cf28cf9e0f8c078a591cb0af63c9162e 100644 --- a/lib/manager/npm/post-update/index.js +++ b/lib/manager/npm/post-update/index.js @@ -303,7 +303,8 @@ async function getAdditionalFiles(config, packageFiles) { upath.join(config.localDir, lockFileDir), env, fileName, - config.skipInstalls + config.skipInstalls, + config.binarySource ); if (res.error) { // istanbul ignore if @@ -354,7 +355,8 @@ async function getAdditionalFiles(config, packageFiles) { const lockFileName = upath.join(lockFileDir, 'yarn.lock'); const res = await yarn.generateLockFile( upath.join(config.localDir, lockFileDir), - env + env, + config.binarysource ); if (res.error) { // istanbul ignore if @@ -406,7 +408,8 @@ async function getAdditionalFiles(config, packageFiles) { logger.debug(`Generating shrinkwrap.yaml for ${lockFileDir}`); const res = await pnpm.generateLockFile( upath.join(config.localDir, lockFileDir), - env + env, + config.binarySource ); if (res.error) { // istanbul ignore if @@ -470,7 +473,8 @@ async function getAdditionalFiles(config, packageFiles) { lernaPackageFile.lernaClient, upath.join(config.localDir, lernaDir), env, - config.skipInstalls + config.skipInstalls, + config.binarySource ); // istanbul ignore else if (res.error) { diff --git a/lib/manager/npm/post-update/lerna.js b/lib/manager/npm/post-update/lerna.js index 03590c1e354ef627d3c35f5c9a113d47da491354..09b6538359d2eb45f83fed28d9ac0298d1c0ad0f 100644 --- a/lib/manager/npm/post-update/lerna.js +++ b/lib/manager/npm/post-update/lerna.js @@ -4,7 +4,13 @@ module.exports = { generateLockFiles, }; -async function generateLockFiles(lernaClient, cwd, env, skipInstalls) { +async function generateLockFiles( + lernaClient, + cwd, + env, + skipInstalls, + binarySource +) { if (!lernaClient) { logger.warn('No lernaClient specified - returning'); return { error: false }; @@ -38,6 +44,9 @@ async function generateLockFiles(lernaClient, cwd, env, skipInstalls) { '--ignore-scripts --ignore-engines --ignore-platform --mutex network:31879'; } cmd = `npm i -g -C ~/.npm/lerna@${lernaVersion} lerna@${lernaVersion} && ${lernaClient} install ${params} && ~/.npm/lerna@${lernaVersion}/bin/lerna bootstrap -- ${params}`; + if (binarySource === 'global') { + cmd = `${lernaClient} install ${params} && lerna bootstrap -- ${params}`; + } logger.debug({ cmd }); // TODO: Switch to native util.promisify once using only node 8 ({ stdout, stderr } = await exec(cmd, { diff --git a/lib/manager/npm/post-update/npm.js b/lib/manager/npm/post-update/npm.js index 9559d900f979ea172403b5f549abfd9d34254de5..3238f1b7f67d463695d479571649b3c21d19c547 100644 --- a/lib/manager/npm/post-update/npm.js +++ b/lib/manager/npm/post-update/npm.js @@ -7,7 +7,13 @@ module.exports = { generateLockFile, }; -async function generateLockFile(cwd, env, filename, skipInstalls) { +async function generateLockFile( + cwd, + env, + filename, + skipInstalls, + binarySource +) { logger.debug(`Spawning npm install to create ${cwd}/${filename}`); let lockFile = null; let stdout; @@ -52,6 +58,9 @@ async function generateLockFile(cwd, env, filename, skipInstalls) { } } } + if (binarySource === 'global') { + cmd = 'npm'; + } cmd = `${cmd} --version && ${cmd} install`; if (skipInstalls) { cmd += ' --package-lock-only --no-audit'; diff --git a/lib/manager/npm/post-update/pnpm.js b/lib/manager/npm/post-update/pnpm.js index ef925c54af004a5632d33243b70776d3d7b6b973..3e276100628ac5025ac2db35839c657233634842 100644 --- a/lib/manager/npm/post-update/pnpm.js +++ b/lib/manager/npm/post-update/pnpm.js @@ -7,7 +7,7 @@ module.exports = { generateLockFile, }; -async function generateLockFile(cwd, env) { +async function generateLockFile(cwd, env, binarySource) { logger.debug(`Spawning pnpm install to create ${cwd}/shrinkwrap.yaml`); let lockFile = null; let stdout; @@ -52,6 +52,9 @@ async function generateLockFile(cwd, env) { } } } + if (binarySource === 'global') { + cmd = 'pnpm'; + } logger.debug(`Using pnpm: ${cmd}`); cmd += ' install'; cmd += ' --shrinkwrap-only'; diff --git a/lib/manager/npm/post-update/yarn.js b/lib/manager/npm/post-update/yarn.js index 122d88214c10a05961ae4cc20ef1584616ca40fb..7dbae5a1f2deae08319f324ae0378ad585dd0d7f 100644 --- a/lib/manager/npm/post-update/yarn.js +++ b/lib/manager/npm/post-update/yarn.js @@ -7,7 +7,7 @@ module.exports = { generateLockFile, }; -async function generateLockFile(cwd, env) { +async function generateLockFile(cwd, env, binarySource) { logger.debug(`Spawning yarn install to create ${cwd}/yarn.lock`); let lockFile = null; let stdout; @@ -52,6 +52,9 @@ async function generateLockFile(cwd, env) { } } } + if (binarySource) { + cmd = 'yarn'; + } logger.debug(`Using yarn: ${cmd}`); cmd += ' install'; cmd += ' --ignore-scripts'; diff --git a/test/workers/branch/lock-files/lerna.spec.js b/test/workers/branch/lock-files/lerna.spec.js index 25f6700a25563d47b0eb929d7d8a2a2333c06088..06adb3ac972a77112baf410a106dbaa67017ab3a 100644 --- a/test/workers/branch/lock-files/lerna.spec.js +++ b/test/workers/branch/lock-files/lerna.spec.js @@ -28,11 +28,13 @@ describe('generateLockFiles()', () => { ); exec.mockReturnValueOnce({}); const skipInstalls = false; + const binarySource = 'global'; const res = await lernaHelper.generateLockFiles( 'npm', 'some-dir', {}, - skipInstalls + skipInstalls, + binarySource ); expect(res.error).toBe(false); }); diff --git a/test/workers/branch/lock-files/npm.spec.js b/test/workers/branch/lock-files/npm.spec.js index 3e6a131342c70bd63af8b72686341c72c98fd476..15a233b676bd3131735e69563f96affe1253826c 100644 --- a/test/workers/branch/lock-files/npm.spec.js +++ b/test/workers/branch/lock-files/npm.spec.js @@ -37,11 +37,13 @@ describe('generateLockFile', () => { }); fs.readFile = jest.fn(() => 'package-lock-contents'); const skipInstalls = false; + const binarySource = 'global'; const res = await npmHelper.generateLockFile( 'some-dir', {}, 'package-lock.json', - skipInstalls + skipInstalls, + binarySource ); expect(fs.readFile.mock.calls.length).toEqual(1); expect(res.error).not.toBeDefined(); diff --git a/test/workers/branch/lock-files/pnpm.spec.js b/test/workers/branch/lock-files/pnpm.spec.js index aca930976edb4a2617098ce7284d7c43b199e1c2..6cadb05f2367947823292d91b3aea8685c0e32ee 100644 --- a/test/workers/branch/lock-files/pnpm.spec.js +++ b/test/workers/branch/lock-files/pnpm.spec.js @@ -87,7 +87,11 @@ describe('generateLockFile', () => { stderror: '', }); fs.readFile = jest.fn(() => 'package-lock-contents'); - const res = await pnpmHelper.generateLockFile('some-dir'); + const res = await pnpmHelper.generateLockFile( + 'some-dir', + undefined, + 'global' + ); expect(fs.readFile.mock.calls.length).toEqual(1); expect(res.lockFile).toEqual('package-lock-contents'); }); diff --git a/test/workers/branch/lock-files/yarn.spec.js b/test/workers/branch/lock-files/yarn.spec.js index ce44c4595339ae465d22074330e6d2055724e765..3e442cb934b326664ba378f3533d0bc34f98481e 100644 --- a/test/workers/branch/lock-files/yarn.spec.js +++ b/test/workers/branch/lock-files/yarn.spec.js @@ -87,7 +87,11 @@ describe('generateLockFile', () => { stderror: '', }); fs.readFile = jest.fn(() => 'package-lock-contents'); - const res = await yarnHelper.generateLockFile('some-dir'); + const res = await yarnHelper.generateLockFile( + 'some-dir', + undefined, + 'global' + ); expect(fs.readFile.mock.calls.length).toEqual(1); expect(res.lockFile).toEqual('package-lock-contents'); }); diff --git a/test/workers/repository/updates/__snapshots__/flatten.spec.js.snap b/test/workers/repository/updates/__snapshots__/flatten.spec.js.snap index 5654110755e36af7e5f896940d829b45ba41c284..1272d80c041d002ac3f9c0e702f49df9f4354c79 100644 --- a/test/workers/repository/updates/__snapshots__/flatten.spec.js.snap +++ b/test/workers/repository/updates/__snapshots__/flatten.spec.js.snap @@ -7,6 +7,7 @@ Array [ "automerge": false, "automergeComment": "automergeComment", "automergeType": "pr", + "binarySource": "bundled", "branchName": "{{{branchPrefix}}}{{{managerBranchPrefix}}}{{{branchTopic}}}", "branchPrefix": "renovate/", "branchTopic": "{{{depNameSanitized}}}-{{{newMajor}}}{{#if isPatch}}.{{{newMinor}}}{{/if}}.x", @@ -78,6 +79,7 @@ Array [ "automerge": false, "automergeComment": "automergeComment", "automergeType": "pr", + "binarySource": "bundled", "branchName": "{{{branchPrefix}}}{{{managerBranchPrefix}}}{{{branchTopic}}}", "branchPrefix": "renovate/", "branchTopic": "{{{depNameSanitized}}}-{{{newMajor}}}{{#if isPatch}}.{{{newMinor}}}{{/if}}.x", @@ -149,6 +151,7 @@ Array [ "automerge": false, "automergeComment": "automergeComment", "automergeType": "pr", + "binarySource": "bundled", "branchName": "{{{branchPrefix}}}{{{managerBranchPrefix}}}{{{branchTopic}}}", "branchPrefix": "renovate/", "branchTopic": "lock-file-maintenance", @@ -220,6 +223,7 @@ Array [ "automerge": false, "automergeComment": "automergeComment", "automergeType": "pr", + "binarySource": "bundled", "branchName": "{{{branchPrefix}}}{{{managerBranchPrefix}}}{{{branchTopic}}}", "branchPrefix": "renovate/", "branchTopic": "{{{depNameSanitized}}}-{{{newMajor}}}{{#if isPatch}}.{{{newMinor}}}{{/if}}.x", @@ -291,6 +295,7 @@ Array [ "automerge": false, "automergeComment": "automergeComment", "automergeType": "pr", + "binarySource": "bundled", "branchName": "{{{branchPrefix}}}{{{managerBranchPrefix}}}{{{branchTopic}}}", "branchPrefix": "renovate/", "branchTopic": "lock-file-maintenance", @@ -362,6 +367,7 @@ Array [ "automerge": false, "automergeComment": "automergeComment", "automergeType": "pr", + "binarySource": "bundled", "branchName": "{{{branchPrefix}}}{{{managerBranchPrefix}}}{{{branchTopic}}}", "branchPrefix": "renovate/", "branchTopic": "{{{depNameSanitized}}}-{{{newMajor}}}{{#if isPatch}}.{{{newMinor}}}{{/if}}.x", @@ -433,6 +439,7 @@ Array [ "automerge": false, "automergeComment": "automergeComment", "automergeType": "pr", + "binarySource": "bundled", "branchName": "{{{branchPrefix}}}{{{managerBranchPrefix}}}{{{branchTopic}}}", "branchPrefix": "renovate/", "branchTopic": "{{{depNameSanitized}}}-{{{newMajor}}}{{#if isPatch}}.{{{newMinor}}}{{/if}}.x", @@ -504,6 +511,7 @@ Array [ "automerge": false, "automergeComment": "automergeComment", "automergeType": "pr", + "binarySource": "bundled", "branchName": "{{{branchPrefix}}}{{{managerBranchPrefix}}}{{{branchTopic}}}", "branchPrefix": "renovate/", "branchTopic": "{{{depNameSanitized}}}-{{{newMajor}}}{{#if isPatch}}.{{{newMinor}}}{{/if}}.x", diff --git a/website/docs/self-hosted-configuration.md b/website/docs/self-hosted-configuration.md index 51bbc56ecd70622e5ffd7b4abfc8ae0be74f9999..242756ccee404e15f02569076bfd1afed728ca81 100644 --- a/website/docs/self-hosted-configuration.md +++ b/website/docs/self-hosted-configuration.md @@ -11,6 +11,10 @@ The below configuration options are applicable only if you are running your own Be cautious when using this option - it will run Renovate over _every_ repository that the bot account has access to. +## binarySource + +Set this to 'global' if you wish Renovate to use globally-installed binaries (`npm`, `yarn`, etc) instead of using its bundled versions. + ## endpoint ## exposeEnv