From 482012a148876e8e312b46b567c2c04922f6f3fe Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Sun, 4 Apr 2021 09:18:56 +0200 Subject: [PATCH 01/21] feat: remove RENOVATE_LEGACY_GIT_AUTHOR_EMAIL (#9389) Removes RENOVATE_LEGACY_GIT_AUTHOR_EMAIL support. Closes #9111 BREAKING CHANGE: RENOVATE_LEGACY_GIT_AUTHOR_EMAIL is no longer supported. Use `ignoredAuthors` in config instead. --- docs/usage/self-hosted-experimental.md | 5 ----- lib/util/git/index.ts | 1 - 2 files changed, 6 deletions(-) diff --git a/docs/usage/self-hosted-experimental.md b/docs/usage/self-hosted-experimental.md index 1151bd65d624ac..2f00716900c3b6 100644 --- a/docs/usage/self-hosted-experimental.md +++ b/docs/usage/self-hosted-experimental.md @@ -27,11 +27,6 @@ If set to any integer, Renovate will use this integer instead of the default npm If set to any value, Renovate will skip its default artifacts filter check in the Maven datasource. Skiping the check will speed things up, but may result in versions being returned which don't properly exist on the server. -## RENOVATE_LEGACY_GIT_AUTHOR_EMAIL - -An additional `gitAuthor` email to ignore. -This variable is deprecated: use `ignoredAuthors` instead. - ## RENOVATE_PAGINATE_ALL If set to any value, Renovate will always paginate requests to GitHub fully, instead of stopping after 10 pages. diff --git a/lib/util/git/index.ts b/lib/util/git/index.ts index 3ced1d68ead6f5..829f18abe8cdcd 100644 --- a/lib/util/git/index.ts +++ b/lib/util/git/index.ts @@ -488,7 +488,6 @@ export async function isBranchModified(branchName: string): Promise { ).trim(); const { gitAuthorEmail } = config; if ( - lastAuthor === process.env.RENOVATE_LEGACY_GIT_AUTHOR_EMAIL || // remove in next major release lastAuthor === gitAuthorEmail || config.ignoredAuthors.some((ignoredAuthor) => lastAuthor === ignoredAuthor) ) { From 8516aacd7fe8cf3205e583fab70280268da9c3a9 Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Wed, 21 Apr 2021 09:04:07 +0200 Subject: [PATCH 02/21] feat: drop NPM_TOKEN support (#9391) Removes support for NPM_TOKEN. BREAKING CHANGE: Do not use NPM_TOKEN in env to configure npm authentication. Configure hostRules instead. --- docs/usage/private-modules.md | 2 +- lib/config/presets/npm/index.spec.ts | 1 - .../npm/__snapshots__/index.spec.ts.snap | 39 ------------------- lib/datasource/npm/index.spec.ts | 16 -------- lib/datasource/npm/npmrc.spec.ts | 1 - lib/datasource/npm/npmrc.ts | 5 --- lib/manager/npm/post-update/lerna.ts | 1 - lib/manager/npm/post-update/npm.ts | 1 - lib/manager/npm/post-update/pnpm.ts | 1 - lib/manager/npm/post-update/yarn.ts | 1 - 10 files changed, 1 insertion(+), 67 deletions(-) diff --git a/docs/usage/private-modules.md b/docs/usage/private-modules.md index 44d95db472515c..2c8e596f774dc9 100644 --- a/docs/usage/private-modules.md +++ b/docs/usage/private-modules.md @@ -64,7 +64,7 @@ module.exports = { }; ``` -**NOTE:** Do not use `NPM_TOKEN` as an environment variable, it's incompatible with `hostRules` and will be deprecated soon. +**NOTE:** Do not use `NPM_TOKEN` as an environment variable. ### Commit .npmrc file into repository diff --git a/lib/config/presets/npm/index.spec.ts b/lib/config/presets/npm/index.spec.ts index 931ae3d39d6c60..fa5bd9afd76e95 100644 --- a/lib/config/presets/npm/index.spec.ts +++ b/lib/config/presets/npm/index.spec.ts @@ -7,7 +7,6 @@ jest.mock('registry-auth-token'); jest.mock('delay'); describe(getName(__filename), () => { - delete process.env.NPM_TOKEN; beforeEach(() => { jest.resetAllMocks(); setAdminConfig(); diff --git a/lib/datasource/npm/__snapshots__/index.spec.ts.snap b/lib/datasource/npm/__snapshots__/index.spec.ts.snap index 85d618101b79ab..ac9065cc23dea7 100644 --- a/lib/datasource/npm/__snapshots__/index.spec.ts.snap +++ b/lib/datasource/npm/__snapshots__/index.spec.ts.snap @@ -519,45 +519,6 @@ Array [ ] `; -exports[`datasource/npm/index should use NPM_TOKEN if provided 1`] = ` -Object { - "name": "@foobar/core", - "registryUrl": "https://registry.npmjs.org/", - "releases": Array [ - Object { - "releaseTimestamp": "2018-05-06T05:21:53.000Z", - "version": "0.0.1", - }, - Object { - "releaseTimestamp": "2018-05-07T05:21:53.000Z", - "version": "0.0.2", - }, - ], - "sourceDirectory": "src/a", - "sourceUrl": "https://github.com/renovateapp/dummy", - "tags": Object { - "latest": "0.0.1", - }, - "versions": Object {}, -} -`; - -exports[`datasource/npm/index should use NPM_TOKEN if provided 2`] = ` -Array [ - Object { - "headers": Object { - "accept": "application/json", - "accept-encoding": "gzip, deflate, br", - "authorization": "Bearer some-token", - "host": "registry.npmjs.org", - "user-agent": "https://github.com/renovatebot/renovate", - }, - "method": "GET", - "url": "https://registry.npmjs.org/@foobar%2Fcore", - }, -] -`; - exports[`datasource/npm/index should use default registry if missing from npmrc 1`] = ` Object { "name": "foobar", diff --git a/lib/datasource/npm/index.spec.ts b/lib/datasource/npm/index.spec.ts index a4979577cf60cb..1b630c14be2635 100644 --- a/lib/datasource/npm/index.spec.ts +++ b/lib/datasource/npm/index.spec.ts @@ -15,7 +15,6 @@ const registryAuthToken: jest.Mock<_registryAuthToken.NpmCredentials> = _registr let npmResponse: any; describe(getName(__filename), () => { - delete process.env.NPM_TOKEN; beforeEach(() => { jest.resetAllMocks(); httpMock.setup(); @@ -269,21 +268,6 @@ describe(getName(__filename), () => { expect(httpMock.getTrace()).toMatchSnapshot(); }); - it('should use NPM_TOKEN if provided', async () => { - httpMock - .scope('https://registry.npmjs.org', { - reqheaders: { authorization: 'Bearer some-token' }, - }) - .get('/@foobar%2Fcore') - .reply(200, { ...npmResponse, name: '@foobar/core' }); - const oldToken = process.env.NPM_TOKEN; - process.env.NPM_TOKEN = 'some-token'; - const res = await getPkgReleases({ datasource, depName: '@foobar/core' }); - process.env.NPM_TOKEN = oldToken; - expect(res).toMatchSnapshot(); - expect(httpMock.getTrace()).toMatchSnapshot(); - }); - it('should use host rules by hostName if provided', async () => { hostRules.add({ hostType: 'npm', diff --git a/lib/datasource/npm/npmrc.spec.ts b/lib/datasource/npm/npmrc.spec.ts index d340093435907f..186e4969726351 100644 --- a/lib/datasource/npm/npmrc.spec.ts +++ b/lib/datasource/npm/npmrc.spec.ts @@ -9,7 +9,6 @@ const sanitize = mocked(_sanitize); describe(getName(__filename), () => { beforeEach(() => { - delete process.env.NPM_TOKEN; setNpmrc(''); setAdminConfig(); jest.resetAllMocks(); diff --git a/lib/datasource/npm/npmrc.ts b/lib/datasource/npm/npmrc.ts index 7afc4c89b13e52..dae13dfca01852 100644 --- a/lib/datasource/npm/npmrc.ts +++ b/lib/datasource/npm/npmrc.ts @@ -129,11 +129,6 @@ export function resolvePackage(packageName: string): PackageResolution { { token: maskToken(authInfo.token), npmName: packageName }, 'Using auth (via npmrc) for npm lookup' ); - } else if (process.env.NPM_TOKEN && process.env.NPM_TOKEN !== 'undefined') { - logger.warn( - 'Support for NPM_TOKEN in env will be dropped in the next major release' - ); - headers.authorization = `Bearer ${process.env.NPM_TOKEN}`; } return { headers, packageUrl, registryUrl }; } diff --git a/lib/manager/npm/post-update/lerna.ts b/lib/manager/npm/post-update/lerna.ts index 08cfc8be3d4c6c..acba413c40c108 100644 --- a/lib/manager/npm/post-update/lerna.ts +++ b/lib/manager/npm/post-update/lerna.ts @@ -99,7 +99,6 @@ export async function generateLockFiles( if (getAdminConfig().trustLevel === 'high') { execOptions.extraEnv.NPM_AUTH = env.NPM_AUTH; execOptions.extraEnv.NPM_EMAIL = env.NPM_EMAIL; - execOptions.extraEnv.NPM_TOKEN = env.NPM_TOKEN; } if (config.dockerMapDotfiles) { const homeDir = diff --git a/lib/manager/npm/post-update/npm.ts b/lib/manager/npm/post-update/npm.ts index d3e43876605615..0025d620fe4c76 100644 --- a/lib/manager/npm/post-update/npm.ts +++ b/lib/manager/npm/post-update/npm.ts @@ -74,7 +74,6 @@ export async function generateLockFile( if (getAdminConfig().trustLevel === 'high') { execOptions.extraEnv.NPM_AUTH = env.NPM_AUTH; execOptions.extraEnv.NPM_EMAIL = env.NPM_EMAIL; - execOptions.extraEnv.NPM_TOKEN = env.NPM_TOKEN; } if (config.dockerMapDotfiles) { const homeDir = diff --git a/lib/manager/npm/post-update/pnpm.ts b/lib/manager/npm/post-update/pnpm.ts index 7816267e786744..6541a412870a23 100644 --- a/lib/manager/npm/post-update/pnpm.ts +++ b/lib/manager/npm/post-update/pnpm.ts @@ -53,7 +53,6 @@ export async function generateLockFile( if (getAdminConfig().trustLevel === 'high') { execOptions.extraEnv.NPM_AUTH = env.NPM_AUTH; execOptions.extraEnv.NPM_EMAIL = env.NPM_EMAIL; - execOptions.extraEnv.NPM_TOKEN = env.NPM_TOKEN; } if (config.dockerMapDotfiles) { const homeDir = diff --git a/lib/manager/npm/post-update/yarn.ts b/lib/manager/npm/post-update/yarn.ts index e179f717703ead..34aed8c7cdbf68 100644 --- a/lib/manager/npm/post-update/yarn.ts +++ b/lib/manager/npm/post-update/yarn.ts @@ -124,7 +124,6 @@ export async function generateLockFile( if (getAdminConfig().trustLevel === 'high') { execOptions.extraEnv.NPM_AUTH = env.NPM_AUTH; execOptions.extraEnv.NPM_EMAIL = env.NPM_EMAIL; - execOptions.extraEnv.NPM_TOKEN = env.NPM_TOKEN; } if (config.dockerMapDotfiles) { const homeDir = From f74e0d7c3f76c75d15d12c529482dcb2f770b8e5 Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Sun, 4 Apr 2021 10:58:32 +0200 Subject: [PATCH 03/21] feat: remove logLevel support in config (#9390) Remove support for logLevel in config. Must be configured using LOG_LEVEL instead. Closes #8291 BREAKING CHANGE: Configure LOG_LEVEL in env and not in config or CLI --- docs/usage/self-hosted-configuration.md | 12 ------------ lib/config/definitions.ts | 7 ------- lib/config/index.ts | 11 +---------- lib/config/types.ts | 1 - 4 files changed, 1 insertion(+), 30 deletions(-) diff --git a/docs/usage/self-hosted-configuration.md b/docs/usage/self-hosted-configuration.md index b6673d42fc629a..93af532f4906e1 100644 --- a/docs/usage/self-hosted-configuration.md +++ b/docs/usage/self-hosted-configuration.md @@ -233,18 +233,6 @@ If left as default (null), a random short ID will be selected. ## logFileLevel -## logLevel - -We recommend that you run the Renovate bot at the debug level if you can. -Use the environment variable `LOG_LEVEL=debug` to run Renovate at the debug level. - -When you use `LOG_LEVEL=debug`, debug logging starts from the beginning of the app. -If you had configured debug logging in a file config, then the debug logging starts _after_ the file config is parsed. - -Additionally, if you configure `LOG_FORMAT=json` in env then logging will be done in JSON format instead of "pretty" format, which is usually better if you're doing any ingestion or parsing of the logs. - -Warning: Configuring `logLevel` config option or `--log-level` cli option is deprecated and will be removed in a major version. - ## onboarding Set this to `false` only if all three statements are true: diff --git a/lib/config/definitions.ts b/lib/config/definitions.ts index ecc1d455c5f7b1..5bf8d99305ef2b 100644 --- a/lib/config/definitions.ts +++ b/lib/config/definitions.ts @@ -294,13 +294,6 @@ const options: RenovateOptions[] = [ admin: true, }, // Log options - { - name: 'logLevel', - description: 'Logging level. Deprecated, use `LOG_LEVEL` environment.', - stage: 'global', - type: 'string', - allowedValues: ['fatal', 'error', 'warn', 'info', 'debug', 'trace'], - }, { name: 'logFile', description: 'Log file path.', diff --git a/lib/config/index.ts b/lib/config/index.ts index 6fbe43fc3c351c..a005f9bf1ee8ed 100644 --- a/lib/config/index.ts +++ b/lib/config/index.ts @@ -1,4 +1,4 @@ -import { addStream, levels, logger, setContext } from '../logger'; +import { addStream, logger, setContext } from '../logger'; import { get, getLanguageList, getManagerList } from '../manager'; import { ensureDir, getSubDirectory, readFile } from '../util/fs'; import { ensureTrailingSlash } from '../util/url'; @@ -75,15 +75,6 @@ export async function parseConfigs( delete config.privateKeyPath; } - // Deprecated set log level: https://github.com/renovatebot/renovate/issues/8291 - // istanbul ignore if - if (config.logLevel) { - logger.warn( - 'Configuring logLevel in CLI or file is deprecated. Use LOG_LEVEL environment variable instead' - ); - levels('stdout', config.logLevel); - } - if (config.logContext) { // This only has an effect if logContext was defined via file or CLI, otherwise it would already have been detected in env setContext(config.logContext); diff --git a/lib/config/types.ts b/lib/config/types.ts index 21806dd46c7ec6..b2c9ca6b37fb42 100644 --- a/lib/config/types.ts +++ b/lib/config/types.ts @@ -74,7 +74,6 @@ export interface GlobalOnlyConfig { gitPrivateKey?: string; logFile?: string; logFileLevel?: LogLevel; - logLevel?: LogLevel; prCommitsPerRunLimit?: number; privateKeyPath?: string; redisUrl?: string; From 6c381cf00527a926715b828a615315590e4696a6 Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Thu, 15 Apr 2021 22:15:30 +0200 Subject: [PATCH 04/21] feat: split trustLevel into separate options (#9388) Removes trustLevel and replaces it with 3 other options instead. No longer necessary to set anything additional is configuring `allowedPostUpgradeCommands` BREAKING CHANGE: `trustLevel` is no longer supported and instead broken into `allowCustomCrateRegistries` , `allowScripts` , and `exposeAllEnv`. --- docs/usage/self-hosted-configuration.md | 20 +++++++------- .../__snapshots__/migration.spec.ts.snap | 6 +++-- lib/config/admin.ts | 4 ++- lib/config/definitions.ts | 26 +++++++++++++++---- lib/config/migration.spec.ts | 1 + lib/config/migration.ts | 11 +++++--- lib/config/types.ts | 4 ++- .../crate/__snapshots__/index.spec.ts.snap | 2 +- lib/datasource/crate/index.spec.ts | 12 ++++----- lib/datasource/crate/index.ts | 4 +-- lib/datasource/npm/index.spec.ts | 4 +-- lib/datasource/npm/npmrc.spec.ts | 2 +- lib/datasource/npm/npmrc.ts | 8 +++--- lib/manager/composer/artifacts.spec.ts | 5 ++-- lib/manager/composer/artifacts.ts | 2 +- lib/manager/npm/extract/index.ts | 2 +- lib/manager/npm/post-update/lerna.spec.ts | 2 +- lib/manager/npm/post-update/lerna.ts | 7 ++--- lib/manager/npm/post-update/npm.ts | 2 +- lib/manager/npm/post-update/pnpm.ts | 4 +-- lib/manager/npm/post-update/yarn.ts | 4 +-- lib/manager/pip_requirements/extract.spec.ts | 2 +- lib/manager/pip_requirements/extract.ts | 2 +- lib/util/exec/env.spec.ts | 2 +- lib/util/exec/env.ts | 2 +- lib/util/exec/exec.spec.ts | 2 +- lib/workers/branch/index.spec.ts | 8 +++--- 27 files changed, 88 insertions(+), 62 deletions(-) diff --git a/docs/usage/self-hosted-configuration.md b/docs/usage/self-hosted-configuration.md index 93af532f4906e1..7b2bbd01ad6e75 100644 --- a/docs/usage/self-hosted-configuration.md +++ b/docs/usage/self-hosted-configuration.md @@ -9,6 +9,8 @@ The configuration options listed in this document are applicable to self-hosted Please also see [Self-Hosted Experimental Options](./self-hosted-experimental.md). +## allowCustomCrateRegistries + ## allowPostUpgradeCommandTemplating Set to true to allow templating of dependency level post-upgrade commands. @@ -52,6 +54,8 @@ npm ci --ignore-scripts npx ng update @angular/core --from=10.0.0 --to=11.0.0 --migrate-only --allow-dirty --force ``` +## allowScripts + ## allowedPostUpgradeCommands A list of regular expressions that determine which commands in `postUpgradeTasks` are allowed to be executed. @@ -186,6 +190,13 @@ e.g. ## endpoint +## exposeAllEnv + +By default, Renovate will only pass a limited set of environment variables to package managers. +Potentially, there could be leaks of confidential data if a script you don't trust enumerates all values in env, so set this to true only if you trust the repositories which the bot runs against. + +Setting this to true will also allow for variable substitution in `.npmrc` files. + ## force This object is used as a "force override" when you need to make sure certain configuration overrides whatever is configured in the repository. @@ -375,13 +386,4 @@ This is currently applicable to `npm` and `lerna`/`npm` only, and only used in c ## token -## trustLevel - -Setting trustLevel to `"high"` can make sense in many self-hosted cases where the bot operator trusts the content in each repository. - -Setting trustLevel=high means: - -- Child processes are run with full access to `env` -- `.npmrc` files can have environment variable substitution performed - ## username diff --git a/lib/config/__snapshots__/migration.spec.ts.snap b/lib/config/__snapshots__/migration.spec.ts.snap index 48456d788edf78..a9d93e6307f2b3 100644 --- a/lib/config/__snapshots__/migration.spec.ts.snap +++ b/lib/config/__snapshots__/migration.spec.ts.snap @@ -78,6 +78,8 @@ Array [ exports[`config/migration migrateConfig(config, parentConfig) migrates config 1`] = ` Object { "additionalBranchPrefix": "{{parentDir}}-", + "allowCustomCrateRegistries": true, + "allowScripts": true, "autodiscover": true, "automerge": false, "automergeType": "branch", @@ -94,6 +96,7 @@ Object { "dependencyDashboard": true, "dependencyDashboardTitle": "foo", "enabled": true, + "exposeAllEnv": true, "extends": Array [ ":automergeBranch", "config:js-app", @@ -109,8 +112,8 @@ Object { "includeForks": true, "lockFileMaintenance": Object { "automerge": true, + "exposeAllEnv": false, "schedule": "before 5am", - "trustLevel": "low", }, "major": Object { "automerge": false, @@ -243,7 +246,6 @@ Object { "travis": Object { "enabled": true, }, - "trustLevel": "high", } `; diff --git a/lib/config/admin.ts b/lib/config/admin.ts index 6d6fd61fc69edd..feb3701c818dcd 100644 --- a/lib/config/admin.ts +++ b/lib/config/admin.ts @@ -4,15 +4,17 @@ let adminConfig: RepoAdminConfig = {}; // TODO: once admin config work is complete, add a test to make sure this list includes all options with admin=true export const repoAdminOptions = [ + 'allowCustomCrateRegistries', 'allowPostUpgradeCommandTemplating', + 'allowScripts', 'allowedPostUpgradeCommands', 'customEnvVariables', 'dockerChildPrefix', 'dockerImagePrefix', 'dockerUser', 'dryRun', + 'exposeAllEnv', 'privateKey', - 'trustLevel', ]; export function setAdminConfig(config: RenovateConfig = {}): void { diff --git a/lib/config/definitions.ts b/lib/config/definitions.ts index 5bf8d99305ef2b..92b85aadaf02af 100644 --- a/lib/config/definitions.ts +++ b/lib/config/definitions.ts @@ -473,17 +473,33 @@ const options: RenovateOptions[] = [ default: false, }, { - name: 'trustLevel', + name: 'exposeAllEnv', description: - 'Set this to "high" if the bot should trust the repository owners/contents.', + 'Configure this to true to allow passing of all env variables to package managers.', admin: true, - type: 'string', - default: 'low', + type: 'boolean', + default: false, + }, + { + name: 'allowScripts', + description: + 'Configure this to true if repositories are allowed to run install scripts.', + admin: true, + type: 'boolean', + default: false, + }, + { + name: 'allowCustomCrateRegistries', + description: + 'Configure this to true if custom crate registries are allowed.', + admin: true, + type: 'boolean', + default: false, }, { name: 'ignoreScripts', description: - 'Configure this to true if trustLevel is high but you wish to skip running scripts when updating lock files.', + 'Configure this to true if allowScripts=true but you wish to skip running scripts when updating lock files.', type: 'boolean', default: false, }, diff --git a/lib/config/migration.spec.ts b/lib/config/migration.spec.ts index 7bd348c5ea4996..6f19f5c6cacffe 100644 --- a/lib/config/migration.spec.ts +++ b/lib/config/migration.spec.ts @@ -56,6 +56,7 @@ describe(getName(__filename), () => { masterIssueTitle: 'foo', gomodTidy: true, upgradeInRange: true, + trustLevel: 'high', automergeType: 'branch-push', branchName: '{{{branchPrefix}}}{{{managerBranchPrefix}}}{{{branchTopic}}}{{{baseDir}}}', diff --git a/lib/config/migration.ts b/lib/config/migration.ts index 8b4f7ad5b18d5b..32ddd4566b6eaa 100644 --- a/lib/config/migration.ts +++ b/lib/config/migration.ts @@ -191,11 +191,14 @@ export function migrateConfig( migratedConfig.rebaseWhen = 'never'; } } else if (key === 'exposeEnv') { + migratedConfig.exposeAllEnv = val; delete migratedConfig.exposeEnv; - if (val === true) { - migratedConfig.trustLevel = 'high'; - } else if (val === false) { - migratedConfig.trustLevel = 'low'; + } else if (key === 'trustLevel') { + delete migratedConfig.trustLevel; + if (val === 'high') { + migratedConfig.allowCustomCrateRegistries ??= true; + migratedConfig.allowScripts ??= true; + migratedConfig.exposeAllEnv ??= true; } } else if ( key === 'branchName' && diff --git a/lib/config/types.ts b/lib/config/types.ts index b2c9ca6b37fb42..2ef022c21c49b8 100644 --- a/lib/config/types.ts +++ b/lib/config/types.ts @@ -83,15 +83,17 @@ export interface GlobalOnlyConfig { // Config options used within the repository worker, but not user configurable // The below should contain config options where admin=true export interface RepoAdminConfig { + allowCustomCrateRegistries?: boolean; allowPostUpgradeCommandTemplating?: boolean; + allowScripts?: boolean; allowedPostUpgradeCommands?: string[]; customEnvVariables?: Record; dockerChildPrefix?: string; dockerImagePrefix?: string; dockerUser?: string; dryRun?: boolean; + exposeAllEnv?: boolean; privateKey?: string | Buffer; - trustLevel?: 'low' | 'high'; } export interface LegacyAdminConfig { diff --git a/lib/datasource/crate/__snapshots__/index.spec.ts.snap b/lib/datasource/crate/__snapshots__/index.spec.ts.snap index 48572b6e73a18d..6e8b60c6991564 100644 --- a/lib/datasource/crate/__snapshots__/index.spec.ts.snap +++ b/lib/datasource/crate/__snapshots__/index.spec.ts.snap @@ -331,7 +331,7 @@ Array [ ] `; -exports[`datasource/crate/index getReleases refuses to clone if trustLevel is not high 1`] = `null`; +exports[`datasource/crate/index getReleases refuses to clone if allowCustomCrateRegistries is not true 1`] = `null`; exports[`datasource/crate/index getReleases returns null for 404 1`] = ` Array [ diff --git a/lib/datasource/crate/index.spec.ts b/lib/datasource/crate/index.spec.ts index a83b9f6293da56..dd8e79fdefb2cb 100644 --- a/lib/datasource/crate/index.spec.ts +++ b/lib/datasource/crate/index.spec.ts @@ -225,7 +225,7 @@ describe(getName(__filename), () => { expect(res).toBeDefined(); expect(httpMock.getTrace()).toMatchSnapshot(); }); - it('refuses to clone if trustLevel is not high', async () => { + it('refuses to clone if allowCustomCrateRegistries is not true', async () => { const { mockClone } = setupGitMocks(); const url = 'https://dl.cloudsmith.io/basic/myorg/myrepo/cargo/index.git'; @@ -240,7 +240,7 @@ describe(getName(__filename), () => { }); it('clones cloudsmith private registry', async () => { const { mockClone } = setupGitMocks(); - setAdminConfig({ trustLevel: 'high' }); + setAdminConfig({ allowCustomCrateRegistries: true }); const url = 'https://dl.cloudsmith.io/basic/myorg/myrepo/cargo/index.git'; const res = await getPkgReleases({ datasource, @@ -254,7 +254,7 @@ describe(getName(__filename), () => { }); it('clones other private registry', async () => { const { mockClone } = setupGitMocks(); - setAdminConfig({ trustLevel: 'high' }); + setAdminConfig({ allowCustomCrateRegistries: true }); const url = 'https://github.com/mcorbin/testregistry'; const res = await getPkgReleases({ datasource, @@ -268,7 +268,7 @@ describe(getName(__filename), () => { }); it('clones once then reuses the cache', async () => { const { mockClone } = setupGitMocks(); - setAdminConfig({ trustLevel: 'high' }); + setAdminConfig({ allowCustomCrateRegistries: true }); const url = 'https://github.com/mcorbin/othertestregistry'; await getPkgReleases({ datasource, @@ -284,7 +284,7 @@ describe(getName(__filename), () => { }); it('guards against race conditions while cloning', async () => { const { mockClone } = setupGitMocks(250); - setAdminConfig({ trustLevel: 'high' }); + setAdminConfig({ allowCustomCrateRegistries: true }); const url = 'https://github.com/mcorbin/othertestregistry'; await Promise.all([ @@ -310,7 +310,7 @@ describe(getName(__filename), () => { }); it('returns null when git clone fails', async () => { setupErrorGitMock(); - setAdminConfig({ trustLevel: 'high' }); + setAdminConfig({ allowCustomCrateRegistries: true }); const url = 'https://github.com/mcorbin/othertestregistry'; const result = await getPkgReleases({ diff --git a/lib/datasource/crate/index.ts b/lib/datasource/crate/index.ts index cce827f726b39f..44d39cb1852829 100644 --- a/lib/datasource/crate/index.ts +++ b/lib/datasource/crate/index.ts @@ -163,9 +163,9 @@ async function fetchRegistryInfo( }; if (flavor !== RegistryFlavor.CratesIo) { - if (getAdminConfig().trustLevel !== 'high') { + if (!getAdminConfig().allowCustomCrateRegistries) { logger.warn( - 'crate datasource: trustLevel=high is required for registries other than crates.io, bailing out' + 'crate datasource: allowCustomCrateRegistries=true is required for registries other than crates.io, bailing out' ); return null; } diff --git a/lib/datasource/npm/index.spec.ts b/lib/datasource/npm/index.spec.ts index 1b630c14be2635..d5091d722de3ad 100644 --- a/lib/datasource/npm/index.spec.ts +++ b/lib/datasource/npm/index.spec.ts @@ -359,7 +359,7 @@ describe(getName(__filename), () => { .reply(200, npmResponse); process.env.REGISTRY = 'https://registry.from-env.com'; process.env.RENOVATE_CACHE_NPM_MINUTES = '15'; - setAdminConfig({ trustLevel: 'high' }); + setAdminConfig({ exposeAllEnv: true }); // eslint-disable-next-line no-template-curly-in-string const npmrc = 'registry=${REGISTRY}'; const res = await getPkgReleases({ datasource, depName: 'foobar', npmrc }); @@ -368,7 +368,7 @@ describe(getName(__filename), () => { }); it('should throw error if necessary env var is not present', () => { - setAdminConfig({ trustLevel: 'high' }); + setAdminConfig({ exposeAllEnv: true }); // eslint-disable-next-line no-template-curly-in-string expect(() => setNpmrc('registry=${REGISTRY_MISSING}')).toThrow( Error('env-replace') diff --git a/lib/datasource/npm/npmrc.spec.ts b/lib/datasource/npm/npmrc.spec.ts index 186e4969726351..41fff3d27c3457 100644 --- a/lib/datasource/npm/npmrc.spec.ts +++ b/lib/datasource/npm/npmrc.spec.ts @@ -38,7 +38,7 @@ describe(getName(__filename), () => { }); it('sanitize _authtoken with high trust', () => { - setAdminConfig({ trustLevel: 'high' }); + setAdminConfig({ exposeAllEnv: true }); process.env.TEST_TOKEN = 'test'; setNpmrc( // eslint-disable-next-line no-template-curly-in-string diff --git a/lib/datasource/npm/npmrc.ts b/lib/datasource/npm/npmrc.ts index dae13dfca01852..3641998d365c9a 100644 --- a/lib/datasource/npm/npmrc.ts +++ b/lib/datasource/npm/npmrc.ts @@ -61,13 +61,13 @@ export function setNpmrc(input?: string): void { npmrcRaw = input; logger.debug('Setting npmrc'); npmrc = ini.parse(input.replace(/\\n/g, '\n')); - const { trustLevel } = getAdminConfig(); + const { exposeAllEnv } = getAdminConfig(); for (const [key, val] of Object.entries(npmrc)) { - if (trustLevel !== 'high') { + if (!exposeAllEnv) { sanitize(key, val); } if ( - trustLevel !== 'high' && + !exposeAllEnv && key.endsWith('registry') && val && val.includes('localhost') @@ -80,7 +80,7 @@ export function setNpmrc(input?: string): void { return; } } - if (trustLevel !== 'high') { + if (!exposeAllEnv) { return; } for (const key of Object.keys(npmrc)) { diff --git a/lib/manager/composer/artifacts.spec.ts b/lib/manager/composer/artifacts.spec.ts index d7798754387c6c..fca585b9583432 100644 --- a/lib/manager/composer/artifacts.spec.ts +++ b/lib/manager/composer/artifacts.spec.ts @@ -30,6 +30,7 @@ const config = { localDir: join('/tmp/github/some/repo'), cacheDir: join('/tmp/renovate/cache'), composerIgnorePlatformReqs: true, + ignoreScripts: false, }; const repoStatus = partial({ @@ -46,7 +47,7 @@ describe('.updateArtifacts()', () => { await setUtilConfig(config); docker.resetPrefetchedImages(); hostRules.clear(); - setAdminConfig(); + setAdminConfig({ allowScripts: false }); }); it('returns if no composer.lock found', async () => { expect( @@ -63,7 +64,7 @@ describe('.updateArtifacts()', () => { const execSnapshots = mockExecAll(exec); fs.readLocalFile.mockReturnValueOnce('Current composer.lock' as any); git.getRepoStatus.mockResolvedValue(repoStatus); - setAdminConfig({ trustLevel: 'high' }); + setAdminConfig({ allowScripts: true }); expect( await composer.updateArtifacts({ packageFileName: 'composer.json', diff --git a/lib/manager/composer/artifacts.ts b/lib/manager/composer/artifacts.ts index 9515106780c284..bffbe7510c707e 100644 --- a/lib/manager/composer/artifacts.ts +++ b/lib/manager/composer/artifacts.ts @@ -151,7 +151,7 @@ export async function updateArtifacts({ args += ' --ignore-platform-reqs'; } args += ' --no-ansi --no-interaction'; - if (getAdminConfig().trustLevel !== 'high' || config.ignoreScripts) { + if (!getAdminConfig().allowScripts || config.ignoreScripts) { args += ' --no-scripts --no-autoloader'; } logger.debug({ cmd, args }, 'composer command'); diff --git a/lib/manager/npm/extract/index.ts b/lib/manager/npm/extract/index.ts index 7bccc130f11d2a..aacf7d55444bef 100644 --- a/lib/manager/npm/extract/index.ts +++ b/lib/manager/npm/extract/index.ts @@ -107,7 +107,7 @@ export async function extractPackageFile( npmrc = npmrc.replace(/(^|\n)package-lock.*?(\n|$)/g, '\n'); } if (is.string(npmrc)) { - if (npmrc.includes('=${') && getAdminConfig().trustLevel !== 'high') { + if (npmrc.includes('=${') && !getAdminConfig().exposeAllEnv) { logger.debug('Discarding .npmrc file with variables'); ignoreNpmrcFile = true; npmrc = undefined; diff --git a/lib/manager/npm/post-update/lerna.spec.ts b/lib/manager/npm/post-update/lerna.spec.ts index 0dddb7c585fe5d..b5a596d671bbc5 100644 --- a/lib/manager/npm/post-update/lerna.spec.ts +++ b/lib/manager/npm/post-update/lerna.spec.ts @@ -109,7 +109,7 @@ describe(getName(__filename), () => { }); it('allows scripts for trust level high', async () => { const execSnapshots = mockExecAll(exec); - setAdminConfig({ trustLevel: 'high' }); + setAdminConfig({ allowScripts: true }); const res = await lernaHelper.generateLockFiles( lernaPkgFile('npm'), 'some-dir', diff --git a/lib/manager/npm/post-update/lerna.ts b/lib/manager/npm/post-update/lerna.ts index acba413c40c108..2ce9e38d4a8362 100644 --- a/lib/manager/npm/post-update/lerna.ts +++ b/lib/manager/npm/post-update/lerna.ts @@ -72,10 +72,7 @@ export async function generateLockFiles( return { error: false }; } let lernaCommand = `lerna bootstrap --no-ci --ignore-scripts -- `; - if ( - getAdminConfig().trustLevel === 'high' && - config.ignoreScripts !== false - ) { + if (getAdminConfig().allowScripts && config.ignoreScripts !== false) { cmdOptions = cmdOptions.replace('--ignore-scripts ', ''); lernaCommand = lernaCommand.replace('--ignore-scripts ', ''); } @@ -96,7 +93,7 @@ export async function generateLockFiles( }, }; // istanbul ignore if - if (getAdminConfig().trustLevel === 'high') { + if (getAdminConfig().exposeAllEnv) { execOptions.extraEnv.NPM_AUTH = env.NPM_AUTH; execOptions.extraEnv.NPM_EMAIL = env.NPM_EMAIL; } diff --git a/lib/manager/npm/post-update/npm.ts b/lib/manager/npm/post-update/npm.ts index 0025d620fe4c76..a11bce39231f08 100644 --- a/lib/manager/npm/post-update/npm.ts +++ b/lib/manager/npm/post-update/npm.ts @@ -71,7 +71,7 @@ export async function generateLockFile( }, }; // istanbul ignore if - if (getAdminConfig().trustLevel === 'high') { + if (getAdminConfig().exposeAllEnv) { execOptions.extraEnv.NPM_AUTH = env.NPM_AUTH; execOptions.extraEnv.NPM_EMAIL = env.NPM_EMAIL; } diff --git a/lib/manager/npm/post-update/pnpm.ts b/lib/manager/npm/post-update/pnpm.ts index 6541a412870a23..b9842631f96f53 100644 --- a/lib/manager/npm/post-update/pnpm.ts +++ b/lib/manager/npm/post-update/pnpm.ts @@ -50,7 +50,7 @@ export async function generateLockFile( }, }; // istanbul ignore if - if (getAdminConfig().trustLevel === 'high') { + if (getAdminConfig().exposeAllEnv) { execOptions.extraEnv.NPM_AUTH = env.NPM_AUTH; execOptions.extraEnv.NPM_EMAIL = env.NPM_EMAIL; } @@ -62,7 +62,7 @@ export async function generateLockFile( } cmd = 'pnpm'; let args = 'install --recursive --lockfile-only'; - if (getAdminConfig().trustLevel !== 'high' || config.ignoreScripts) { + if (!getAdminConfig().allowScripts || config.ignoreScripts) { args += ' --ignore-scripts'; args += ' --ignore-pnpmfile'; } diff --git a/lib/manager/npm/post-update/yarn.ts b/lib/manager/npm/post-update/yarn.ts index 34aed8c7cdbf68..5e7d4958273365 100644 --- a/lib/manager/npm/post-update/yarn.ts +++ b/lib/manager/npm/post-update/yarn.ts @@ -102,7 +102,7 @@ export async function generateLockFile( extraEnv.YARN_ENABLE_IMMUTABLE_INSTALLS = 'false'; extraEnv.YARN_HTTP_TIMEOUT = '100000'; } - if (getAdminConfig().trustLevel !== 'high' || config.ignoreScripts) { + if (!getAdminConfig().allowScripts || config.ignoreScripts) { if (isYarn1) { cmdOptions += ' --ignore-scripts'; } else { @@ -121,7 +121,7 @@ export async function generateLockFile( }, }; // istanbul ignore if - if (getAdminConfig().trustLevel === 'high') { + if (getAdminConfig().exposeAllEnv) { execOptions.extraEnv.NPM_AUTH = env.NPM_AUTH; execOptions.extraEnv.NPM_EMAIL = env.NPM_EMAIL; } diff --git a/lib/manager/pip_requirements/extract.spec.ts b/lib/manager/pip_requirements/extract.spec.ts index 6226ab5fc424da..9607c03eebc135 100644 --- a/lib/manager/pip_requirements/extract.spec.ts +++ b/lib/manager/pip_requirements/extract.spec.ts @@ -129,7 +129,7 @@ describe(getName(__filename), () => { }); it('should replace env vars in high trust mode', () => { process.env.PIP_TEST_TOKEN = 'its-a-secret'; - setAdminConfig({ trustLevel: 'high' }); + setAdminConfig({ exposeAllEnv: true }); const res = extractPackageFile(requirements7, 'unused_file_name', {}); expect(res.registryUrls).toEqual([ 'https://pypi.org/pypi/', diff --git a/lib/manager/pip_requirements/extract.ts b/lib/manager/pip_requirements/extract.ts index 87e2ffaec01963..87fc491b410ce2 100644 --- a/lib/manager/pip_requirements/extract.ts +++ b/lib/manager/pip_requirements/extract.ts @@ -84,7 +84,7 @@ export function extractPackageFile( res.registryUrls = registryUrls.map((url) => { // handle the optional quotes in eg. `--extra-index-url "https://foo.bar"` const cleaned = url.replace(/^"/, '').replace(/"$/, ''); - if (getAdminConfig().trustLevel !== 'high') { + if (!getAdminConfig().exposeAllEnv) { return cleaned; } // interpolate any environment variables diff --git a/lib/util/exec/env.spec.ts b/lib/util/exec/env.spec.ts index e3a0eabc258ad3..ebc1c16900a513 100644 --- a/lib/util/exec/env.spec.ts +++ b/lib/util/exec/env.spec.ts @@ -58,7 +58,7 @@ describe('getChildProcess environment when trustlevel set to low', () => { describe('getChildProcessEnv when trustlevel set to high', () => { it('returns process.env if trustlevel set to high', () => { - setAdminConfig({ trustLevel: 'high' }); + setAdminConfig({ exposeAllEnv: true }); expect(getChildProcessEnv()).toMatchObject(process.env); }); }); diff --git a/lib/util/exec/env.ts b/lib/util/exec/env.ts index 38950e4e867a95..faffd61bf81526 100644 --- a/lib/util/exec/env.ts +++ b/lib/util/exec/env.ts @@ -17,7 +17,7 @@ export function getChildProcessEnv( customEnvVars: string[] = [] ): NodeJS.ProcessEnv { const env: NodeJS.ProcessEnv = {}; - if (getAdminConfig().trustLevel === 'high') { + if (getAdminConfig().exposeAllEnv) { return { ...env, ...process.env }; } const envVars = [...basicEnvVars, ...customEnvVars]; diff --git a/lib/util/exec/exec.spec.ts b/lib/util/exec/exec.spec.ts index f5a67fbda53284..e5db81a628a4e8 100644 --- a/lib/util/exec/exec.spec.ts +++ b/lib/util/exec/exec.spec.ts @@ -194,7 +194,7 @@ describe(getName(__filename), () => { maxBuffer: 10485760, }, ], - adminConfig: { trustLevel: 'high' }, + adminConfig: { exposeAllEnv: true }, }, ], diff --git a/lib/workers/branch/index.spec.ts b/lib/workers/branch/index.spec.ts index a38f6cce331b99..73d68242507905 100644 --- a/lib/workers/branch/index.spec.ts +++ b/lib/workers/branch/index.spec.ts @@ -736,7 +736,7 @@ describe(getName(__filename), () => { const adminConfig = { allowedPostUpgradeCommands: ['^echo {{{versioning}}}$'], allowPostUpgradeCommandTemplating: true, - trustLevel: 'high', + exposeAllEnv: true, }; setAdminConfig(adminConfig); @@ -816,7 +816,7 @@ describe(getName(__filename), () => { const adminConfig = { allowedPostUpgradeCommands: ['^exit 1$'], allowPostUpgradeCommandTemplating: true, - trustLevel: 'high', + exposeAllEnv: true, }; setAdminConfig(adminConfig); @@ -885,7 +885,7 @@ describe(getName(__filename), () => { const adminConfig = { allowedPostUpgradeCommands: ['^echo {{{versioning}}}$'], allowPostUpgradeCommandTemplating: false, - trustLevel: 'high', + exposeAllEnv: true, }; setAdminConfig(adminConfig); const result = await branchWorker.processBranch({ @@ -965,7 +965,7 @@ describe(getName(__filename), () => { const adminConfig = { allowedPostUpgradeCommands: ['^echo {{{depName}}}$'], allowPostUpgradeCommandTemplating: true, - trustLevel: 'high', + exposeAllEnv: true, }; setAdminConfig(adminConfig); From aa717ea0f2e70cc0003959bdfb6852fd751e3972 Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Wed, 21 Apr 2021 09:04:47 +0200 Subject: [PATCH 05/21] feat(config): remove manager additionalBranchPrefix defaults (#9373) Resets any language or manager` additionalBranchPrefix` values to empty string. Add the `compatibility:additionalBranchPrefix` prefix to restore previous behavior. BREAKING CHANGE: Removal of default `additionalBranchPrefix` values will cause branch names to change for docker/helm/buildkite/cargo/homebrew. --- docs/usage/configuration-options.md | 2 +- docs/usage/configuration-templates.md | 3 +-- lib/config/presets/index.ts | 1 + lib/config/presets/internal/compatibility.ts | 24 ++++++++++++++++++++ lib/config/presets/internal/index.ts | 2 ++ lib/datasource/docker/index.ts | 1 - lib/datasource/helm/index.ts | 1 - lib/manager/buildkite/index.ts | 1 - lib/manager/cargo/index.ts | 1 - lib/manager/homebrew/index.ts | 1 - lib/workers/repository/updates/flatten.ts | 9 -------- 11 files changed, 29 insertions(+), 17 deletions(-) create mode 100644 lib/config/presets/internal/compatibility.ts diff --git a/docs/usage/configuration-options.md b/docs/usage/configuration-options.md index 522eb4fe24a59d..b82cf05f174de7 100644 --- a/docs/usage/configuration-options.md +++ b/docs/usage/configuration-options.md @@ -69,7 +69,7 @@ With the above config: ## additionalBranchPrefix This value defaults to an empty string, and is typically not necessary. -Some managers populate this field for historical reasons, for example we use `docker-` for Docker branches, so they may look like `renovate/docker-ubuntu-16.x`. +Some managers previously populated this field, but they no longer do so by default. You normally don't need to configure this, but one example where it can be useful is combining with `parentDir` in monorepos to split PRs based on where the package definition is located, e.g. ```json diff --git a/docs/usage/configuration-templates.md b/docs/usage/configuration-templates.md index 10911f76f2857f..c239ac69fe898a 100644 --- a/docs/usage/configuration-templates.md +++ b/docs/usage/configuration-templates.md @@ -21,8 +21,7 @@ Most users will be happy with the default `branchPrefix` of `renovate/`, but you Say you don't want the forward slashes, in that case you would use `renovate-` as your `branchPrefix`. The onboarding PR will always use `renovate/configure`. -`additionalBranchPrefix` is optional and by default is empty for all JavaScript dependencies. -We use `docker-` for all Docker updates, branches will look like this: `renovate/docker-ubuntu-16.x`. +`additionalBranchPrefix` is optional and by default is empty. `branchTopic` depends on the package manager and upgrade type, so you will see a lot of variety. This is probably a setting you want to change yourself. diff --git a/lib/config/presets/index.ts b/lib/config/presets/index.ts index 356d47782ecccd..7e71fc68e1716f 100644 --- a/lib/config/presets/index.ts +++ b/lib/config/presets/index.ts @@ -100,6 +100,7 @@ export function parsePreset(input: string): ParsedPreset { str = str.slice(0, str.indexOf('(')); } const presetsPackages = [ + 'compatibility', 'config', 'default', 'docker', diff --git a/lib/config/presets/internal/compatibility.ts b/lib/config/presets/internal/compatibility.ts new file mode 100644 index 00000000000000..ce1175f569fb34 --- /dev/null +++ b/lib/config/presets/internal/compatibility.ts @@ -0,0 +1,24 @@ +import { Preset } from '../types'; + +export const presets: Record = { + additionalBranchPrefix: { + buildkite: { + additionalBranchPrefix: 'buildkite-', + }, + cargo: { + additionalBranchPrefix: 'rust-', + }, + docker: { + additionalBranchPrefix: 'docker-', + }, + homebrew: { + additionalBranchPrefix: 'homebrew-', + }, + packageRules: [ + { + matchDatasources: ['helm'], + additionalBranchPrefix: 'helm-', + }, + ], + }, +}; diff --git a/lib/config/presets/internal/index.ts b/lib/config/presets/internal/index.ts index fbbdd6a790ede3..e152b9747e19d7 100644 --- a/lib/config/presets/internal/index.ts +++ b/lib/config/presets/internal/index.ts @@ -1,4 +1,5 @@ import type { Preset, PresetConfig } from '../types'; +import * as compatibilityPreset from './compatibility'; import * as configPreset from './config'; import * as defaultPreset from './default'; import * as dockerPreset from './docker'; @@ -13,6 +14,7 @@ import * as schedulePreset from './schedule'; import * as workaroundsPreset from './workarounds'; export const groups: Record> = { + compatibility: compatibilityPreset.presets, config: configPreset.presets, default: defaultPreset.presets, docker: dockerPreset.presets, diff --git a/lib/datasource/docker/index.ts b/lib/datasource/docker/index.ts index 7cc5bc301f6c01..cbc83ef5c5a81c 100644 --- a/lib/datasource/docker/index.ts +++ b/lib/datasource/docker/index.ts @@ -26,7 +26,6 @@ export const defaultVersioning = dockerVersioning.id; export const registryStrategy = 'first'; export const defaultConfig = { - additionalBranchPrefix: 'docker-', commitMessageTopic: '{{{depName}}} Docker tag', major: { enabled: false }, commitMessageExtra: diff --git a/lib/datasource/helm/index.ts b/lib/datasource/helm/index.ts index ea1105841ac2d0..af28e7caee5fbe 100644 --- a/lib/datasource/helm/index.ts +++ b/lib/datasource/helm/index.ts @@ -17,7 +17,6 @@ export const defaultRegistryUrls = ['https://charts.helm.sh/stable']; export const registryStrategy = 'first'; export const defaultConfig = { - additionalBranchPrefix: 'helm-', commitMessageTopic: 'Helm release {{depName}}', group: { commitMessageTopic: '{{{groupName}}} Helm releases', diff --git a/lib/manager/buildkite/index.ts b/lib/manager/buildkite/index.ts index a97b1018ed28c4..d678d7fd3c206d 100644 --- a/lib/manager/buildkite/index.ts +++ b/lib/manager/buildkite/index.ts @@ -7,5 +7,4 @@ export const defaultConfig = { commitMessageTopic: 'buildkite plugin {{depName}}', commitMessageExtra: 'to {{#if isMajor}}v{{{newMajor}}}{{else}}{{{newValue}}}{{/if}}', - additionalBranchPrefix: 'buildkite-', }; diff --git a/lib/manager/cargo/index.ts b/lib/manager/cargo/index.ts index e18f8527d5244c..e91db57470e3be 100644 --- a/lib/manager/cargo/index.ts +++ b/lib/manager/cargo/index.ts @@ -10,7 +10,6 @@ export { extractPackageFile, updateArtifacts, language }; export const defaultConfig = { commitMessageTopic: 'Rust crate {{depName}}', - additionalBranchPrefix: 'rust-', fileMatch: ['(^|/)Cargo.toml$'], versioning: cargoVersioning.id, rangeStrategy: 'bump', diff --git a/lib/manager/homebrew/index.ts b/lib/manager/homebrew/index.ts index 62bb3b08a55d92..b45e932cf7f9a7 100644 --- a/lib/manager/homebrew/index.ts +++ b/lib/manager/homebrew/index.ts @@ -3,6 +3,5 @@ export { updateDependency } from './update'; export const defaultConfig = { commitMessageTopic: 'Homebrew Formula {{depName}}', - additionalBranchPrefix: 'homebrew-', fileMatch: ['^Formula/[^/]+[.]rb$'], }; diff --git a/lib/workers/repository/updates/flatten.ts b/lib/workers/repository/updates/flatten.ts index 6261b851c88ca9..7c7ef3008846ab 100644 --- a/lib/workers/repository/updates/flatten.ts +++ b/lib/workers/repository/updates/flatten.ts @@ -4,7 +4,6 @@ import { mergeChildConfig, } from '../../../config'; import type { RenovateConfig } from '../../../config/types'; -import { LANGUAGE_DOCKER } from '../../../constants/languages'; import { getDefaultConfig } from '../../../datasource'; import { get } from '../../../manager'; import { applyPackageRules } from '../../../util/package-rules'; @@ -27,14 +26,6 @@ export function applyUpdateConfig(input: BranchUpgradeConfig): any { .replace(/-+/, '-') .toLowerCase() : undefined; - if ( - updateConfig.language === LANGUAGE_DOCKER && - /(^|\/)node$/.exec(updateConfig.depName) && - updateConfig.depName !== 'calico/node' - ) { - updateConfig.additionalBranchPrefix = ''; - updateConfig.depNameSanitized = 'node'; - } generateBranchName(updateConfig); return updateConfig; } From d5d295426f6775c93caa83a0f08daadd58899d24 Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Wed, 21 Apr 2021 09:05:17 +0200 Subject: [PATCH 06/21] feat: updateType=patch (#9393) Changes behavior so that patch updateType is not rewritten to minor by default. Closes #2818 BREAKING CHANGE: patch updates are not considered updateType=minor by default. --- docs/usage/configuration-options.md | 1 - docs/usage/faq.md | 5 +- lib/config/definitions.ts | 3 +- .../lookup/__snapshots__/index.spec.ts.snap | 64 +++++++++---------- .../repository/process/lookup/index.spec.ts | 8 +-- .../repository/process/lookup/update-type.ts | 5 +- 6 files changed, 39 insertions(+), 47 deletions(-) diff --git a/docs/usage/configuration-options.md b/docs/usage/configuration-options.md index b82cf05f174de7..aaf2fd8b912372 100644 --- a/docs/usage/configuration-options.md +++ b/docs/usage/configuration-options.md @@ -1517,7 +1517,6 @@ For example to apply a special label for Major updates: ## patch Add to this object if you wish to define rules that apply only to patch updates. -Only applies if `separateMinorPatch` is set to true. ## php diff --git a/docs/usage/faq.md b/docs/usage/faq.md index bcf253b27896bf..5c71756c2c5e31 100644 --- a/docs/usage/faq.md +++ b/docs/usage/faq.md @@ -208,10 +208,7 @@ To learn more read the section below. You can see in the example above that Renovate won't normally open a PR for the `snorgleborf` patch release. -There are 2 ways to tell Renovate to open a separate PR for the patch release: - -- Set `separateMinorPatch` to `true` -- Set `automerge` to the value: `"patch"` +You can tell Renovate to open a separate PR for the patch release by setting `separateMinorPatch` to `true`. In both cases, Renovate will open 3 PRs: diff --git a/lib/config/definitions.ts b/lib/config/definitions.ts index 92b85aadaf02af..7ba77d22b16033 100644 --- a/lib/config/definitions.ts +++ b/lib/config/definitions.ts @@ -1077,8 +1077,7 @@ const options: RenovateOptions[] = [ }, { name: 'patch', - description: - 'Configuration to apply when an update type is patch. Only applies if `separateMinorPatch` is set to true.', + description: 'Configuration to apply when an update type is patch.', stage: 'package', type: 'object', default: {}, diff --git a/lib/workers/repository/process/lookup/__snapshots__/index.spec.ts.snap b/lib/workers/repository/process/lookup/__snapshots__/index.spec.ts.snap index 35d60b78c71ea5..871c729a8f4b3a 100644 --- a/lib/workers/repository/process/lookup/__snapshots__/index.spec.ts.snap +++ b/lib/workers/repository/process/lookup/__snapshots__/index.spec.ts.snap @@ -50,7 +50,7 @@ Array [ "newValue": "==0.9.7", "newVersion": "0.9.7", "releaseTimestamp": "2013-09-04T17:07:22.948Z", - "updateType": "minor", + "updateType": "patch", }, Object { "bucket": "major", @@ -446,30 +446,7 @@ Array [ "newValue": "0.9.7", "newVersion": "0.9.7", "releaseTimestamp": "2013-09-04T17:07:22.948Z", - "updateType": "minor", - }, - Object { - "bucket": "major", - "newMajor": 1, - "newMinor": 4, - "newValue": "1.4.1", - "newVersion": "1.4.1", - "releaseTimestamp": "2015-05-17T04:25:07.299Z", - "updateType": "major", - }, -] -`; - -exports[`workers/repository/process/lookup/index .lookupUpdates() returns minor update if separate patches not configured 1`] = ` -Array [ - Object { - "bucket": "non-major", - "newMajor": 0, - "newMinor": 9, - "newValue": "0.9.7", - "newVersion": "0.9.7", - "releaseTimestamp": "2013-09-04T17:07:22.948Z", - "updateType": "minor", + "updateType": "patch", }, Object { "bucket": "major", @@ -552,6 +529,29 @@ Array [ ] `; +exports[`workers/repository/process/lookup/index .lookupUpdates() returns patch update even if separate patches not configured 1`] = ` +Array [ + Object { + "bucket": "non-major", + "newMajor": 0, + "newMinor": 9, + "newValue": "0.9.7", + "newVersion": "0.9.7", + "releaseTimestamp": "2013-09-04T17:07:22.948Z", + "updateType": "patch", + }, + Object { + "bucket": "major", + "newMajor": 1, + "newMinor": 4, + "newValue": "1.4.1", + "newVersion": "1.4.1", + "releaseTimestamp": "2015-05-17T04:25:07.299Z", + "updateType": "major", + }, +] +`; + exports[`workers/repository/process/lookup/index .lookupUpdates() returns patch update if separateMinorPatch 1`] = ` Array [ Object { @@ -617,7 +617,7 @@ Array [ "newValue": "3.1.0-dev.20180813", "newVersion": "3.1.0-dev.20180813", "releaseTimestamp": "2018-08-13T19:05:14.347Z", - "updateType": "minor", + "updateType": "patch", }, ] `; @@ -631,7 +631,7 @@ Array [ "newValue": "2.5.17-beta.0", "newVersion": "2.5.17-beta.0", "releaseTimestamp": "2018-03-23T23:29:13.819Z", - "updateType": "minor", + "updateType": "patch", }, ] `; @@ -655,7 +655,7 @@ Array [ "newValue": "3.0.1-insiders.20180726", "newVersion": "3.0.1-insiders.20180726", "releaseTimestamp": "2018-07-26T18:20:51.679Z", - "updateType": "minor", + "updateType": "patch", }, ] `; @@ -682,7 +682,7 @@ Array [ "newValue": "3.0.1-insiders.20180726", "newVersion": "3.0.1-insiders.20180726", "releaseTimestamp": "2018-07-26T18:20:51.679Z", - "updateType": "minor", + "updateType": "patch", }, ] `; @@ -696,7 +696,7 @@ Array [ "newValue": "3.0.1", "newVersion": "3.0.1", "releaseTimestamp": "2018-07-30T16:21:13.150Z", - "updateType": "minor", + "updateType": "patch", }, ] `; @@ -723,7 +723,7 @@ Array [ "newValue": "^0.0.35", "newVersion": "0.0.35", "releaseTimestamp": "2017-04-27T16:59:06.479Z", - "updateType": "minor", + "updateType": "patch", }, ] `; @@ -1503,7 +1503,7 @@ Array [ "newValue": "1.0.1", "newVersion": "1.0.1", "releaseTimestamp": "2014-03-11T18:47:17.560Z", - "updateType": "minor", + "updateType": "patch", }, ] `; diff --git a/lib/workers/repository/process/lookup/index.spec.ts b/lib/workers/repository/process/lookup/index.spec.ts index 93413f8a63acdb..1edb6aa299597f 100644 --- a/lib/workers/repository/process/lookup/index.spec.ts +++ b/lib/workers/repository/process/lookup/index.spec.ts @@ -186,7 +186,7 @@ describe(getName(__filename), () => { Error(CONFIG_VALIDATION) ); }); - it('returns minor update if separate patches not configured', async () => { + it('returns patch update even if separate patches not configured', async () => { config.currentValue = '0.9.0'; config.rangeStrategy = 'pin'; config.depName = 'q'; @@ -195,8 +195,8 @@ describe(getName(__filename), () => { const res = await lookup.lookupUpdates(config); expect(res.updates).toMatchSnapshot(); expect(res.updates).toHaveLength(2); - expect(res.updates[0].updateType).not.toEqual('patch'); - expect(res.updates[1].updateType).not.toEqual('patch'); + expect(res.updates[0].updateType).toEqual('patch'); + expect(res.updates[1].updateType).toEqual('major'); }); it('returns minor update if automerging both patch and minor', async () => { config.patch = { @@ -212,7 +212,7 @@ describe(getName(__filename), () => { nock('https://registry.npmjs.org').get('/q').reply(200, qJson); const res = await lookup.lookupUpdates(config); expect(res.updates).toMatchSnapshot(); - expect(res.updates[0].updateType).toEqual('minor'); + expect(res.updates[0].updateType).toEqual('patch'); }); it('returns patch update if separateMinorPatch', async () => { config.separateMinorPatch = true; diff --git a/lib/workers/repository/process/lookup/update-type.ts b/lib/workers/repository/process/lookup/update-type.ts index 956d7b310a88ed..90768a16d11d3f 100644 --- a/lib/workers/repository/process/lookup/update-type.ts +++ b/lib/workers/repository/process/lookup/update-type.ts @@ -19,8 +19,5 @@ export function getUpdateType( if (versioning.getMinor(newVersion) > versioning.getMinor(currentVersion)) { return 'minor'; } - if (config.separateMinorPatch) { - return 'patch'; - } - return 'minor'; + return 'patch'; } From c2980e9f6b2aec40e611cf2fa6154cd50547da6a Mon Sep 17 00:00:00 2001 From: Sebastian Poxhofer Date: Sun, 4 Apr 2021 14:48:52 +0200 Subject: [PATCH 07/21] feat(terraform): rework dep types (#9116) Improves the `depType` values returned by the terraform manager. Closes #8792 BREAKING CHANGE: Values for extracted `depType` in terraform manager have changed, please see the `terraform` manager readme for details. --- .../__snapshots__/extract.spec.ts.snap | 87 ++++++++++--------- lib/manager/terraform/extract.ts | 7 +- lib/manager/terraform/modules.ts | 6 +- lib/manager/terraform/providers.ts | 2 +- lib/manager/terraform/readme.md | 41 ++++++--- lib/manager/terraform/required-providers.ts | 8 ++ lib/manager/terraform/required-version.ts | 1 + lib/manager/terraform/resources.ts | 5 +- 8 files changed, 98 insertions(+), 59 deletions(-) diff --git a/lib/manager/terraform/__snapshots__/extract.spec.ts.snap b/lib/manager/terraform/__snapshots__/extract.spec.ts.snap index a7c0567b1cf466..1fba3faa42c84d 100644 --- a/lib/manager/terraform/__snapshots__/extract.spec.ts.snap +++ b/lib/manager/terraform/__snapshots__/extract.spec.ts.snap @@ -7,7 +7,7 @@ Object { "currentValue": "1.0.1", "datasource": "helm", "depName": "redis", - "depType": "helm", + "depType": "helm_release", "registryUrls": Array [ "https://charts.helm.sh/stable", ], @@ -15,7 +15,7 @@ Object { Object { "datasource": "helm", "depName": "redis", - "depType": "helm", + "depType": "helm_release", "registryUrls": Array [ "https://charts.helm.sh/stable", ], @@ -23,7 +23,7 @@ Object { Object { "datasource": "helm", "depName": "./charts/example", - "depType": "helm", + "depType": "helm_release", "registryUrls": Array [ undefined, ], @@ -33,7 +33,7 @@ Object { "currentValue": "4.0.1", "datasource": "helm", "depName": undefined, - "depType": "helm", + "depType": "helm_release", "registryUrls": Array [ "https://charts.helm.sh/stable", ], @@ -43,7 +43,7 @@ Object { "currentValue": "5.0.1", "datasource": "helm", "depName": "redis", - "depType": "helm", + "depType": "helm_release", "registryUrls": Array [ "https://charts.helm.sh/stable", ], @@ -52,7 +52,7 @@ Object { "currentValue": "6.0.1", "datasource": "helm", "depName": "redis", - "depType": "helm", + "depType": "helm_release", "registryUrls": Array [ undefined, ], @@ -68,86 +68,86 @@ Object { "currentValue": "v1.0.0", "datasource": "github-tags", "depName": "github.com/hashicorp/example", - "depType": "github", + "depType": "module", "lookupName": "hashicorp/example", }, Object { "currentValue": "next", "datasource": "github-tags", "depName": "github.com/hashicorp/example", - "depType": "github", + "depType": "module", "lookupName": "hashicorp/example", }, Object { "currentValue": "tfmodule_one-v0.0.9", "datasource": "github-tags", "depName": "github.com/githubuser/myrepo", - "depType": "github", + "depType": "module", "lookupName": "githubuser/myrepo", }, Object { "currentValue": "v1.0.0", "datasource": "github-tags", "depName": "github.com/hashicorp/example.2.3", - "depType": "github", + "depType": "module", "lookupName": "hashicorp/example.2.3", }, Object { "currentValue": "v1.0.0", "datasource": "github-tags", "depName": "github.com/hashicorp/example.2.3", - "depType": "github", + "depType": "module", "lookupName": "hashicorp/example.2.3", }, Object { "currentValue": "0.1.0", "datasource": "terraform-module", "depName": "hashicorp/consul/aws", - "depType": "terraform", + "depType": "module", }, Object { "currentValue": "v0.1.0", "datasource": "github-tags", "depName": "github.com/tieto-cem/terraform-aws-ecs-task-definition", - "depType": "github", + "depType": "module", "lookupName": "tieto-cem/terraform-aws-ecs-task-definition", }, Object { "currentValue": "v0.1.0", "datasource": "github-tags", "depName": "github.com/tieto-cem/terraform-aws-ecs-task-definition", - "depType": "github", + "depType": "module", "lookupName": "tieto-cem/terraform-aws-ecs-task-definition", }, Object { "currentValue": "v2.0.0", "datasource": "github-tags", "depName": "github.com/hashicorp/example", - "depType": "github", + "depType": "module", "lookupName": "hashicorp/example", }, Object { "datasource": "terraform-module", "depName": "terraform-aws-modules/security-group/aws", - "depType": "terraform", + "depType": "module", }, Object { "currentValue": "<= 2.4.0", "datasource": "terraform-module", "depName": "terraform-aws-modules/security-group/aws", - "depType": "terraform", + "depType": "module", }, Object { "currentValue": "1.28.3", "datasource": "terraform-module", "depName": "particuleio/addons/kubernetes", - "depType": "terraform", + "depType": "module", }, Object { "currentValue": "~> 1.1.0", "datasource": "terraform-module", "depName": "app.terraform.io/example-corp/k8s-cluster/azurerm", - "depType": "terraform", + "depType": "module", "registryUrls": Array [ "https://app.terraform.io", ], @@ -156,7 +156,7 @@ Object { "currentValue": "~> 1.1", "datasource": "terraform-module", "depName": "app.terraform.io/example-corp/k8s-cluster/azurerm", - "depType": "terraform", + "depType": "module", "registryUrls": Array [ "https://app.terraform.io", ], @@ -165,7 +165,7 @@ Object { "currentValue": "~~ 1.1", "datasource": "terraform-module", "depName": "app.terraform.io/example-corp/k8s-cluster/azurerm", - "depType": "terraform", + "depType": "module", "registryUrls": Array [ "https://app.terraform.io", ], @@ -174,7 +174,7 @@ Object { "currentValue": ">= 1.0.0, <= 2.0.0", "datasource": "terraform-module", "depName": "hashicorp/consul/aws", - "depType": "terraform", + "depType": "module", }, Object { "skipReason": "local", @@ -186,89 +186,90 @@ Object { "currentValue": "1.36.1", "datasource": "terraform-provider", "depName": "azurerm", - "depType": "terraform", + "depType": "provider", }, Object { "currentValue": "=2.4", "datasource": "terraform-provider", "depName": "gitlab", - "depType": "terraform", + "depType": "provider", }, Object { "currentValue": "=1.3", "datasource": "terraform-provider", "depName": "gitlab", - "depType": "terraform", + "depType": "provider", }, Object { "datasource": "terraform-provider", "depName": "helm", - "depType": "terraform", + "depType": "provider", }, Object { "currentValue": "V1.9", "datasource": "terraform-provider", "depName": "newrelic", - "depType": "terraform", + "depType": "provider", }, Object { "currentValue": "v1.0.0", "datasource": "git-tags", "depName": "bitbucket.com/hashicorp/example", - "depType": "gitTags", + "depType": "module", "lookupName": "https://bitbucket.com/hashicorp/example", }, Object { "currentValue": "v1.0.0", "datasource": "git-tags", "depName": "bitbucket.com/hashicorp/example", - "depType": "gitTags", + "depType": "module", "lookupName": "https://bitbucket.com/hashicorp/example", }, Object { "currentValue": "next", "datasource": "git-tags", "depName": "bitbucket.com/hashicorp/example", - "depType": "gitTags", + "depType": "module", "lookupName": "https://bitbucket.com/hashicorp/example", }, Object { "currentValue": "v1.0.1", "datasource": "git-tags", "depName": "bitbucket.com/hashicorp/example", - "depType": "gitTags", + "depType": "module", "lookupName": "https://bitbucket.com/hashicorp/example", }, Object { "currentValue": "v1.0.2", "datasource": "git-tags", "depName": "bitbucket.com/hashicorp/example", - "depType": "gitTags", + "depType": "module", "lookupName": "http://bitbucket.com/hashicorp/example", }, Object { "currentValue": "v1.0.3", "datasource": "git-tags", "depName": "bitbucket.com/hashicorp/example", - "depType": "gitTags", + "depType": "module", "lookupName": "ssh://git@bitbucket.com/hashicorp/example", }, Object { "currentValue": ">= 2.7.0", "datasource": "terraform-provider", "depName": "aws", - "depType": "terraform", + "depType": "required_provider", }, Object { "currentValue": ">= 2.0.0", "datasource": "terraform-provider", "depName": "azurerm", - "depType": "terraform", + "depType": "required_provider", }, Object { "currentValue": ">= 0.13", "datasource": "github-tags", "depName": "hashicorp/terraform", + "depType": "required_version", "extractVersion": "v(?.*)$", "lineNumber": 230, }, @@ -276,7 +277,7 @@ Object { "currentValue": "2.7.2", "datasource": "terraform-provider", "depName": "docker", - "depType": "terraform", + "depType": "required_provider", "registryUrls": Array [ "https://releases.hashicorp.com", ], @@ -285,34 +286,34 @@ Object { "currentValue": "2.7.0", "datasource": "terraform-provider", "depName": "aws", - "depType": "terraform", + "depType": "required_provider", "lookupName": "aws", }, Object { "currentValue": "=2.27.0", "datasource": "terraform-provider", "depName": "azurerm", - "depType": "terraform", + "depType": "required_provider", }, Object { "currentValue": "1.2.4", "datasource": "terraform-provider", "depName": "invalid", - "depType": "terraform", + "depType": "required_provider", "skipReason": "unsupported-url", }, Object { "currentValue": "1.2.4", "datasource": "terraform-provider", "depName": "helm", - "depType": "terraform", + "depType": "required_provider", "lookupName": "hashicorp/helm", }, Object { "currentValue": ">= 1.0", "datasource": "terraform-provider", "depName": "kubernetes", - "depType": "terraform", + "depType": "required_provider", "lookupName": "hashicorp/kubernetes", "registryUrls": Array [ "https://terraform.example.com", @@ -324,6 +325,7 @@ Object { "currentValue": "1.7.8", "datasource": "docker", "depName": "nginx", + "depType": "docker_image", "replaceString": "nginx:1.7.8", }, Object { @@ -332,6 +334,7 @@ Object { Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", "datasource": "docker", + "depType": "docker_image", "replaceString": "\${data.docker_registry_image.ubuntu.name}", "skipReason": "contains-variable", }, @@ -341,6 +344,7 @@ Object { "currentValue": "1.7.8", "datasource": "docker", "depName": "nginx", + "depType": "docker_container", "replaceString": "nginx:1.7.8", }, Object { @@ -352,6 +356,7 @@ Object { "currentValue": "v1", "datasource": "docker", "depName": "repo.mycompany.com:8080/foo-service", + "depType": "docker_service", "replaceString": "repo.mycompany.com:8080/foo-service:v1", }, Object { diff --git a/lib/manager/terraform/extract.ts b/lib/manager/terraform/extract.ts index 4658a80336cbe7..0048bde408dc4a 100644 --- a/lib/manager/terraform/extract.ts +++ b/lib/manager/terraform/extract.ts @@ -5,7 +5,10 @@ import { analyzeTerraformProvider, extractTerraformProvider, } from './providers'; -import { extractTerraformRequiredProviders } from './required-providers'; +import { + analyzeTerraformRequiredProvider, + extractTerraformRequiredProviders, +} from './required-providers'; import { analyseTerraformVersion, extractTerraformRequiredVersion, @@ -98,6 +101,8 @@ export function extractPackageFile(content: string): PackageFile | null { deps.forEach((dep) => { switch (dep.managerData.terraformDependencyType) { case TerraformDependencyTypes.required_providers: + analyzeTerraformRequiredProvider(dep); + break; case TerraformDependencyTypes.provider: analyzeTerraformProvider(dep); break; diff --git a/lib/manager/terraform/modules.ts b/lib/manager/terraform/modules.ts index f3336a1ab7ff09..692c120328e77f 100644 --- a/lib/manager/terraform/modules.ts +++ b/lib/manager/terraform/modules.ts @@ -30,12 +30,12 @@ export function analyseTerraformModule(dep: PackageDependency): void { /* eslint-disable no-param-reassign */ if (githubRefMatch) { dep.lookupName = githubRefMatch.groups.project.replace(/\.git$/, ''); - dep.depType = 'github'; + dep.depType = 'module'; dep.depName = 'github.com/' + dep.lookupName; dep.currentValue = githubRefMatch.groups.tag; dep.datasource = datasourceGithubTags.id; } else if (gitTagsRefMatch) { - dep.depType = 'gitTags'; + dep.depType = 'module'; if (gitTagsRefMatch.groups.path.includes('//')) { logger.debug('Terraform module contains subdirectory'); dep.depName = gitTagsRefMatch.groups.path.split('//')[0]; @@ -56,7 +56,7 @@ export function analyseTerraformModule(dep: PackageDependency): void { if (hostnameMatch) { dep.registryUrls = [`https://${hostnameMatch.groups.hostname}`]; } - dep.depType = 'terraform'; + dep.depType = 'module'; dep.depName = moduleParts.join('/'); dep.datasource = datasourceTerraformModule.id; } diff --git a/lib/manager/terraform/providers.ts b/lib/manager/terraform/providers.ts index 7be0e7653a3889..aa06ad0d73609c 100644 --- a/lib/manager/terraform/providers.ts +++ b/lib/manager/terraform/providers.ts @@ -61,7 +61,7 @@ export function extractTerraformProvider( export function analyzeTerraformProvider(dep: PackageDependency): void { /* eslint-disable no-param-reassign */ - dep.depType = 'terraform'; + dep.depType = 'provider'; dep.depName = dep.managerData.moduleName; dep.datasource = datasourceTerraformProvider.id; diff --git a/lib/manager/terraform/readme.md b/lib/manager/terraform/readme.md index 4dd83219332888..9d3138c89cb327 100644 --- a/lib/manager/terraform/readme.md +++ b/lib/manager/terraform/readme.md @@ -1,21 +1,38 @@ -Currently Terraform support is limited to Terraform registry sources and GitHub sources that include SemVer refs, e.g. like `github.com/hashicorp/example?ref=v1.0.0`. +Currently, Terraform supports renovating the following dependencies, where sub points represent hosting options of the dependencies: -Fixed versions like the following will receive a PR whenever there is a newer version available: +- modules + - GitTags + - GithubTags + - TerraformRegistry ( Public and Private ) +- providers ( deprecated in Terraform 0.13.0 ) + - TerraformRegistry ( Public and Private ) +- required_providers block ( Terraform >= 0.13.0) + - TerraformRegistry ( Public and Private ) +- required_version +- helm_release + - chart repository ( Public and Private ) +- docker\_\* + - Docker registry ( Public and Private ) -``` -module "consul" { - source = "hashicorp/consul/aws" - version = "0.0.5" - servers = 3 -} -``` - -The following _range_ constraints are also supported: +Terraform range constraints are supported: - `>= 1.2.0`: version 1.2.0 or newer - `<= 1.2.0`: version 1.2.0 or older - `~> 1.2.0`: any non-beta version >= 1.2.0 and < 1.3.0, e.g. 1.2.X - `~> 1.2`: any non-beta version >= 1.2.0 and < 2.0.0, e.g. 1.X.Y -- `>= 1.0.0`, <= 2.0.0`: any version between 1.0.0 and 2.0.0 inclusive +- `>= 1.0.0, <= 2.0.0`: any version between 1.0.0 and 2.0.0 inclusive + +For fine-grained control, e.g. to turn off only parts of this manager, there are following `depTypes` provided: + +| resource | depType | +| --------------------------- | :---------------: | +| terraform provider | provider | +| required terraform provider | required_provider | +| required terraform version | required_version | +| terraform module | module | +| helm release | helm_release | +| docker container | docker_container | +| docker image | docker_image | +| docker service | docker_service | If you need to change the versioning format, read the [versioning](https://docs.renovatebot.com/modules/versioning/) documentation to learn more. diff --git a/lib/manager/terraform/required-providers.ts b/lib/manager/terraform/required-providers.ts index 9319737a69c94f..44b1186210c23e 100644 --- a/lib/manager/terraform/required-providers.ts +++ b/lib/manager/terraform/required-providers.ts @@ -1,4 +1,5 @@ import type { PackageDependency } from '../types'; +import { analyzeTerraformProvider } from './providers'; import { ExtractionResult, TerraformDependencyTypes, @@ -72,3 +73,10 @@ export function extractTerraformRequiredProviders( } while (line.trim() !== '}'); return { lineNumber, dependencies: deps }; } + +export function analyzeTerraformRequiredProvider(dep: PackageDependency): void { + /* eslint-disable no-param-reassign */ + analyzeTerraformProvider(dep); + dep.depType = `required_provider`; + /* eslint-enable no-param-reassign */ +} diff --git a/lib/manager/terraform/required-version.ts b/lib/manager/terraform/required-version.ts index f5deb89a8b87fd..c8bb1e4dad6f32 100644 --- a/lib/manager/terraform/required-version.ts +++ b/lib/manager/terraform/required-version.ts @@ -48,6 +48,7 @@ export function extractTerraformRequiredVersion( export function analyseTerraformVersion(dep: PackageDependency): void { /* eslint-disable no-param-reassign */ + dep.depType = 'required_version'; dep.datasource = datasourceGithubTags.id; dep.depName = 'hashicorp/terraform'; dep.extractVersion = 'v(?.*)$'; diff --git a/lib/manager/terraform/resources.ts b/lib/manager/terraform/resources.ts index 62c986261c8806..4937a8e98ef4d6 100644 --- a/lib/manager/terraform/resources.ts +++ b/lib/manager/terraform/resources.ts @@ -73,6 +73,7 @@ export function analyseTerraformResource( case TerraformResourceTypes.docker_container: if (dep.managerData.image) { applyDockerDependency(dep, dep.managerData.image); + dep.depType = 'docker_container'; } else { dep.skipReason = SkipReason.InvalidDependencySpecification; } @@ -81,6 +82,7 @@ export function analyseTerraformResource( case TerraformResourceTypes.docker_image: if (dep.managerData.name) { applyDockerDependency(dep, dep.managerData.name); + dep.depType = 'docker_image'; } else { dep.skipReason = SkipReason.InvalidDependencySpecification; } @@ -89,6 +91,7 @@ export function analyseTerraformResource( case TerraformResourceTypes.docker_service: if (dep.managerData.image) { applyDockerDependency(dep, dep.managerData.image); + dep.depType = 'docker_service'; } else { dep.skipReason = SkipReason.InvalidDependencySpecification; } @@ -100,7 +103,7 @@ export function analyseTerraformResource( } else if (checkIfStringIsPath(dep.managerData.chart)) { dep.skipReason = SkipReason.LocalChart; } - dep.depType = 'helm'; + dep.depType = 'helm_release'; dep.registryUrls = [dep.managerData.repository]; dep.depName = dep.managerData.chart; dep.datasource = datasourceHelm.id; From c67b068627fdde35444b39905143461bbbb9beba Mon Sep 17 00:00:00 2001 From: HonkingGoose <34918129+HonkingGoose@users.noreply.github.com> Date: Sun, 4 Apr 2021 14:50:26 +0200 Subject: [PATCH 08/21] docs: improve sentences (#9395) --- docs/usage/self-hosted-configuration.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/usage/self-hosted-configuration.md b/docs/usage/self-hosted-configuration.md index 7b2bbd01ad6e75..931d24e8ccc6cc 100644 --- a/docs/usage/self-hosted-configuration.md +++ b/docs/usage/self-hosted-configuration.md @@ -192,10 +192,11 @@ e.g. ## exposeAllEnv -By default, Renovate will only pass a limited set of environment variables to package managers. -Potentially, there could be leaks of confidential data if a script you don't trust enumerates all values in env, so set this to true only if you trust the repositories which the bot runs against. +By default, Renovate only passes a limited set of environment variables to package managers. +Confidential data can be leaked if a malicious script enumerates all environment variables. +Set `exposeAllEnv` to `true` only if you have reviewed (and trust) the repositories which Renovate bot runs against. -Setting this to true will also allow for variable substitution in `.npmrc` files. +Setting this to `true` will also allow for variable substitution in `.npmrc` files. ## force From 55debcc6cd12071aedced2f1713b37065ab8b0c4 Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Mon, 5 Apr 2021 17:35:38 +0200 Subject: [PATCH 09/21] docs: outdated remove trustLevel doc references --- docs/usage/configuration-options.md | 1 - docs/usage/self-hosted-configuration.md | 4 +--- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/docs/usage/configuration-options.md b/docs/usage/configuration-options.md index aaf2fd8b912372..c7b4c91d667881 100644 --- a/docs/usage/configuration-options.md +++ b/docs/usage/configuration-options.md @@ -1541,7 +1541,6 @@ If enabled Renovate will pin Docker images by means of their SHA256 digest and n Post-upgrade tasks are commands that are executed by Renovate after a dependency has been updated but before the commit is created. The intention is to run any additional command line tools that would modify existing files or generate new files when a dependency changes. -This is only available on Renovate instances that have a `trustLevel` of 'high'. Each command must match at least one of the patterns defined in `allowedPostUpgradeTasks` in order to be executed. If the list of allowed tasks is empty then no tasks will be executed. diff --git a/docs/usage/self-hosted-configuration.md b/docs/usage/self-hosted-configuration.md index 931d24e8ccc6cc..2525f100708a0d 100644 --- a/docs/usage/self-hosted-configuration.md +++ b/docs/usage/self-hosted-configuration.md @@ -60,14 +60,12 @@ npx ng update @angular/core --from=10.0.0 --to=11.0.0 --migrate-only --allow-dir A list of regular expressions that determine which commands in `postUpgradeTasks` are allowed to be executed. If this list is empty then no tasks will be executed. -Also you need to have `"trustLevel": "high"`, otherwise these tasks will be ignored. e.g. ```json { - "allowedPostUpgradeCommands": ["^tslint --fix$", "^tslint --[a-z]+$"], - "trustLevel": "high" + "allowedPostUpgradeCommands": ["^tslint --fix$", "^tslint --[a-z]+$"] } ``` From 305b449df22f3f472dc1fe7da4ef2f5001342259 Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Wed, 21 Apr 2021 17:55:23 +0200 Subject: [PATCH 10/21] refactor: skipInstalls -> artifactUpdateApproach (#9119) Renames skipInstalls to artifactUpdateApproach and changes from boolean to enum. BREAKING CHANGE: skipInstalls has been changed to artifactsUpdateApproach --- docs/usage/self-hosted-configuration.md | 14 +++++----- .../__snapshots__/migration.spec.ts.snap | 2 ++ lib/config/definitions.ts | 9 +++--- lib/config/migration.spec.ts | 2 ++ lib/config/migration.ts | 7 +++++ .../extract/__snapshots__/index.spec.ts.snap | 28 +++++++++---------- lib/manager/npm/extract/index.ts | 24 +++++----------- lib/manager/npm/post-update/lerna.spec.ts | 8 +++--- lib/manager/npm/post-update/lerna.ts | 6 ++-- lib/manager/npm/post-update/npm.spec.ts | 20 ++++++------- lib/manager/npm/post-update/npm.ts | 4 +-- lib/manager/npm/post-update/yarn.ts | 2 +- lib/manager/types.ts | 5 +--- .../__snapshots__/manager-files.spec.ts.snap | 2 +- 14 files changed, 66 insertions(+), 67 deletions(-) diff --git a/docs/usage/self-hosted-configuration.md b/docs/usage/self-hosted-configuration.md index 2525f100708a0d..f3567222b3f933 100644 --- a/docs/usage/self-hosted-configuration.md +++ b/docs/usage/self-hosted-configuration.md @@ -28,7 +28,7 @@ module.exports = { In the `renovate.json` file, define the commands and files to be included in the final commit. -The command to install dependencies (`npm ci --ignore-scripts`) is necessary because, by default, the installation of dependencies is skipped (see the `skipInstalls` admin option). +The command to install dependencies (`npm ci --ignore-scripts`) is necessary because, by default, the installation of dependencies is skipped (see the `artifactUpdateApproach` admin option). ```json { @@ -69,6 +69,12 @@ e.g. } ``` +## artifactUpdateApproach + +By default, Renovate will use the most efficient approach to updating package files and lock files, which in most cases skips the need to perform a full module install by the bot. +If this is set to 'deep', then a full install of modules will be done. +This is currently applicable to `npm` and `yarn` only, and automatically set to `deep` when a full install is detected as necessary. + ## autodiscover When you enable `autodiscover`, by default, Renovate will run on _every_ repository that the bot account can access. @@ -377,12 +383,6 @@ It could then be used in a repository config or preset like so: Secret names must start with a upper or lower case character and can contain only characters, digits, or underscores. -## skipInstalls - -By default, Renovate will use the most efficient approach to updating package files and lock files, which in most cases skips the need to perform a full module install by the bot. -If this is set to false, then a full install of modules will be done. -This is currently applicable to `npm` and `lerna`/`npm` only, and only used in cases where bugs in `npm` result in incorrect lock files being updated. - ## token ## username diff --git a/lib/config/__snapshots__/migration.spec.ts.snap b/lib/config/__snapshots__/migration.spec.ts.snap index a9d93e6307f2b3..27d5183112d3f3 100644 --- a/lib/config/__snapshots__/migration.spec.ts.snap +++ b/lib/config/__snapshots__/migration.spec.ts.snap @@ -80,6 +80,7 @@ Object { "additionalBranchPrefix": "{{parentDir}}-", "allowCustomCrateRegistries": true, "allowScripts": true, + "artifactUpdateApproach": "shallow", "autodiscover": true, "automerge": false, "automergeType": "branch", @@ -173,6 +174,7 @@ Object { "versioning": "maven", }, Object { + "artifactUpdateApproach": "deep", "matchDepTypes": Array [ "peerDependencies", ], diff --git a/lib/config/definitions.ts b/lib/config/definitions.ts index 7ba77d22b16033..6db106c11f72c6 100644 --- a/lib/config/definitions.ts +++ b/lib/config/definitions.ts @@ -564,11 +564,12 @@ const options: RenovateOptions[] = [ type: 'boolean', }, { - name: 'skipInstalls', + name: 'artifactUpdateApproach', description: - 'Skip installing modules/dependencies if lock file updating is possible alone.', - type: 'boolean', - default: null, + 'Whether to employ a deep or shallow approach to artifact updating.', + type: 'string', + allowedValues: ['auto', 'deep', 'shallow'], + default: 'auto', admin: true, }, { diff --git a/lib/config/migration.spec.ts b/lib/config/migration.spec.ts index 6f19f5c6cacffe..477b523b2ead92 100644 --- a/lib/config/migration.spec.ts +++ b/lib/config/migration.spec.ts @@ -52,6 +52,7 @@ describe(getName(__filename), () => { binarySource: 'auto', automergeMinor: true, automergePatch: true, + skipInstalls: true, masterIssue: 'true', masterIssueTitle: 'foo', gomodTidy: true, @@ -95,6 +96,7 @@ describe(getName(__filename), () => { ], peerDependencies: { versionStrategy: 'widen', + skipInstalls: false, }, packageRules: [ { diff --git a/lib/config/migration.ts b/lib/config/migration.ts index 32ddd4566b6eaa..982da884faa34c 100644 --- a/lib/config/migration.ts +++ b/lib/config/migration.ts @@ -172,6 +172,13 @@ export function migrateConfig( migratedConfig[key] = val.replace(/{{depNameShort}}/g, '{{depName}}'); } else if (key === 'gitFs') { delete migratedConfig.gitFs; + } else if (key === 'skipInstalls') { + delete migratedConfig.skipInstalls; + if (val) { + migratedConfig.artifactUpdateApproach = 'shallow'; + } else { + migratedConfig.artifactUpdateApproach = 'deep'; + } } else if (key === 'rebaseStalePrs') { delete migratedConfig.rebaseStalePrs; if (!migratedConfig.rebaseWhen) { diff --git a/lib/manager/npm/extract/__snapshots__/index.spec.ts.snap b/lib/manager/npm/extract/__snapshots__/index.spec.ts.snap index e0b886ce2fb95c..3200c3f4e36426 100644 --- a/lib/manager/npm/extract/__snapshots__/index.spec.ts.snap +++ b/lib/manager/npm/extract/__snapshots__/index.spec.ts.snap @@ -15,6 +15,7 @@ Object { "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { + "hasFileRefs": false, "lernaJsonFile": undefined, }, "npmLock": undefined, @@ -23,7 +24,6 @@ Object { "packageJsonName": undefined, "packageJsonType": "app", "pnpmShrinkwrap": undefined, - "skipInstalls": true, "yarnLock": undefined, "yarnWorkspacesPackages": undefined, "yarnrc": undefined, @@ -139,6 +139,7 @@ Object { "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { + "hasFileRefs": true, "lernaJsonFile": undefined, }, "npmLock": undefined, @@ -147,7 +148,6 @@ Object { "packageJsonName": undefined, "packageJsonType": "library", "pnpmShrinkwrap": undefined, - "skipInstalls": false, "yarnLock": undefined, "yarnWorkspacesPackages": undefined, "yarnrc": undefined, @@ -303,6 +303,7 @@ Object { "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { + "hasFileRefs": false, "lernaJsonFile": undefined, }, "npmLock": undefined, @@ -311,7 +312,6 @@ Object { "packageJsonName": undefined, "packageJsonType": "app", "pnpmShrinkwrap": undefined, - "skipInstalls": true, "yarnLock": undefined, "yarnWorkspacesPackages": undefined, "yarnrc": undefined, @@ -353,6 +353,7 @@ Object { "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { + "hasFileRefs": false, "lernaJsonFile": undefined, }, "npmLock": undefined, @@ -361,7 +362,6 @@ Object { "packageJsonName": undefined, "packageJsonType": "app", "pnpmShrinkwrap": undefined, - "skipInstalls": false, "yarnLock": undefined, "yarnWorkspacesPackages": undefined, "yarnrc": undefined, @@ -414,6 +414,7 @@ Object { "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { + "hasFileRefs": false, "lernaJsonFile": undefined, }, "npmLock": undefined, @@ -422,7 +423,6 @@ Object { "packageJsonName": undefined, "packageJsonType": "library", "pnpmShrinkwrap": undefined, - "skipInstalls": true, "yarnLock": undefined, "yarnWorkspacesPackages": undefined, "yarnrc": undefined, @@ -469,6 +469,7 @@ Object { "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { + "hasFileRefs": false, "lernaJsonFile": undefined, }, "npmLock": undefined, @@ -477,7 +478,6 @@ Object { "packageJsonName": undefined, "packageJsonType": "library", "pnpmShrinkwrap": undefined, - "skipInstalls": true, "yarnLock": undefined, "yarnWorkspacesPackages": undefined, "yarnrc": undefined, @@ -606,6 +606,7 @@ Object { "lernaClient": "npm", "lernaPackages": undefined, "managerData": Object { + "hasFileRefs": false, "lernaJsonFile": "lerna.json", }, "npmLock": undefined, @@ -614,7 +615,6 @@ Object { "packageJsonName": "renovate", "packageJsonType": "app", "pnpmShrinkwrap": undefined, - "skipInstalls": true, "yarnLock": undefined, "yarnWorkspacesPackages": undefined, "yarnrc": undefined, @@ -743,6 +743,7 @@ Object { "lernaClient": "yarn", "lernaPackages": undefined, "managerData": Object { + "hasFileRefs": false, "lernaJsonFile": "lerna.json", }, "npmLock": undefined, @@ -751,7 +752,6 @@ Object { "packageJsonName": "renovate", "packageJsonType": "app", "pnpmShrinkwrap": undefined, - "skipInstalls": true, "yarnLock": undefined, "yarnWorkspacesPackages": undefined, "yarnrc": undefined, @@ -880,6 +880,7 @@ Object { "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { + "hasFileRefs": false, "lernaJsonFile": undefined, }, "npmLock": undefined, @@ -888,7 +889,6 @@ Object { "packageJsonName": "renovate", "packageJsonType": "app", "pnpmShrinkwrap": undefined, - "skipInstalls": true, "yarnLock": "yarn.lock", "yarnWorkspacesPackages": undefined, "yarnrc": undefined, @@ -903,6 +903,7 @@ Object { "lernaClient": "npm", "lernaPackages": undefined, "managerData": Object { + "hasFileRefs": false, "lernaJsonFile": "lerna.json", }, "npmLock": undefined, @@ -911,7 +912,6 @@ Object { "packageJsonName": "@a/b", "packageJsonType": "app", "pnpmShrinkwrap": undefined, - "skipInstalls": true, "yarnLock": undefined, "yarnWorkspacesPackages": Array [ "packages/*", @@ -1042,6 +1042,7 @@ Object { "lernaClient": "npm", "lernaPackages": undefined, "managerData": Object { + "hasFileRefs": false, "lernaJsonFile": "lerna.json", }, "npmLock": undefined, @@ -1050,7 +1051,6 @@ Object { "packageJsonName": "renovate", "packageJsonType": "app", "pnpmShrinkwrap": undefined, - "skipInstalls": true, "yarnLock": undefined, "yarnWorkspacesPackages": undefined, "yarnrc": undefined, @@ -1065,6 +1065,7 @@ Object { "lernaClient": "npm", "lernaPackages": undefined, "managerData": Object { + "hasFileRefs": false, "lernaJsonFile": "lerna.json", }, "npmLock": undefined, @@ -1073,7 +1074,6 @@ Object { "packageJsonName": "@a/b", "packageJsonType": "app", "pnpmShrinkwrap": undefined, - "skipInstalls": true, "yarnLock": undefined, "yarnWorkspacesPackages": Array [ "packages/*", @@ -1090,6 +1090,7 @@ Object { "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { + "hasFileRefs": false, "lernaJsonFile": undefined, }, "npmLock": undefined, @@ -1098,7 +1099,6 @@ Object { "packageJsonName": "@a/b", "packageJsonType": "app", "pnpmShrinkwrap": undefined, - "skipInstalls": true, "yarnLock": undefined, "yarnWorkspacesPackages": Array [ "packages/*", @@ -1229,6 +1229,7 @@ Object { "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { + "hasFileRefs": false, "lernaJsonFile": undefined, }, "npmLock": undefined, @@ -1237,7 +1238,6 @@ Object { "packageJsonName": "renovate", "packageJsonType": "app", "pnpmShrinkwrap": undefined, - "skipInstalls": true, "yarnLock": undefined, "yarnWorkspacesPackages": undefined, "yarnrc": undefined, diff --git a/lib/manager/npm/extract/index.ts b/lib/manager/npm/extract/index.ts index aacf7d55444bef..727484819f6183 100644 --- a/lib/manager/npm/extract/index.ts +++ b/lib/manager/npm/extract/index.ts @@ -126,7 +126,7 @@ export async function extractPackageFile( let lernaJsonFile: string; let lernaPackages: string[]; let lernaClient: 'yarn' | 'npm'; - let hasFancyRefs = false; + let hasFileRefs = false; let lernaJson: { packages: string[]; npmClient: string; @@ -224,7 +224,6 @@ export async function extractPackageFile( if (dep.currentValue.startsWith('npm:')) { dep.npmPackageAlias = true; - hasFancyRefs = true; const valSplit = dep.currentValue.replace('npm:', '').split('@'); if (valSplit.length === 2) { dep.lookupName = valSplit[0]; @@ -238,7 +237,11 @@ export async function extractPackageFile( } if (dep.currentValue.startsWith('file:')) { dep.skipReason = SkipReason.File; - hasFancyRefs = true; + // https://github.com/npm/cli/issues/1432 + // Explanation: + // - npm install --package-lock-only is buggy for transitive deps in file: references + // - So we set artifactUpdateApproach to false if file: refs are found *and* the user hasn't explicitly set the value already + hasFileRefs = true; return dep; } if (isValid(dep.currentValue)) { @@ -344,19 +347,6 @@ export async function extractPackageFile( return null; } } - let skipInstalls = config.skipInstalls; - if (skipInstalls === null) { - if (hasFancyRefs) { - // https://github.com/npm/cli/issues/1432 - // Explanation: - // - npm install --package-lock-only is buggy for transitive deps in file: and npm: references - // - So we set skipInstalls to false if file: or npm: refs are found *and* the user hasn't explicitly set the value already - logger.debug('Automatically setting skipInstalls to false'); - skipInstalls = false; - } else { - skipInstalls = true; - } - } return { deps, @@ -368,11 +358,11 @@ export async function extractPackageFile( yarnrc, ...lockFiles, managerData: { + hasFileRefs, lernaJsonFile, }, lernaClient, lernaPackages, - skipInstalls, yarnWorkspacesPackages, constraints, }; diff --git a/lib/manager/npm/post-update/lerna.spec.ts b/lib/manager/npm/post-update/lerna.spec.ts index b5a596d671bbc5..7ba6d474d67c37 100644 --- a/lib/manager/npm/post-update/lerna.spec.ts +++ b/lib/manager/npm/post-update/lerna.spec.ts @@ -47,26 +47,26 @@ describe(getName(__filename), () => { }); it('generates package-lock.json files', async () => { const execSnapshots = mockExecAll(exec); - const skipInstalls = true; + const artifactUpdateApproach = 'shallow'; const res = await lernaHelper.generateLockFiles( lernaPkgFile('npm'), 'some-dir', {}, {}, - skipInstalls + artifactUpdateApproach ); expect(res.error).toBe(false); expect(execSnapshots).toMatchSnapshot(); }); it('performs full npm install', async () => { const execSnapshots = mockExecAll(exec); - const skipInstalls = false; + const artifactUpdateApproach = 'deep'; const res = await lernaHelper.generateLockFiles( lernaPkgFile('npm'), 'some-dir', {}, {}, - skipInstalls + artifactUpdateApproach ); expect(res.error).toBe(false); expect(execSnapshots).toMatchSnapshot(); diff --git a/lib/manager/npm/post-update/lerna.ts b/lib/manager/npm/post-update/lerna.ts index 2ce9e38d4a8362..89946ac87a974a 100644 --- a/lib/manager/npm/post-update/lerna.ts +++ b/lib/manager/npm/post-update/lerna.ts @@ -33,7 +33,7 @@ export async function generateLockFiles( cwd: string, config: PostUpdateConfig, env: NodeJS.ProcessEnv, - skipInstalls?: boolean + artifactUpdateApproach?: string ): Promise { const lernaClient = lernaPackageFile.lernaClient; if (!lernaClient) { @@ -52,7 +52,7 @@ export async function generateLockFiles( installYarn += `@${quote(yarnCompatibility)}`; } preCommands.push(installYarn); - if (skipInstalls !== false) { + if (artifactUpdateApproach !== 'deep') { preCommands.push(getOptimizeCommand()); } cmdOptions = '--ignore-scripts --ignore-engines --ignore-platform'; @@ -64,7 +64,7 @@ export async function generateLockFiles( } preCommands.push(installNpm, 'hash -d npm'); cmdOptions = '--ignore-scripts --no-audit'; - if (skipInstalls !== false) { + if (artifactUpdateApproach !== 'deep') { cmdOptions += ' --package-lock-only'; } } else { diff --git a/lib/manager/npm/post-update/npm.spec.ts b/lib/manager/npm/post-update/npm.spec.ts index f235cb63cc2af1..d17d200d5d37c3 100644 --- a/lib/manager/npm/post-update/npm.spec.ts +++ b/lib/manager/npm/post-update/npm.spec.ts @@ -26,7 +26,7 @@ describe('generateLockFile', () => { it('generates lock files', async () => { const execSnapshots = mockExecAll(exec); fs.readFile = jest.fn(() => 'package-lock-contents') as never; - const skipInstalls = true; + const artifactUpdateApproach = 'deep'; const dockerMapDotfiles = true; const postUpdateOptions = ['npmDedupe']; const updates = [ @@ -36,7 +36,7 @@ describe('generateLockFile', () => { 'some-dir', {}, 'package-lock.json', - { dockerMapDotfiles, skipInstalls, postUpdateOptions }, + { dockerMapDotfiles, artifactUpdateApproach, postUpdateOptions }, updates ); expect(fs.readFile).toHaveBeenCalledTimes(1); @@ -47,7 +47,7 @@ describe('generateLockFile', () => { it('performs lock file updates', async () => { const execSnapshots = mockExecAll(exec); fs.readFile = jest.fn(() => 'package-lock-contents') as never; - const skipInstalls = true; + const artifactUpdateApproach = 'shallow'; const updates = [ { depName: 'some-dep', newVersion: '1.0.1', isLockfileUpdate: true }, ]; @@ -55,7 +55,7 @@ describe('generateLockFile', () => { 'some-dir', {}, 'package-lock.json', - { skipInstalls }, + { artifactUpdateApproach }, updates ); expect(fs.readFile).toHaveBeenCalledTimes(1); @@ -68,12 +68,12 @@ describe('generateLockFile', () => { fs.pathExists.mockResolvedValueOnce(true); fs.move = jest.fn(); fs.readFile = jest.fn(() => 'package-lock-contents') as never; - const skipInstalls = true; + const artifactUpdateApproach = 'shallow'; const res = await npmHelper.generateLockFile( 'some-dir', {}, 'npm-shrinkwrap.json', - { skipInstalls } + { artifactUpdateApproach } ); expect(fs.pathExists).toHaveBeenCalledWith( upath.join('some-dir', 'package-lock.json') @@ -97,12 +97,12 @@ describe('generateLockFile', () => { fs.pathExists.mockResolvedValueOnce(false); fs.move = jest.fn(); fs.readFile = jest.fn((_, _1) => 'package-lock-contents') as never; - const skipInstalls = true; + const artifactUpdateApproach = 'shallow'; const res = await npmHelper.generateLockFile( 'some-dir', {}, 'npm-shrinkwrap.json', - { skipInstalls } + { artifactUpdateApproach } ); expect(fs.pathExists).toHaveBeenCalledWith( upath.join('some-dir', 'package-lock.json') @@ -120,13 +120,13 @@ describe('generateLockFile', () => { it('performs full install', async () => { const execSnapshots = mockExecAll(exec); fs.readFile = jest.fn(() => 'package-lock-contents') as never; - const skipInstalls = false; + const artifactUpdateApproach = 'deep'; const binarySource = BinarySource.Global; const res = await npmHelper.generateLockFile( 'some-dir', {}, 'package-lock.json', - { skipInstalls, binarySource } + { artifactUpdateApproach, binarySource } ); expect(fs.readFile).toHaveBeenCalledTimes(1); expect(res.error).toBeUndefined(); diff --git a/lib/manager/npm/post-update/npm.ts b/lib/manager/npm/post-update/npm.ts index a11bce39231f08..305bcfb09917f8 100644 --- a/lib/manager/npm/post-update/npm.ts +++ b/lib/manager/npm/post-update/npm.ts @@ -26,7 +26,7 @@ export async function generateLockFile( upgrades: Upgrade[] = [] ): Promise { logger.debug(`Spawning npm install to create ${cwd}/${filename}`); - const { skipInstalls, postUpdateOptions } = config; + const { artifactUpdateApproach } = config; let lockFile = null; try { @@ -49,7 +49,7 @@ export async function generateLockFile( const preCommands = [installNpm, 'hash -d npm']; const commands = []; let cmdOptions = ''; - if (postUpdateOptions?.includes('npmDedupe') || skipInstalls === false) { + if (artifactUpdateApproach === 'deep') { logger.debug('Performing node_modules install'); cmdOptions += '--ignore-scripts --no-audit'; } else { diff --git a/lib/manager/npm/post-update/yarn.ts b/lib/manager/npm/post-update/yarn.ts index 5e7d4958273365..be153bbee74291 100644 --- a/lib/manager/npm/post-update/yarn.ts +++ b/lib/manager/npm/post-update/yarn.ts @@ -82,7 +82,7 @@ export async function generateLockFile( CI: 'true', }; - if (isYarn1 && config.skipInstalls !== false) { + if (isYarn1 && config.artifactUpdateApproach !== 'deep') { const { offlineMirror, yarnPath } = await checkYarnrc(cwd); if (!offlineMirror) { logger.debug('Updating yarn.lock only - skipping node_modules'); diff --git a/lib/manager/types.ts b/lib/manager/types.ts index 2c167ecc539103..a0e31935fe05eb 100644 --- a/lib/manager/types.ts +++ b/lib/manager/types.ts @@ -25,7 +25,6 @@ export interface ExtractConfig extends ManagerConfig { aliases?: Record; ignoreNpmrcFile?: boolean; yarnrc?: string; - skipInstalls?: boolean; versioning?: string; updateInternalDeps?: boolean; } @@ -100,7 +99,6 @@ export interface PackageFile> packageJsonType?: 'app' | 'library'; packageFileVersion?: string; parent?: string; - skipInstalls?: boolean; yarnrc?: string; yarnWorkspacesPackages?: string[] | string; matchStrings?: string[]; @@ -277,8 +275,7 @@ export interface PostUpdateConfig extends ManagerConfig, Record { cacheDir?: string; updatedPackageFiles?: File[]; postUpdateOptions?: string[]; - skipInstalls?: boolean; - + artifactUpdateApproach?: 'auto' | 'deep' | 'shallow'; platform?: string; upgrades?: Upgrade[]; npmLock?: string; diff --git a/lib/workers/repository/extract/__snapshots__/manager-files.spec.ts.snap b/lib/workers/repository/extract/__snapshots__/manager-files.spec.ts.snap index 7b05cb15e52b9f..917cd12286f155 100644 --- a/lib/workers/repository/extract/__snapshots__/manager-files.spec.ts.snap +++ b/lib/workers/repository/extract/__snapshots__/manager-files.spec.ts.snap @@ -18,6 +18,7 @@ Array [ "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { + "hasFileRefs": false, "lernaJsonFile": undefined, }, "npmLock": undefined, @@ -27,7 +28,6 @@ Array [ "packageJsonName": undefined, "packageJsonType": "app", "pnpmShrinkwrap": undefined, - "skipInstalls": undefined, "yarnLock": undefined, "yarnWorkspacesPackages": undefined, "yarnrc": undefined, From 7067b3963858bab37da4ff6dbb3959f46bd4a540 Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Tue, 6 Apr 2021 13:06:40 +0200 Subject: [PATCH 11/21] feat(npm): remove ignoreNpmrcFile support (#9409) Removes support for the ignoreNpmrcFile config option. BREAKING CHANGE: ignoreNpmrcFile is no longer supported. Use an empty string for config.npmrc instead. --- docs/usage/configuration-options.md | 7 ---- .../__snapshots__/migration.spec.ts.snap | 1 + lib/config/definitions.ts | 6 --- lib/config/migration.spec.ts | 1 + lib/config/migration.ts | 3 ++ .../extract/__snapshots__/index.spec.ts.snap | 14 ------- lib/manager/npm/extract/index.spec.ts | 16 +++++++- lib/manager/npm/extract/index.ts | 39 ++++++++----------- lib/manager/npm/post-update/index.ts | 3 -- lib/manager/types.ts | 3 +- .../__snapshots__/manager-files.spec.ts.snap | 1 - lib/workers/repository/init/config.ts | 1 - 12 files changed, 37 insertions(+), 58 deletions(-) diff --git a/docs/usage/configuration-options.md b/docs/usage/configuration-options.md index c7b4c91d667881..b21d513dc1b8a5 100644 --- a/docs/usage/configuration-options.md +++ b/docs/usage/configuration-options.md @@ -969,13 +969,6 @@ The above is the same as if you wrote this package rule: } ``` -## ignoreNpmrcFile - -By default, Renovate will look for and use any `.npmrc` file it finds in a repository. -Additionally, it will be read in by `npm` or `yarn` at the time of lock file generation. -Sometimes this causes problems, for example if the file contains placeholder values, so you can configure this to `true` and Renovate will ignore any `.npmrc` files it finds and temporarily remove the file before running `npm install` or `yarn install`. -Renovate will try to configure this to `true` also if you have configured any `npmrc` string within your config file. - ## ignorePaths Using this setting, you can selectively ignore package files that you don't want Renovate autodiscovering. diff --git a/lib/config/__snapshots__/migration.spec.ts.snap b/lib/config/__snapshots__/migration.spec.ts.snap index 27d5183112d3f3..c9c32342a28022 100644 --- a/lib/config/__snapshots__/migration.spec.ts.snap +++ b/lib/config/__snapshots__/migration.spec.ts.snap @@ -125,6 +125,7 @@ Object { "minor": Object { "automerge": true, }, + "npmrc": "", "nvmrc": Object { "packageRules": Array [ Object { diff --git a/lib/config/definitions.ts b/lib/config/definitions.ts index 6db106c11f72c6..bc4584035147ff 100644 --- a/lib/config/definitions.ts +++ b/lib/config/definitions.ts @@ -572,12 +572,6 @@ const options: RenovateOptions[] = [ default: 'auto', admin: true, }, - { - name: 'ignoreNpmrcFile', - description: 'Whether to ignore any .npmrc file found in repository.', - type: 'boolean', - default: false, - }, { name: 'autodiscover', description: 'Autodiscover all repositories.', diff --git a/lib/config/migration.spec.ts b/lib/config/migration.spec.ts index 477b523b2ead92..ba6fff96902167 100644 --- a/lib/config/migration.spec.ts +++ b/lib/config/migration.spec.ts @@ -44,6 +44,7 @@ describe(getName(__filename), () => { onboarding: 'false' as never, multipleMajorPrs: true, gitFs: false, + ignoreNpmrcFile: true, separateMajorReleases: true, separatePatchReleases: true, suppressNotifications: ['lockFileErrors', 'prEditNotification'], diff --git a/lib/config/migration.ts b/lib/config/migration.ts index 982da884faa34c..64cbd52c81ff19 100644 --- a/lib/config/migration.ts +++ b/lib/config/migration.ts @@ -207,6 +207,9 @@ export function migrateConfig( migratedConfig.allowScripts ??= true; migratedConfig.exposeAllEnv ??= true; } + } else if (key === 'ignoreNpmrcFile') { + delete migratedConfig.ignoreNpmrcFile; + migratedConfig.npmrc ||= ''; } else if ( key === 'branchName' && is.string(val) && diff --git a/lib/manager/npm/extract/__snapshots__/index.spec.ts.snap b/lib/manager/npm/extract/__snapshots__/index.spec.ts.snap index 3200c3f4e36426..ec3e8ca7139576 100644 --- a/lib/manager/npm/extract/__snapshots__/index.spec.ts.snap +++ b/lib/manager/npm/extract/__snapshots__/index.spec.ts.snap @@ -11,7 +11,6 @@ Object { "skipReason": "invalid-name", }, ], - "ignoreNpmrcFile": undefined, "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { @@ -135,7 +134,6 @@ Object { "prettyDepType": "engine", }, ], - "ignoreNpmrcFile": undefined, "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { @@ -299,7 +297,6 @@ Object { "sourceUrl": "https://github.com/owner/n", }, ], - "ignoreNpmrcFile": undefined, "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { @@ -349,7 +346,6 @@ Object { "skipReason": "unknown-version", }, ], - "ignoreNpmrcFile": undefined, "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { @@ -410,7 +406,6 @@ Object { "skipReason": "unknown-volta", }, ], - "ignoreNpmrcFile": undefined, "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { @@ -465,7 +460,6 @@ Object { "skipReason": "unknown-version", }, ], - "ignoreNpmrcFile": undefined, "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { @@ -602,7 +596,6 @@ Object { "prettyDepType": "resolutions", }, ], - "ignoreNpmrcFile": undefined, "lernaClient": "npm", "lernaPackages": undefined, "managerData": Object { @@ -739,7 +732,6 @@ Object { "prettyDepType": "resolutions", }, ], - "ignoreNpmrcFile": undefined, "lernaClient": "yarn", "lernaPackages": undefined, "managerData": Object { @@ -876,7 +868,6 @@ Object { "prettyDepType": "resolutions", }, ], - "ignoreNpmrcFile": undefined, "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { @@ -899,7 +890,6 @@ exports[`manager/npm/extract/index .extractPackageFile() finds complex yarn work Object { "constraints": Object {}, "deps": Array [], - "ignoreNpmrcFile": undefined, "lernaClient": "npm", "lernaPackages": undefined, "managerData": Object { @@ -1038,7 +1028,6 @@ Object { "prettyDepType": "resolutions", }, ], - "ignoreNpmrcFile": undefined, "lernaClient": "npm", "lernaPackages": undefined, "managerData": Object { @@ -1061,7 +1050,6 @@ exports[`manager/npm/extract/index .extractPackageFile() finds simple yarn works Object { "constraints": Object {}, "deps": Array [], - "ignoreNpmrcFile": undefined, "lernaClient": "npm", "lernaPackages": undefined, "managerData": Object { @@ -1086,7 +1074,6 @@ exports[`manager/npm/extract/index .extractPackageFile() finds simple yarn works Object { "constraints": Object {}, "deps": Array [], - "ignoreNpmrcFile": undefined, "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { @@ -1225,7 +1212,6 @@ Object { "prettyDepType": "resolutions", }, ], - "ignoreNpmrcFile": undefined, "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { diff --git a/lib/manager/npm/extract/index.spec.ts b/lib/manager/npm/extract/index.spec.ts index fa78521e8218ba..e4d6bac61dc2b0 100644 --- a/lib/manager/npm/extract/index.spec.ts +++ b/lib/manager/npm/extract/index.spec.ts @@ -113,6 +113,20 @@ describe(getName(__filename), () => { ); expect(res.npmrc).toBeDefined(); }); + it('ignores .npmrc when config.npmrc is defined', async () => { + fs.readLocalFile = jest.fn((fileName) => { + if (fileName === '.npmrc') { + return 'some-npmrc\n'; + } + return null; + }); + const res = await npmExtract.extractPackageFile( + input01Content, + 'package.json', + { npmrc: 'some-configured-npmrc' } + ); + expect(res.npmrc).toBeUndefined(); + }); it('finds and discards .npmrc', async () => { fs.readLocalFile = jest.fn((fileName) => { if (fileName === '.npmrc') { @@ -126,7 +140,7 @@ describe(getName(__filename), () => { 'package.json', {} ); - expect(res.npmrc).toBeUndefined(); + expect(res.npmrc).toEqual(''); }); it('finds lerna', async () => { fs.readLocalFile = jest.fn((fileName) => { diff --git a/lib/manager/npm/extract/index.ts b/lib/manager/npm/extract/index.ts index 727484819f6183..cbc04c1596e629 100644 --- a/lib/manager/npm/extract/index.ts +++ b/lib/manager/npm/extract/index.ts @@ -6,11 +6,7 @@ import * as datasourceGithubTags from '../../../datasource/github-tags'; import { id as npmId } from '../../../datasource/npm'; import { logger } from '../../../logger'; import { SkipReason } from '../../../types'; -import { - deleteLocalFile, - getSiblingFileName, - readLocalFile, -} from '../../../util/fs'; +import { getSiblingFileName, readLocalFile } from '../../../util/fs'; import * as nodeVersioning from '../../../versioning/node'; import { isValid, isVersion } from '../../../versioning/npm'; import type { @@ -95,26 +91,24 @@ export async function extractPackageFile( delete lockFiles.shrinkwrapJson; let npmrc: string; - let ignoreNpmrcFile: boolean; const npmrcFileName = getSiblingFileName(fileName, '.npmrc'); - // istanbul ignore if - if (config.ignoreNpmrcFile) { - await deleteLocalFile(npmrcFileName); - } else { - npmrc = await readLocalFile(npmrcFileName, 'utf8'); - if (npmrc?.includes('package-lock')) { - logger.debug('Stripping package-lock setting from npmrc'); - npmrc = npmrc.replace(/(^|\n)package-lock.*?(\n|$)/g, '\n'); - } - if (is.string(npmrc)) { + const npmrcContent = await readLocalFile(npmrcFileName, 'utf8'); + if (is.string(npmrcContent)) { + if (is.string(config.npmrc)) { + logger.debug( + { npmrcFileName }, + 'Repo .npmrc file is ignored due to presence of config.npmrc' + ); + } else { + npmrc = npmrcContent; + if (npmrc?.includes('package-lock')) { + logger.debug('Stripping package-lock setting from .npmrc'); + npmrc = npmrc.replace(/(^|\n)package-lock.*?(\n|$)/g, '\n'); + } if (npmrc.includes('=${') && !getAdminConfig().exposeAllEnv) { - logger.debug('Discarding .npmrc file with variables'); - ignoreNpmrcFile = true; - npmrc = undefined; - await deleteLocalFile(npmrcFileName); + logger.debug('Overriding .npmrc file with variables'); + npmrc = ''; } - } else { - npmrc = undefined; } } const yarnrcFileName = getSiblingFileName(fileName, '.yarnrc'); @@ -354,7 +348,6 @@ export async function extractPackageFile( packageFileVersion, packageJsonType, npmrc, - ignoreNpmrcFile, yarnrc, ...lockFiles, managerData: { diff --git a/lib/manager/npm/post-update/index.ts b/lib/manager/npm/post-update/index.ts index 083272c1612b0f..aa992b653e70e8 100644 --- a/lib/manager/npm/post-update/index.ts +++ b/lib/manager/npm/post-update/index.ts @@ -144,9 +144,6 @@ export async function writeExistingFiles( } catch (err) /* istanbul ignore next */ { logger.warn({ npmrcFilename, err }, 'Error writing .npmrc'); } - } else if (config.ignoreNpmrcFile) { - logger.debug('Removing ignored .npmrc file before artifact generation'); - await remove(npmrcFilename); } if (packageFile.yarnrc) { logger.debug(`Writing .yarnrc to ${basedir}`); diff --git a/lib/manager/types.ts b/lib/manager/types.ts index a0e31935fe05eb..d19073f1ff208b 100644 --- a/lib/manager/types.ts +++ b/lib/manager/types.ts @@ -23,7 +23,7 @@ export interface ExtractConfig extends ManagerConfig { endpoint?: string; gradle?: { timeout?: number }; aliases?: Record; - ignoreNpmrcFile?: boolean; + npmrc?: string; yarnrc?: string; versioning?: string; updateInternalDeps?: boolean; @@ -89,7 +89,6 @@ export interface PackageFile> datasource?: string; registryUrls?: string[]; deps: PackageDependency[]; - ignoreNpmrcFile?: boolean; lernaClient?: string; lernaPackages?: string[]; mavenProps?: Record; diff --git a/lib/workers/repository/extract/__snapshots__/manager-files.spec.ts.snap b/lib/workers/repository/extract/__snapshots__/manager-files.spec.ts.snap index 917cd12286f155..579ce1c3515dc0 100644 --- a/lib/workers/repository/extract/__snapshots__/manager-files.spec.ts.snap +++ b/lib/workers/repository/extract/__snapshots__/manager-files.spec.ts.snap @@ -14,7 +14,6 @@ Array [ "prettyDepType": "dependency", }, ], - "ignoreNpmrcFile": undefined, "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { diff --git a/lib/workers/repository/init/config.ts b/lib/workers/repository/init/config.ts index fb802acef351f8..15a92b1e2f9b1a 100644 --- a/lib/workers/repository/init/config.ts +++ b/lib/workers/repository/init/config.ts @@ -203,7 +203,6 @@ export async function mergeRenovateConfig( 'Ignoring any .npmrc files in repository due to configured npmrc' ); npmApi.setNpmrc(resolvedConfig.npmrc); - resolvedConfig.ignoreNpmrcFile = true; } // istanbul ignore if if (resolvedConfig.hostRules) { From 2bad77ba49e87c8d1894d2f6aad671085760cf79 Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Tue, 6 Apr 2021 14:20:07 +0200 Subject: [PATCH 12/21] feat(npm): remove ~/.npmrc support (#9400) Drops support for reading `.npmrc` from the bot's home directory. BREAKING CHANGE: Renovate will no longer read from ~/.npmrc. Configure `npmrc` in config instead. --- docs/development/local-development.md | 1 - docs/usage/private-modules.md | 16 +--------------- .../npm/__snapshots__/index.spec.ts.snap | 2 +- lib/datasource/npm/index.spec.ts | 2 +- lib/datasource/npm/npmrc.spec.ts | 2 +- lib/datasource/npm/npmrc.ts | 10 +++++----- 6 files changed, 9 insertions(+), 24 deletions(-) diff --git a/docs/development/local-development.md b/docs/development/local-development.md index 06de394c7a06bf..da8d7ac4678e63 100644 --- a/docs/development/local-development.md +++ b/docs/development/local-development.md @@ -75,7 +75,6 @@ The Renovate project uses the [Yarn](https://github.com/yarnpkg/yarn) package ma To ensure everything is working properly on your end, you must: -1. Make sure you don't have a local `.npmrc` file that overrides npm's default registry 1. Install all dependencies with `yarn install` 1. Make a build with `yarn build`, which should pass with no errors 1. Verify all tests pass and have 100% test coverage, by running `yarn test` diff --git a/docs/usage/private-modules.md b/docs/usage/private-modules.md index 2c8e596f774dc9..de8f6e3a801f4a 100644 --- a/docs/usage/private-modules.md +++ b/docs/usage/private-modules.md @@ -33,8 +33,6 @@ The recommended approaches in order of preference are: **Self-hosted hostRules**: Configure a hostRules entry in the bot's `config.js` with the `hostType`, `hostName` and `token` specified -**Self-hosted .npmrc**: copy an `.npmrc` file to the home dir of the bot. - **Renovate App with private modules from npmjs.org**: Add an encrypted `npmToken` to your Renovate config **Renovate App with a private registry**: Add an unencrypted `npmrc` plus an encrypted `npmToken` in config @@ -66,21 +64,9 @@ module.exports = { **NOTE:** Do not use `NPM_TOKEN` as an environment variable. -### Commit .npmrc file into repository - -One approach that many projects use for private repositories is to simply check in an authenticated `.npmrc` into the repository that is then shared between all developers. -Therefore anyone running `npm install` or `yarn install` from the project root will be automatically authenticated with npm without having to distribute npm logins to every developer and make sure they've run `npm login` first before installing. - -The good news is that this works for Renovate too. -If Renovate detects a `.npmrc` or `.yarnrc` file then it will use it for its install. - -Does not work if using binarySource=docker. -_This method will be deprecated soon_ - ### Add npmrc string to Renovate config -The above solution maybe have a downside that all users of the repository (e.g. developers) will also use any `.npmrc` that is checked into the repository, instead of their own one in `~/.npmrc`. -To avoid this, you can instead add your `.npmrc` authentication line to your Renovate config under the field `npmrc`. e.g. a `renovate.json` might look like this: +You can add an `.npmrc` authentication line to your Renovate config under the field `npmrc`. e.g. a `renovate.json` might look like this: ```json { diff --git a/lib/datasource/npm/__snapshots__/index.spec.ts.snap b/lib/datasource/npm/__snapshots__/index.spec.ts.snap index ac9065cc23dea7..847462a985443d 100644 --- a/lib/datasource/npm/__snapshots__/index.spec.ts.snap +++ b/lib/datasource/npm/__snapshots__/index.spec.ts.snap @@ -522,7 +522,7 @@ Array [ exports[`datasource/npm/index should use default registry if missing from npmrc 1`] = ` Object { "name": "foobar", - "registryUrl": "https://registry.npmjs.org", + "registryUrl": "https://registry.npmjs.org/", "releases": Array [ Object { "releaseTimestamp": "2018-05-06T05:21:53.000Z", diff --git a/lib/datasource/npm/index.spec.ts b/lib/datasource/npm/index.spec.ts index d5091d722de3ad..d398428ebf8c67 100644 --- a/lib/datasource/npm/index.spec.ts +++ b/lib/datasource/npm/index.spec.ts @@ -314,7 +314,7 @@ describe(getName(__filename), () => { setNpmrc(npmrcContent); setNpmrc(npmrcContent); setNpmrc(); - expect(getNpmrc()).toBeNull(); + expect(getNpmrc()).toEqual({}); }); it('should use default registry if missing from npmrc', async () => { diff --git a/lib/datasource/npm/npmrc.spec.ts b/lib/datasource/npm/npmrc.spec.ts index 41fff3d27c3457..ed44bfee821bb1 100644 --- a/lib/datasource/npm/npmrc.spec.ts +++ b/lib/datasource/npm/npmrc.spec.ts @@ -51,6 +51,6 @@ describe(getName(__filename), () => { it('ignores localhost', () => { setNpmrc(`registry=http://localhost`); expect(sanitize.add).toHaveBeenCalledTimes(0); - expect(getNpmrc()).toBeNull(); + expect(getNpmrc()).toEqual({}); }); }); diff --git a/lib/datasource/npm/npmrc.ts b/lib/datasource/npm/npmrc.ts index 3641998d365c9a..b7d700acac3c6a 100644 --- a/lib/datasource/npm/npmrc.ts +++ b/lib/datasource/npm/npmrc.ts @@ -9,8 +9,8 @@ import type { OutgoingHttpHeaders } from '../../util/http/types'; import { maskToken } from '../../util/mask'; import { add } from '../../util/sanitize'; -let npmrc: Record | null = null; -let npmrcRaw: string; +let npmrc: Record = {}; +let npmrcRaw = ''; export type Npmrc = Record; @@ -89,8 +89,8 @@ export function setNpmrc(input?: string): void { } } else if (npmrc) { logger.debug('Resetting npmrc'); - npmrc = null; - npmrcRaw = null; + npmrc = {}; + npmrcRaw = ''; } } @@ -106,7 +106,7 @@ export function resolvePackage(packageName: string): PackageResolution { try { registryUrl = getRegistryUrl(scope, getNpmrc()); } catch (err) { - registryUrl = 'https://registry.npmjs.org'; + registryUrl = 'https://registry.npmjs.org/'; } const packageUrl = url.resolve( registryUrl, From 67228ea638154b1781219621dfc4d8f4d25cc308 Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Wed, 21 Apr 2021 09:08:10 +0200 Subject: [PATCH 13/21] feat(config): delay preset resolution until after platform initialization (#9415) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Delay config preset resolution in admin config until after platform initialization. This will enable resolution of private “local>…” presets to work. BREAKING CHANGE: Config presets will be resolved after platform initialization, so from now on platform credentials cannot be placed in presets. --- lib/config/index.ts | 9 ++++----- lib/constants/error-messages.ts | 1 + lib/workers/global/index.ts | 12 ++++++++++++ 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/lib/config/index.ts b/lib/config/index.ts index a005f9bf1ee8ed..366813c25a0c80 100644 --- a/lib/config/index.ts +++ b/lib/config/index.ts @@ -7,7 +7,6 @@ import * as defaultsParser from './defaults'; import * as definitions from './definitions'; import * as envParser from './env'; import * as fileParser from './file'; -import { resolveConfigPresets } from './presets'; import type { GlobalConfig, ManagerConfig, @@ -47,10 +46,10 @@ export async function parseConfigs( logger.debug('Parsing configs'); // Get configs - const defaultConfig = await resolveConfigPresets(defaultsParser.getConfig()); - const fileConfig = await resolveConfigPresets(fileParser.getConfig(env)); - const cliConfig = await resolveConfigPresets(cliParser.getConfig(argv)); - const envConfig = await resolveConfigPresets(envParser.getConfig(env)); + const defaultConfig = defaultsParser.getConfig(); + const fileConfig = fileParser.getConfig(env); + const cliConfig = cliParser.getConfig(argv); + const envConfig = envParser.getConfig(env); let config: GlobalConfig = mergeChildConfig(fileConfig, envConfig); config = mergeChildConfig(config, cliConfig); diff --git a/lib/constants/error-messages.ts b/lib/constants/error-messages.ts index b032e18fcee8a2..eec1bbff1ecdff 100644 --- a/lib/constants/error-messages.ts +++ b/lib/constants/error-messages.ts @@ -12,6 +12,7 @@ export const PLATFORM_RATE_LIMIT_EXCEEDED = 'rate-limit-exceeded'; // Config Error export const CONFIG_VALIDATION = 'config-validation'; +export const CONFIG_PRESETS_INVALID = 'config-presets-invalid'; export const CONFIG_SECRETS_EXPOSED = 'config-secrets-exposed'; export const CONFIG_SECRETS_INVALID = 'config-secrets-invalid'; diff --git a/lib/workers/global/index.ts b/lib/workers/global/index.ts index 0d7978fb735f75..d7715983fe8c8c 100644 --- a/lib/workers/global/index.ts +++ b/lib/workers/global/index.ts @@ -5,12 +5,14 @@ import { satisfies } from 'semver'; import upath from 'upath'; import * as pkg from '../../../package.json'; import * as configParser from '../../config'; +import { resolveConfigPresets } from '../../config/presets'; import { validateConfigSecrets } from '../../config/secrets'; import type { GlobalConfig, RenovateConfig, RenovateRepository, } from '../../config/types'; +import { CONFIG_PRESETS_INVALID } from '../../constants/error-messages'; import { getProblems, logger, setMeta } from '../../logger'; import { setUtilConfig } from '../../util'; import * as hostRules from '../../util/host-rules'; @@ -70,6 +72,14 @@ function checkEnv(): void { } } +export async function validatePresets(config: GlobalConfig): Promise { + try { + await resolveConfigPresets(config); + } catch (err) /* istanbul ignore next */ { + throw new Error(CONFIG_PRESETS_INVALID); + } +} + export async function start(): Promise { let config: GlobalConfig; try { @@ -78,6 +88,8 @@ export async function start(): Promise { // initialize all submodules config = await globalInitialize(config); + await validatePresets(config); + checkEnv(); // validate secrets. Will throw and abort if invalid From 3904e902111f13371e0c1513035c8d602ada31e9 Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Sat, 10 Apr 2021 06:23:11 +0200 Subject: [PATCH 14/21] feat: drop dockerMapDotFiles (#9417) Drops support for dockerMapDotfiles BREAKING CHANGE: dockerMapDotfiles is no longer supported --- docs/usage/self-hosted-configuration.md | 11 ---- lib/config/definitions.ts | 8 --- .../__snapshots__/lerna.spec.ts.snap | 59 ------------------- lib/manager/npm/post-update/lerna.spec.ts | 16 +---- lib/manager/npm/post-update/lerna.ts | 7 --- lib/manager/npm/post-update/npm.spec.ts | 3 +- lib/manager/npm/post-update/npm.ts | 6 -- lib/manager/npm/post-update/pnpm.spec.ts | 1 - lib/manager/npm/post-update/pnpm.ts | 6 -- lib/manager/npm/post-update/yarn.spec.ts | 2 - lib/manager/npm/post-update/yarn.ts | 6 -- 11 files changed, 2 insertions(+), 123 deletions(-) diff --git a/docs/usage/self-hosted-configuration.md b/docs/usage/self-hosted-configuration.md index f3567222b3f933..58a81776bb32bb 100644 --- a/docs/usage/self-hosted-configuration.md +++ b/docs/usage/self-hosted-configuration.md @@ -164,17 +164,6 @@ You would use put this in your configuration file: If you pulled a new `node` image, the final image would be `ghcr.io/renovatebot/node` instead of `docker.io/renovate/node`. -## dockerMapDotfiles - -This is used if you want to map "dotfiles" from your host computer home directory to containers that Renovate creates, e.g. for updating lock files. -Currently applicable to `.npmrc` only. - -```json -{ - "dockerMapDotfiles": true -} -``` - ## dockerUser Override default user and group used by Docker-based binaries. diff --git a/lib/config/definitions.ts b/lib/config/definitions.ts index bc4584035147ff..54f8f9eb9a71df 100644 --- a/lib/config/definitions.ts +++ b/lib/config/definitions.ts @@ -254,14 +254,6 @@ const options: RenovateOptions[] = [ type: 'object', default: false, }, - { - name: 'dockerMapDotfiles', - description: - 'Map relevant home directory dotfiles into containers when binarySource=docker.', - admin: true, - type: 'boolean', - default: false, - }, { name: 'dockerChildPrefix', description: diff --git a/lib/manager/npm/post-update/__snapshots__/lerna.spec.ts.snap b/lib/manager/npm/post-update/__snapshots__/lerna.spec.ts.snap index e8f5d06c35c0a7..4dc615e84774c2 100644 --- a/lib/manager/npm/post-update/__snapshots__/lerna.spec.ts.snap +++ b/lib/manager/npm/post-update/__snapshots__/lerna.spec.ts.snap @@ -236,65 +236,6 @@ Array [ ] `; -exports[`manager/npm/post-update/lerna generateLockFiles() maps dot files 1`] = ` -Array [ - Object { - "cmd": "lerna info || echo \\"Ignoring lerna info failure\\"", - "options": Object { - "cwd": "some-dir", - "encoding": "utf-8", - "env": Object { - "HOME": "/home/user", - "HTTPS_PROXY": "https://example.com", - "HTTP_PROXY": "http://example.com", - "LANG": "en_US.UTF-8", - "LC_ALL": "en_US", - "NO_PROXY": "localhost", - "PATH": "/tmp/path", - }, - "maxBuffer": 10485760, - "timeout": 900000, - }, - }, - Object { - "cmd": "npm install --ignore-scripts --no-audit --package-lock-only", - "options": Object { - "cwd": "some-dir", - "encoding": "utf-8", - "env": Object { - "HOME": "/home/user", - "HTTPS_PROXY": "https://example.com", - "HTTP_PROXY": "http://example.com", - "LANG": "en_US.UTF-8", - "LC_ALL": "en_US", - "NO_PROXY": "localhost", - "PATH": "/tmp/path", - }, - "maxBuffer": 10485760, - "timeout": 900000, - }, - }, - Object { - "cmd": "lerna bootstrap --no-ci --ignore-scripts -- --ignore-scripts --no-audit --package-lock-only", - "options": Object { - "cwd": "some-dir", - "encoding": "utf-8", - "env": Object { - "HOME": "/home/user", - "HTTPS_PROXY": "https://example.com", - "HTTP_PROXY": "http://example.com", - "LANG": "en_US.UTF-8", - "LC_ALL": "en_US", - "NO_PROXY": "localhost", - "PATH": "/tmp/path", - }, - "maxBuffer": 10485760, - "timeout": 900000, - }, - }, -] -`; - exports[`manager/npm/post-update/lerna generateLockFiles() performs full npm install 1`] = ` Array [ Object { diff --git a/lib/manager/npm/post-update/lerna.spec.ts b/lib/manager/npm/post-update/lerna.spec.ts index 7ba6d474d67c37..8e771c6eab2bcc 100644 --- a/lib/manager/npm/post-update/lerna.spec.ts +++ b/lib/manager/npm/post-update/lerna.spec.ts @@ -93,27 +93,13 @@ describe(getName(__filename), () => { expect(res.error).toBe(false); expect(execSnapshots).toMatchSnapshot(); }); - it('maps dot files', async () => { - const execSnapshots = mockExecAll(exec); - const res = await lernaHelper.generateLockFiles( - lernaPkgFile('npm'), - 'some-dir', - { - dockerMapDotfiles: true, - constraints: { npm: '^6.0.0' }, - }, - {} - ); - expect(res.error).toBe(false); - expect(execSnapshots).toMatchSnapshot(); - }); it('allows scripts for trust level high', async () => { const execSnapshots = mockExecAll(exec); setAdminConfig({ allowScripts: true }); const res = await lernaHelper.generateLockFiles( lernaPkgFile('npm'), 'some-dir', - {}, + { constraints: { npm: '^6.0.0' } }, {} ); expect(res.error).toBe(false); diff --git a/lib/manager/npm/post-update/lerna.ts b/lib/manager/npm/post-update/lerna.ts index 89946ac87a974a..e66c779dedba42 100644 --- a/lib/manager/npm/post-update/lerna.ts +++ b/lib/manager/npm/post-update/lerna.ts @@ -1,6 +1,5 @@ import semver, { validRange } from 'semver'; import { quote } from 'shlex'; -import { join } from 'upath'; import { getAdminConfig } from '../../../config/admin'; import { TEMPORARY_ERROR } from '../../../constants/error-messages'; import { logger } from '../../../logger'; @@ -97,12 +96,6 @@ export async function generateLockFiles( execOptions.extraEnv.NPM_AUTH = env.NPM_AUTH; execOptions.extraEnv.NPM_EMAIL = env.NPM_EMAIL; } - if (config.dockerMapDotfiles) { - const homeDir = - process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE; - const homeNpmrc = join(homeDir, '.npmrc'); - execOptions.docker.volumes = [[homeNpmrc, '/home/ubuntu/.npmrc']]; - } const lernaVersion = getLernaVersion(lernaPackageFile); logger.debug('Using lerna version ' + lernaVersion); preCommands.push(`npm i -g lerna@${quote(lernaVersion)}`); diff --git a/lib/manager/npm/post-update/npm.spec.ts b/lib/manager/npm/post-update/npm.spec.ts index d17d200d5d37c3..08a02a81165659 100644 --- a/lib/manager/npm/post-update/npm.spec.ts +++ b/lib/manager/npm/post-update/npm.spec.ts @@ -27,7 +27,6 @@ describe('generateLockFile', () => { const execSnapshots = mockExecAll(exec); fs.readFile = jest.fn(() => 'package-lock-contents') as never; const artifactUpdateApproach = 'deep'; - const dockerMapDotfiles = true; const postUpdateOptions = ['npmDedupe']; const updates = [ { depName: 'some-dep', newVersion: '1.0.1', isLockfileUpdate: false }, @@ -36,7 +35,7 @@ describe('generateLockFile', () => { 'some-dir', {}, 'package-lock.json', - { dockerMapDotfiles, artifactUpdateApproach, postUpdateOptions }, + { artifactUpdateApproach, postUpdateOptions }, updates ); expect(fs.readFile).toHaveBeenCalledTimes(1); diff --git a/lib/manager/npm/post-update/npm.ts b/lib/manager/npm/post-update/npm.ts index 305bcfb09917f8..31e78e3c9595a7 100644 --- a/lib/manager/npm/post-update/npm.ts +++ b/lib/manager/npm/post-update/npm.ts @@ -75,12 +75,6 @@ export async function generateLockFile( execOptions.extraEnv.NPM_AUTH = env.NPM_AUTH; execOptions.extraEnv.NPM_EMAIL = env.NPM_EMAIL; } - if (config.dockerMapDotfiles) { - const homeDir = - process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE; - const homeNpmrc = join(homeDir, '.npmrc'); - execOptions.docker.volumes = [[homeNpmrc, '/home/ubuntu/.npmrc']]; - } if (!upgrades.every((upgrade) => upgrade.isLockfileUpdate)) { // This command updates the lock file based on package.json diff --git a/lib/manager/npm/post-update/pnpm.spec.ts b/lib/manager/npm/post-update/pnpm.spec.ts index f1146a0d018a09..195690f3d41cf7 100644 --- a/lib/manager/npm/post-update/pnpm.spec.ts +++ b/lib/manager/npm/post-update/pnpm.spec.ts @@ -24,7 +24,6 @@ describe('generateLockFile', () => { env.getChildProcessEnv.mockReturnValue(envMock.basic); }); it('generates lock files', async () => { - config.dockerMapDotfiles = true; const execSnapshots = mockExecAll(exec); fs.readFile = jest.fn(() => 'package-lock-contents') as never; const res = await pnpmHelper.generateLockFile('some-dir', {}, config); diff --git a/lib/manager/npm/post-update/pnpm.ts b/lib/manager/npm/post-update/pnpm.ts index b9842631f96f53..f6a802fc609a01 100644 --- a/lib/manager/npm/post-update/pnpm.ts +++ b/lib/manager/npm/post-update/pnpm.ts @@ -54,12 +54,6 @@ export async function generateLockFile( execOptions.extraEnv.NPM_AUTH = env.NPM_AUTH; execOptions.extraEnv.NPM_EMAIL = env.NPM_EMAIL; } - if (config.dockerMapDotfiles) { - const homeDir = - process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE; - const homeNpmrc = join(homeDir, '.npmrc'); - execOptions.docker.volumes = [[homeNpmrc, '/home/ubuntu/.npmrc']]; - } cmd = 'pnpm'; let args = 'install --recursive --lockfile-only'; if (!getAdminConfig().allowScripts || config.ignoreScripts) { diff --git a/lib/manager/npm/post-update/yarn.spec.ts b/lib/manager/npm/post-update/yarn.spec.ts index 0274362190686b..84173a6d8232a8 100644 --- a/lib/manager/npm/post-update/yarn.spec.ts +++ b/lib/manager/npm/post-update/yarn.spec.ts @@ -54,7 +54,6 @@ describe(getName(__filename), () => { ); }); const config = { - dockerMapDotfiles: true, constraints: { yarn: yarnCompatibility, }, @@ -140,7 +139,6 @@ describe(getName(__filename), () => { ); }); const config = { - dockerMapDotfiles: true, constraints: { yarn: yarnCompatibility, }, diff --git a/lib/manager/npm/post-update/yarn.ts b/lib/manager/npm/post-update/yarn.ts index be153bbee74291..d7756d9fc7b64f 100644 --- a/lib/manager/npm/post-update/yarn.ts +++ b/lib/manager/npm/post-update/yarn.ts @@ -125,12 +125,6 @@ export async function generateLockFile( execOptions.extraEnv.NPM_AUTH = env.NPM_AUTH; execOptions.extraEnv.NPM_EMAIL = env.NPM_EMAIL; } - if (config.dockerMapDotfiles) { - const homeDir = - process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE; - const homeNpmrc = join(homeDir, '.npmrc'); - execOptions.docker.volumes = [[homeNpmrc, '/home/ubuntu/.npmrc']]; - } // This command updates the lock file based on package.json commands.push(`yarn install ${cmdOptions}`.trim()); From 45fcaa4fe4e61a8a423e8eccf89243fc5f93349d Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Wed, 7 Apr 2021 09:55:22 +0200 Subject: [PATCH 15/21] refactor(config): explicit migration string check --- lib/config/migration.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/config/migration.ts b/lib/config/migration.ts index 64cbd52c81ff19..aa109e44fe7c6d 100644 --- a/lib/config/migration.ts +++ b/lib/config/migration.ts @@ -209,7 +209,9 @@ export function migrateConfig( } } else if (key === 'ignoreNpmrcFile') { delete migratedConfig.ignoreNpmrcFile; - migratedConfig.npmrc ||= ''; + if (!is.string(migratedConfig.npmrc)) { + migratedConfig.npmrc = ''; + } } else if ( key === 'branchName' && is.string(val) && From c9fac511f9316af83891d30adb778993d8050305 Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Fri, 9 Apr 2021 16:15:43 +0200 Subject: [PATCH 16/21] feat: group:Nodejs (#9469) Remove hardcoded Node.js rules from docker extract and instead add group:nodeJs to group:recommended BREAKING CHANGE: node images founds in Dockerfiles will no longer have hardcoded commitMessageTopic. Add group:Nodejs or config:base to extends for backwards compatibility. --- lib/config/presets/internal/group.ts | 14 +++++++++++++ .../__snapshots__/extract.spec.ts.snap | 5 ----- .../__snapshots__/extract.spec.ts.snap | 1 - .../__snapshots__/extract.spec.ts.snap | 2 -- .../__snapshots__/extract.spec.ts.snap | 20 ------------------- lib/manager/dockerfile/extract.ts | 8 -------- .../__snapshots__/extract.spec.ts.snap | 1 - .../__snapshots__/extract.spec.ts.snap | 1 - .../__snapshots__/extract.spec.ts.snap | 1 - 9 files changed, 14 insertions(+), 39 deletions(-) diff --git a/lib/config/presets/internal/group.ts b/lib/config/presets/internal/group.ts index edfcd3b643464b..20a4c9a135f8b7 100644 --- a/lib/config/presets/internal/group.ts +++ b/lib/config/presets/internal/group.ts @@ -29,10 +29,24 @@ const staticGroups = { }, ], }, + nodeJs: { + description: + "Group anything that looks like Node.js together so that it's updated together", + packageRules: [ + { + matchDatasources: ['docker'], + matchPackageNames: ['node'], + matchPackagePatterns: ['/node$'], + excludePackageNames: ['calico/node'], + commitMessageTopic: 'Node.js', + }, + ], + }, recommended: { description: 'Use curated list of recommended non-monorepo package groupings', extends: [ + 'group:nodeJs', 'group:allApollographql', 'group:fortawesome', 'group:fusionjs', diff --git a/lib/manager/circleci/__snapshots__/extract.spec.ts.snap b/lib/manager/circleci/__snapshots__/extract.spec.ts.snap index 099414ce7920f5..e6ff11b229c9b1 100644 --- a/lib/manager/circleci/__snapshots__/extract.spec.ts.snap +++ b/lib/manager/circleci/__snapshots__/extract.spec.ts.snap @@ -4,7 +4,6 @@ exports[`manager/circleci/extract extractPackageFile() extracts image without le Array [ Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": undefined, "currentValue": "14.8.0", "datasource": "docker", @@ -20,7 +19,6 @@ exports[`manager/circleci/extract extractPackageFile() extracts multiple image l Array [ Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": undefined, "currentValue": undefined, "datasource": "docker", @@ -31,7 +29,6 @@ Array [ }, Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": undefined, "currentValue": "4", "datasource": "docker", @@ -42,7 +39,6 @@ Array [ }, Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": undefined, "currentValue": "6", "datasource": "docker", @@ -53,7 +49,6 @@ Array [ }, Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": undefined, "currentValue": "8.9.0", "datasource": "docker", diff --git a/lib/manager/cloudbuild/__snapshots__/extract.spec.ts.snap b/lib/manager/cloudbuild/__snapshots__/extract.spec.ts.snap index ffd3d8a3be8486..6bffda93dcec3e 100644 --- a/lib/manager/cloudbuild/__snapshots__/extract.spec.ts.snap +++ b/lib/manager/cloudbuild/__snapshots__/extract.spec.ts.snap @@ -12,7 +12,6 @@ Array [ }, Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": undefined, "currentValue": "12", "datasource": "docker", diff --git a/lib/manager/docker-compose/__snapshots__/extract.spec.ts.snap b/lib/manager/docker-compose/__snapshots__/extract.spec.ts.snap index ce8eb2b879c7e3..6867cb5fa55d5f 100644 --- a/lib/manager/docker-compose/__snapshots__/extract.spec.ts.snap +++ b/lib/manager/docker-compose/__snapshots__/extract.spec.ts.snap @@ -12,7 +12,6 @@ Array [ }, Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": undefined, "currentValue": "10.0.0", "datasource": "docker", @@ -148,7 +147,6 @@ Array [ }, Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": undefined, "currentValue": "10.0.0", "datasource": "docker", diff --git a/lib/manager/dockerfile/__snapshots__/extract.spec.ts.snap b/lib/manager/dockerfile/__snapshots__/extract.spec.ts.snap index c1ebae9f7b88c3..7b7696e59e5ab1 100644 --- a/lib/manager/dockerfile/__snapshots__/extract.spec.ts.snap +++ b/lib/manager/dockerfile/__snapshots__/extract.spec.ts.snap @@ -4,7 +4,6 @@ exports[`manager/dockerfile/extract extractPackageFile() detects ["stage"] and [ Array [ Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": undefined, "currentValue": "8.15.1-alpine", "datasource": "docker", @@ -123,7 +122,6 @@ exports[`manager/dockerfile/extract extractPackageFile() extracts images on adja Array [ Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": "sha256:d743b4141b02fcfb8beb68f92b4cd164f60ee457bf2d053f36785bf86de16b0d", "currentValue": "8.11.3-alpine", "datasource": "docker", @@ -147,7 +145,6 @@ exports[`manager/dockerfile/extract extractPackageFile() extracts multiple FROM Array [ Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": undefined, "currentValue": "6.12.3", "datasource": "docker", @@ -185,7 +182,6 @@ exports[`manager/dockerfile/extract extractPackageFile() handles abnormal spacin Array [ Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": undefined, "currentValue": "8.7.0", "datasource": "docker", @@ -214,7 +210,6 @@ exports[`manager/dockerfile/extract extractPackageFile() handles comments 1`] = Array [ Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": undefined, "currentValue": undefined, "datasource": "docker", @@ -229,7 +224,6 @@ exports[`manager/dockerfile/extract extractPackageFile() handles custom hosts 1` Array [ Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": undefined, "currentValue": "8", "datasource": "docker", @@ -244,7 +238,6 @@ exports[`manager/dockerfile/extract extractPackageFile() handles custom hosts an Array [ Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": undefined, "currentValue": "8-alpine", "datasource": "docker", @@ -259,7 +252,6 @@ exports[`manager/dockerfile/extract extractPackageFile() handles custom hosts wi Array [ Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": undefined, "currentValue": "8", "datasource": "docker", @@ -274,7 +266,6 @@ exports[`manager/dockerfile/extract extractPackageFile() handles custom hosts wi Array [ Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": undefined, "currentValue": "8", "datasource": "docker", @@ -289,7 +280,6 @@ exports[`manager/dockerfile/extract extractPackageFile() handles custom hosts wi Array [ Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": undefined, "currentValue": undefined, "datasource": "docker", @@ -304,7 +294,6 @@ exports[`manager/dockerfile/extract extractPackageFile() handles digest 1`] = ` Array [ Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": "sha256:eb85fc5b1198f5e1ec025ea07586bdbbf397e7d82df66c90d7511f533517e063", "currentValue": undefined, "datasource": "docker", @@ -319,7 +308,6 @@ exports[`manager/dockerfile/extract extractPackageFile() handles from as 1`] = ` Array [ Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": undefined, "currentValue": "8.9.0-alpine", "datasource": "docker", @@ -334,7 +322,6 @@ exports[`manager/dockerfile/extract extractPackageFile() handles naked dep 1`] = Array [ Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": undefined, "currentValue": undefined, "datasource": "docker", @@ -349,7 +336,6 @@ exports[`manager/dockerfile/extract extractPackageFile() handles namespaced imag Array [ Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": undefined, "currentValue": "8", "datasource": "docker", @@ -364,7 +350,6 @@ exports[`manager/dockerfile/extract extractPackageFile() handles tag 1`] = ` Array [ Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": undefined, "currentValue": "8.9.0-alpine", "datasource": "docker", @@ -379,7 +364,6 @@ exports[`manager/dockerfile/extract extractPackageFile() handles tag and digest Array [ Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": "sha256:eb85fc5b1198f5e1ec025ea07586bdbbf397e7d82df66c90d7511f533517e063", "currentValue": "8.9.0", "datasource": "docker", @@ -409,7 +393,6 @@ exports[`manager/dockerfile/extract extractPackageFile() is case insensitive 1`] Array [ Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": undefined, "currentValue": undefined, "datasource": "docker", @@ -424,7 +407,6 @@ exports[`manager/dockerfile/extract extractPackageFile() skips index reference C Array [ Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": undefined, "currentValue": "6.12.3", "datasource": "docker", @@ -439,7 +421,6 @@ exports[`manager/dockerfile/extract extractPackageFile() skips named multistage Array [ Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": undefined, "currentValue": "6.12.3", "datasource": "docker", @@ -454,7 +435,6 @@ exports[`manager/dockerfile/extract extractPackageFile() skips named multistage Array [ Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": undefined, "currentValue": "6.12.3", "datasource": "docker", diff --git a/lib/manager/dockerfile/extract.ts b/lib/manager/dockerfile/extract.ts index fae09b1aff9eab..01d9e58af7be95 100644 --- a/lib/manager/dockerfile/extract.ts +++ b/lib/manager/dockerfile/extract.ts @@ -48,14 +48,6 @@ export function getDep( '{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}'; } dep.datasource = datasourceDocker.id; - if ( - dep.depName && - (dep.depName === 'node' || dep.depName.endsWith('/node')) && - dep.depName !== 'calico/node' - ) { - dep.commitMessageTopic = 'Node.js'; - } - if (dep.depName === 'ubuntu') { dep.versioning = ubuntuVersioning.id; } diff --git a/lib/manager/droneci/__snapshots__/extract.spec.ts.snap b/lib/manager/droneci/__snapshots__/extract.spec.ts.snap index 3723edeab59ae7..4d74cfdddd02b0 100644 --- a/lib/manager/droneci/__snapshots__/extract.spec.ts.snap +++ b/lib/manager/droneci/__snapshots__/extract.spec.ts.snap @@ -13,7 +13,6 @@ Array [ }, Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": "sha256:36adc17e9cceab32179d3314da9cb9c737ffb11f0de4e688f407ad6d9ca32201", "currentValue": "10.0.0", "datasource": "docker", diff --git a/lib/manager/github-actions/__snapshots__/extract.spec.ts.snap b/lib/manager/github-actions/__snapshots__/extract.spec.ts.snap index 900449a8c59363..d7d3f17dee9b11 100644 --- a/lib/manager/github-actions/__snapshots__/extract.spec.ts.snap +++ b/lib/manager/github-actions/__snapshots__/extract.spec.ts.snap @@ -67,7 +67,6 @@ Array [ }, Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": "sha256:7b65413af120ec5328077775022c78101f103258a1876ec2f83890bce416e896", "currentValue": "6", "datasource": "docker", diff --git a/lib/manager/gitlabci/__snapshots__/extract.spec.ts.snap b/lib/manager/gitlabci/__snapshots__/extract.spec.ts.snap index 0cb54034e6210a..89a2a0259235a0 100644 --- a/lib/manager/gitlabci/__snapshots__/extract.spec.ts.snap +++ b/lib/manager/gitlabci/__snapshots__/extract.spec.ts.snap @@ -148,7 +148,6 @@ Array [ "deps": Array [ Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": undefined, "currentValue": "12", "datasource": "docker", From 8a63f20810a95dafd81be3a6f6e13aa7f7948c96 Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Fri, 9 Apr 2021 17:04:43 +0200 Subject: [PATCH 17/21] feat(docker): enable major updates by default (#9470) Removes default settings which disabled docker major updates by default. BREAKING CHANGE: Major updates for docker will now be enabled by default. --- lib/datasource/docker/index.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/datasource/docker/index.ts b/lib/datasource/docker/index.ts index cbc83ef5c5a81c..368c8c070b2d9f 100644 --- a/lib/datasource/docker/index.ts +++ b/lib/datasource/docker/index.ts @@ -27,7 +27,6 @@ export const registryStrategy = 'first'; export const defaultConfig = { commitMessageTopic: '{{{depName}}} Docker tag', - major: { enabled: false }, commitMessageExtra: 'to v{{#if isMajor}}{{{newMajor}}}{{else}}{{{newVersion}}}{{/if}}', digest: { From 26b27620861b5aca86d0f77bd067eafe41a3dc4c Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Sat, 10 Apr 2021 06:31:07 +0200 Subject: [PATCH 18/21] chore: update snapshot --- lib/manager/docker-compose/__snapshots__/extract.spec.ts.snap | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/manager/docker-compose/__snapshots__/extract.spec.ts.snap b/lib/manager/docker-compose/__snapshots__/extract.spec.ts.snap index 6867cb5fa55d5f..716a76d5bdd2c3 100644 --- a/lib/manager/docker-compose/__snapshots__/extract.spec.ts.snap +++ b/lib/manager/docker-compose/__snapshots__/extract.spec.ts.snap @@ -79,7 +79,6 @@ Array [ }, Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": undefined, "currentValue": "10.0.0", "datasource": "docker", From 3e45ccdecfb24736837b6b422ca7216ff07f9f25 Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Sat, 10 Apr 2021 06:53:58 +0200 Subject: [PATCH 19/21] feat(npm): retain npmrc lines without variables (#9484) Instead of ignoring the entire .npmrc file if it contains environment variables, instead just strip out the necessary lines. BREAKING: .npmrc files with environment variables will no longer be completely ignore - instead only the lines with variables will be stripped. --- lib/manager/npm/extract/index.spec.ts | 6 +++--- lib/manager/npm/extract/index.ts | 10 ++++++++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/lib/manager/npm/extract/index.spec.ts b/lib/manager/npm/extract/index.spec.ts index e4d6bac61dc2b0..beda16f2a1b85c 100644 --- a/lib/manager/npm/extract/index.spec.ts +++ b/lib/manager/npm/extract/index.spec.ts @@ -127,11 +127,11 @@ describe(getName(__filename), () => { ); expect(res.npmrc).toBeUndefined(); }); - it('finds and discards .npmrc', async () => { + it('finds and filters .npmrc with variables', async () => { fs.readLocalFile = jest.fn((fileName) => { if (fileName === '.npmrc') { // eslint-disable-next-line - return '//registry.npmjs.org/:_authToken=${NPM_AUTH_TOKEN}\n'; + return 'registry=https://registry.npmjs.org\n//registry.npmjs.org/:_authToken=${NPM_AUTH_TOKEN}\n'; } return null; }); @@ -140,7 +140,7 @@ describe(getName(__filename), () => { 'package.json', {} ); - expect(res.npmrc).toEqual(''); + expect(res.npmrc).toEqual('registry=https://registry.npmjs.org\n'); }); it('finds lerna', async () => { fs.readLocalFile = jest.fn((fileName) => { diff --git a/lib/manager/npm/extract/index.ts b/lib/manager/npm/extract/index.ts index cbc04c1596e629..7d745f386604d9 100644 --- a/lib/manager/npm/extract/index.ts +++ b/lib/manager/npm/extract/index.ts @@ -106,8 +106,14 @@ export async function extractPackageFile( npmrc = npmrc.replace(/(^|\n)package-lock.*?(\n|$)/g, '\n'); } if (npmrc.includes('=${') && !getAdminConfig().exposeAllEnv) { - logger.debug('Overriding .npmrc file with variables'); - npmrc = ''; + logger.debug( + { npmrcFileName }, + 'Stripping .npmrc file of lines with variables' + ); + npmrc = npmrc + .split('\n') + .filter((line) => !line.includes('=${')) + .join('\n'); } } } From b701371285334801a1828f867bdfeb29d8873e75 Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Wed, 21 Apr 2021 17:53:57 +0200 Subject: [PATCH 20/21] refactor: artifactUpdateApproach -> skipInstalls Roll back the previous refactor. --- docs/usage/self-hosted-configuration.md | 14 +++++----- .../__snapshots__/migration.spec.ts.snap | 2 -- lib/config/definitions.ts | 9 +++--- lib/config/migration.spec.ts | 2 -- lib/config/migration.ts | 7 ----- .../extract/__snapshots__/index.spec.ts.snap | 28 +++++++++---------- lib/manager/npm/extract/index.ts | 19 +++++++++---- lib/manager/npm/post-update/lerna.spec.ts | 8 +++--- lib/manager/npm/post-update/lerna.ts | 6 ++-- lib/manager/npm/post-update/npm.spec.ts | 20 ++++++------- lib/manager/npm/post-update/npm.ts | 4 +-- lib/manager/npm/post-update/yarn.ts | 2 +- lib/manager/types.ts | 5 +++- .../__snapshots__/manager-files.spec.ts.snap | 2 +- 14 files changed, 64 insertions(+), 64 deletions(-) diff --git a/docs/usage/self-hosted-configuration.md b/docs/usage/self-hosted-configuration.md index 58a81776bb32bb..86c10c63deae4d 100644 --- a/docs/usage/self-hosted-configuration.md +++ b/docs/usage/self-hosted-configuration.md @@ -28,7 +28,7 @@ module.exports = { In the `renovate.json` file, define the commands and files to be included in the final commit. -The command to install dependencies (`npm ci --ignore-scripts`) is necessary because, by default, the installation of dependencies is skipped (see the `artifactUpdateApproach` admin option). +The command to install dependencies (`npm ci --ignore-scripts`) is necessary because, by default, the installation of dependencies is skipped (see the `skipInstalls` admin option). ```json { @@ -69,12 +69,6 @@ e.g. } ``` -## artifactUpdateApproach - -By default, Renovate will use the most efficient approach to updating package files and lock files, which in most cases skips the need to perform a full module install by the bot. -If this is set to 'deep', then a full install of modules will be done. -This is currently applicable to `npm` and `yarn` only, and automatically set to `deep` when a full install is detected as necessary. - ## autodiscover When you enable `autodiscover`, by default, Renovate will run on _every_ repository that the bot account can access. @@ -372,6 +366,12 @@ It could then be used in a repository config or preset like so: Secret names must start with a upper or lower case character and can contain only characters, digits, or underscores. +## skipInstalls + +By default, Renovate will use the most efficient approach to updating package files and lock files, which in most cases skips the need to perform a full module install by the bot. +If this is set to false, then a full install of modules will be done. +This is currently applicable to `npm` and `lerna`/`npm` only, and only used in cases where bugs in `npm` result in incorrect lock files being updated. + ## token ## username diff --git a/lib/config/__snapshots__/migration.spec.ts.snap b/lib/config/__snapshots__/migration.spec.ts.snap index c9c32342a28022..7713dfac4bc167 100644 --- a/lib/config/__snapshots__/migration.spec.ts.snap +++ b/lib/config/__snapshots__/migration.spec.ts.snap @@ -80,7 +80,6 @@ Object { "additionalBranchPrefix": "{{parentDir}}-", "allowCustomCrateRegistries": true, "allowScripts": true, - "artifactUpdateApproach": "shallow", "autodiscover": true, "automerge": false, "automergeType": "branch", @@ -175,7 +174,6 @@ Object { "versioning": "maven", }, Object { - "artifactUpdateApproach": "deep", "matchDepTypes": Array [ "peerDependencies", ], diff --git a/lib/config/definitions.ts b/lib/config/definitions.ts index 54f8f9eb9a71df..76dcf0d28c0de3 100644 --- a/lib/config/definitions.ts +++ b/lib/config/definitions.ts @@ -556,12 +556,11 @@ const options: RenovateOptions[] = [ type: 'boolean', }, { - name: 'artifactUpdateApproach', + name: 'skipInstalls', description: - 'Whether to employ a deep or shallow approach to artifact updating.', - type: 'string', - allowedValues: ['auto', 'deep', 'shallow'], - default: 'auto', + 'Skip installing modules/dependencies if lock file updating is possible alone.', + type: 'boolean', + default: null, admin: true, }, { diff --git a/lib/config/migration.spec.ts b/lib/config/migration.spec.ts index ba6fff96902167..eb384c3abe331e 100644 --- a/lib/config/migration.spec.ts +++ b/lib/config/migration.spec.ts @@ -53,7 +53,6 @@ describe(getName(__filename), () => { binarySource: 'auto', automergeMinor: true, automergePatch: true, - skipInstalls: true, masterIssue: 'true', masterIssueTitle: 'foo', gomodTidy: true, @@ -97,7 +96,6 @@ describe(getName(__filename), () => { ], peerDependencies: { versionStrategy: 'widen', - skipInstalls: false, }, packageRules: [ { diff --git a/lib/config/migration.ts b/lib/config/migration.ts index aa109e44fe7c6d..559a1d8c1a6a81 100644 --- a/lib/config/migration.ts +++ b/lib/config/migration.ts @@ -172,13 +172,6 @@ export function migrateConfig( migratedConfig[key] = val.replace(/{{depNameShort}}/g, '{{depName}}'); } else if (key === 'gitFs') { delete migratedConfig.gitFs; - } else if (key === 'skipInstalls') { - delete migratedConfig.skipInstalls; - if (val) { - migratedConfig.artifactUpdateApproach = 'shallow'; - } else { - migratedConfig.artifactUpdateApproach = 'deep'; - } } else if (key === 'rebaseStalePrs') { delete migratedConfig.rebaseStalePrs; if (!migratedConfig.rebaseWhen) { diff --git a/lib/manager/npm/extract/__snapshots__/index.spec.ts.snap b/lib/manager/npm/extract/__snapshots__/index.spec.ts.snap index ec3e8ca7139576..4898775c004ac5 100644 --- a/lib/manager/npm/extract/__snapshots__/index.spec.ts.snap +++ b/lib/manager/npm/extract/__snapshots__/index.spec.ts.snap @@ -14,7 +14,6 @@ Object { "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { - "hasFileRefs": false, "lernaJsonFile": undefined, }, "npmLock": undefined, @@ -23,6 +22,7 @@ Object { "packageJsonName": undefined, "packageJsonType": "app", "pnpmShrinkwrap": undefined, + "skipInstalls": true, "yarnLock": undefined, "yarnWorkspacesPackages": undefined, "yarnrc": undefined, @@ -137,7 +137,6 @@ Object { "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { - "hasFileRefs": true, "lernaJsonFile": undefined, }, "npmLock": undefined, @@ -146,6 +145,7 @@ Object { "packageJsonName": undefined, "packageJsonType": "library", "pnpmShrinkwrap": undefined, + "skipInstalls": false, "yarnLock": undefined, "yarnWorkspacesPackages": undefined, "yarnrc": undefined, @@ -300,7 +300,6 @@ Object { "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { - "hasFileRefs": false, "lernaJsonFile": undefined, }, "npmLock": undefined, @@ -309,6 +308,7 @@ Object { "packageJsonName": undefined, "packageJsonType": "app", "pnpmShrinkwrap": undefined, + "skipInstalls": true, "yarnLock": undefined, "yarnWorkspacesPackages": undefined, "yarnrc": undefined, @@ -349,7 +349,6 @@ Object { "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { - "hasFileRefs": false, "lernaJsonFile": undefined, }, "npmLock": undefined, @@ -358,6 +357,7 @@ Object { "packageJsonName": undefined, "packageJsonType": "app", "pnpmShrinkwrap": undefined, + "skipInstalls": true, "yarnLock": undefined, "yarnWorkspacesPackages": undefined, "yarnrc": undefined, @@ -409,7 +409,6 @@ Object { "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { - "hasFileRefs": false, "lernaJsonFile": undefined, }, "npmLock": undefined, @@ -418,6 +417,7 @@ Object { "packageJsonName": undefined, "packageJsonType": "library", "pnpmShrinkwrap": undefined, + "skipInstalls": true, "yarnLock": undefined, "yarnWorkspacesPackages": undefined, "yarnrc": undefined, @@ -463,7 +463,6 @@ Object { "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { - "hasFileRefs": false, "lernaJsonFile": undefined, }, "npmLock": undefined, @@ -472,6 +471,7 @@ Object { "packageJsonName": undefined, "packageJsonType": "library", "pnpmShrinkwrap": undefined, + "skipInstalls": true, "yarnLock": undefined, "yarnWorkspacesPackages": undefined, "yarnrc": undefined, @@ -599,7 +599,6 @@ Object { "lernaClient": "npm", "lernaPackages": undefined, "managerData": Object { - "hasFileRefs": false, "lernaJsonFile": "lerna.json", }, "npmLock": undefined, @@ -608,6 +607,7 @@ Object { "packageJsonName": "renovate", "packageJsonType": "app", "pnpmShrinkwrap": undefined, + "skipInstalls": true, "yarnLock": undefined, "yarnWorkspacesPackages": undefined, "yarnrc": undefined, @@ -735,7 +735,6 @@ Object { "lernaClient": "yarn", "lernaPackages": undefined, "managerData": Object { - "hasFileRefs": false, "lernaJsonFile": "lerna.json", }, "npmLock": undefined, @@ -744,6 +743,7 @@ Object { "packageJsonName": "renovate", "packageJsonType": "app", "pnpmShrinkwrap": undefined, + "skipInstalls": true, "yarnLock": undefined, "yarnWorkspacesPackages": undefined, "yarnrc": undefined, @@ -871,7 +871,6 @@ Object { "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { - "hasFileRefs": false, "lernaJsonFile": undefined, }, "npmLock": undefined, @@ -880,6 +879,7 @@ Object { "packageJsonName": "renovate", "packageJsonType": "app", "pnpmShrinkwrap": undefined, + "skipInstalls": true, "yarnLock": "yarn.lock", "yarnWorkspacesPackages": undefined, "yarnrc": undefined, @@ -893,7 +893,6 @@ Object { "lernaClient": "npm", "lernaPackages": undefined, "managerData": Object { - "hasFileRefs": false, "lernaJsonFile": "lerna.json", }, "npmLock": undefined, @@ -902,6 +901,7 @@ Object { "packageJsonName": "@a/b", "packageJsonType": "app", "pnpmShrinkwrap": undefined, + "skipInstalls": true, "yarnLock": undefined, "yarnWorkspacesPackages": Array [ "packages/*", @@ -1031,7 +1031,6 @@ Object { "lernaClient": "npm", "lernaPackages": undefined, "managerData": Object { - "hasFileRefs": false, "lernaJsonFile": "lerna.json", }, "npmLock": undefined, @@ -1040,6 +1039,7 @@ Object { "packageJsonName": "renovate", "packageJsonType": "app", "pnpmShrinkwrap": undefined, + "skipInstalls": true, "yarnLock": undefined, "yarnWorkspacesPackages": undefined, "yarnrc": undefined, @@ -1053,7 +1053,6 @@ Object { "lernaClient": "npm", "lernaPackages": undefined, "managerData": Object { - "hasFileRefs": false, "lernaJsonFile": "lerna.json", }, "npmLock": undefined, @@ -1062,6 +1061,7 @@ Object { "packageJsonName": "@a/b", "packageJsonType": "app", "pnpmShrinkwrap": undefined, + "skipInstalls": true, "yarnLock": undefined, "yarnWorkspacesPackages": Array [ "packages/*", @@ -1077,7 +1077,6 @@ Object { "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { - "hasFileRefs": false, "lernaJsonFile": undefined, }, "npmLock": undefined, @@ -1086,6 +1085,7 @@ Object { "packageJsonName": "@a/b", "packageJsonType": "app", "pnpmShrinkwrap": undefined, + "skipInstalls": true, "yarnLock": undefined, "yarnWorkspacesPackages": Array [ "packages/*", @@ -1215,7 +1215,6 @@ Object { "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { - "hasFileRefs": false, "lernaJsonFile": undefined, }, "npmLock": undefined, @@ -1224,6 +1223,7 @@ Object { "packageJsonName": "renovate", "packageJsonType": "app", "pnpmShrinkwrap": undefined, + "skipInstalls": true, "yarnLock": undefined, "yarnWorkspacesPackages": undefined, "yarnrc": undefined, diff --git a/lib/manager/npm/extract/index.ts b/lib/manager/npm/extract/index.ts index 7d745f386604d9..c10c120f9a87cd 100644 --- a/lib/manager/npm/extract/index.ts +++ b/lib/manager/npm/extract/index.ts @@ -237,10 +237,6 @@ export async function extractPackageFile( } if (dep.currentValue.startsWith('file:')) { dep.skipReason = SkipReason.File; - // https://github.com/npm/cli/issues/1432 - // Explanation: - // - npm install --package-lock-only is buggy for transitive deps in file: references - // - So we set artifactUpdateApproach to false if file: refs are found *and* the user hasn't explicitly set the value already hasFileRefs = true; return dep; } @@ -347,6 +343,19 @@ export async function extractPackageFile( return null; } } + let skipInstalls = config.skipInstalls; + if (skipInstalls === null) { + if (hasFileRefs) { + // https://github.com/npm/cli/issues/1432 + // Explanation: + // - npm install --package-lock-only is buggy for transitive deps in file: references + // - So we set skipInstalls to false if file: refs are found *and* the user hasn't explicitly set the value already + logger.debug('Automatically setting skipInstalls to false'); + skipInstalls = false; + } else { + skipInstalls = true; + } + } return { deps, @@ -357,11 +366,11 @@ export async function extractPackageFile( yarnrc, ...lockFiles, managerData: { - hasFileRefs, lernaJsonFile, }, lernaClient, lernaPackages, + skipInstalls, yarnWorkspacesPackages, constraints, }; diff --git a/lib/manager/npm/post-update/lerna.spec.ts b/lib/manager/npm/post-update/lerna.spec.ts index 8e771c6eab2bcc..267bef2c31d306 100644 --- a/lib/manager/npm/post-update/lerna.spec.ts +++ b/lib/manager/npm/post-update/lerna.spec.ts @@ -47,26 +47,26 @@ describe(getName(__filename), () => { }); it('generates package-lock.json files', async () => { const execSnapshots = mockExecAll(exec); - const artifactUpdateApproach = 'shallow'; + const skipInstalls = true; const res = await lernaHelper.generateLockFiles( lernaPkgFile('npm'), 'some-dir', {}, {}, - artifactUpdateApproach + skipInstalls ); expect(res.error).toBe(false); expect(execSnapshots).toMatchSnapshot(); }); it('performs full npm install', async () => { const execSnapshots = mockExecAll(exec); - const artifactUpdateApproach = 'deep'; + const skipInstalls = false; const res = await lernaHelper.generateLockFiles( lernaPkgFile('npm'), 'some-dir', {}, {}, - artifactUpdateApproach + skipInstalls ); expect(res.error).toBe(false); expect(execSnapshots).toMatchSnapshot(); diff --git a/lib/manager/npm/post-update/lerna.ts b/lib/manager/npm/post-update/lerna.ts index e66c779dedba42..4cf0bc54750c0c 100644 --- a/lib/manager/npm/post-update/lerna.ts +++ b/lib/manager/npm/post-update/lerna.ts @@ -32,7 +32,7 @@ export async function generateLockFiles( cwd: string, config: PostUpdateConfig, env: NodeJS.ProcessEnv, - artifactUpdateApproach?: string + skipInstalls?: boolean ): Promise { const lernaClient = lernaPackageFile.lernaClient; if (!lernaClient) { @@ -51,7 +51,7 @@ export async function generateLockFiles( installYarn += `@${quote(yarnCompatibility)}`; } preCommands.push(installYarn); - if (artifactUpdateApproach !== 'deep') { + if (skipInstalls !== false) { preCommands.push(getOptimizeCommand()); } cmdOptions = '--ignore-scripts --ignore-engines --ignore-platform'; @@ -63,7 +63,7 @@ export async function generateLockFiles( } preCommands.push(installNpm, 'hash -d npm'); cmdOptions = '--ignore-scripts --no-audit'; - if (artifactUpdateApproach !== 'deep') { + if (skipInstalls !== false) { cmdOptions += ' --package-lock-only'; } } else { diff --git a/lib/manager/npm/post-update/npm.spec.ts b/lib/manager/npm/post-update/npm.spec.ts index 08a02a81165659..b896545b9bde2e 100644 --- a/lib/manager/npm/post-update/npm.spec.ts +++ b/lib/manager/npm/post-update/npm.spec.ts @@ -26,7 +26,7 @@ describe('generateLockFile', () => { it('generates lock files', async () => { const execSnapshots = mockExecAll(exec); fs.readFile = jest.fn(() => 'package-lock-contents') as never; - const artifactUpdateApproach = 'deep'; + const skipInstalls = true; const postUpdateOptions = ['npmDedupe']; const updates = [ { depName: 'some-dep', newVersion: '1.0.1', isLockfileUpdate: false }, @@ -35,7 +35,7 @@ describe('generateLockFile', () => { 'some-dir', {}, 'package-lock.json', - { artifactUpdateApproach, postUpdateOptions }, + { skipInstalls, postUpdateOptions }, updates ); expect(fs.readFile).toHaveBeenCalledTimes(1); @@ -46,7 +46,7 @@ describe('generateLockFile', () => { it('performs lock file updates', async () => { const execSnapshots = mockExecAll(exec); fs.readFile = jest.fn(() => 'package-lock-contents') as never; - const artifactUpdateApproach = 'shallow'; + const skipInstalls = true; const updates = [ { depName: 'some-dep', newVersion: '1.0.1', isLockfileUpdate: true }, ]; @@ -54,7 +54,7 @@ describe('generateLockFile', () => { 'some-dir', {}, 'package-lock.json', - { artifactUpdateApproach }, + { skipInstalls }, updates ); expect(fs.readFile).toHaveBeenCalledTimes(1); @@ -67,12 +67,12 @@ describe('generateLockFile', () => { fs.pathExists.mockResolvedValueOnce(true); fs.move = jest.fn(); fs.readFile = jest.fn(() => 'package-lock-contents') as never; - const artifactUpdateApproach = 'shallow'; + const skipInstalls = true; const res = await npmHelper.generateLockFile( 'some-dir', {}, 'npm-shrinkwrap.json', - { artifactUpdateApproach } + { skipInstalls } ); expect(fs.pathExists).toHaveBeenCalledWith( upath.join('some-dir', 'package-lock.json') @@ -96,12 +96,12 @@ describe('generateLockFile', () => { fs.pathExists.mockResolvedValueOnce(false); fs.move = jest.fn(); fs.readFile = jest.fn((_, _1) => 'package-lock-contents') as never; - const artifactUpdateApproach = 'shallow'; + const skipInstalls = true; const res = await npmHelper.generateLockFile( 'some-dir', {}, 'npm-shrinkwrap.json', - { artifactUpdateApproach } + { skipInstalls } ); expect(fs.pathExists).toHaveBeenCalledWith( upath.join('some-dir', 'package-lock.json') @@ -119,13 +119,13 @@ describe('generateLockFile', () => { it('performs full install', async () => { const execSnapshots = mockExecAll(exec); fs.readFile = jest.fn(() => 'package-lock-contents') as never; - const artifactUpdateApproach = 'deep'; + const skipInstalls = false; const binarySource = BinarySource.Global; const res = await npmHelper.generateLockFile( 'some-dir', {}, 'package-lock.json', - { artifactUpdateApproach, binarySource } + { skipInstalls, binarySource } ); expect(fs.readFile).toHaveBeenCalledTimes(1); expect(res.error).toBeUndefined(); diff --git a/lib/manager/npm/post-update/npm.ts b/lib/manager/npm/post-update/npm.ts index 31e78e3c9595a7..8b28332155c787 100644 --- a/lib/manager/npm/post-update/npm.ts +++ b/lib/manager/npm/post-update/npm.ts @@ -26,7 +26,7 @@ export async function generateLockFile( upgrades: Upgrade[] = [] ): Promise { logger.debug(`Spawning npm install to create ${cwd}/${filename}`); - const { artifactUpdateApproach } = config; + const { skipInstalls, postUpdateOptions } = config; let lockFile = null; try { @@ -49,7 +49,7 @@ export async function generateLockFile( const preCommands = [installNpm, 'hash -d npm']; const commands = []; let cmdOptions = ''; - if (artifactUpdateApproach === 'deep') { + if (postUpdateOptions?.includes('npmDedupe') || skipInstalls === false) { logger.debug('Performing node_modules install'); cmdOptions += '--ignore-scripts --no-audit'; } else { diff --git a/lib/manager/npm/post-update/yarn.ts b/lib/manager/npm/post-update/yarn.ts index d7756d9fc7b64f..f555bcbce78f02 100644 --- a/lib/manager/npm/post-update/yarn.ts +++ b/lib/manager/npm/post-update/yarn.ts @@ -82,7 +82,7 @@ export async function generateLockFile( CI: 'true', }; - if (isYarn1 && config.artifactUpdateApproach !== 'deep') { + if (isYarn1 && config.skipInstalls !== false) { const { offlineMirror, yarnPath } = await checkYarnrc(cwd); if (!offlineMirror) { logger.debug('Updating yarn.lock only - skipping node_modules'); diff --git a/lib/manager/types.ts b/lib/manager/types.ts index d19073f1ff208b..c73d71f4775962 100644 --- a/lib/manager/types.ts +++ b/lib/manager/types.ts @@ -25,6 +25,7 @@ export interface ExtractConfig extends ManagerConfig { aliases?: Record; npmrc?: string; yarnrc?: string; + skipInstalls?: boolean; versioning?: string; updateInternalDeps?: boolean; } @@ -98,6 +99,7 @@ export interface PackageFile> packageJsonType?: 'app' | 'library'; packageFileVersion?: string; parent?: string; + skipInstalls?: boolean; yarnrc?: string; yarnWorkspacesPackages?: string[] | string; matchStrings?: string[]; @@ -274,7 +276,8 @@ export interface PostUpdateConfig extends ManagerConfig, Record { cacheDir?: string; updatedPackageFiles?: File[]; postUpdateOptions?: string[]; - artifactUpdateApproach?: 'auto' | 'deep' | 'shallow'; + skipInstalls?: boolean; + platform?: string; upgrades?: Upgrade[]; npmLock?: string; diff --git a/lib/workers/repository/extract/__snapshots__/manager-files.spec.ts.snap b/lib/workers/repository/extract/__snapshots__/manager-files.spec.ts.snap index 579ce1c3515dc0..52bad56bc98bae 100644 --- a/lib/workers/repository/extract/__snapshots__/manager-files.spec.ts.snap +++ b/lib/workers/repository/extract/__snapshots__/manager-files.spec.ts.snap @@ -17,7 +17,6 @@ Array [ "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { - "hasFileRefs": false, "lernaJsonFile": undefined, }, "npmLock": undefined, @@ -27,6 +26,7 @@ Array [ "packageJsonName": undefined, "packageJsonType": "app", "pnpmShrinkwrap": undefined, + "skipInstalls": undefined, "yarnLock": undefined, "yarnWorkspacesPackages": undefined, "yarnrc": undefined, From 31edce41e8679cecd9fe0176c0d2717298782e5f Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Thu, 22 Apr 2021 07:58:49 +0200 Subject: [PATCH 21/21] chore: revert hasFancyRefs --- .../npm/extract/__snapshots__/index.spec.ts.snap | 2 +- lib/manager/npm/extract/index.ts | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/lib/manager/npm/extract/__snapshots__/index.spec.ts.snap b/lib/manager/npm/extract/__snapshots__/index.spec.ts.snap index 4898775c004ac5..4d7be39d441995 100644 --- a/lib/manager/npm/extract/__snapshots__/index.spec.ts.snap +++ b/lib/manager/npm/extract/__snapshots__/index.spec.ts.snap @@ -357,7 +357,7 @@ Object { "packageJsonName": undefined, "packageJsonType": "app", "pnpmShrinkwrap": undefined, - "skipInstalls": true, + "skipInstalls": false, "yarnLock": undefined, "yarnWorkspacesPackages": undefined, "yarnrc": undefined, diff --git a/lib/manager/npm/extract/index.ts b/lib/manager/npm/extract/index.ts index c10c120f9a87cd..b6192925fe83f7 100644 --- a/lib/manager/npm/extract/index.ts +++ b/lib/manager/npm/extract/index.ts @@ -126,7 +126,7 @@ export async function extractPackageFile( let lernaJsonFile: string; let lernaPackages: string[]; let lernaClient: 'yarn' | 'npm'; - let hasFileRefs = false; + let hasFancyRefs = false; let lernaJson: { packages: string[]; npmClient: string; @@ -224,6 +224,7 @@ export async function extractPackageFile( if (dep.currentValue.startsWith('npm:')) { dep.npmPackageAlias = true; + hasFancyRefs = true; const valSplit = dep.currentValue.replace('npm:', '').split('@'); if (valSplit.length === 2) { dep.lookupName = valSplit[0]; @@ -237,7 +238,7 @@ export async function extractPackageFile( } if (dep.currentValue.startsWith('file:')) { dep.skipReason = SkipReason.File; - hasFileRefs = true; + hasFancyRefs = true; return dep; } if (isValid(dep.currentValue)) { @@ -345,11 +346,11 @@ export async function extractPackageFile( } let skipInstalls = config.skipInstalls; if (skipInstalls === null) { - if (hasFileRefs) { + if (hasFancyRefs) { // https://github.com/npm/cli/issues/1432 // Explanation: - // - npm install --package-lock-only is buggy for transitive deps in file: references - // - So we set skipInstalls to false if file: refs are found *and* the user hasn't explicitly set the value already + // - npm install --package-lock-only is buggy for transitive deps in file: and npm: references + // - So we set skipInstalls to false if file: or npm: refs are found *and* the user hasn't explicitly set the value already logger.debug('Automatically setting skipInstalls to false'); skipInstalls = false; } else {