From be95cc50083715c33036d4b5c1ac3d0d76718470 Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Wed, 5 Apr 2023 06:44:55 +0200 Subject: [PATCH 01/23] feat!: allow post upgrade templating by default (#21326) Co-authored-by: HonkingGoose <34918129+HonkingGoose@users.noreply.github.com> --- docs/usage/configuration-options.md | 2 +- docs/usage/self-hosted-configuration.md | 8 +++----- lib/config/options/index.ts | 4 ++-- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/docs/usage/configuration-options.md b/docs/usage/configuration-options.md index d26d31e7c16b77..2798e19d4809c9 100644 --- a/docs/usage/configuration-options.md +++ b/docs/usage/configuration-options.md @@ -2588,7 +2588,7 @@ The `postUpgradeTasks` configuration consists of three fields: A list of commands that are executed after Renovate has updated a dependency but before the commit is made. -You can use variable templating in your commands if [`allowPostUpgradeCommandTemplating`](https://docs.renovatebot.com/self-hosted-configuration/#allowpostupgradecommandtemplating) is enabled. +You can use variable templating in your commands as long as [`allowPostUpgradeCommandTemplating`](https://docs.renovatebot.com/self-hosted-configuration/#allowpostupgradecommandtemplating) is enabled. !!! note diff --git a/docs/usage/self-hosted-configuration.md b/docs/usage/self-hosted-configuration.md index fcf72c943a86ab..5ec088cc99c488 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 149a9ecc82140b..f6d57749435536 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 1b5c45b0b7279369a28dae822906d3708054ade1 Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Wed, 5 Apr 2023 11:27:22 +0200 Subject: [PATCH 02/23] 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 2798e19d4809c9..bcb4b2a9833f60 100644 --- a/docs/usage/configuration-options.md +++ b/docs/usage/configuration-options.md @@ -2505,28 +2505,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 4df1b7f68c178b..20a20649dbdc9d 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 f6d57749435536..851df24cfe72c3 100644 --- a/lib/config/options/index.ts +++ b/lib/config/options/index.ts @@ -2610,7 +2610,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 82b25a0c1506e7a5936ab7542f7d04053a2bb8c8 Mon Sep 17 00:00:00 2001 From: Michael Kriese Date: Wed, 26 Apr 2023 08:26:13 +0200 Subject: [PATCH 03/23] 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 0a1081d77f158ced0bc7e68948b58002179c522d Mon Sep 17 00:00:00 2001 From: Bastian Gutschke Date: Wed, 26 Apr 2023 19:05:27 +0200 Subject: [PATCH 04/23] 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 bcb4b2a9833f60..66dbfe514dd06c 100644 --- a/docs/usage/configuration-options.md +++ b/docs/usage/configuration-options.md @@ -2597,6 +2597,7 @@ You can use variable templating in your commands as long as [`allowPostUpgradeCo ### 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 ac726d6524b5d2ce34fd21d441e47b5fe8fcd04c Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Fri, 5 May 2023 19:47:16 +0200 Subject: [PATCH 05/23] 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 66dbfe514dd06c..bf4bf759d2f228 100644 --- a/docs/usage/configuration-options.md +++ b/docs/usage/configuration-options.md @@ -3251,9 +3251,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 8bbd60c4c5ff9918eb8c2e4d2d16b082d1adacc7 Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Sun, 7 May 2023 22:07:47 +0200 Subject: [PATCH 06/23] 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 3c164bf6ab0b6d1436e4b21835cd45920110545a Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Wed, 24 May 2023 08:07:00 +0200 Subject: [PATCH 07/23] 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 bf4bf759d2f228..10656ac14783ac 100644 --- a/docs/usage/configuration-options.md +++ b/docs/usage/configuration-options.md @@ -2279,11 +2279,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 851df24cfe72c3..8c6b5d3045da9a 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 d9f6967889dc0f788ff67e3f0b10e0197b4ccdcc Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Thu, 25 May 2023 17:46:28 +0200 Subject: [PATCH 08/23] feat!: merge matchPaths and matchFiles into matchFileNames (#22406) Co-authored-by: HonkingGoose <34918129+HonkingGoose@users.noreply.github.com> --- 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 | 15 +--- 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, 119 insertions(+), 171 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 10656ac14783ac..ebee850dd52918 100644 --- a/docs/usage/configuration-options.md +++ b/docs/usage/configuration-options.md @@ -1855,28 +1855,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 } ] @@ -2171,23 +2171,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 @@ -2247,38 +2274,6 @@ See also `excludePackagePrefixes`. Just 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 8c6b5d3045da9a..b1af37df71f2b7 100644 --- a/lib/config/options/index.ts +++ b/lib/config/options/index.ts @@ -1294,20 +1294,9 @@ const options: RenovateOptions[] = [ env: false, }, { - name: 'matchFiles', + name: 'matchFileNames', description: - 'List of strings to do an exact match against package files with full path. Only works inside a `packageRules` object.', - type: 'array', - subType: 'string', - stage: 'repository', - parent: 'packageRules', - cli: false, - env: false, - }, - { - name: 'matchPaths', - description: - 'List of glob patterns to match against package files. Only works inside a `packageRules` object.', + 'List of glob patterns to match against package or lock files (with full repo path). Only works inside a `packageRules` object.', type: 'array', subType: 'string', stage: 'repository', 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 4af1aefdcaa7cb..1ef8851dc17914 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 = fileName; 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 3bc72f6005b0bafbc4e3c5a419f7041061f203da Mon Sep 17 00:00:00 2001 From: RahulGautamSingh Date: Fri, 9 Jun 2023 05:42:21 +0545 Subject: [PATCH 09/23] remove skipInstall from config/options --- lib/config/options/index.ts | 8 -------- 1 file changed, 8 deletions(-) diff --git a/lib/config/options/index.ts b/lib/config/options/index.ts index b1af37df71f2b7..81bd692cfcaed2 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.', From c0efe7305f5292f66bd7831b21407be542f3e4bc Mon Sep 17 00:00:00 2001 From: RahulGautamSingh Date: Fri, 9 Jun 2023 05:39:44 +0545 Subject: [PATCH 10/23] remove skipInstall config option --- docs/usage/self-hosted-configuration.md | 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 ++--- 5 files changed, 14 insertions(+), 25 deletions(-) diff --git a/docs/usage/self-hosted-configuration.md b/docs/usage/self-hosted-configuration.md index 5ec088cc99c488..a1c5d56a45bde6 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 { @@ -796,12 +796,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/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 6013a242400032..4adc83fbc6faa7 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 1ef8851dc17914..53ad30a9b6c4b0 100644 --- a/lib/modules/manager/npm/extract/index.ts +++ b/lib/modules/manager/npm/extract/index.ts @@ -467,19 +467,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; From 6a8c7ad0720a4fe4f99313949b7a25457fa763d3 Mon Sep 17 00:00:00 2001 From: RahulGautamSingh Date: Fri, 9 Jun 2023 08:05:50 +0545 Subject: [PATCH 11/23] fix tests --- .../repository/extract/extract-fingerprint-config.spec.ts | 4 ---- 1 file changed, 4 deletions(-) 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 1169d19a33a50e5cc89c5fc9ff910ecfd24a1bef Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Wed, 5 Apr 2023 06:44:55 +0200 Subject: [PATCH 12/23] 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 13/23] 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 14/23] 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 15/23] 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 16/23] 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 17/23] 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 18/23] 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 1351666dcaa6b26c1728e8181cc3eea72ce394d6 Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Thu, 25 May 2023 17:46:28 +0200 Subject: [PATCH 19/23] feat!: merge matchPaths and matchFiles into matchFileNames (#22406) Co-authored-by: HonkingGoose <34918129+HonkingGoose@users.noreply.github.com> --- 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/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 +- 22 files changed, 117 insertions(+), 158 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/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 6f83ca3ebce5ef5d432a483f99831d245e669caa Mon Sep 17 00:00:00 2001 From: RahulGautamSingh Date: Mon, 12 Jun 2023 18:50:44 +0545 Subject: [PATCH 20/23] Update lib/config/options/index.ts --- lib/config/options/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/config/options/index.ts b/lib/config/options/index.ts index fc6ba85d045b02..b4fc079f25c7e6 100644 --- a/lib/config/options/index.ts +++ b/lib/config/options/index.ts @@ -1286,7 +1286,7 @@ const options: RenovateOptions[] = [ env: false, }, { - name: 'matchFileNames', + name: 'matchFiles', 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', From b28f7a93d7bb6c690394c96d8af50e0561739214 Mon Sep 17 00:00:00 2001 From: RahulGautamSingh Date: Mon, 12 Jun 2023 18:51:54 +0545 Subject: [PATCH 21/23] Update docs/usage/configuration-options.md --- docs/usage/configuration-options.md | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/docs/usage/configuration-options.md b/docs/usage/configuration-options.md index de10a2d2312913..acd6a58f18dc4a 100644 --- a/docs/usage/configuration-options.md +++ b/docs/usage/configuration-options.md @@ -2210,20 +2210,6 @@ The following example matches any `package.json`, including files like `backend/ } ``` -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 From a33b3ecdac867fa3c47875775efdfcc929cbc772 Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Thu, 25 May 2023 17:46:28 +0200 Subject: [PATCH 22/23] 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 | 2 +- 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(+), 159 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..ad8973d41114fe 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', 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 107e2bcd6a361364c6d81b8f1911686123d0d243 Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Thu, 25 May 2023 17:46:28 +0200 Subject: [PATCH 23/23] 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, },