From 1169d19a33a50e5cc89c5fc9ff910ecfd24a1bef Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Wed, 5 Apr 2023 06:44:55 +0200 Subject: [PATCH 01/21] feat!: allow post upgrade templating by default (#21326) Co-authored-by: HonkingGoose <34918129+HonkingGoose@users.noreply.github.com> --- docs/usage/self-hosted-configuration.md | 8 +++----- lib/config/options/index.ts | 4 ++-- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/docs/usage/self-hosted-configuration.md b/docs/usage/self-hosted-configuration.md index a46d563be6d49e..7f5a8d29a0cb20 100644 --- a/docs/usage/self-hosted-configuration.md +++ b/docs/usage/self-hosted-configuration.md @@ -19,15 +19,10 @@ Please also see [Self-Hosted Experimental Options](./self-hosted-experimental.md ## allowPostUpgradeCommandTemplating -Set to `true` to allow templating of dependency level post-upgrade commands. - Let's look at an example of configuring packages with existing Angular migrations. -Add two properties to `config.js`: `allowPostUpgradeCommandTemplating` and `allowedPostUpgradeCommands`: - ```javascript module.exports = { - allowPostUpgradeCommandTemplating: true, allowedPostUpgradeCommands: ['^npm ci --ignore-scripts$', '^npx ng update'], }; ``` @@ -60,6 +55,9 @@ npm ci --ignore-scripts npx ng update @angular/core --from=10.0.0 --to=11.0.0 --migrate-only --allow-dirty --force ``` +If you wish to disable templating because of any security or performance concern, you may set `allowPostUpgradeCommandTemplating` to `false`. +But before you disable templating completely, try the `allowedPostUpgradeCommands` config option to limit what commands are allowed to run. + ## allowScripts ## allowedPostUpgradeCommands diff --git a/lib/config/options/index.ts b/lib/config/options/index.ts index f71066be46c06b..c4f17846cbd2a7 100644 --- a/lib/config/options/index.ts +++ b/lib/config/options/index.ts @@ -24,9 +24,9 @@ const options: RenovateOptions[] = [ { name: 'allowPostUpgradeCommandTemplating', description: - 'Set this to `true` to allow templating for post-upgrade commands.', + 'Set this to `false` to disable template compilation for post-upgrade commands.', type: 'boolean', - default: false, + default: true, globalOnly: true, }, { From a9f52197561479de4120c82858406f5b01a6858a Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Wed, 5 Apr 2023 11:27:22 +0200 Subject: [PATCH 02/21] feat(automerge)!: default to platformAutomerge=true (#21327) Co-authored-by: HonkingGoose <34918129+HonkingGoose@users.noreply.github.com> --- docs/usage/configuration-options.md | 10 +++++----- docs/usage/key-concepts/automerge.md | 12 +++++------- lib/config/options/index.ts | 2 +- lib/modules/platform/gitea/index.md | 2 +- 4 files changed, 12 insertions(+), 14 deletions(-) diff --git a/docs/usage/configuration-options.md b/docs/usage/configuration-options.md index 5283cde1724deb..fce02cbd7176aa 100644 --- a/docs/usage/configuration-options.md +++ b/docs/usage/configuration-options.md @@ -2513,28 +2513,28 @@ If enabled Renovate will pin Docker images or GitHub Actions by means of their S ## platformAutomerge -!!! warning - Before you enable `platformAutomerge` you should enable your Git hosting platform's capabilities to enforce test passing before PR merge. +!!! note + If you use the default `platformAutomerge=true` then you should enable your Git hosting platform's capabilities to enforce test passing before PR merge. If you don't do this, the platform might merge Renovate PRs even if the repository's tests haven't started, are in still in progress, or possibly even when they have failed. On GitHub this is called "Require status checks before merging", which you can find in the "Branch protection rules" section of the settings for your repository. [GitHub docs, about protected branches](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/defining-the-mergeability-of-pull-requests/about-protected-branches) [GitHub docs, require status checks before merging](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/defining-the-mergeability-of-pull-requests/about-protected-branches#require-status-checks-before-merging) If you're using another platform, search their documentation for a similar feature. -If you have enabled `automerge` and set `automergeType=pr` in the Renovate config, then you can also set `platformAutomerge` to `true` to speed up merging via the platform's native automerge functionality. +If you have enabled `automerge` and set `automergeType=pr` in the Renovate config, then leaving `platformAutomerge` as `true` speeds up merging via the platform's native automerge functionality. Renovate tries platform-native automerge only when it initially creates the PR. Any PR that is being updated will be automerged with the Renovate-based automerge. `platformAutomerge` will configure PRs to be merged after all (if any) branch policies have been met. -This option is available for Azure, GitHub and GitLab. +This option is available for Azure, Gitea, GitHub and GitLab. It falls back to Renovate-based automerge if the platform-native automerge is not available. You can also fine-tune the behavior by setting `packageRules` if you want to use it selectively (e.g. per-package). Note that the outcome of `rebaseWhen=auto` can differ when `platformAutomerge=true`. Normally when you set `rebaseWhen=auto` Renovate rebases any branch that's behind the base branch automatically, and some people rely on that. -This behavior is no longer guaranteed when you enable `platformAutomerge` because the platform might automerge a branch which is not up-to-date. +This behavior is no longer guaranteed when `platformAutomerge` is `true` because the platform might automerge a branch which is not up-to-date. For example, GitHub might automerge a Renovate branch even if it's behind the base branch at the time. Please check platform specific docs for version requirements. diff --git a/docs/usage/key-concepts/automerge.md b/docs/usage/key-concepts/automerge.md index 579ebc8a9bc948..d4203845fb680c 100644 --- a/docs/usage/key-concepts/automerge.md +++ b/docs/usage/key-concepts/automerge.md @@ -100,9 +100,8 @@ Say you want to automerge `patch` and `minor` updates for packages in the `group ### Faster merges with platform-native automerge -You can speed up merges by letting Renovate use your platform's native automerge. -The config option is called `platformAutomerge`. -If `automerge=true` and `automergeType=pr` then you can set `platformAutomerge=true`. +By default, Renovate uses platform-native automerge to speed up automerging. +If you don't want Renovate to use the platform-native automerge, then set `platformAutomerge` to `false`. For example: @@ -112,7 +111,7 @@ For example: "enabled": true, "automerge": true, "automergeType": "pr", - "platformAutomerge": true + "platformAutomerge": false } } ``` @@ -155,11 +154,10 @@ On `github.com`, go to your repository's "homepage", click on Settings, scroll d Then go to your repository's branch protection rules for your base branch (usually `main`) and enable the "Require merge queue" setting. Confirm you've set the correct "required checks" for your base branch. -Finally, allow Renovate to automerge by setting `automerge=true` and `platformAutomerge=true` in your Renovate config file, for example: +Finally, allow Renovate to automerge by setting `automerge=true` in your Renovate config file, for example: ```json { - "platformAutomerge": true, "packageRules": [ { "description": "Automerge non-major updates", @@ -180,7 +178,7 @@ On `github.com`, go to your repository's "homepage", click on Settings, scroll d Go to your repository's branch protection rules for your base branch (usually `main`) and enable the "Require merge queue" setting. Confirm you've set the correct "required checks" for your base branch. -Finally, allow Renovate to automerge by setting `automerge=true` and `platformAutomerge=true` in your Renovate config file (see earlier example). +Finally, allow Renovate to automerge by setting `automerge=true` in your Renovate config file (see earlier example). ## Automerging and scheduling diff --git a/lib/config/options/index.ts b/lib/config/options/index.ts index c4f17846cbd2a7..fa50c18406e1c9 100644 --- a/lib/config/options/index.ts +++ b/lib/config/options/index.ts @@ -2611,7 +2611,7 @@ const options: RenovateOptions[] = [ description: `Controls if platform-native auto-merge is used.`, type: 'boolean', supportedPlatforms: ['azure', 'gitea', 'github', 'gitlab'], - default: false, + default: true, }, { name: 'userStrings', diff --git a/lib/modules/platform/gitea/index.md b/lib/modules/platform/gitea/index.md index 098fb39be1f9fc..1f68d933542c5e 100644 --- a/lib/modules/platform/gitea/index.md +++ b/lib/modules/platform/gitea/index.md @@ -18,7 +18,7 @@ Either the account should have full name and email address set to allow Renovate ## Unsupported platform features/concepts - **Adding reviewers to PRs not supported**: Gitea versions older than `v1.14.0` do not have the required API. -- **Setting `platformAutomerge` to use platform-native automerge for PRs not supported**: Gitea versions older than v1.17.0 do not have the required API. +- **`platformAutomerge` (`true` by default) for platform-native automerge not supported**: Gitea versions older than v1.17.0 do not have the required API. - **Git upload filters**: If you're using a Gitea version older than `v1.16.0` then you must enable [clone filters](https://docs.gitea.io/en-us/clone-filters/). ## Features awaiting implementation From c1b63f6d793afaa1fae5b2cc42fad9e634f4b23e Mon Sep 17 00:00:00 2001 From: Michael Kriese Date: Wed, 26 Apr 2023 08:26:13 +0200 Subject: [PATCH 03/21] feat(platform/gitlab)!: prefer `commit_email` (#21122 gitAuthor discover for GitLab now prefers the field `commit_email` over `email`. BREAKING CHANGE: GitLab gitAuthor will change from the account's "email" to "commit_email" if they are different. --- lib/modules/platform/gitlab/index.ts | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/lib/modules/platform/gitlab/index.ts b/lib/modules/platform/gitlab/index.ts index 17e6a497288831..d9fadc2ad9f9c9 100644 --- a/lib/modules/platform/gitlab/index.ts +++ b/lib/modules/platform/gitlab/index.ts @@ -107,12 +107,16 @@ export async function initPlatform({ try { if (!gitAuthor) { const user = ( - await gitlabApi.getJson<{ email: string; name: string; id: number }>( - `user`, - { token } - ) + await gitlabApi.getJson<{ + email: string; + name: string; + id: number; + commit_email?: string; + }>(`user`, { token }) ).body; - platformConfig.gitAuthor = `${user.name} <${user.email}>`; + platformConfig.gitAuthor = `${user.name} <${ + user.commit_email ?? user.email + }>`; } // istanbul ignore if: experimental feature if (process.env.RENOVATE_X_PLATFORM_VERSION) { From ca7357fd5fb5281cae3e58bffc0be4a1373c175f Mon Sep 17 00:00:00 2001 From: Bastian Gutschke Date: Wed, 26 Apr 2023 19:05:27 +0200 Subject: [PATCH 04/21] fix(post-upgrade-tasks)!: enable dot option for file filters (#21282) Set `{ dot: true }` for minimatch. BREAKING CHANGE: dot files will now be included by default for all minimatch results --- docs/usage/configuration-options.md | 1 + .../repository/update/branch/execute-post-upgrade-commands.ts | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/usage/configuration-options.md b/docs/usage/configuration-options.md index fce02cbd7176aa..57b16c87ee19d0 100644 --- a/docs/usage/configuration-options.md +++ b/docs/usage/configuration-options.md @@ -2605,6 +2605,7 @@ You can use variable templating in your commands if [`allowPostUpgradeCommandTem ### fileFilters A list of glob-style matchers that determine which files will be included in the final commit made by Renovate. +Dotfiles are included. ### executionMode diff --git a/lib/workers/repository/update/branch/execute-post-upgrade-commands.ts b/lib/workers/repository/update/branch/execute-post-upgrade-commands.ts index be8b39f4ec65c6..9efb844b0dc2bb 100644 --- a/lib/workers/repository/update/branch/execute-post-upgrade-commands.ts +++ b/lib/workers/repository/update/branch/execute-post-upgrade-commands.ts @@ -106,7 +106,7 @@ export async function postUpgradeCommandsExecutor( for (const relativePath of status.modified.concat(status.not_added)) { for (const pattern of fileFilters) { - if (minimatch(relativePath, pattern)) { + if (minimatch(relativePath, pattern, { dot: true })) { logger.debug( { file: relativePath, pattern }, 'Post-upgrade file saved' @@ -134,7 +134,7 @@ export async function postUpgradeCommandsExecutor( for (const relativePath of status.deleted || []) { for (const pattern of fileFilters) { - if (minimatch(relativePath, pattern)) { + if (minimatch(relativePath, pattern, { dot: true })) { logger.debug( { file: relativePath, pattern }, 'Post-upgrade file removed' From bbc72d95635dafe82e50e3139c72e7ccee5838f3 Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Fri, 5 May 2023 19:47:16 +0200 Subject: [PATCH 05/21] feat(npm)!: disable rollbackPrs for npm by default (#21970) --- docs/usage/configuration-options.md | 5 ++--- lib/config/index.spec.ts | 1 - lib/modules/manager/npm/index.ts | 1 - 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/docs/usage/configuration-options.md b/docs/usage/configuration-options.md index 57b16c87ee19d0..d7f0554f864b93 100644 --- a/docs/usage/configuration-options.md +++ b/docs/usage/configuration-options.md @@ -3268,9 +3268,8 @@ There are times when a dependency version in use by a project gets removed from For some registries, existing releases or even whole packages can be removed or "yanked" at any time, while for some registries only very new or unused releases can be removed. Renovate's "rollback" feature exists to propose a downgrade to the next-highest release if the current release is no longer found in the registry. -Renovate does not create these rollback PRs by default, with one exception: npm packages get a rollback PR if needed. - -You can configure the `rollbackPrs` property globally, per-language, or per-package to override the default behavior. +Renovate does not create these rollback PRs by default, so this functionality needs to be opted-into. +We recommend you do this selectively with `packageRules` and not globally. ## ruby diff --git a/lib/config/index.spec.ts b/lib/config/index.spec.ts index 001ea8c8b53488..94e6822cf72dfc 100644 --- a/lib/config/index.spec.ts +++ b/lib/config/index.spec.ts @@ -91,7 +91,6 @@ describe('config/index', () => { const config = getManagerConfig(parentConfig, 'npm'); expect(config).toContainEntries([ ['fileMatch', ['(^|/)package\\.json$']], - ['rollbackPrs', true], ]); expect(getManagerConfig(parentConfig, 'html')).toContainEntries([ ['fileMatch', ['\\.html?$']], diff --git a/lib/modules/manager/npm/index.ts b/lib/modules/manager/npm/index.ts index 3ac8a7f281b4ea..9d309bd8a23348 100644 --- a/lib/modules/manager/npm/index.ts +++ b/lib/modules/manager/npm/index.ts @@ -17,7 +17,6 @@ export const supportsLockFileMaintenance = true; export const defaultConfig = { fileMatch: ['(^|/)package\\.json$'], - rollbackPrs: true, versioning: npmVersioning.id, digest: { prBodyDefinitions: { From 3f432a426b94dff85be098864d7982d0e54f0a54 Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Sun, 7 May 2023 22:07:47 +0200 Subject: [PATCH 06/21] fix(presets)!: remove compatibility:additionalBranchPrefix (#22015) --- lib/config/presets/common.ts | 1 + lib/config/presets/internal/compatibility.ts | 28 -------------------- lib/config/presets/internal/index.ts | 2 -- 3 files changed, 1 insertion(+), 30 deletions(-) delete mode 100644 lib/config/presets/internal/compatibility.ts diff --git a/lib/config/presets/common.ts b/lib/config/presets/common.ts index 8ae2839ed0b5c7..8e0a6a03327b97 100644 --- a/lib/config/presets/common.ts +++ b/lib/config/presets/common.ts @@ -12,6 +12,7 @@ export const removedPresets: Record = { ':masterIssueApproval': ':dependencyDashboardApproval', ':switchToGradleLite': null, ':unpublishSafe': 'npm:unpublishSafe', + 'compatibility:additionalBranchPrefix': null, 'config:application': 'config:js-app', 'config:base-js': 'config:base', 'config:library': 'config:js-lib', diff --git a/lib/config/presets/internal/compatibility.ts b/lib/config/presets/internal/compatibility.ts deleted file mode 100644 index 57e12a8d82fb2e..00000000000000 --- a/lib/config/presets/internal/compatibility.ts +++ /dev/null @@ -1,28 +0,0 @@ -import type { Preset } from '../types'; - -/* eslint sort-keys: ["error", "asc", {caseSensitive: false, natural: true}] */ - -export const presets: Record = { - additionalBranchPrefix: { - buildkite: { - additionalBranchPrefix: 'buildkite-', - }, - cargo: { - additionalBranchPrefix: 'rust-', - }, - description: - 'Backwards-compatibility preset to restore `additionalBranchPrefix` settings for multiple managers which were removed in Renovate `v25`.', - docker: { - additionalBranchPrefix: 'docker-', - }, - homebrew: { - additionalBranchPrefix: 'homebrew-', - }, - packageRules: [ - { - additionalBranchPrefix: 'helm-', - matchDatasources: ['helm'], - }, - ], - }, -}; diff --git a/lib/config/presets/internal/index.ts b/lib/config/presets/internal/index.ts index 63765664558b69..e37788d17fc4c8 100644 --- a/lib/config/presets/internal/index.ts +++ b/lib/config/presets/internal/index.ts @@ -1,5 +1,4 @@ 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'; @@ -17,7 +16,6 @@ import * as workaroundsPreset from './workarounds'; /* eslint sort-keys: ["error", "asc", {caseSensitive: false, natural: true}] */ export const groups: Record> = { - compatibility: compatibilityPreset.presets, config: configPreset.presets, default: defaultPreset.presets, docker: dockerPreset.presets, From 6e95ba75e20954fda58733ab8544b7715da33c2f Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Wed, 24 May 2023 08:07:00 +0200 Subject: [PATCH 07/21] feat(package-rules)!: remove fuzzy matchPaths matching (#22394) --- docs/usage/configuration-options.md | 5 ----- lib/config/options/index.ts | 2 +- lib/util/package-rules/index.spec.ts | 2 +- lib/util/package-rules/paths.spec.ts | 11 ++--------- lib/util/package-rules/paths.ts | 20 +++----------------- 5 files changed, 7 insertions(+), 33 deletions(-) diff --git a/docs/usage/configuration-options.md b/docs/usage/configuration-options.md index d7f0554f864b93..2b2a12eed1a1fc 100644 --- a/docs/usage/configuration-options.md +++ b/docs/usage/configuration-options.md @@ -2287,11 +2287,6 @@ The following matches any file in directories starting with `app/`: } ``` - -!!! warning - Partial matches for `matchPaths` are deprecated. - Please use a `minimatch` glob pattern or switch to [`matchFiles`](#matchfiles) if you need exact matching. - ### matchSourceUrlPrefixes Here's an example of where you use this to group together all packages from the `renovatebot` GitHub org: diff --git a/lib/config/options/index.ts b/lib/config/options/index.ts index fa50c18406e1c9..ed4eefcab2fbad 100644 --- a/lib/config/options/index.ts +++ b/lib/config/options/index.ts @@ -1307,7 +1307,7 @@ const options: RenovateOptions[] = [ { name: 'matchPaths', description: - 'List of strings or glob patterns to match against package files. Only works inside a `packageRules` object.', + 'List of glob patterns to match against package files. Only works inside a `packageRules` object.', type: 'array', subType: 'string', stage: 'repository', diff --git a/lib/util/package-rules/index.spec.ts b/lib/util/package-rules/index.spec.ts index 9e6f48f4b38d11..ecfeee4914794c 100644 --- a/lib/util/package-rules/index.spec.ts +++ b/lib/util/package-rules/index.spec.ts @@ -989,7 +989,7 @@ describe('util/package-rules/index', () => { ...config, depName: 'test', }); - expect(res3.x).toBeDefined(); + expect(res3.x).toBeUndefined(); }); it('empty rules', () => { diff --git a/lib/util/package-rules/paths.spec.ts b/lib/util/package-rules/paths.spec.ts index 9b0c1db55484aa..4e0bfed3567995 100644 --- a/lib/util/package-rules/paths.spec.ts +++ b/lib/util/package-rules/paths.spec.ts @@ -17,7 +17,7 @@ describe('util/package-rules/paths', () => { expect(result).toBeFalse(); }); - it('should return true and log warning on partial match only', () => { + it('should return false on partial match only', () => { const result = pathsMatcher.matches( { packageFile: 'opentelemetry/http/package.json', @@ -26,14 +26,7 @@ describe('util/package-rules/paths', () => { matchPaths: ['opentelemetry/http'], } ); - expect(result).toBeTrue(); - expect(logger.warn).toHaveBeenCalledWith( - { - packageFile: 'opentelemetry/http/package.json', - rulePath: 'opentelemetry/http', - }, - 'Partial matches for `matchPaths` are deprecated. Please use a minimatch glob pattern or switch to `matchFiles` if you need exact matching.' - ); + expect(result).toBeFalse(); }); it('should return true and not log warning on partial and glob match', () => { diff --git a/lib/util/package-rules/paths.ts b/lib/util/package-rules/paths.ts index 7bd882c56966e0..7fa70aaa9ef991 100644 --- a/lib/util/package-rules/paths.ts +++ b/lib/util/package-rules/paths.ts @@ -1,7 +1,6 @@ import is from '@sindresorhus/is'; import { minimatch } from 'minimatch'; import type { PackageRule, PackageRuleInputConfig } from '../../config/types'; -import { logger } from '../../logger'; import { Matcher } from './base'; export class PathsMatcher extends Matcher { @@ -16,21 +15,8 @@ export class PathsMatcher extends Matcher { return false; } - return matchPaths.some((rulePath) => { - if (minimatch(packageFile, rulePath, { dot: true })) { - return true; - } - - if (packageFile.includes(rulePath)) { - logger.warn( - { - rulePath, - packageFile, - }, - 'Partial matches for `matchPaths` are deprecated. Please use a minimatch glob pattern or switch to `matchFiles` if you need exact matching.' - ); - return true; - } - }); + return matchPaths.some((rulePath) => + minimatch(packageFile, rulePath, { dot: true }) + ); } } From 107e2bcd6a361364c6d81b8f1911686123d0d243 Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Thu, 25 May 2023 17:46:28 +0200 Subject: [PATCH 08/21] feat!: merge matchPaths and matchFiles into matchFileNames (#22406) --- docs/usage/configuration-options.md | 77 +++++++++---------- .../__snapshots__/migration.spec.ts.snap | 16 ++-- lib/config/migration.spec.ts | 30 +++++++- .../custom/automerge-major-migration.spec.ts | 4 +- .../custom/automerge-minor-migration.spec.ts | 4 +- .../custom/automerge-patch-migration.spec.ts | 4 +- .../custom/package-rules-migration.spec.ts | 2 +- .../custom/package-rules-migration.ts | 4 +- lib/config/options/index.ts | 13 +--- lib/config/presets/internal/default.ts | 2 +- lib/config/types.ts | 4 +- lib/config/validation.ts | 3 +- lib/modules/manager/npm/extract/index.ts | 2 +- lib/util/package-rules/files.spec.ts | 6 +- lib/util/package-rules/files.ts | 18 +++-- lib/util/package-rules/index.spec.ts | 6 +- lib/util/package-rules/matchers.ts | 6 +- lib/util/package-rules/paths.spec.ts | 45 ----------- lib/util/package-rules/paths.ts | 22 ------ .../__snapshots__/vulnerability.spec.ts.snap | 10 +-- .../repository/init/vulnerability.spec.ts | 2 +- lib/workers/repository/init/vulnerability.ts | 6 +- .../repository/updates/flatten.spec.ts | 2 +- 23 files changed, 118 insertions(+), 170 deletions(-) delete mode 100644 lib/util/package-rules/paths.spec.ts delete mode 100644 lib/util/package-rules/paths.ts diff --git a/docs/usage/configuration-options.md b/docs/usage/configuration-options.md index 2b2a12eed1a1fc..acd6a58f18dc4a 100644 --- a/docs/usage/configuration-options.md +++ b/docs/usage/configuration-options.md @@ -1863,28 +1863,28 @@ Example: The above rule will group together the `neutrino` package and any package matching `@neutrino/*`. -Path rules are convenient to use if you wish to apply configuration rules to certain package files using patterns. +File name matches are convenient to use if you wish to apply configuration rules to certain package or lock files using patterns. For example, if you have an `examples` directory and you want all updates to those examples to use the `chore` prefix instead of `fix`, then you could add this configuration: ```json { "packageRules": [ { - "matchPaths": ["examples/**"], + "matchFileNames": ["examples/**"], "extends": [":semanticCommitTypeAll(chore)"] } ] } ``` -If you wish to limit Renovate to apply configuration rules to certain files in the root repository directory, you have to use `matchPaths` with a `minimatch` pattern or use [`matchFiles`](#matchfiles) with an exact match. +If you wish to limit Renovate to apply configuration rules to certain files in the root repository directory, you have to use `matchFileNames` with a `minimatch` pattern (which can include an exact file name match). For example you have multiple `package.json` and want to use `dependencyDashboardApproval` only on the root `package.json`: ```json { "packageRules": [ { - "matchFiles": ["package.json"], + "matchFileNames": ["package.json"], "dependencyDashboardApproval": true } ] @@ -2179,23 +2179,50 @@ Use the syntax `!/ /` like this: } ``` -### matchFiles +### matchFileNames -Renovate will compare `matchFiles` for an exact match against the dependency's package file or lock file. +Renovate will compare `matchFileNames` glob matching against the dependency's package file or lock file. -For example the following would match `package.json` but not `package/frontend/package.json`: +The following example matches `package.json` but _not_ `package/frontend/package.json`: ```json { "packageRules": [ { - "matchFiles": ["package.json"] + "matchFileNames": ["package.json"], + "labels": ["npm"] } ] } ``` -Use [`matchPaths`](#matchpaths) instead if you need more flexible matching. +The following example matches any `package.json`, including files like `backend/package.json`: + +```json +{ + "packageRules": [ + { + "description": "Group dependencies from package.json files", + "matchFileNames": ["**/package.json"], + "groupName": "All package.json changes" + } + ] +} +``` + +The following example matches any file in directories starting with `app/`: + +```json +{ + "packageRules": [ + { + "description": "Group all dependencies from the app directory", + "matchFileNames": ["app/**"], + "groupName": "App dependencies" + } + ] +} +``` ### matchDepNames @@ -2255,38 +2282,6 @@ See also `excludePackagePrefixes`. Like the earlier `matchPackagePatterns` example, the above will configure `rangeStrategy` to `replace` for any package starting with `angular`. -### matchPaths - -Renovate finds the file(s) listed in `matchPaths` with a `minimatch` glob pattern. - -For example the following matches any `package.json`, including files like `backend/package.json`: - -```json -{ - "packageRules": [ - { - "description": "Group dependencies from package.json files", - "matchPaths": ["**/package.json"], - "groupName": "All package.json changes" - } - ] -} -``` - -The following matches any file in directories starting with `app/`: - -```json -{ - "packageRules": [ - { - "description": "Group all dependencies from the app directory", - "matchPaths": ["app/**"], - "groupName": "App dependencies" - } - ] -} -``` - ### matchSourceUrlPrefixes Here's an example of where you use this to group together all packages from the `renovatebot` GitHub org: diff --git a/lib/config/__snapshots__/migration.spec.ts.snap b/lib/config/__snapshots__/migration.spec.ts.snap index 572cc3bbdb1787..c4df79d9deb94f 100644 --- a/lib/config/__snapshots__/migration.spec.ts.snap +++ b/lib/config/__snapshots__/migration.spec.ts.snap @@ -164,7 +164,7 @@ exports[`config/migration migrateConfig(config, parentConfig) migrates config 1` "extends": [ "node", ], - "matchPaths": [ + "matchFileNames": [ "node/**", ], }, @@ -211,7 +211,7 @@ exports[`config/migration migrateConfig(config, parentConfig) migrates config 1` "extends": [ "foo", ], - "matchPaths": [ + "matchFileNames": [ "examples/**", ], }, @@ -293,7 +293,7 @@ exports[`config/migration migrateConfig(config, parentConfig) migrates more pack "matchDepTypes": [ "devDependencies", ], - "matchPaths": [ + "matchFileNames": [ "package.json", ], "rangeStrategy": "pin", @@ -302,7 +302,7 @@ exports[`config/migration migrateConfig(config, parentConfig) migrates more pack "matchDepTypes": [ "dependencies", ], - "matchPaths": [ + "matchFileNames": [ "package.json", ], "rangeStrategy": "pin", @@ -332,13 +332,13 @@ exports[`config/migration migrateConfig(config, parentConfig) migrates packageFi ], "packageRules": [ { - "matchPaths": [ + "matchFileNames": [ "backend/package.json", ], "rangeStrategy": "replace", }, { - "matchPaths": [ + "matchFileNames": [ "frontend/package.json", ], "rangeStrategy": "pin", @@ -347,7 +347,7 @@ exports[`config/migration migrateConfig(config, parentConfig) migrates packageFi "matchDepTypes": [ "devDependencies", ], - "matchPaths": [ + "matchFileNames": [ "other/package.json", ], "rangeStrategy": "pin", @@ -356,7 +356,7 @@ exports[`config/migration migrateConfig(config, parentConfig) migrates packageFi "matchDepTypes": [ "dependencies", ], - "matchPaths": [ + "matchFileNames": [ "other/package.json", ], "rangeStrategy": "pin", diff --git a/lib/config/migration.spec.ts b/lib/config/migration.spec.ts index fcb40a6609d2d6..eae90ddd53c9fe 100644 --- a/lib/config/migration.spec.ts +++ b/lib/config/migration.spec.ts @@ -568,13 +568,41 @@ describe('config/migration', () => { matchManagers: ['dockerfile'], matchPackageNames: ['foo'], matchPackagePatterns: ['^bar'], - matchPaths: ['package.json'], + matchFileNames: ['package.json'], matchSourceUrlPrefixes: ['https://github.com/lodash'], matchUpdateTypes: ['major'], }, ], }); }); + + it('migrates in order of precedence', () => { + const config: TestRenovateConfig = { + packageRules: [ + { + matchFiles: ['matchFiles'], + matchPaths: ['matchPaths'], + }, + { + matchPaths: ['matchPaths'], + matchFiles: ['matchFiles'], + }, + ], + }; + const { isMigrated, migratedConfig } = + configMigration.migrateConfig(config); + expect(isMigrated).toBeTrue(); + expect(migratedConfig).toEqual({ + packageRules: [ + { + matchFileNames: ['matchPaths'], + }, + { + matchFileNames: ['matchFiles'], + }, + ], + }); + }); }); it('it migrates nested packageRules', () => { diff --git a/lib/config/migrations/custom/automerge-major-migration.spec.ts b/lib/config/migrations/custom/automerge-major-migration.spec.ts index 0d2a9a7d30ba60..9dd5ebd21c87d0 100644 --- a/lib/config/migrations/custom/automerge-major-migration.spec.ts +++ b/lib/config/migrations/custom/automerge-major-migration.spec.ts @@ -19,13 +19,13 @@ describe('config/migrations/custom/automerge-major-migration', () => { { automergeMajor: 'some-value', major: { - matchFiles: ['test'], + matchFileNames: ['test'], }, }, { major: { automerge: true, - matchFiles: ['test'], + matchFileNames: ['test'], }, } ); diff --git a/lib/config/migrations/custom/automerge-minor-migration.spec.ts b/lib/config/migrations/custom/automerge-minor-migration.spec.ts index 9597466a7b3682..5ce417773f84c6 100644 --- a/lib/config/migrations/custom/automerge-minor-migration.spec.ts +++ b/lib/config/migrations/custom/automerge-minor-migration.spec.ts @@ -19,13 +19,13 @@ describe('config/migrations/custom/automerge-minor-migration', () => { { automergeMinor: 'some-value', minor: { - matchFiles: ['test'], + matchFileNames: ['test'], }, }, { minor: { automerge: true, - matchFiles: ['test'], + matchFileNames: ['test'], }, } ); diff --git a/lib/config/migrations/custom/automerge-patch-migration.spec.ts b/lib/config/migrations/custom/automerge-patch-migration.spec.ts index bc7014fa541f61..124f599fe921b3 100644 --- a/lib/config/migrations/custom/automerge-patch-migration.spec.ts +++ b/lib/config/migrations/custom/automerge-patch-migration.spec.ts @@ -19,13 +19,13 @@ describe('config/migrations/custom/automerge-patch-migration', () => { { automergePatch: 'some-value', patch: { - matchFiles: ['test'], + matchFileNames: ['test'], }, }, { patch: { automerge: true, - matchFiles: ['test'], + matchFileNames: ['test'], }, } ); diff --git a/lib/config/migrations/custom/package-rules-migration.spec.ts b/lib/config/migrations/custom/package-rules-migration.spec.ts index e77f20476fab5e..b5f6afaf7a016a 100644 --- a/lib/config/migrations/custom/package-rules-migration.spec.ts +++ b/lib/config/migrations/custom/package-rules-migration.spec.ts @@ -48,7 +48,7 @@ describe('config/migrations/custom/package-rules-migration', () => { { packageRules: [ { - matchPaths: [], + matchFileNames: [], packgageRules: { languages: ['javascript'], }, diff --git a/lib/config/migrations/custom/package-rules-migration.ts b/lib/config/migrations/custom/package-rules-migration.ts index e3be4c4c910ac0..9da8469fe3c23c 100644 --- a/lib/config/migrations/custom/package-rules-migration.ts +++ b/lib/config/migrations/custom/package-rules-migration.ts @@ -2,7 +2,9 @@ import type { PackageRule } from '../../types'; import { AbstractMigration } from '../base/abstract-migration'; export const renameMap = { - paths: 'matchPaths', + matchFiles: 'matchFileNames', + matchPaths: 'matchFileNames', + paths: 'matchFileNames', languages: 'matchLanguages', baseBranchList: 'matchBaseBranches', managers: 'matchManagers', diff --git a/lib/config/options/index.ts b/lib/config/options/index.ts index ed4eefcab2fbad..4957af9fdb3a2c 100644 --- a/lib/config/options/index.ts +++ b/lib/config/options/index.ts @@ -1294,7 +1294,7 @@ const options: RenovateOptions[] = [ env: false, }, { - name: 'matchFiles', + name: 'matchFileNames', description: 'List of strings to do an exact match against package and lock files with full path. Only works inside a `packageRules` object.', type: 'array', @@ -1304,17 +1304,6 @@ const options: RenovateOptions[] = [ cli: false, env: false, }, - { - name: 'matchPaths', - description: - 'List of glob patterns to match against package files. Only works inside a `packageRules` object.', - type: 'array', - subType: 'string', - stage: 'repository', - parent: 'packageRules', - cli: false, - env: false, - }, // Version behaviour { name: 'allowedVersions', diff --git a/lib/config/presets/internal/default.ts b/lib/config/presets/internal/default.ts index 4a7ca0f2577a20..f65b0c48c93eb9 100644 --- a/lib/config/presets/internal/default.ts +++ b/lib/config/presets/internal/default.ts @@ -361,7 +361,7 @@ export const presets: Record = { 'Use semanticCommitType `{{arg0}}` for all package files matching path `{{arg1}}`.', packageRules: [ { - matchPaths: ['{{arg0}}'], + matchFileNames: ['{{arg0}}'], semanticCommitType: '{{arg1}}', }, ], diff --git a/lib/config/types.ts b/lib/config/types.ts index 5c390b09c825a0..a06a7adc8d8ba6 100644 --- a/lib/config/types.ts +++ b/lib/config/types.ts @@ -313,8 +313,7 @@ export interface PackageRule Record { description?: string | string[]; isVulnerabilityAlert?: boolean; - matchFiles?: string[]; - matchPaths?: string[]; + matchFileNames?: string[]; matchLanguages?: string[]; matchBaseBranches?: string[]; matchManagers?: string | string[]; @@ -459,6 +458,7 @@ export type RenovateOptions = export interface PackageRuleInputConfig extends Record { versioning?: string; packageFile?: string; + lockFiles?: string[]; depType?: string; depTypes?: string[]; depName?: string; diff --git a/lib/config/validation.ts b/lib/config/validation.ts index f5c7b59c5c5657..254e36cb40c8f2 100644 --- a/lib/config/validation.ts +++ b/lib/config/validation.ts @@ -311,8 +311,7 @@ export async function validateConfig( } const selectors = [ - 'matchFiles', - 'matchPaths', + 'matchFileNames', 'matchLanguages', 'matchBaseBranches', 'matchManagers', diff --git a/lib/modules/manager/npm/extract/index.ts b/lib/modules/manager/npm/extract/index.ts index 00c3fb7d3e0444..467cdef6b849fc 100644 --- a/lib/modules/manager/npm/extract/index.ts +++ b/lib/modules/manager/npm/extract/index.ts @@ -64,7 +64,7 @@ export async function extractPackageFile( const error = new Error(CONFIG_VALIDATION); error.validationSource = packageFile; error.validationError = - 'Nested package.json must not contain renovate configuration. Please use `packageRules` with `matchPaths` in your main config instead.'; + 'Nested package.json must not contain Renovate configuration. Please use `packageRules` with `matchFileNames` in your main config instead.'; throw error; } const packageJsonName = packageJson.name; diff --git a/lib/util/package-rules/files.spec.ts b/lib/util/package-rules/files.spec.ts index 374d2650355465..ac30c31247f00d 100644 --- a/lib/util/package-rules/files.spec.ts +++ b/lib/util/package-rules/files.spec.ts @@ -1,7 +1,7 @@ -import { FilesMatcher } from './files'; +import { FileNamesMatcher } from './files'; describe('util/package-rules/files', () => { - const fileMatcher = new FilesMatcher(); + const fileMatcher = new FileNamesMatcher(); describe('match', () => { it('should return false if packageFile is not defined', () => { @@ -10,7 +10,7 @@ describe('util/package-rules/files', () => { packageFile: undefined, }, { - matchFiles: ['frontend/package.json'], + matchFileNames: ['frontend/package.json'], } ); expect(result).toBeFalse(); diff --git a/lib/util/package-rules/files.ts b/lib/util/package-rules/files.ts index e1ab76f4d70192..bb6cd57a3c5c90 100644 --- a/lib/util/package-rules/files.ts +++ b/lib/util/package-rules/files.ts @@ -1,23 +1,27 @@ import is from '@sindresorhus/is'; +import { minimatch } from 'minimatch'; import type { PackageRule, PackageRuleInputConfig } from '../../config/types'; import { Matcher } from './base'; -export class FilesMatcher extends Matcher { +export class FileNamesMatcher extends Matcher { override matches( { packageFile, lockFiles }: PackageRuleInputConfig, - { matchFiles }: PackageRule + { matchFileNames }: PackageRule ): boolean | null { - if (is.undefined(matchFiles)) { + if (is.undefined(matchFileNames)) { return null; } if (is.undefined(packageFile)) { return false; } - return matchFiles.some( - (fileName) => - packageFile === fileName || - (is.array(lockFiles) && lockFiles?.includes(fileName)) + return matchFileNames.some( + (matchFileName) => + minimatch(packageFile, matchFileName, { dot: true }) || + (is.array(lockFiles) && + lockFiles.some((lockFile) => + minimatch(lockFile, matchFileName, { dot: true }) + )) ); } } diff --git a/lib/util/package-rules/index.spec.ts b/lib/util/package-rules/index.spec.ts index ecfeee4914794c..0718b5243126a8 100644 --- a/lib/util/package-rules/index.spec.ts +++ b/lib/util/package-rules/index.spec.ts @@ -930,7 +930,7 @@ describe('util/package-rules/index', () => { packageFile: 'examples/foo/package.json', packageRules: [ { - matchFiles: ['package.json'], + matchFileNames: ['package.json'], x: 1, }, ], @@ -954,7 +954,7 @@ describe('util/package-rules/index', () => { lockFiles: ['yarn.lock'], packageRules: [ { - matchFiles: ['yarn.lock'], + matchFileNames: ['yarn.lock'], x: 1, }, ], @@ -968,7 +968,7 @@ describe('util/package-rules/index', () => { packageFile: 'examples/foo/package.json', packageRules: [ { - matchPaths: ['examples/**', 'lib/'], + matchFileNames: ['examples/**', 'lib/'], x: 1, }, ], diff --git a/lib/util/package-rules/matchers.ts b/lib/util/package-rules/matchers.ts index 2a11fdd8180d58..dd2672c777b678 100644 --- a/lib/util/package-rules/matchers.ts +++ b/lib/util/package-rules/matchers.ts @@ -5,14 +5,13 @@ import { DatasourcesMatcher } from './datasources'; import { DepNameMatcher } from './dep-names'; import { DepPatternsMatcher } from './dep-patterns'; import { DepTypesMatcher } from './dep-types'; -import { FilesMatcher } from './files'; +import { FileNamesMatcher } from './files'; import { LanguagesMatcher } from './languages'; import { ManagersMatcher } from './managers'; import { MergeConfidenceMatcher } from './merge-confidence'; import { PackageNameMatcher } from './package-names'; import { PackagePatternsMatcher } from './package-patterns'; import { PackagePrefixesMatcher } from './package-prefixes'; -import { PathsMatcher } from './paths'; import { SourceUrlPrefixesMatcher } from './sourceurl-prefixes'; import { SourceUrlsMatcher } from './sourceurls'; import type { MatcherApi } from './types'; @@ -29,8 +28,7 @@ matchers.push([ new PackagePatternsMatcher(), new PackagePrefixesMatcher(), ]); -matchers.push([new FilesMatcher()]); -matchers.push([new PathsMatcher()]); +matchers.push([new FileNamesMatcher()]); matchers.push([new DepTypesMatcher()]); matchers.push([new LanguagesMatcher()]); matchers.push([new BaseBranchesMatcher()]); diff --git a/lib/util/package-rules/paths.spec.ts b/lib/util/package-rules/paths.spec.ts deleted file mode 100644 index 4e0bfed3567995..00000000000000 --- a/lib/util/package-rules/paths.spec.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { logger } from '../../logger'; -import { PathsMatcher } from './paths'; - -describe('util/package-rules/paths', () => { - const pathsMatcher = new PathsMatcher(); - - describe('match', () => { - it('should return false if packageFile is not defined', () => { - const result = pathsMatcher.matches( - { - packageFile: undefined, - }, - { - matchPaths: ['opentelemetry/http'], - } - ); - expect(result).toBeFalse(); - }); - - it('should return false on partial match only', () => { - const result = pathsMatcher.matches( - { - packageFile: 'opentelemetry/http/package.json', - }, - { - matchPaths: ['opentelemetry/http'], - } - ); - expect(result).toBeFalse(); - }); - - it('should return true and not log warning on partial and glob match', () => { - const result = pathsMatcher.matches( - { - packageFile: 'package.json', - }, - { - matchPaths: ['package.json'], - } - ); - expect(result).toBeTrue(); - expect(logger.warn).not.toHaveBeenCalled(); - }); - }); -}); diff --git a/lib/util/package-rules/paths.ts b/lib/util/package-rules/paths.ts deleted file mode 100644 index 7fa70aaa9ef991..00000000000000 --- a/lib/util/package-rules/paths.ts +++ /dev/null @@ -1,22 +0,0 @@ -import is from '@sindresorhus/is'; -import { minimatch } from 'minimatch'; -import type { PackageRule, PackageRuleInputConfig } from '../../config/types'; -import { Matcher } from './base'; - -export class PathsMatcher extends Matcher { - override matches( - { packageFile }: PackageRuleInputConfig, - { matchPaths }: PackageRule - ): boolean | null { - if (is.undefined(matchPaths)) { - return null; - } - if (is.undefined(packageFile)) { - return false; - } - - return matchPaths.some((rulePath) => - minimatch(packageFile, rulePath, { dot: true }) - ); - } -} diff --git a/lib/workers/repository/init/__snapshots__/vulnerability.spec.ts.snap b/lib/workers/repository/init/__snapshots__/vulnerability.spec.ts.snap index e731e34f30e745..1c6a552c0026b5 100644 --- a/lib/workers/repository/init/__snapshots__/vulnerability.spec.ts.snap +++ b/lib/workers/repository/init/__snapshots__/vulnerability.spec.ts.snap @@ -7,7 +7,7 @@ exports[`workers/repository/init/vulnerability detectVulnerabilityAlerts() retur "matchDatasources": [ "npm", ], - "matchFiles": [ + "matchFileNames": [ "backend/package-lock.json", ], "matchPackageNames": [ @@ -31,7 +31,7 @@ exports[`workers/repository/init/vulnerability detectVulnerabilityAlerts() retur "matchDatasources": [ "go", ], - "matchFiles": [ + "matchFileNames": [ "go.mod", ], "matchPackageNames": [ @@ -61,7 +61,7 @@ go", "matchDatasources": [ "github-tags", ], - "matchFiles": [ + "matchFileNames": [ ".github/workflows/build.yaml", ], "matchPackageNames": [ @@ -91,7 +91,7 @@ actions", "matchDatasources": [ "pypi", ], - "matchFiles": [ + "matchFileNames": [ "requirements.txt", ], "matchPackageNames": [ @@ -136,7 +136,7 @@ Ansible before versions 2.1.4, 2.2.1 is vulnerable to an improper input validati "matchDatasources": [ "maven", ], - "matchFiles": [ + "matchFileNames": [ "pom.xml", ], "matchPackageNames": [ diff --git a/lib/workers/repository/init/vulnerability.spec.ts b/lib/workers/repository/init/vulnerability.spec.ts index 7b47d5ab7aa06a..90e0b9f328cc6d 100644 --- a/lib/workers/repository/init/vulnerability.spec.ts +++ b/lib/workers/repository/init/vulnerability.spec.ts @@ -332,7 +332,7 @@ describe('workers/repository/init/vulnerability', () => { const res = await detectVulnerabilityAlerts(config); expect(res.packageRules).toMatchSnapshot(); expect(res.packageRules).toHaveLength(5); - expect(res.packageRules?.[1]?.matchFiles?.[0]).toBe('go.mod'); + expect(res.packageRules?.[1]?.matchFileNames?.[0]).toBe('go.mod'); expect(res.packageRules?.[2]?.matchCurrentVersion).toBe('1.8.2'); expect(res.remediations).toMatchSnapshot({ 'backend/package-lock.json': [ diff --git a/lib/workers/repository/init/vulnerability.ts b/lib/workers/repository/init/vulnerability.ts index 7cf228988eb556..69a5cc44c46c39 100644 --- a/lib/workers/repository/init/vulnerability.ts +++ b/lib/workers/repository/init/vulnerability.ts @@ -208,7 +208,7 @@ export async function detectVulnerabilityAlerts( datasource === PypiDatasource.id ? `==${val.firstPatchedVersion!}` : val.firstPatchedVersion; - const matchFiles = + const matchFileNames = datasource === GoDatasource.id ? [fileName.replace('go.sum', 'go.mod')] : [fileName]; @@ -216,7 +216,7 @@ export async function detectVulnerabilityAlerts( matchDatasources: [datasource], matchPackageNames: [depName], matchCurrentVersion, - matchFiles, + matchFileNames, }; const supportedRemediationFileTypes = ['package-lock.json']; if ( @@ -252,7 +252,7 @@ export async function detectVulnerabilityAlerts( // istanbul ignore if if ( config.transitiveRemediation && - matchRule.matchFiles?.[0] === 'package.json' + matchRule.matchFileNames?.[0] === 'package.json' ) { matchRule.force!.rangeStrategy = 'replace'; } diff --git a/lib/workers/repository/updates/flatten.spec.ts b/lib/workers/repository/updates/flatten.spec.ts index b0c83caf13de27..88e3cd8e61565a 100644 --- a/lib/workers/repository/updates/flatten.spec.ts +++ b/lib/workers/repository/updates/flatten.spec.ts @@ -24,7 +24,7 @@ describe('workers/repository/updates/flatten', () => { automerge: true, }, { - matchPaths: ['frontend/package.json'], + matchFileNames: ['frontend/package.json'], lockFileMaintenance: { enabled: false, }, From fa90bf37d84938a2b499a3fbb67a5c07cf8a6150 Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Mon, 12 Jun 2023 16:42:51 +0200 Subject: [PATCH 09/21] refactor!: rename renovate/stability-days check to renovate/minimum-release-age Closes #21442 --- docs/usage/configuration-options.md | 6 +++--- lib/modules/platform/bitbucket/index.spec.ts | 4 ++-- lib/modules/platform/gitea/index.spec.ts | 4 ++-- lib/modules/platform/github/index.spec.ts | 2 +- lib/modules/platform/gitlab/index.spec.ts | 4 ++-- lib/workers/repository/update/branch/index.ts | 10 +++++----- .../update/branch/status-checks.spec.ts | 16 ++++++++-------- .../repository/update/branch/status-checks.ts | 12 ++++++------ lib/workers/repository/update/pr/index.spec.ts | 8 ++++---- lib/workers/repository/update/pr/index.ts | 4 ++-- 10 files changed, 35 insertions(+), 35 deletions(-) diff --git a/docs/usage/configuration-options.md b/docs/usage/configuration-options.md index acd6a58f18dc4a..8621353e4dffc9 100644 --- a/docs/usage/configuration-options.md +++ b/docs/usage/configuration-options.md @@ -1602,7 +1602,7 @@ If you are more interested in including only certain package managers (e.g. `npm ## internalChecksAsSuccess -By default, internal Renovate checks such as `renovate/stability-days` are not counted towards a branch being "green" or not. +By default, internal Renovate checks such as `renovate/minimum-release-age` are not counted towards a branch being "green" or not. This is primarily to prevent automerge when the only check is a passing Renovate check. Internal checks will always be counted/considered if they are in pending or failed states. @@ -1730,7 +1730,7 @@ Maven users: you cannot use `minimumReleaseAge` if a Maven source returns unreli !!! note - Configuring this option will add a `renovate/stability-days` option to the status checks. + Configuring this option will add a `renovate/minimum-release-age` option to the status checks. There are a couple of uses for `minimumReleaseAge`: @@ -1760,7 +1760,7 @@ Set `minimumReleaseAge` to `3 days` for npm packages to prevent relying on a pac #### Await X time duration before Automerging If you enabled `automerge` _and_ `minimumReleaseAge`, it means that PRs will be created immediately but automerging will be delayed until the time-duration has passed. -This works because Renovate will add a "renovate/stability-days" pending status check to each branch/PR and that pending check will prevent the branch going green to automerge. +This works because Renovate will add a "renovate/minimum-release-age" pending status check to each branch/PR and that pending check will prevent the branch going green to automerge. diff --git a/lib/modules/platform/bitbucket/index.spec.ts b/lib/modules/platform/bitbucket/index.spec.ts index 4e1cd431905e7f..d24f890ab71c8d 100644 --- a/lib/modules/platform/bitbucket/index.spec.ts +++ b/lib/modules/platform/bitbucket/index.spec.ts @@ -297,7 +297,7 @@ describe('modules/platform/bitbucket/index', () => { .reply(200, { values: [ { - key: 'renovate/stability-days', + key: 'renovate/minimum-release-age', state: 'SUCCESSFUL', }, ], @@ -373,7 +373,7 @@ describe('modules/platform/bitbucket/index', () => { .reply(200, { values: [ { - key: 'renovate/stability-days', + key: 'renovate/minimum-release-age', state: 'SUCCESSFUL', }, ], diff --git a/lib/modules/platform/gitea/index.spec.ts b/lib/modules/platform/gitea/index.spec.ts index a306b76a7bf4aa..2a298c6fe41751 100644 --- a/lib/modules/platform/gitea/index.spec.ts +++ b/lib/modules/platform/gitea/index.spec.ts @@ -676,7 +676,7 @@ describe('modules/platform/gitea/index', () => { { id: 1, status: 'success', - context: 'renovate/stability-days', + context: 'renovate/minimum-release-age', description: 'internal check', target_url: '', created_at: '', @@ -695,7 +695,7 @@ describe('modules/platform/gitea/index', () => { { id: 1, status: 'success', - context: 'renovate/stability-days', + context: 'renovate/minimum-release-age', description: 'internal check', target_url: '', created_at: '', diff --git a/lib/modules/platform/github/index.spec.ts b/lib/modules/platform/github/index.spec.ts index 3714876461c986..71cd214c3d97b4 100644 --- a/lib/modules/platform/github/index.spec.ts +++ b/lib/modules/platform/github/index.spec.ts @@ -1080,7 +1080,7 @@ describe('modules/platform/github/index', () => { state: 'success', statuses: [ { - context: 'renovate/stability-days', + context: 'renovate/minimum-release-age', state: 'success', }, ], diff --git a/lib/modules/platform/gitlab/index.spec.ts b/lib/modules/platform/gitlab/index.spec.ts index 500e7ccb6b8603..6a79dc03806fdc 100644 --- a/lib/modules/platform/gitlab/index.spec.ts +++ b/lib/modules/platform/gitlab/index.spec.ts @@ -585,7 +585,7 @@ describe('modules/platform/gitlab/index', () => { '/api/v4/projects/some%2Frepo/repository/commits/0d9c7726c3d628b7e28af234595cfd20febdbf8e/statuses' ) .reply(200, [ - { context: 'renovate/stability-days', status: 'success' }, + { context: 'renovate/minimum-release-age', status: 'success' }, { context: 'renovate/other', status: 'success' }, ]) .get( @@ -603,7 +603,7 @@ describe('modules/platform/gitlab/index', () => { '/api/v4/projects/some%2Frepo/repository/commits/0d9c7726c3d628b7e28af234595cfd20febdbf8e/statuses' ) .reply(200, [ - { name: 'renovate/stability-days', status: 'success' }, + { name: 'renovate/minimum-release-age', status: 'success' }, { name: 'renovate/other', status: 'success' }, ]) .get( diff --git a/lib/workers/repository/update/branch/index.ts b/lib/workers/repository/update/branch/index.ts index 003da47bb0c4ba..54a084a798aa33 100644 --- a/lib/workers/repository/update/branch/index.ts +++ b/lib/workers/repository/update/branch/index.ts @@ -46,7 +46,7 @@ import { getUpdatedPackageFiles } from './get-updated'; import { handleClosedPr, handleModifiedPr } from './handle-existing'; import { shouldReuseExistingBranch } from './reuse'; import { isScheduledNow } from './schedule'; -import { setConfidence, setStability } from './status-checks'; +import { setAge, setConfidence } from './status-checks'; async function rebaseCheck( config: RenovateConfig, @@ -333,7 +333,7 @@ export async function processBranch( ) { // Only set a stability status check if one or more of the updates contain // both a minimumReleaseAge setting and a releaseTimestamp - config.stabilityStatus = 'green'; + config.ageStatus = 'green'; // Default to 'success' but set 'pending' if any update is pending for (const upgrade of config.upgrades) { if ( @@ -350,7 +350,7 @@ export async function processBranch( }, 'Update has not passed minimum release age' ); - config.stabilityStatus = 'yellow'; + config.ageStatus = 'yellow'; continue; } } @@ -385,7 +385,7 @@ export async function processBranch( if ( !dependencyDashboardCheck && !branchExists && - config.stabilityStatus === 'yellow' && + config.ageStatus === 'yellow' && ['not-pending', 'status-success'].includes(config.prCreation!) ) { logger.debug( @@ -585,7 +585,7 @@ export async function processBranch( } // Set branch statuses await setArtifactErrorStatus(config); - await setStability(config); + await setAge(config); await setConfidence(config); // new commit means status check are pretty sure pending but maybe not reported yet diff --git a/lib/workers/repository/update/branch/status-checks.spec.ts b/lib/workers/repository/update/branch/status-checks.spec.ts index 93a811f14f4639..deef27f3b21ba3 100644 --- a/lib/workers/repository/update/branch/status-checks.spec.ts +++ b/lib/workers/repository/update/branch/status-checks.spec.ts @@ -3,8 +3,8 @@ import { ConfidenceConfig, StabilityConfig, resolveBranchStatus, + setAge, setConfidence, - setStability, } from './status-checks'; describe('workers/repository/update/branch/status-checks', () => { @@ -23,28 +23,28 @@ describe('workers/repository/update/branch/status-checks', () => { }); it('returns if not configured', async () => { - await setStability(config); + await setAge(config); expect(platform.getBranchStatusCheck).toHaveBeenCalledTimes(0); }); it('sets status yellow', async () => { - config.stabilityStatus = 'yellow'; - await setStability(config); + config.ageStatus = 'yellow'; + await setAge(config); expect(platform.getBranchStatusCheck).toHaveBeenCalledTimes(1); expect(platform.setBranchStatus).toHaveBeenCalledTimes(1); }); it('sets status green', async () => { - config.stabilityStatus = 'green'; - await setStability(config); + config.ageStatus = 'green'; + await setAge(config); expect(platform.getBranchStatusCheck).toHaveBeenCalledTimes(1); expect(platform.setBranchStatus).toHaveBeenCalledTimes(1); }); it('skips status if already set', async () => { - config.stabilityStatus = 'green'; + config.ageStatus = 'green'; platform.getBranchStatusCheck.mockResolvedValueOnce('green'); - await setStability(config); + await setAge(config); expect(platform.getBranchStatusCheck).toHaveBeenCalledTimes(1); expect(platform.setBranchStatus).toHaveBeenCalledTimes(0); }); diff --git a/lib/workers/repository/update/branch/status-checks.ts b/lib/workers/repository/update/branch/status-checks.ts index 6fe93414f0f6be..a75528a9439f6b 100644 --- a/lib/workers/repository/update/branch/status-checks.ts +++ b/lib/workers/repository/update/branch/status-checks.ts @@ -54,24 +54,24 @@ async function setStatusCheck( } export interface StabilityConfig extends RenovateConfig { - stabilityStatus?: BranchStatus; + ageStatus?: BranchStatus; branchName: string; } -export async function setStability(config: StabilityConfig): Promise { - if (!config.stabilityStatus) { +export async function setAge(config: StabilityConfig): Promise { + if (!config.ageStatus) { return; } - const context = `renovate/stability-days`; + const context = `renovate/minimum-release-age`; const description = - config.stabilityStatus === 'green' + config.ageStatus === 'green' ? 'Updates have met minimum release age requirement' : 'Updates have not met minimum release age requirement'; await setStatusCheck( config.branchName, context, description, - config.stabilityStatus, + config.ageStatus, config.productLinks?.documentation ); } diff --git a/lib/workers/repository/update/pr/index.spec.ts b/lib/workers/repository/update/pr/index.spec.ts index 2daad4639762e0..c37d82d58cbacf 100644 --- a/lib/workers/repository/update/pr/index.spec.ts +++ b/lib/workers/repository/update/pr/index.spec.ts @@ -188,7 +188,7 @@ describe('workers/repository/update/pr/index', () => { expect(prCache.setPrCache).not.toHaveBeenCalled(); }); - it('skips PR creation due to stabilityStatus', async () => { + it('skips PR creation due to ageStatus', async () => { const now = DateTime.now(); const then = now.minus({ hours: 1 }); @@ -198,7 +198,7 @@ describe('workers/repository/update/pr/index', () => { const res = await ensurePr({ ...config, prCreation: 'not-pending', - stabilityStatus: 'green', + ageStatus: 'green', }); expect(res).toEqual({ @@ -482,7 +482,7 @@ describe('workers/repository/update/pr/index', () => { ...config, automerge: true, automergeType: 'branch', - stabilityStatus: 'green', + ageStatus: 'green', prNotPendingHours: 1, }); @@ -503,7 +503,7 @@ describe('workers/repository/update/pr/index', () => { ...config, automerge: true, automergeType: 'branch', - stabilityStatus: 'green', + ageStatus: 'green', prNotPendingHours: 2, }); diff --git a/lib/workers/repository/update/pr/index.ts b/lib/workers/repository/update/pr/index.ts index cadbb3bea8df14..4964dbfed98f5b 100644 --- a/lib/workers/repository/update/pr/index.ts +++ b/lib/workers/repository/update/pr/index.ts @@ -160,7 +160,7 @@ export async function ensurePr( ) { logger.debug(`Branch automerge is enabled`); if ( - config.stabilityStatus !== 'yellow' && + config.ageStatus !== 'yellow' && (await getBranchStatus()) === 'yellow' && is.number(config.prNotPendingHours) ) { @@ -200,7 +200,7 @@ export async function ensurePr( const elapsedHours = getElapsedHours(lastCommitTime); if ( !dependencyDashboardCheck && - ((config.stabilityStatus && config.stabilityStatus !== 'yellow') || + ((config.ageStatus && config.ageStatus !== 'yellow') || (is.number(config.prNotPendingHours) && elapsedHours < config.prNotPendingHours)) ) { From d2c6725ba7314344844640cdcf835bc1e3dffccc Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Wed, 5 Apr 2023 06:44:55 +0200 Subject: [PATCH 10/21] feat!: allow post upgrade templating by default (#21326) Co-authored-by: HonkingGoose <34918129+HonkingGoose@users.noreply.github.com> --- docs/usage/self-hosted-configuration.md | 8 +++----- lib/config/options/index.ts | 4 ++-- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/docs/usage/self-hosted-configuration.md b/docs/usage/self-hosted-configuration.md index a46d563be6d49e..7f5a8d29a0cb20 100644 --- a/docs/usage/self-hosted-configuration.md +++ b/docs/usage/self-hosted-configuration.md @@ -19,15 +19,10 @@ Please also see [Self-Hosted Experimental Options](./self-hosted-experimental.md ## allowPostUpgradeCommandTemplating -Set to `true` to allow templating of dependency level post-upgrade commands. - Let's look at an example of configuring packages with existing Angular migrations. -Add two properties to `config.js`: `allowPostUpgradeCommandTemplating` and `allowedPostUpgradeCommands`: - ```javascript module.exports = { - allowPostUpgradeCommandTemplating: true, allowedPostUpgradeCommands: ['^npm ci --ignore-scripts$', '^npx ng update'], }; ``` @@ -60,6 +55,9 @@ npm ci --ignore-scripts npx ng update @angular/core --from=10.0.0 --to=11.0.0 --migrate-only --allow-dirty --force ``` +If you wish to disable templating because of any security or performance concern, you may set `allowPostUpgradeCommandTemplating` to `false`. +But before you disable templating completely, try the `allowedPostUpgradeCommands` config option to limit what commands are allowed to run. + ## allowScripts ## allowedPostUpgradeCommands diff --git a/lib/config/options/index.ts b/lib/config/options/index.ts index f71066be46c06b..c4f17846cbd2a7 100644 --- a/lib/config/options/index.ts +++ b/lib/config/options/index.ts @@ -24,9 +24,9 @@ const options: RenovateOptions[] = [ { name: 'allowPostUpgradeCommandTemplating', description: - 'Set this to `true` to allow templating for post-upgrade commands.', + 'Set this to `false` to disable template compilation for post-upgrade commands.', type: 'boolean', - default: false, + default: true, globalOnly: true, }, { From 4c0bb3acf20c91c2f61352fcef40afe02c28b9c7 Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Wed, 5 Apr 2023 11:27:22 +0200 Subject: [PATCH 11/21] feat(automerge)!: default to platformAutomerge=true (#21327) Co-authored-by: HonkingGoose <34918129+HonkingGoose@users.noreply.github.com> --- docs/usage/configuration-options.md | 10 +++++----- docs/usage/key-concepts/automerge.md | 12 +++++------- lib/config/options/index.ts | 2 +- lib/modules/platform/gitea/index.md | 2 +- 4 files changed, 12 insertions(+), 14 deletions(-) diff --git a/docs/usage/configuration-options.md b/docs/usage/configuration-options.md index 5283cde1724deb..fce02cbd7176aa 100644 --- a/docs/usage/configuration-options.md +++ b/docs/usage/configuration-options.md @@ -2513,28 +2513,28 @@ If enabled Renovate will pin Docker images or GitHub Actions by means of their S ## platformAutomerge -!!! warning - Before you enable `platformAutomerge` you should enable your Git hosting platform's capabilities to enforce test passing before PR merge. +!!! note + If you use the default `platformAutomerge=true` then you should enable your Git hosting platform's capabilities to enforce test passing before PR merge. If you don't do this, the platform might merge Renovate PRs even if the repository's tests haven't started, are in still in progress, or possibly even when they have failed. On GitHub this is called "Require status checks before merging", which you can find in the "Branch protection rules" section of the settings for your repository. [GitHub docs, about protected branches](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/defining-the-mergeability-of-pull-requests/about-protected-branches) [GitHub docs, require status checks before merging](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/defining-the-mergeability-of-pull-requests/about-protected-branches#require-status-checks-before-merging) If you're using another platform, search their documentation for a similar feature. -If you have enabled `automerge` and set `automergeType=pr` in the Renovate config, then you can also set `platformAutomerge` to `true` to speed up merging via the platform's native automerge functionality. +If you have enabled `automerge` and set `automergeType=pr` in the Renovate config, then leaving `platformAutomerge` as `true` speeds up merging via the platform's native automerge functionality. Renovate tries platform-native automerge only when it initially creates the PR. Any PR that is being updated will be automerged with the Renovate-based automerge. `platformAutomerge` will configure PRs to be merged after all (if any) branch policies have been met. -This option is available for Azure, GitHub and GitLab. +This option is available for Azure, Gitea, GitHub and GitLab. It falls back to Renovate-based automerge if the platform-native automerge is not available. You can also fine-tune the behavior by setting `packageRules` if you want to use it selectively (e.g. per-package). Note that the outcome of `rebaseWhen=auto` can differ when `platformAutomerge=true`. Normally when you set `rebaseWhen=auto` Renovate rebases any branch that's behind the base branch automatically, and some people rely on that. -This behavior is no longer guaranteed when you enable `platformAutomerge` because the platform might automerge a branch which is not up-to-date. +This behavior is no longer guaranteed when `platformAutomerge` is `true` because the platform might automerge a branch which is not up-to-date. For example, GitHub might automerge a Renovate branch even if it's behind the base branch at the time. Please check platform specific docs for version requirements. diff --git a/docs/usage/key-concepts/automerge.md b/docs/usage/key-concepts/automerge.md index 579ebc8a9bc948..d4203845fb680c 100644 --- a/docs/usage/key-concepts/automerge.md +++ b/docs/usage/key-concepts/automerge.md @@ -100,9 +100,8 @@ Say you want to automerge `patch` and `minor` updates for packages in the `group ### Faster merges with platform-native automerge -You can speed up merges by letting Renovate use your platform's native automerge. -The config option is called `platformAutomerge`. -If `automerge=true` and `automergeType=pr` then you can set `platformAutomerge=true`. +By default, Renovate uses platform-native automerge to speed up automerging. +If you don't want Renovate to use the platform-native automerge, then set `platformAutomerge` to `false`. For example: @@ -112,7 +111,7 @@ For example: "enabled": true, "automerge": true, "automergeType": "pr", - "platformAutomerge": true + "platformAutomerge": false } } ``` @@ -155,11 +154,10 @@ On `github.com`, go to your repository's "homepage", click on Settings, scroll d Then go to your repository's branch protection rules for your base branch (usually `main`) and enable the "Require merge queue" setting. Confirm you've set the correct "required checks" for your base branch. -Finally, allow Renovate to automerge by setting `automerge=true` and `platformAutomerge=true` in your Renovate config file, for example: +Finally, allow Renovate to automerge by setting `automerge=true` in your Renovate config file, for example: ```json { - "platformAutomerge": true, "packageRules": [ { "description": "Automerge non-major updates", @@ -180,7 +178,7 @@ On `github.com`, go to your repository's "homepage", click on Settings, scroll d Go to your repository's branch protection rules for your base branch (usually `main`) and enable the "Require merge queue" setting. Confirm you've set the correct "required checks" for your base branch. -Finally, allow Renovate to automerge by setting `automerge=true` and `platformAutomerge=true` in your Renovate config file (see earlier example). +Finally, allow Renovate to automerge by setting `automerge=true` in your Renovate config file (see earlier example). ## Automerging and scheduling diff --git a/lib/config/options/index.ts b/lib/config/options/index.ts index c4f17846cbd2a7..fa50c18406e1c9 100644 --- a/lib/config/options/index.ts +++ b/lib/config/options/index.ts @@ -2611,7 +2611,7 @@ const options: RenovateOptions[] = [ description: `Controls if platform-native auto-merge is used.`, type: 'boolean', supportedPlatforms: ['azure', 'gitea', 'github', 'gitlab'], - default: false, + default: true, }, { name: 'userStrings', diff --git a/lib/modules/platform/gitea/index.md b/lib/modules/platform/gitea/index.md index 098fb39be1f9fc..1f68d933542c5e 100644 --- a/lib/modules/platform/gitea/index.md +++ b/lib/modules/platform/gitea/index.md @@ -18,7 +18,7 @@ Either the account should have full name and email address set to allow Renovate ## Unsupported platform features/concepts - **Adding reviewers to PRs not supported**: Gitea versions older than `v1.14.0` do not have the required API. -- **Setting `platformAutomerge` to use platform-native automerge for PRs not supported**: Gitea versions older than v1.17.0 do not have the required API. +- **`platformAutomerge` (`true` by default) for platform-native automerge not supported**: Gitea versions older than v1.17.0 do not have the required API. - **Git upload filters**: If you're using a Gitea version older than `v1.16.0` then you must enable [clone filters](https://docs.gitea.io/en-us/clone-filters/). ## Features awaiting implementation From 94d73e4b5828e48bc063dea4623fbc04fd7175e7 Mon Sep 17 00:00:00 2001 From: Michael Kriese Date: Wed, 26 Apr 2023 08:26:13 +0200 Subject: [PATCH 12/21] feat(platform/gitlab)!: prefer `commit_email` (#21122 gitAuthor discover for GitLab now prefers the field `commit_email` over `email`. BREAKING CHANGE: GitLab gitAuthor will change from the account's "email" to "commit_email" if they are different. --- lib/modules/platform/gitlab/index.ts | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/lib/modules/platform/gitlab/index.ts b/lib/modules/platform/gitlab/index.ts index 17e6a497288831..d9fadc2ad9f9c9 100644 --- a/lib/modules/platform/gitlab/index.ts +++ b/lib/modules/platform/gitlab/index.ts @@ -107,12 +107,16 @@ export async function initPlatform({ try { if (!gitAuthor) { const user = ( - await gitlabApi.getJson<{ email: string; name: string; id: number }>( - `user`, - { token } - ) + await gitlabApi.getJson<{ + email: string; + name: string; + id: number; + commit_email?: string; + }>(`user`, { token }) ).body; - platformConfig.gitAuthor = `${user.name} <${user.email}>`; + platformConfig.gitAuthor = `${user.name} <${ + user.commit_email ?? user.email + }>`; } // istanbul ignore if: experimental feature if (process.env.RENOVATE_X_PLATFORM_VERSION) { From 4d951332e5aa608b6ad273b4ec63bfc0482a56fc Mon Sep 17 00:00:00 2001 From: Bastian Gutschke Date: Wed, 26 Apr 2023 19:05:27 +0200 Subject: [PATCH 13/21] fix(post-upgrade-tasks)!: enable dot option for file filters (#21282) Set `{ dot: true }` for minimatch. BREAKING CHANGE: dot files will now be included by default for all minimatch results --- docs/usage/configuration-options.md | 1 + .../repository/update/branch/execute-post-upgrade-commands.ts | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/usage/configuration-options.md b/docs/usage/configuration-options.md index fce02cbd7176aa..57b16c87ee19d0 100644 --- a/docs/usage/configuration-options.md +++ b/docs/usage/configuration-options.md @@ -2605,6 +2605,7 @@ You can use variable templating in your commands if [`allowPostUpgradeCommandTem ### fileFilters A list of glob-style matchers that determine which files will be included in the final commit made by Renovate. +Dotfiles are included. ### executionMode diff --git a/lib/workers/repository/update/branch/execute-post-upgrade-commands.ts b/lib/workers/repository/update/branch/execute-post-upgrade-commands.ts index be8b39f4ec65c6..9efb844b0dc2bb 100644 --- a/lib/workers/repository/update/branch/execute-post-upgrade-commands.ts +++ b/lib/workers/repository/update/branch/execute-post-upgrade-commands.ts @@ -106,7 +106,7 @@ export async function postUpgradeCommandsExecutor( for (const relativePath of status.modified.concat(status.not_added)) { for (const pattern of fileFilters) { - if (minimatch(relativePath, pattern)) { + if (minimatch(relativePath, pattern, { dot: true })) { logger.debug( { file: relativePath, pattern }, 'Post-upgrade file saved' @@ -134,7 +134,7 @@ export async function postUpgradeCommandsExecutor( for (const relativePath of status.deleted || []) { for (const pattern of fileFilters) { - if (minimatch(relativePath, pattern)) { + if (minimatch(relativePath, pattern, { dot: true })) { logger.debug( { file: relativePath, pattern }, 'Post-upgrade file removed' From 1b0570a82765fd1c8da4d39b6ff7c8c917d11be3 Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Fri, 5 May 2023 19:47:16 +0200 Subject: [PATCH 14/21] feat(npm)!: disable rollbackPrs for npm by default (#21970) --- docs/usage/configuration-options.md | 5 ++--- lib/config/index.spec.ts | 1 - lib/modules/manager/npm/index.ts | 1 - 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/docs/usage/configuration-options.md b/docs/usage/configuration-options.md index 57b16c87ee19d0..d7f0554f864b93 100644 --- a/docs/usage/configuration-options.md +++ b/docs/usage/configuration-options.md @@ -3268,9 +3268,8 @@ There are times when a dependency version in use by a project gets removed from For some registries, existing releases or even whole packages can be removed or "yanked" at any time, while for some registries only very new or unused releases can be removed. Renovate's "rollback" feature exists to propose a downgrade to the next-highest release if the current release is no longer found in the registry. -Renovate does not create these rollback PRs by default, with one exception: npm packages get a rollback PR if needed. - -You can configure the `rollbackPrs` property globally, per-language, or per-package to override the default behavior. +Renovate does not create these rollback PRs by default, so this functionality needs to be opted-into. +We recommend you do this selectively with `packageRules` and not globally. ## ruby diff --git a/lib/config/index.spec.ts b/lib/config/index.spec.ts index 001ea8c8b53488..94e6822cf72dfc 100644 --- a/lib/config/index.spec.ts +++ b/lib/config/index.spec.ts @@ -91,7 +91,6 @@ describe('config/index', () => { const config = getManagerConfig(parentConfig, 'npm'); expect(config).toContainEntries([ ['fileMatch', ['(^|/)package\\.json$']], - ['rollbackPrs', true], ]); expect(getManagerConfig(parentConfig, 'html')).toContainEntries([ ['fileMatch', ['\\.html?$']], diff --git a/lib/modules/manager/npm/index.ts b/lib/modules/manager/npm/index.ts index 3ac8a7f281b4ea..9d309bd8a23348 100644 --- a/lib/modules/manager/npm/index.ts +++ b/lib/modules/manager/npm/index.ts @@ -17,7 +17,6 @@ export const supportsLockFileMaintenance = true; export const defaultConfig = { fileMatch: ['(^|/)package\\.json$'], - rollbackPrs: true, versioning: npmVersioning.id, digest: { prBodyDefinitions: { From 90975fbabde3bc3f72ffb2ee8207a3222b1056ff Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Sun, 7 May 2023 22:07:47 +0200 Subject: [PATCH 15/21] fix(presets)!: remove compatibility:additionalBranchPrefix (#22015) --- lib/config/presets/common.ts | 1 + lib/config/presets/internal/compatibility.ts | 28 -------------------- lib/config/presets/internal/index.ts | 2 -- 3 files changed, 1 insertion(+), 30 deletions(-) delete mode 100644 lib/config/presets/internal/compatibility.ts diff --git a/lib/config/presets/common.ts b/lib/config/presets/common.ts index 8ae2839ed0b5c7..8e0a6a03327b97 100644 --- a/lib/config/presets/common.ts +++ b/lib/config/presets/common.ts @@ -12,6 +12,7 @@ export const removedPresets: Record = { ':masterIssueApproval': ':dependencyDashboardApproval', ':switchToGradleLite': null, ':unpublishSafe': 'npm:unpublishSafe', + 'compatibility:additionalBranchPrefix': null, 'config:application': 'config:js-app', 'config:base-js': 'config:base', 'config:library': 'config:js-lib', diff --git a/lib/config/presets/internal/compatibility.ts b/lib/config/presets/internal/compatibility.ts deleted file mode 100644 index 57e12a8d82fb2e..00000000000000 --- a/lib/config/presets/internal/compatibility.ts +++ /dev/null @@ -1,28 +0,0 @@ -import type { Preset } from '../types'; - -/* eslint sort-keys: ["error", "asc", {caseSensitive: false, natural: true}] */ - -export const presets: Record = { - additionalBranchPrefix: { - buildkite: { - additionalBranchPrefix: 'buildkite-', - }, - cargo: { - additionalBranchPrefix: 'rust-', - }, - description: - 'Backwards-compatibility preset to restore `additionalBranchPrefix` settings for multiple managers which were removed in Renovate `v25`.', - docker: { - additionalBranchPrefix: 'docker-', - }, - homebrew: { - additionalBranchPrefix: 'homebrew-', - }, - packageRules: [ - { - additionalBranchPrefix: 'helm-', - matchDatasources: ['helm'], - }, - ], - }, -}; diff --git a/lib/config/presets/internal/index.ts b/lib/config/presets/internal/index.ts index 63765664558b69..e37788d17fc4c8 100644 --- a/lib/config/presets/internal/index.ts +++ b/lib/config/presets/internal/index.ts @@ -1,5 +1,4 @@ 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'; @@ -17,7 +16,6 @@ import * as workaroundsPreset from './workarounds'; /* eslint sort-keys: ["error", "asc", {caseSensitive: false, natural: true}] */ export const groups: Record> = { - compatibility: compatibilityPreset.presets, config: configPreset.presets, default: defaultPreset.presets, docker: dockerPreset.presets, From 88ab057e3c4a1ad30e7dfa01592d891256600303 Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Wed, 24 May 2023 08:07:00 +0200 Subject: [PATCH 16/21] feat(package-rules)!: remove fuzzy matchPaths matching (#22394) --- docs/usage/configuration-options.md | 5 ----- lib/config/options/index.ts | 2 +- lib/util/package-rules/index.spec.ts | 2 +- lib/util/package-rules/paths.spec.ts | 11 ++--------- lib/util/package-rules/paths.ts | 20 +++----------------- 5 files changed, 7 insertions(+), 33 deletions(-) diff --git a/docs/usage/configuration-options.md b/docs/usage/configuration-options.md index d7f0554f864b93..2b2a12eed1a1fc 100644 --- a/docs/usage/configuration-options.md +++ b/docs/usage/configuration-options.md @@ -2287,11 +2287,6 @@ The following matches any file in directories starting with `app/`: } ``` - -!!! warning - Partial matches for `matchPaths` are deprecated. - Please use a `minimatch` glob pattern or switch to [`matchFiles`](#matchfiles) if you need exact matching. - ### matchSourceUrlPrefixes Here's an example of where you use this to group together all packages from the `renovatebot` GitHub org: diff --git a/lib/config/options/index.ts b/lib/config/options/index.ts index fa50c18406e1c9..ed4eefcab2fbad 100644 --- a/lib/config/options/index.ts +++ b/lib/config/options/index.ts @@ -1307,7 +1307,7 @@ const options: RenovateOptions[] = [ { name: 'matchPaths', description: - 'List of strings or glob patterns to match against package files. Only works inside a `packageRules` object.', + 'List of glob patterns to match against package files. Only works inside a `packageRules` object.', type: 'array', subType: 'string', stage: 'repository', diff --git a/lib/util/package-rules/index.spec.ts b/lib/util/package-rules/index.spec.ts index 9e6f48f4b38d11..ecfeee4914794c 100644 --- a/lib/util/package-rules/index.spec.ts +++ b/lib/util/package-rules/index.spec.ts @@ -989,7 +989,7 @@ describe('util/package-rules/index', () => { ...config, depName: 'test', }); - expect(res3.x).toBeDefined(); + expect(res3.x).toBeUndefined(); }); it('empty rules', () => { diff --git a/lib/util/package-rules/paths.spec.ts b/lib/util/package-rules/paths.spec.ts index 9b0c1db55484aa..4e0bfed3567995 100644 --- a/lib/util/package-rules/paths.spec.ts +++ b/lib/util/package-rules/paths.spec.ts @@ -17,7 +17,7 @@ describe('util/package-rules/paths', () => { expect(result).toBeFalse(); }); - it('should return true and log warning on partial match only', () => { + it('should return false on partial match only', () => { const result = pathsMatcher.matches( { packageFile: 'opentelemetry/http/package.json', @@ -26,14 +26,7 @@ describe('util/package-rules/paths', () => { matchPaths: ['opentelemetry/http'], } ); - expect(result).toBeTrue(); - expect(logger.warn).toHaveBeenCalledWith( - { - packageFile: 'opentelemetry/http/package.json', - rulePath: 'opentelemetry/http', - }, - 'Partial matches for `matchPaths` are deprecated. Please use a minimatch glob pattern or switch to `matchFiles` if you need exact matching.' - ); + expect(result).toBeFalse(); }); it('should return true and not log warning on partial and glob match', () => { diff --git a/lib/util/package-rules/paths.ts b/lib/util/package-rules/paths.ts index 7bd882c56966e0..7fa70aaa9ef991 100644 --- a/lib/util/package-rules/paths.ts +++ b/lib/util/package-rules/paths.ts @@ -1,7 +1,6 @@ import is from '@sindresorhus/is'; import { minimatch } from 'minimatch'; import type { PackageRule, PackageRuleInputConfig } from '../../config/types'; -import { logger } from '../../logger'; import { Matcher } from './base'; export class PathsMatcher extends Matcher { @@ -16,21 +15,8 @@ export class PathsMatcher extends Matcher { return false; } - return matchPaths.some((rulePath) => { - if (minimatch(packageFile, rulePath, { dot: true })) { - return true; - } - - if (packageFile.includes(rulePath)) { - logger.warn( - { - rulePath, - packageFile, - }, - 'Partial matches for `matchPaths` are deprecated. Please use a minimatch glob pattern or switch to `matchFiles` if you need exact matching.' - ); - return true; - } - }); + return matchPaths.some((rulePath) => + minimatch(packageFile, rulePath, { dot: true }) + ); } } From 86831e44571cc2f31e4ac34cf6cb6219d3fc8028 Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Thu, 25 May 2023 17:46:28 +0200 Subject: [PATCH 17/21] feat!: merge matchPaths and matchFiles into matchFileNames (#22406) --- docs/usage/configuration-options.md | 77 +++++++++---------- .../__snapshots__/migration.spec.ts.snap | 16 ++-- lib/config/migration.spec.ts | 30 +++++++- .../custom/automerge-major-migration.spec.ts | 4 +- .../custom/automerge-minor-migration.spec.ts | 4 +- .../custom/automerge-patch-migration.spec.ts | 4 +- .../custom/package-rules-migration.spec.ts | 2 +- .../custom/package-rules-migration.ts | 4 +- lib/config/options/index.ts | 13 +--- lib/config/presets/internal/default.ts | 2 +- lib/config/types.ts | 4 +- lib/config/validation.ts | 3 +- lib/modules/manager/npm/extract/index.ts | 2 +- lib/util/package-rules/files.spec.ts | 6 +- lib/util/package-rules/files.ts | 18 +++-- lib/util/package-rules/index.spec.ts | 6 +- lib/util/package-rules/matchers.ts | 6 +- lib/util/package-rules/paths.spec.ts | 45 ----------- lib/util/package-rules/paths.ts | 22 ------ .../__snapshots__/vulnerability.spec.ts.snap | 10 +-- .../repository/init/vulnerability.spec.ts | 2 +- lib/workers/repository/init/vulnerability.ts | 6 +- .../repository/updates/flatten.spec.ts | 2 +- 23 files changed, 118 insertions(+), 170 deletions(-) delete mode 100644 lib/util/package-rules/paths.spec.ts delete mode 100644 lib/util/package-rules/paths.ts diff --git a/docs/usage/configuration-options.md b/docs/usage/configuration-options.md index 2b2a12eed1a1fc..acd6a58f18dc4a 100644 --- a/docs/usage/configuration-options.md +++ b/docs/usage/configuration-options.md @@ -1863,28 +1863,28 @@ Example: The above rule will group together the `neutrino` package and any package matching `@neutrino/*`. -Path rules are convenient to use if you wish to apply configuration rules to certain package files using patterns. +File name matches are convenient to use if you wish to apply configuration rules to certain package or lock files using patterns. For example, if you have an `examples` directory and you want all updates to those examples to use the `chore` prefix instead of `fix`, then you could add this configuration: ```json { "packageRules": [ { - "matchPaths": ["examples/**"], + "matchFileNames": ["examples/**"], "extends": [":semanticCommitTypeAll(chore)"] } ] } ``` -If you wish to limit Renovate to apply configuration rules to certain files in the root repository directory, you have to use `matchPaths` with a `minimatch` pattern or use [`matchFiles`](#matchfiles) with an exact match. +If you wish to limit Renovate to apply configuration rules to certain files in the root repository directory, you have to use `matchFileNames` with a `minimatch` pattern (which can include an exact file name match). For example you have multiple `package.json` and want to use `dependencyDashboardApproval` only on the root `package.json`: ```json { "packageRules": [ { - "matchFiles": ["package.json"], + "matchFileNames": ["package.json"], "dependencyDashboardApproval": true } ] @@ -2179,23 +2179,50 @@ Use the syntax `!/ /` like this: } ``` -### matchFiles +### matchFileNames -Renovate will compare `matchFiles` for an exact match against the dependency's package file or lock file. +Renovate will compare `matchFileNames` glob matching against the dependency's package file or lock file. -For example the following would match `package.json` but not `package/frontend/package.json`: +The following example matches `package.json` but _not_ `package/frontend/package.json`: ```json { "packageRules": [ { - "matchFiles": ["package.json"] + "matchFileNames": ["package.json"], + "labels": ["npm"] } ] } ``` -Use [`matchPaths`](#matchpaths) instead if you need more flexible matching. +The following example matches any `package.json`, including files like `backend/package.json`: + +```json +{ + "packageRules": [ + { + "description": "Group dependencies from package.json files", + "matchFileNames": ["**/package.json"], + "groupName": "All package.json changes" + } + ] +} +``` + +The following example matches any file in directories starting with `app/`: + +```json +{ + "packageRules": [ + { + "description": "Group all dependencies from the app directory", + "matchFileNames": ["app/**"], + "groupName": "App dependencies" + } + ] +} +``` ### matchDepNames @@ -2255,38 +2282,6 @@ See also `excludePackagePrefixes`. Like the earlier `matchPackagePatterns` example, the above will configure `rangeStrategy` to `replace` for any package starting with `angular`. -### matchPaths - -Renovate finds the file(s) listed in `matchPaths` with a `minimatch` glob pattern. - -For example the following matches any `package.json`, including files like `backend/package.json`: - -```json -{ - "packageRules": [ - { - "description": "Group dependencies from package.json files", - "matchPaths": ["**/package.json"], - "groupName": "All package.json changes" - } - ] -} -``` - -The following matches any file in directories starting with `app/`: - -```json -{ - "packageRules": [ - { - "description": "Group all dependencies from the app directory", - "matchPaths": ["app/**"], - "groupName": "App dependencies" - } - ] -} -``` - ### matchSourceUrlPrefixes Here's an example of where you use this to group together all packages from the `renovatebot` GitHub org: diff --git a/lib/config/__snapshots__/migration.spec.ts.snap b/lib/config/__snapshots__/migration.spec.ts.snap index 572cc3bbdb1787..c4df79d9deb94f 100644 --- a/lib/config/__snapshots__/migration.spec.ts.snap +++ b/lib/config/__snapshots__/migration.spec.ts.snap @@ -164,7 +164,7 @@ exports[`config/migration migrateConfig(config, parentConfig) migrates config 1` "extends": [ "node", ], - "matchPaths": [ + "matchFileNames": [ "node/**", ], }, @@ -211,7 +211,7 @@ exports[`config/migration migrateConfig(config, parentConfig) migrates config 1` "extends": [ "foo", ], - "matchPaths": [ + "matchFileNames": [ "examples/**", ], }, @@ -293,7 +293,7 @@ exports[`config/migration migrateConfig(config, parentConfig) migrates more pack "matchDepTypes": [ "devDependencies", ], - "matchPaths": [ + "matchFileNames": [ "package.json", ], "rangeStrategy": "pin", @@ -302,7 +302,7 @@ exports[`config/migration migrateConfig(config, parentConfig) migrates more pack "matchDepTypes": [ "dependencies", ], - "matchPaths": [ + "matchFileNames": [ "package.json", ], "rangeStrategy": "pin", @@ -332,13 +332,13 @@ exports[`config/migration migrateConfig(config, parentConfig) migrates packageFi ], "packageRules": [ { - "matchPaths": [ + "matchFileNames": [ "backend/package.json", ], "rangeStrategy": "replace", }, { - "matchPaths": [ + "matchFileNames": [ "frontend/package.json", ], "rangeStrategy": "pin", @@ -347,7 +347,7 @@ exports[`config/migration migrateConfig(config, parentConfig) migrates packageFi "matchDepTypes": [ "devDependencies", ], - "matchPaths": [ + "matchFileNames": [ "other/package.json", ], "rangeStrategy": "pin", @@ -356,7 +356,7 @@ exports[`config/migration migrateConfig(config, parentConfig) migrates packageFi "matchDepTypes": [ "dependencies", ], - "matchPaths": [ + "matchFileNames": [ "other/package.json", ], "rangeStrategy": "pin", diff --git a/lib/config/migration.spec.ts b/lib/config/migration.spec.ts index fcb40a6609d2d6..eae90ddd53c9fe 100644 --- a/lib/config/migration.spec.ts +++ b/lib/config/migration.spec.ts @@ -568,13 +568,41 @@ describe('config/migration', () => { matchManagers: ['dockerfile'], matchPackageNames: ['foo'], matchPackagePatterns: ['^bar'], - matchPaths: ['package.json'], + matchFileNames: ['package.json'], matchSourceUrlPrefixes: ['https://github.com/lodash'], matchUpdateTypes: ['major'], }, ], }); }); + + it('migrates in order of precedence', () => { + const config: TestRenovateConfig = { + packageRules: [ + { + matchFiles: ['matchFiles'], + matchPaths: ['matchPaths'], + }, + { + matchPaths: ['matchPaths'], + matchFiles: ['matchFiles'], + }, + ], + }; + const { isMigrated, migratedConfig } = + configMigration.migrateConfig(config); + expect(isMigrated).toBeTrue(); + expect(migratedConfig).toEqual({ + packageRules: [ + { + matchFileNames: ['matchPaths'], + }, + { + matchFileNames: ['matchFiles'], + }, + ], + }); + }); }); it('it migrates nested packageRules', () => { diff --git a/lib/config/migrations/custom/automerge-major-migration.spec.ts b/lib/config/migrations/custom/automerge-major-migration.spec.ts index 0d2a9a7d30ba60..9dd5ebd21c87d0 100644 --- a/lib/config/migrations/custom/automerge-major-migration.spec.ts +++ b/lib/config/migrations/custom/automerge-major-migration.spec.ts @@ -19,13 +19,13 @@ describe('config/migrations/custom/automerge-major-migration', () => { { automergeMajor: 'some-value', major: { - matchFiles: ['test'], + matchFileNames: ['test'], }, }, { major: { automerge: true, - matchFiles: ['test'], + matchFileNames: ['test'], }, } ); diff --git a/lib/config/migrations/custom/automerge-minor-migration.spec.ts b/lib/config/migrations/custom/automerge-minor-migration.spec.ts index 9597466a7b3682..5ce417773f84c6 100644 --- a/lib/config/migrations/custom/automerge-minor-migration.spec.ts +++ b/lib/config/migrations/custom/automerge-minor-migration.spec.ts @@ -19,13 +19,13 @@ describe('config/migrations/custom/automerge-minor-migration', () => { { automergeMinor: 'some-value', minor: { - matchFiles: ['test'], + matchFileNames: ['test'], }, }, { minor: { automerge: true, - matchFiles: ['test'], + matchFileNames: ['test'], }, } ); diff --git a/lib/config/migrations/custom/automerge-patch-migration.spec.ts b/lib/config/migrations/custom/automerge-patch-migration.spec.ts index bc7014fa541f61..124f599fe921b3 100644 --- a/lib/config/migrations/custom/automerge-patch-migration.spec.ts +++ b/lib/config/migrations/custom/automerge-patch-migration.spec.ts @@ -19,13 +19,13 @@ describe('config/migrations/custom/automerge-patch-migration', () => { { automergePatch: 'some-value', patch: { - matchFiles: ['test'], + matchFileNames: ['test'], }, }, { patch: { automerge: true, - matchFiles: ['test'], + matchFileNames: ['test'], }, } ); diff --git a/lib/config/migrations/custom/package-rules-migration.spec.ts b/lib/config/migrations/custom/package-rules-migration.spec.ts index e77f20476fab5e..b5f6afaf7a016a 100644 --- a/lib/config/migrations/custom/package-rules-migration.spec.ts +++ b/lib/config/migrations/custom/package-rules-migration.spec.ts @@ -48,7 +48,7 @@ describe('config/migrations/custom/package-rules-migration', () => { { packageRules: [ { - matchPaths: [], + matchFileNames: [], packgageRules: { languages: ['javascript'], }, diff --git a/lib/config/migrations/custom/package-rules-migration.ts b/lib/config/migrations/custom/package-rules-migration.ts index e3be4c4c910ac0..9da8469fe3c23c 100644 --- a/lib/config/migrations/custom/package-rules-migration.ts +++ b/lib/config/migrations/custom/package-rules-migration.ts @@ -2,7 +2,9 @@ import type { PackageRule } from '../../types'; import { AbstractMigration } from '../base/abstract-migration'; export const renameMap = { - paths: 'matchPaths', + matchFiles: 'matchFileNames', + matchPaths: 'matchFileNames', + paths: 'matchFileNames', languages: 'matchLanguages', baseBranchList: 'matchBaseBranches', managers: 'matchManagers', diff --git a/lib/config/options/index.ts b/lib/config/options/index.ts index ed4eefcab2fbad..4957af9fdb3a2c 100644 --- a/lib/config/options/index.ts +++ b/lib/config/options/index.ts @@ -1294,7 +1294,7 @@ const options: RenovateOptions[] = [ env: false, }, { - name: 'matchFiles', + name: 'matchFileNames', description: 'List of strings to do an exact match against package and lock files with full path. Only works inside a `packageRules` object.', type: 'array', @@ -1304,17 +1304,6 @@ const options: RenovateOptions[] = [ cli: false, env: false, }, - { - name: 'matchPaths', - description: - 'List of glob patterns to match against package files. Only works inside a `packageRules` object.', - type: 'array', - subType: 'string', - stage: 'repository', - parent: 'packageRules', - cli: false, - env: false, - }, // Version behaviour { name: 'allowedVersions', diff --git a/lib/config/presets/internal/default.ts b/lib/config/presets/internal/default.ts index 4a7ca0f2577a20..f65b0c48c93eb9 100644 --- a/lib/config/presets/internal/default.ts +++ b/lib/config/presets/internal/default.ts @@ -361,7 +361,7 @@ export const presets: Record = { 'Use semanticCommitType `{{arg0}}` for all package files matching path `{{arg1}}`.', packageRules: [ { - matchPaths: ['{{arg0}}'], + matchFileNames: ['{{arg0}}'], semanticCommitType: '{{arg1}}', }, ], diff --git a/lib/config/types.ts b/lib/config/types.ts index 5c390b09c825a0..a06a7adc8d8ba6 100644 --- a/lib/config/types.ts +++ b/lib/config/types.ts @@ -313,8 +313,7 @@ export interface PackageRule Record { description?: string | string[]; isVulnerabilityAlert?: boolean; - matchFiles?: string[]; - matchPaths?: string[]; + matchFileNames?: string[]; matchLanguages?: string[]; matchBaseBranches?: string[]; matchManagers?: string | string[]; @@ -459,6 +458,7 @@ export type RenovateOptions = export interface PackageRuleInputConfig extends Record { versioning?: string; packageFile?: string; + lockFiles?: string[]; depType?: string; depTypes?: string[]; depName?: string; diff --git a/lib/config/validation.ts b/lib/config/validation.ts index f5c7b59c5c5657..254e36cb40c8f2 100644 --- a/lib/config/validation.ts +++ b/lib/config/validation.ts @@ -311,8 +311,7 @@ export async function validateConfig( } const selectors = [ - 'matchFiles', - 'matchPaths', + 'matchFileNames', 'matchLanguages', 'matchBaseBranches', 'matchManagers', diff --git a/lib/modules/manager/npm/extract/index.ts b/lib/modules/manager/npm/extract/index.ts index 00c3fb7d3e0444..467cdef6b849fc 100644 --- a/lib/modules/manager/npm/extract/index.ts +++ b/lib/modules/manager/npm/extract/index.ts @@ -64,7 +64,7 @@ export async function extractPackageFile( const error = new Error(CONFIG_VALIDATION); error.validationSource = packageFile; error.validationError = - 'Nested package.json must not contain renovate configuration. Please use `packageRules` with `matchPaths` in your main config instead.'; + 'Nested package.json must not contain Renovate configuration. Please use `packageRules` with `matchFileNames` in your main config instead.'; throw error; } const packageJsonName = packageJson.name; diff --git a/lib/util/package-rules/files.spec.ts b/lib/util/package-rules/files.spec.ts index 374d2650355465..ac30c31247f00d 100644 --- a/lib/util/package-rules/files.spec.ts +++ b/lib/util/package-rules/files.spec.ts @@ -1,7 +1,7 @@ -import { FilesMatcher } from './files'; +import { FileNamesMatcher } from './files'; describe('util/package-rules/files', () => { - const fileMatcher = new FilesMatcher(); + const fileMatcher = new FileNamesMatcher(); describe('match', () => { it('should return false if packageFile is not defined', () => { @@ -10,7 +10,7 @@ describe('util/package-rules/files', () => { packageFile: undefined, }, { - matchFiles: ['frontend/package.json'], + matchFileNames: ['frontend/package.json'], } ); expect(result).toBeFalse(); diff --git a/lib/util/package-rules/files.ts b/lib/util/package-rules/files.ts index e1ab76f4d70192..bb6cd57a3c5c90 100644 --- a/lib/util/package-rules/files.ts +++ b/lib/util/package-rules/files.ts @@ -1,23 +1,27 @@ import is from '@sindresorhus/is'; +import { minimatch } from 'minimatch'; import type { PackageRule, PackageRuleInputConfig } from '../../config/types'; import { Matcher } from './base'; -export class FilesMatcher extends Matcher { +export class FileNamesMatcher extends Matcher { override matches( { packageFile, lockFiles }: PackageRuleInputConfig, - { matchFiles }: PackageRule + { matchFileNames }: PackageRule ): boolean | null { - if (is.undefined(matchFiles)) { + if (is.undefined(matchFileNames)) { return null; } if (is.undefined(packageFile)) { return false; } - return matchFiles.some( - (fileName) => - packageFile === fileName || - (is.array(lockFiles) && lockFiles?.includes(fileName)) + return matchFileNames.some( + (matchFileName) => + minimatch(packageFile, matchFileName, { dot: true }) || + (is.array(lockFiles) && + lockFiles.some((lockFile) => + minimatch(lockFile, matchFileName, { dot: true }) + )) ); } } diff --git a/lib/util/package-rules/index.spec.ts b/lib/util/package-rules/index.spec.ts index ecfeee4914794c..0718b5243126a8 100644 --- a/lib/util/package-rules/index.spec.ts +++ b/lib/util/package-rules/index.spec.ts @@ -930,7 +930,7 @@ describe('util/package-rules/index', () => { packageFile: 'examples/foo/package.json', packageRules: [ { - matchFiles: ['package.json'], + matchFileNames: ['package.json'], x: 1, }, ], @@ -954,7 +954,7 @@ describe('util/package-rules/index', () => { lockFiles: ['yarn.lock'], packageRules: [ { - matchFiles: ['yarn.lock'], + matchFileNames: ['yarn.lock'], x: 1, }, ], @@ -968,7 +968,7 @@ describe('util/package-rules/index', () => { packageFile: 'examples/foo/package.json', packageRules: [ { - matchPaths: ['examples/**', 'lib/'], + matchFileNames: ['examples/**', 'lib/'], x: 1, }, ], diff --git a/lib/util/package-rules/matchers.ts b/lib/util/package-rules/matchers.ts index 2a11fdd8180d58..dd2672c777b678 100644 --- a/lib/util/package-rules/matchers.ts +++ b/lib/util/package-rules/matchers.ts @@ -5,14 +5,13 @@ import { DatasourcesMatcher } from './datasources'; import { DepNameMatcher } from './dep-names'; import { DepPatternsMatcher } from './dep-patterns'; import { DepTypesMatcher } from './dep-types'; -import { FilesMatcher } from './files'; +import { FileNamesMatcher } from './files'; import { LanguagesMatcher } from './languages'; import { ManagersMatcher } from './managers'; import { MergeConfidenceMatcher } from './merge-confidence'; import { PackageNameMatcher } from './package-names'; import { PackagePatternsMatcher } from './package-patterns'; import { PackagePrefixesMatcher } from './package-prefixes'; -import { PathsMatcher } from './paths'; import { SourceUrlPrefixesMatcher } from './sourceurl-prefixes'; import { SourceUrlsMatcher } from './sourceurls'; import type { MatcherApi } from './types'; @@ -29,8 +28,7 @@ matchers.push([ new PackagePatternsMatcher(), new PackagePrefixesMatcher(), ]); -matchers.push([new FilesMatcher()]); -matchers.push([new PathsMatcher()]); +matchers.push([new FileNamesMatcher()]); matchers.push([new DepTypesMatcher()]); matchers.push([new LanguagesMatcher()]); matchers.push([new BaseBranchesMatcher()]); diff --git a/lib/util/package-rules/paths.spec.ts b/lib/util/package-rules/paths.spec.ts deleted file mode 100644 index 4e0bfed3567995..00000000000000 --- a/lib/util/package-rules/paths.spec.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { logger } from '../../logger'; -import { PathsMatcher } from './paths'; - -describe('util/package-rules/paths', () => { - const pathsMatcher = new PathsMatcher(); - - describe('match', () => { - it('should return false if packageFile is not defined', () => { - const result = pathsMatcher.matches( - { - packageFile: undefined, - }, - { - matchPaths: ['opentelemetry/http'], - } - ); - expect(result).toBeFalse(); - }); - - it('should return false on partial match only', () => { - const result = pathsMatcher.matches( - { - packageFile: 'opentelemetry/http/package.json', - }, - { - matchPaths: ['opentelemetry/http'], - } - ); - expect(result).toBeFalse(); - }); - - it('should return true and not log warning on partial and glob match', () => { - const result = pathsMatcher.matches( - { - packageFile: 'package.json', - }, - { - matchPaths: ['package.json'], - } - ); - expect(result).toBeTrue(); - expect(logger.warn).not.toHaveBeenCalled(); - }); - }); -}); diff --git a/lib/util/package-rules/paths.ts b/lib/util/package-rules/paths.ts deleted file mode 100644 index 7fa70aaa9ef991..00000000000000 --- a/lib/util/package-rules/paths.ts +++ /dev/null @@ -1,22 +0,0 @@ -import is from '@sindresorhus/is'; -import { minimatch } from 'minimatch'; -import type { PackageRule, PackageRuleInputConfig } from '../../config/types'; -import { Matcher } from './base'; - -export class PathsMatcher extends Matcher { - override matches( - { packageFile }: PackageRuleInputConfig, - { matchPaths }: PackageRule - ): boolean | null { - if (is.undefined(matchPaths)) { - return null; - } - if (is.undefined(packageFile)) { - return false; - } - - return matchPaths.some((rulePath) => - minimatch(packageFile, rulePath, { dot: true }) - ); - } -} diff --git a/lib/workers/repository/init/__snapshots__/vulnerability.spec.ts.snap b/lib/workers/repository/init/__snapshots__/vulnerability.spec.ts.snap index e731e34f30e745..1c6a552c0026b5 100644 --- a/lib/workers/repository/init/__snapshots__/vulnerability.spec.ts.snap +++ b/lib/workers/repository/init/__snapshots__/vulnerability.spec.ts.snap @@ -7,7 +7,7 @@ exports[`workers/repository/init/vulnerability detectVulnerabilityAlerts() retur "matchDatasources": [ "npm", ], - "matchFiles": [ + "matchFileNames": [ "backend/package-lock.json", ], "matchPackageNames": [ @@ -31,7 +31,7 @@ exports[`workers/repository/init/vulnerability detectVulnerabilityAlerts() retur "matchDatasources": [ "go", ], - "matchFiles": [ + "matchFileNames": [ "go.mod", ], "matchPackageNames": [ @@ -61,7 +61,7 @@ go", "matchDatasources": [ "github-tags", ], - "matchFiles": [ + "matchFileNames": [ ".github/workflows/build.yaml", ], "matchPackageNames": [ @@ -91,7 +91,7 @@ actions", "matchDatasources": [ "pypi", ], - "matchFiles": [ + "matchFileNames": [ "requirements.txt", ], "matchPackageNames": [ @@ -136,7 +136,7 @@ Ansible before versions 2.1.4, 2.2.1 is vulnerable to an improper input validati "matchDatasources": [ "maven", ], - "matchFiles": [ + "matchFileNames": [ "pom.xml", ], "matchPackageNames": [ diff --git a/lib/workers/repository/init/vulnerability.spec.ts b/lib/workers/repository/init/vulnerability.spec.ts index 7b47d5ab7aa06a..90e0b9f328cc6d 100644 --- a/lib/workers/repository/init/vulnerability.spec.ts +++ b/lib/workers/repository/init/vulnerability.spec.ts @@ -332,7 +332,7 @@ describe('workers/repository/init/vulnerability', () => { const res = await detectVulnerabilityAlerts(config); expect(res.packageRules).toMatchSnapshot(); expect(res.packageRules).toHaveLength(5); - expect(res.packageRules?.[1]?.matchFiles?.[0]).toBe('go.mod'); + expect(res.packageRules?.[1]?.matchFileNames?.[0]).toBe('go.mod'); expect(res.packageRules?.[2]?.matchCurrentVersion).toBe('1.8.2'); expect(res.remediations).toMatchSnapshot({ 'backend/package-lock.json': [ diff --git a/lib/workers/repository/init/vulnerability.ts b/lib/workers/repository/init/vulnerability.ts index 7cf228988eb556..69a5cc44c46c39 100644 --- a/lib/workers/repository/init/vulnerability.ts +++ b/lib/workers/repository/init/vulnerability.ts @@ -208,7 +208,7 @@ export async function detectVulnerabilityAlerts( datasource === PypiDatasource.id ? `==${val.firstPatchedVersion!}` : val.firstPatchedVersion; - const matchFiles = + const matchFileNames = datasource === GoDatasource.id ? [fileName.replace('go.sum', 'go.mod')] : [fileName]; @@ -216,7 +216,7 @@ export async function detectVulnerabilityAlerts( matchDatasources: [datasource], matchPackageNames: [depName], matchCurrentVersion, - matchFiles, + matchFileNames, }; const supportedRemediationFileTypes = ['package-lock.json']; if ( @@ -252,7 +252,7 @@ export async function detectVulnerabilityAlerts( // istanbul ignore if if ( config.transitiveRemediation && - matchRule.matchFiles?.[0] === 'package.json' + matchRule.matchFileNames?.[0] === 'package.json' ) { matchRule.force!.rangeStrategy = 'replace'; } diff --git a/lib/workers/repository/updates/flatten.spec.ts b/lib/workers/repository/updates/flatten.spec.ts index b0c83caf13de27..88e3cd8e61565a 100644 --- a/lib/workers/repository/updates/flatten.spec.ts +++ b/lib/workers/repository/updates/flatten.spec.ts @@ -24,7 +24,7 @@ describe('workers/repository/updates/flatten', () => { automerge: true, }, { - matchPaths: ['frontend/package.json'], + matchFileNames: ['frontend/package.json'], lockFileMaintenance: { enabled: false, }, From e5574c613a6e07b5a0d6e0aa6062c37f9498ffc9 Mon Sep 17 00:00:00 2001 From: RahulGautamSingh Date: Mon, 12 Jun 2023 21:22:07 +0545 Subject: [PATCH 18/21] feat!: remove `skipInstalls` config option (#22648) --- docs/usage/self-hosted-configuration.md | 8 +------ lib/config/options/index.ts | 8 ------- lib/config/types.ts | 1 - lib/modules/manager/npm/extract/index.spec.ts | 2 +- lib/modules/manager/npm/extract/index.ts | 22 ++++++++----------- lib/modules/manager/types.ts | 6 ++--- .../extract-fingerprint-config.spec.ts | 4 ---- 7 files changed, 14 insertions(+), 37 deletions(-) diff --git a/docs/usage/self-hosted-configuration.md b/docs/usage/self-hosted-configuration.md index 7f5a8d29a0cb20..52fff74b4e526b 100644 --- a/docs/usage/self-hosted-configuration.md +++ b/docs/usage/self-hosted-configuration.md @@ -29,7 +29,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 needed because, by default, the installation of dependencies is skipped (see the `skipInstalls` global option). +The command to install dependencies (`npm ci --ignore-scripts`) is needed because, by default, the installation of dependencies is skipped. ```json { @@ -798,12 +798,6 @@ It could then be used in a repository config or preset like so: Secret names must start with an upper or lower case character and can have 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 ## unicodeEmoji diff --git a/lib/config/options/index.ts b/lib/config/options/index.ts index 4957af9fdb3a2c..2ecd51ce65f3d6 100644 --- a/lib/config/options/index.ts +++ b/lib/config/options/index.ts @@ -729,14 +729,6 @@ const options: RenovateOptions[] = [ description: 'Set to `false` to disable lock file updating.', type: 'boolean', }, - { - name: 'skipInstalls', - description: - 'Skip installing modules/dependencies if lock file updating is possible without a full install.', - type: 'boolean', - default: null, - globalOnly: true, - }, { name: 'autodiscover', description: 'Autodiscover all repositories.', diff --git a/lib/config/types.ts b/lib/config/types.ts index a06a7adc8d8ba6..473cddaf2aed12 100644 --- a/lib/config/types.ts +++ b/lib/config/types.ts @@ -260,7 +260,6 @@ export interface RenovateConfig secrets?: Record; constraints?: Record; - skipInstalls?: boolean | null; constraintsFiltering?: ConstraintsFilter; diff --git a/lib/modules/manager/npm/extract/index.spec.ts b/lib/modules/manager/npm/extract/index.spec.ts index d43e4702551c73..170f4ff30d151a 100644 --- a/lib/modules/manager/npm/extract/index.spec.ts +++ b/lib/modules/manager/npm/extract/index.spec.ts @@ -9,7 +9,7 @@ const realFs = jest.requireActual( ); const defaultExtractConfig = { - skipInstalls: null, + skipInstalls: true, } satisfies ExtractConfig; const input01Content = Fixtures.get('inputs/01.json', '..'); diff --git a/lib/modules/manager/npm/extract/index.ts b/lib/modules/manager/npm/extract/index.ts index 467cdef6b849fc..6db976a92e5316 100644 --- a/lib/modules/manager/npm/extract/index.ts +++ b/lib/modules/manager/npm/extract/index.ts @@ -473,19 +473,15 @@ export async function extractPackageFile( return null; } } - let skipInstalls = config.skipInstalls; - if (skipInstalls === null) { - if ((hasFancyRefs && lockFiles.npmLock) || yarnZeroInstall) { - // 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 - // - Also, do not skip install if Yarn zero-install is used - logger.debug('Automatically setting skipInstalls to false'); - skipInstalls = false; - } else { - skipInstalls = true; - } + let skipInstalls = true; // skip installing modules by default + if ((hasFancyRefs && lockFiles.npmLock) || yarnZeroInstall) { + // 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 + // - Also, do not skip install if Yarn zero-install is used + logger.debug('Automatically setting skipInstalls to false'); + skipInstalls = false; } return { diff --git a/lib/modules/manager/types.ts b/lib/modules/manager/types.ts index dfb040005aaee0..a8f1f086db6d05 100644 --- a/lib/modules/manager/types.ts +++ b/lib/modules/manager/types.ts @@ -20,7 +20,7 @@ export interface ExtractConfig extends CustomExtractConfig { registryAliases?: Record; npmrc?: string; npmrcMerge?: boolean; - skipInstalls?: boolean | null; + skipInstalls?: boolean; } export interface CustomExtractConfig extends RegexManagerTemplates { @@ -65,7 +65,7 @@ export interface PackageFileContent> lockFiles?: string[]; npmrc?: string; packageFileVersion?: string; - skipInstalls?: boolean | null; + skipInstalls?: boolean; matchStrings?: string[]; matchStringsStrategy?: MatchStringsStrategy; } @@ -275,7 +275,7 @@ export interface PostUpdateConfig> ManagerData { updatedPackageFiles?: FileChange[]; postUpdateOptions?: string[]; - skipInstalls?: boolean | null; + skipInstalls?: boolean; ignoreScripts?: boolean; packageFile?: string; diff --git a/lib/workers/repository/extract/extract-fingerprint-config.spec.ts b/lib/workers/repository/extract/extract-fingerprint-config.spec.ts index c0ac40404f4e46..e3d252ba282147 100644 --- a/lib/workers/repository/extract/extract-fingerprint-config.spec.ts +++ b/lib/workers/repository/extract/extract-fingerprint-config.spec.ts @@ -47,7 +47,6 @@ describe('workers/repository/extract/extract-fingerprint-config', () => { registryAliases: { notStable: 'http://some.link.2', }, - skipInstalls: null, }); expect( fingerprintConfig.managers.find((manager) => manager.manager === 'regex') @@ -66,7 +65,6 @@ describe('workers/repository/extract/extract-fingerprint-config', () => { registryAliases: { stable: 'http://some.link', }, - skipInstalls: null, }); }); @@ -90,7 +88,6 @@ describe('workers/repository/extract/extract-fingerprint-config', () => { npmrc: 'some-string', npmrcMerge: true, registryAliases: {}, - skipInstalls: null, }); expect( fingerprintConfig.managers.find( @@ -109,7 +106,6 @@ describe('workers/repository/extract/extract-fingerprint-config', () => { npmrc: 'some-string', npmrcMerge: true, registryAliases: {}, - skipInstalls: null, }); expect( fingerprintConfig.managers.find((manager) => manager.manager === 'regex') From ad78373ad73307202e4595e560f1e5c0c983fbaa Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Mon, 12 Jun 2023 19:38:29 +0200 Subject: [PATCH 19/21] Update lib/workers/repository/update/branch/status-checks.ts Co-authored-by: Michael Kriese --- lib/workers/repository/update/branch/status-checks.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/workers/repository/update/branch/status-checks.ts b/lib/workers/repository/update/branch/status-checks.ts index a75528a9439f6b..32faf6e1ee3ff6 100644 --- a/lib/workers/repository/update/branch/status-checks.ts +++ b/lib/workers/repository/update/branch/status-checks.ts @@ -53,7 +53,7 @@ async function setStatusCheck( } } -export interface StabilityConfig extends RenovateConfig { +export interface AgeConfig extends RenovateConfig { ageStatus?: BranchStatus; branchName: string; } From 8113e29ccaffbe6c1a17ddc54db95e1c5340b83c Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Mon, 12 Jun 2023 19:45:15 +0200 Subject: [PATCH 20/21] fix lint --- lib/workers/repository/update/branch/status-checks.spec.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/workers/repository/update/branch/status-checks.spec.ts b/lib/workers/repository/update/branch/status-checks.spec.ts index deef27f3b21ba3..1c9d5cede6f8c8 100644 --- a/lib/workers/repository/update/branch/status-checks.spec.ts +++ b/lib/workers/repository/update/branch/status-checks.spec.ts @@ -1,7 +1,7 @@ import { getConfig, platform } from '../../../../../test/util'; import { + AgeConfig, ConfidenceConfig, - StabilityConfig, resolveBranchStatus, setAge, setConfidence, @@ -9,7 +9,7 @@ import { describe('workers/repository/update/branch/status-checks', () => { describe('setStability', () => { - let config: StabilityConfig; + let config: AgeConfig; beforeEach(() => { config = { From dfcca828a1391f829db4523da80cef1211b399ea Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Mon, 12 Jun 2023 19:45:58 +0200 Subject: [PATCH 21/21] fix test --- lib/workers/repository/update/branch/status-checks.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/workers/repository/update/branch/status-checks.ts b/lib/workers/repository/update/branch/status-checks.ts index 32faf6e1ee3ff6..57e99427774343 100644 --- a/lib/workers/repository/update/branch/status-checks.ts +++ b/lib/workers/repository/update/branch/status-checks.ts @@ -58,7 +58,7 @@ export interface AgeConfig extends RenovateConfig { branchName: string; } -export async function setAge(config: StabilityConfig): Promise { +export async function setAge(config: AgeConfig): Promise { if (!config.ageStatus) { return; }