renovate 44.3.0 → 44.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,7 +2,7 @@
2
2
  import { require_punycode } from "./punycode.js";
3
3
  import { pkg } from "./expose.js";
4
4
  import { getEnv } from "./util/env.js";
5
- import { regEx } from "./util/regex.js";
5
+ import { regEx, regexEngineStatus } from "./util/regex.js";
6
6
  import { getConfigFileNames } from "./config/app-strings.js";
7
7
  import { GlobalConfig } from "./config/global.js";
8
8
  import { init, logger } from "./logger/index.js";
@@ -100,6 +100,8 @@ If you have specified global self-hosted configuration (https://docs.renovatebot
100
100
  program.action(async (files, opts) => {
101
101
  const strict = opts.strict ?? false;
102
102
  let filesValidated = 0;
103
+ if (regexEngineStatus.type === "unavailable") logger.warn({ err: regexEngineStatus.err }, "RE2 not usable, falling back to RegExp: regex validation may be inaccurate");
104
+ else if (regexEngineStatus.type === "ignored") logger.debug("RE2 ignored via RENOVATE_X_IGNORE_RE2: regex validation may be inaccurate");
103
105
  if (files.length) {
104
106
  let isGlobalConfig = true;
105
107
  if (opts.global === false) isGlobalConfig = false;
@@ -1 +1 @@
1
- {"version":3,"file":"config-validator.js","names":["getFileConfig"],"sources":["../lib/config-validator.ts"],"sourcesContent":["#!/usr/bin/env node\nimport 'source-map-support/register.js';\nimport './punycode.cjs';\n\nimport { styleText } from 'node:util';\nimport { isNonEmptyStringAndNotWhitespace } from '@sindresorhus/is';\nimport { Command, CommanderError } from 'commander';\nimport { dequal } from 'dequal';\nimport { diffLines } from 'diff';\nimport fs from 'fs-extra';\nimport { getConfigFileNames } from './config/app-strings.ts';\nimport { GlobalConfig } from './config/global.ts';\nimport { massageConfig } from './config/massage.ts';\nimport { migrateConfig } from './config/migration.ts';\nimport type { RenovateConfig } from './config/types.ts';\nimport { validateConfig } from './config/validation.ts';\nimport { pkg } from './expose.ts';\nimport { init, logger } from './logger/index.ts';\nimport { getEnv } from './util/env.ts';\nimport { add as addHostRule } from './util/host-rules.ts';\nimport { regEx } from './util/regex.ts';\nimport { getConfig as getFileConfig } from './workers/global/config/parse/file.ts';\nimport { parseConfigs } from './workers/global/config/parse/index.ts';\nimport { getParsedContent } from './workers/global/config/parse/util.ts';\n\nawait init();\n\nconst { pathExists, readFile } = fs;\n\nlet returnVal = 0;\n\n/**\n * Make sure that we've resolved configuration from the different places that Renovate users would expect them to be specified\n *\n * This then allows a `configType=repo` config to i.e. be validated alongside a `config.js` or `env RENOVATE_ALLOWED_COMMANDS=...`\n *\n * Note that we intentionally don't fully initialize Renovate and its modules, as we're not fully running, and it would require a Platform to be configured\n * */\nasync function partiallyGlobalInitialize(): Promise<void> {\n // NOTE that this doesn't allow command-line arguments\n const globalConfig = await parseConfigs(getEnv(), []);\n GlobalConfig.set(globalConfig);\n\n if (globalConfig.hostRules) {\n for (const hostRule of globalConfig.hostRules) {\n addHostRule(hostRule);\n }\n }\n}\n\nasync function validate(\n configType: 'global' | 'repo',\n desc: string,\n config: RenovateConfig,\n strict: boolean,\n isPreset = false,\n): Promise<void> {\n if (config.hostRules) {\n for (const hostRule of config.hostRules) {\n addHostRule(hostRule);\n }\n }\n const { isMigrated, migratedConfig } = migrateConfig(config);\n if (isMigrated) {\n logger.warn(\n {\n oldConfig: config,\n newConfig: migratedConfig,\n },\n 'Config migration necessary',\n );\n const changedObjects = diffLines(\n JSON.stringify(config, null, 2),\n JSON.stringify(migratedConfig, null, 2),\n { ignoreWhitespace: false, newlineIsToken: false },\n );\n const added = styleText('green', '+ ');\n const removed = styleText('red', '- ');\n const msg = changedObjects\n .flatMap((part) => {\n let linePrefix: string;\n if (part.added) {\n linePrefix = added;\n } else if (part.removed) {\n linePrefix = removed;\n } else {\n linePrefix = ' ';\n }\n return part.value\n .split('\\n')\n .filter(isNonEmptyStringAndNotWhitespace)\n .map((line) =>\n line.replace(regEx(/^(?<ws> *)/), `${linePrefix}$<ws>`),\n );\n })\n .join('\\n');\n // oxlint-disable-next-line renovate/logger-static-message -- the multi-line, colorized diff must be interpolated to stay readable; as a metadata field it is JSON-escaped onto one line\n logger.warn(`Config migration diff:\\n${msg}`);\n if (strict) {\n returnVal = 1;\n }\n }\n const massagedConfig = massageConfig(migratedConfig);\n const res = await validateConfig(configType, massagedConfig, isPreset);\n if (res.errors.length) {\n logger.error(\n { file: desc, errors: res.errors },\n 'Found errors in configuration',\n );\n returnVal = 1;\n }\n if (res.warnings.length) {\n logger.warn(\n { file: desc, warnings: res.warnings },\n 'Found errors in configuration',\n );\n returnVal = 1;\n }\n}\n\ninterface PackageJson {\n renovate?: RenovateConfig;\n 'renovate-config'?: Record<string, RenovateConfig>;\n}\n\n(async () => {\n await partiallyGlobalInitialize();\n\n const program = new Command('renovate-config-validator')\n .summary('Validate Renovate configuration files')\n .description(\n `Validate your Renovate configuration (repo config, shared presets or global configuration) files\\n` +\n // oxlint-disable-next-line renovate/no-hardcoded-docs-url -- CLI help text, no config available\n 'If no [config-files...] are given, renovate-config-validator will look at the default config file locations (https://docs.renovatebot.com/configuration-options/)',\n )\n .addHelpText(\n 'after',\n // oxlint-disable-next-line renovate/no-hardcoded-docs-url -- CLI help text, no config available\n `\nWhen specifying [config-files...], Renovate will treat them as global self-hosted configuration files. You can disable this behaviour with --no-global\n\nExamples:\n\n $ renovate-config-validator\n $ renovate-config-validator --strict\n $ renovate-config-validator first_config.json\n $ renovate-config-validator --strict config.js\n $ renovate-config-validator --no-global renovate.json5\n $ env RENOVATE_CONFIG_FILE=obscure-name.json renovate-config-validator\n\nGlobal configuration:\n\nIf you have specified global self-hosted configuration (https://docs.renovatebot.com/self-hosted-configuration/) in environment variables or in a \\`config.js\\`, this will be detected:\n\n $ env RENOVATE_ALLOWED_ENV='[\"GO*\"]' renovate-config-validator\n # if passing the filename, make sure it's not validating as a global config\n $ env RENOVATE_ALLOWED_ENV='[\"GO*\"]' renovate-config-validator --no-global renovate.json`,\n )\n .argument('[config-files...]')\n .version(pkg.version, '-v, --version')\n .option(\n '--strict',\n 'Fail command if any configuration warnings, errors, or a migration is needed',\n )\n .option(\n '--no-global',\n 'When specifying [config-files], do not treat them as global self-hosted configuration file(s)',\n true,\n )\n // allow us to manage the exit code\n .exitOverride();\n\n program.action(async (files, opts) => {\n const strict = opts.strict ?? false;\n let filesValidated = 0;\n\n if (files.length) {\n let isGlobalConfig = true;\n if (opts.global === false) {\n isGlobalConfig = false;\n }\n const configType = isGlobalConfig ? 'global' : 'repo';\n for (const file of files) {\n try {\n if (!(await pathExists(file))) {\n returnVal = 1;\n logger.error({ file }, 'File does not exist');\n break;\n }\n const parsedContent = await getParsedContent(file);\n try {\n logger.info(`Validating ${file} as ${configType} config`);\n await validate(configType, file, parsedContent, strict);\n } catch (err) {\n logger.warn({ file, err }, 'File is not valid Renovate config');\n returnVal = 1;\n }\n } catch (err) {\n logger.warn({ file, err }, 'File could not be parsed');\n returnVal = 1;\n }\n\n filesValidated++;\n }\n } else {\n for (const file of getConfigFileNames().filter(\n (name) => name !== 'package.json',\n )) {\n try {\n if (!(await pathExists(file))) {\n continue;\n }\n const parsedContent = await getParsedContent(file);\n try {\n logger.info(`Validating ${file}`);\n await validate('repo', file, parsedContent, strict);\n } catch (err) {\n logger.warn({ file, err }, 'File is not valid Renovate config');\n returnVal = 1;\n }\n } catch (err) {\n logger.warn({ file, err }, 'File could not be parsed');\n returnVal = 1;\n }\n\n filesValidated++;\n }\n try {\n const pkgJson = JSON.parse(\n await readFile('package.json', 'utf8'),\n ) as PackageJson;\n if (pkgJson.renovate) {\n logger.info(`Validating package.json > renovate`);\n await validate(\n 'repo',\n 'package.json > renovate',\n pkgJson.renovate,\n strict,\n );\n\n filesValidated++;\n }\n if (pkgJson['renovate-config']) {\n logger.info(`Validating package.json > renovate-config`);\n for (const presetConfig of Object.values(\n pkgJson['renovate-config'],\n )) {\n await validate(\n 'repo',\n 'package.json > renovate-config',\n presetConfig,\n strict,\n true,\n );\n\n filesValidated++;\n }\n }\n } catch {\n // ignore\n }\n try {\n const env = getEnv();\n const fileConfig = await getFileConfig(env);\n if (!dequal(fileConfig, {})) {\n const file = env.RENOVATE_CONFIG_FILE ?? 'config.js';\n logger.info(`Validating ${file}`);\n try {\n await validate('global', file, fileConfig, strict);\n } catch (err) {\n logger.error({ file, err }, 'File is not valid Renovate config');\n returnVal = 1;\n }\n filesValidated++;\n }\n } catch {\n // ignore\n }\n }\n if (returnVal === 0 && filesValidated) {\n logger.info(\n `Config validated successfully against ${filesValidated} file(s)`,\n );\n } else if (!filesValidated) {\n logger.warn(`No files to perform configuration validation against`);\n }\n // Use exitCode (not process.exit) so async log streams can flush\n process.exitCode = returnVal;\n });\n\n await program.parseAsync();\n})().catch((e) => {\n // Commander throws an error at the end of Action execution i.e. as part of the `help` and `version` commands, and so we don't want to return an error code in this case\n if (\n e instanceof CommanderError &&\n (e.code === 'commander.helpDisplayed' || e.code === 'commander.version')\n ) {\n return;\n }\n\n // oxlint-disable-next-line no-console -- intentional: display critical error on CLI\n console.error(e);\n process.exit(99);\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"config-validator.js","names":["getFileConfig"],"sources":["../lib/config-validator.ts"],"sourcesContent":["#!/usr/bin/env node\nimport 'source-map-support/register.js';\nimport './punycode.cjs';\n\nimport { styleText } from 'node:util';\nimport { isNonEmptyStringAndNotWhitespace } from '@sindresorhus/is';\nimport { Command, CommanderError } from 'commander';\nimport { dequal } from 'dequal';\nimport { diffLines } from 'diff';\nimport fs from 'fs-extra';\nimport { getConfigFileNames } from './config/app-strings.ts';\nimport { GlobalConfig } from './config/global.ts';\nimport { massageConfig } from './config/massage.ts';\nimport { migrateConfig } from './config/migration.ts';\nimport type { RenovateConfig } from './config/types.ts';\nimport { validateConfig } from './config/validation.ts';\nimport { pkg } from './expose.ts';\nimport { init, logger } from './logger/index.ts';\nimport { getEnv } from './util/env.ts';\nimport { add as addHostRule } from './util/host-rules.ts';\nimport { regEx, regexEngineStatus } from './util/regex.ts';\nimport { getConfig as getFileConfig } from './workers/global/config/parse/file.ts';\nimport { parseConfigs } from './workers/global/config/parse/index.ts';\nimport { getParsedContent } from './workers/global/config/parse/util.ts';\n\nawait init();\n\nconst { pathExists, readFile } = fs;\n\nlet returnVal = 0;\n\n/**\n * Make sure that we've resolved configuration from the different places that Renovate users would expect them to be specified\n *\n * This then allows a `configType=repo` config to i.e. be validated alongside a `config.js` or `env RENOVATE_ALLOWED_COMMANDS=...`\n *\n * Note that we intentionally don't fully initialize Renovate and its modules, as we're not fully running, and it would require a Platform to be configured\n * */\nasync function partiallyGlobalInitialize(): Promise<void> {\n // NOTE that this doesn't allow command-line arguments\n const globalConfig = await parseConfigs(getEnv(), []);\n GlobalConfig.set(globalConfig);\n\n if (globalConfig.hostRules) {\n for (const hostRule of globalConfig.hostRules) {\n addHostRule(hostRule);\n }\n }\n}\n\nasync function validate(\n configType: 'global' | 'repo',\n desc: string,\n config: RenovateConfig,\n strict: boolean,\n isPreset = false,\n): Promise<void> {\n if (config.hostRules) {\n for (const hostRule of config.hostRules) {\n addHostRule(hostRule);\n }\n }\n const { isMigrated, migratedConfig } = migrateConfig(config);\n if (isMigrated) {\n logger.warn(\n {\n oldConfig: config,\n newConfig: migratedConfig,\n },\n 'Config migration necessary',\n );\n const changedObjects = diffLines(\n JSON.stringify(config, null, 2),\n JSON.stringify(migratedConfig, null, 2),\n { ignoreWhitespace: false, newlineIsToken: false },\n );\n const added = styleText('green', '+ ');\n const removed = styleText('red', '- ');\n const msg = changedObjects\n .flatMap((part) => {\n let linePrefix: string;\n if (part.added) {\n linePrefix = added;\n } else if (part.removed) {\n linePrefix = removed;\n } else {\n linePrefix = ' ';\n }\n return part.value\n .split('\\n')\n .filter(isNonEmptyStringAndNotWhitespace)\n .map((line) =>\n line.replace(regEx(/^(?<ws> *)/), `${linePrefix}$<ws>`),\n );\n })\n .join('\\n');\n // oxlint-disable-next-line renovate/logger-static-message -- the multi-line, colorized diff must be interpolated to stay readable; as a metadata field it is JSON-escaped onto one line\n logger.warn(`Config migration diff:\\n${msg}`);\n if (strict) {\n returnVal = 1;\n }\n }\n const massagedConfig = massageConfig(migratedConfig);\n const res = await validateConfig(configType, massagedConfig, isPreset);\n if (res.errors.length) {\n logger.error(\n { file: desc, errors: res.errors },\n 'Found errors in configuration',\n );\n returnVal = 1;\n }\n if (res.warnings.length) {\n logger.warn(\n { file: desc, warnings: res.warnings },\n 'Found errors in configuration',\n );\n returnVal = 1;\n }\n}\n\ninterface PackageJson {\n renovate?: RenovateConfig;\n 'renovate-config'?: Record<string, RenovateConfig>;\n}\n\n(async () => {\n await partiallyGlobalInitialize();\n\n const program = new Command('renovate-config-validator')\n .summary('Validate Renovate configuration files')\n .description(\n `Validate your Renovate configuration (repo config, shared presets or global configuration) files\\n` +\n // oxlint-disable-next-line renovate/no-hardcoded-docs-url -- CLI help text, no config available\n 'If no [config-files...] are given, renovate-config-validator will look at the default config file locations (https://docs.renovatebot.com/configuration-options/)',\n )\n .addHelpText(\n 'after',\n // oxlint-disable-next-line renovate/no-hardcoded-docs-url -- CLI help text, no config available\n `\nWhen specifying [config-files...], Renovate will treat them as global self-hosted configuration files. You can disable this behaviour with --no-global\n\nExamples:\n\n $ renovate-config-validator\n $ renovate-config-validator --strict\n $ renovate-config-validator first_config.json\n $ renovate-config-validator --strict config.js\n $ renovate-config-validator --no-global renovate.json5\n $ env RENOVATE_CONFIG_FILE=obscure-name.json renovate-config-validator\n\nGlobal configuration:\n\nIf you have specified global self-hosted configuration (https://docs.renovatebot.com/self-hosted-configuration/) in environment variables or in a \\`config.js\\`, this will be detected:\n\n $ env RENOVATE_ALLOWED_ENV='[\"GO*\"]' renovate-config-validator\n # if passing the filename, make sure it's not validating as a global config\n $ env RENOVATE_ALLOWED_ENV='[\"GO*\"]' renovate-config-validator --no-global renovate.json`,\n )\n .argument('[config-files...]')\n .version(pkg.version, '-v, --version')\n .option(\n '--strict',\n 'Fail command if any configuration warnings, errors, or a migration is needed',\n )\n .option(\n '--no-global',\n 'When specifying [config-files], do not treat them as global self-hosted configuration file(s)',\n true,\n )\n // allow us to manage the exit code\n .exitOverride();\n\n program.action(async (files, opts) => {\n const strict = opts.strict ?? false;\n let filesValidated = 0;\n\n // without RE2, patterns are checked by RegExp, which accepts syntax RE2 rejects (e.g. lookahead)\n if (regexEngineStatus.type === 'unavailable') {\n logger.warn(\n { err: regexEngineStatus.err },\n 'RE2 not usable, falling back to RegExp: regex validation may be inaccurate',\n );\n } else if (regexEngineStatus.type === 'ignored') {\n logger.debug(\n 'RE2 ignored via RENOVATE_X_IGNORE_RE2: regex validation may be inaccurate',\n );\n }\n\n if (files.length) {\n let isGlobalConfig = true;\n if (opts.global === false) {\n isGlobalConfig = false;\n }\n const configType = isGlobalConfig ? 'global' : 'repo';\n for (const file of files) {\n try {\n if (!(await pathExists(file))) {\n returnVal = 1;\n logger.error({ file }, 'File does not exist');\n break;\n }\n const parsedContent = await getParsedContent(file);\n try {\n logger.info(`Validating ${file} as ${configType} config`);\n await validate(configType, file, parsedContent, strict);\n } catch (err) {\n logger.warn({ file, err }, 'File is not valid Renovate config');\n returnVal = 1;\n }\n } catch (err) {\n logger.warn({ file, err }, 'File could not be parsed');\n returnVal = 1;\n }\n\n filesValidated++;\n }\n } else {\n for (const file of getConfigFileNames().filter(\n (name) => name !== 'package.json',\n )) {\n try {\n if (!(await pathExists(file))) {\n continue;\n }\n const parsedContent = await getParsedContent(file);\n try {\n logger.info(`Validating ${file}`);\n await validate('repo', file, parsedContent, strict);\n } catch (err) {\n logger.warn({ file, err }, 'File is not valid Renovate config');\n returnVal = 1;\n }\n } catch (err) {\n logger.warn({ file, err }, 'File could not be parsed');\n returnVal = 1;\n }\n\n filesValidated++;\n }\n try {\n const pkgJson = JSON.parse(\n await readFile('package.json', 'utf8'),\n ) as PackageJson;\n if (pkgJson.renovate) {\n logger.info(`Validating package.json > renovate`);\n await validate(\n 'repo',\n 'package.json > renovate',\n pkgJson.renovate,\n strict,\n );\n\n filesValidated++;\n }\n if (pkgJson['renovate-config']) {\n logger.info(`Validating package.json > renovate-config`);\n for (const presetConfig of Object.values(\n pkgJson['renovate-config'],\n )) {\n await validate(\n 'repo',\n 'package.json > renovate-config',\n presetConfig,\n strict,\n true,\n );\n\n filesValidated++;\n }\n }\n } catch {\n // ignore\n }\n try {\n const env = getEnv();\n const fileConfig = await getFileConfig(env);\n if (!dequal(fileConfig, {})) {\n const file = env.RENOVATE_CONFIG_FILE ?? 'config.js';\n logger.info(`Validating ${file}`);\n try {\n await validate('global', file, fileConfig, strict);\n } catch (err) {\n logger.error({ file, err }, 'File is not valid Renovate config');\n returnVal = 1;\n }\n filesValidated++;\n }\n } catch {\n // ignore\n }\n }\n if (returnVal === 0 && filesValidated) {\n logger.info(\n `Config validated successfully against ${filesValidated} file(s)`,\n );\n } else if (!filesValidated) {\n logger.warn(`No files to perform configuration validation against`);\n }\n // Use exitCode (not process.exit) so async log streams can flush\n process.exitCode = returnVal;\n });\n\n await program.parseAsync();\n})().catch((e) => {\n // Commander throws an error at the end of Action execution i.e. as part of the `help` and `version` commands, and so we don't want to return an error code in this case\n if (\n e instanceof CommanderError &&\n (e.code === 'commander.helpDisplayed' || e.code === 'commander.version')\n ) {\n return;\n }\n\n // oxlint-disable-next-line no-console -- intentional: display critical error on CLI\n console.error(e);\n process.exit(99);\n});\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"filter-checks.js","names":[],"sources":["../../../../../lib/workers/repository/process/lookup/filter-checks.ts"],"sourcesContent":["import { mergeChildConfig } from '../../../../config/index.ts';\nimport type {\n MinimumReleaseAgeBehaviour,\n UpdateType,\n} from '../../../../config/types.ts';\nimport { logger } from '../../../../logger/index.ts';\nimport type { Release } from '../../../../modules/datasource/index.ts';\nimport { postprocessRelease } from '../../../../modules/datasource/postprocess-release.ts';\nimport type { VersioningApi } from '../../../../modules/versioning/index.ts';\nimport {\n getMergeConfidenceLevel,\n isActiveConfidenceLevel,\n satisfiesConfidenceLevel,\n} from '../../../../util/merge-confidence/index.ts';\nimport type { MergeConfidence } from '../../../../util/merge-confidence/types.ts';\nimport { checkMinimumReleaseAge } from '../../../../util/minimum-release-age.ts';\nimport { applyPackageRules } from '../../../../util/package-rules/index.ts';\nimport type { LookupUpdateConfig, UpdateResult } from './types.ts';\nimport { getUpdateType } from './update-type.ts';\n\nexport interface InternalChecksResult {\n release?: Release;\n pendingChecks: boolean;\n pendingReleases: Release[];\n}\n\n/** Given an UpdateType, should `minimumReleaseAge` apply to it? **/\nexport function isMinimumReleaseAgeApplicable(\n updateType: UpdateType | undefined,\n): boolean {\n return (\n // Possible, but not wanted, as this is intentionally rolling back to a previous (generally older) release to unblock the build\n updateType !== 'rollback' &&\n // Not yet supported: TODO #40288\n updateType !== 'pin' &&\n // Not yet supported: TODO #44820\n updateType !== 'pinDigest' &&\n // Not yet supported: TODO #39400\n updateType !== 'replacement' &&\n // Not possible, as we delegate to the package manager to perform the required changes to update package(s).\n updateType !== 'lockFileMaintenance' &&\n // Not supported\n updateType !== 'bump' &&\n // Not supported\n updateType !== 'lockfileUpdate'\n );\n}\n\n/** Given an UpdateType, should `minimumConfidence` apply to it? **/\nexport function isMinimumConfidenceApplicable(\n updateType: UpdateType | undefined,\n): boolean {\n return (\n // data collection doesn't include digest updates\n updateType !== 'digest' &&\n // data collection doesn't include digest updates\n updateType !== 'pinDigest'\n );\n}\n\nexport interface MinimumConfidenceCheckResult {\n isPending: boolean;\n}\n\n/**\n * Checks whether a release satisfies `minimumConfidence`.\n *\n * Separate from `internalChecksFilter` to allow reuse.\n */\nexport async function checkMinimumConfidence(\n config: {\n minimumConfidence?: MergeConfidence;\n datasource?: string;\n packageName?: string;\n },\n currentVersion: string,\n candidateVersion: string,\n updateType: UpdateType,\n): Promise<MinimumConfidenceCheckResult> {\n const { minimumConfidence, datasource, packageName } = config;\n if (!isActiveConfidenceLevel(minimumConfidence!)) {\n return { isPending: false };\n }\n\n const confidenceLevel =\n (await getMergeConfidenceLevel(\n datasource!,\n packageName!,\n currentVersion,\n candidateVersion,\n updateType,\n )) ?? 'neutral';\n return {\n isPending: !satisfiesConfidenceLevel(confidenceLevel, minimumConfidence!),\n };\n}\n\nexport async function filterInternalChecks(\n config: Partial<LookupUpdateConfig & UpdateResult>,\n versioningApi: VersioningApi,\n bucket: string,\n sortedReleases: Release[],\n): Promise<InternalChecksResult> {\n const { currentVersion, depName, internalChecksFilter } = config;\n let release: Release | undefined = undefined;\n let pendingChecks = false;\n let pendingReleases: Release[] = [];\n if (internalChecksFilter === 'none') {\n // Don't care if minimumReleaseAge or minimumConfidence are unmet\n release = sortedReleases.pop();\n } else {\n const candidateVersionsWithoutReleaseTimestamp: Record<\n MinimumReleaseAgeBehaviour,\n string[]\n > = {\n 'timestamp-required': [],\n 'timestamp-optional': [],\n };\n\n // iterate through releases from highest to lowest, looking for the first which will pass checks if present\n for (let candidateRelease of sortedReleases.reverse()) {\n // merge the release data into dependency config\n let releaseConfig = mergeChildConfig(config, candidateRelease);\n // calculate updateType and then apply it\n releaseConfig.updateType = getUpdateType(\n releaseConfig,\n versioningApi,\n // TODO #22198\n currentVersion!,\n candidateRelease.version,\n );\n releaseConfig = mergeChildConfig(\n releaseConfig,\n releaseConfig[releaseConfig.updateType]!,\n );\n // Apply packageRules in case any apply to updateType\n releaseConfig = await applyPackageRules(releaseConfig, 'update-type');\n\n const updatedCandidateRelease = await postprocessRelease(\n releaseConfig,\n candidateRelease,\n );\n if (!updatedCandidateRelease) {\n continue;\n }\n candidateRelease = updatedCandidateRelease;\n\n // Now check for a minimumReleaseAge config\n const { updateType } = releaseConfig;\n\n const ageCheck = checkMinimumReleaseAge(\n releaseConfig,\n candidateRelease.releaseTimestamp,\n );\n if (ageCheck.minimumReleaseAgeMs) {\n if (!ageCheck.hasTimestamp) {\n const minimumReleaseAgeBehaviour =\n releaseConfig.minimumReleaseAgeBehaviour;\n // v8 ignore else -- TODO: add test #40625\n if (\n minimumReleaseAgeBehaviour === 'timestamp-required' ||\n minimumReleaseAgeBehaviour === 'timestamp-optional'\n ) {\n candidateVersionsWithoutReleaseTimestamp[\n minimumReleaseAgeBehaviour\n ].push(candidateRelease.version);\n }\n }\n\n if (ageCheck.isPending) {\n // v8 ignore else -- TODO: add test #40625\n if (ageCheck.hasTimestamp) {\n // Skip it if it doesn't pass checks\n logger.trace(\n { depName, check: 'minimumReleaseAge' },\n `Release ${candidateRelease.version} is pending status checks`,\n );\n } // or if there is no timestamp, and we're running in `minimumReleaseAgeBehaviour=timestamp-required`, skip it as we require a timestamp\n pendingReleases.unshift(candidateRelease);\n continue;\n }\n }\n\n const confidenceCheck = await checkMinimumConfidence(\n releaseConfig,\n currentVersion!,\n candidateRelease.version,\n updateType!,\n );\n if (confidenceCheck.isPending) {\n logger.trace(\n { depName, check: 'minimumConfidence' },\n `Release ${candidateRelease.version} is pending status checks`,\n );\n pendingReleases.unshift(candidateRelease);\n continue;\n }\n // If we get to here, then the release is OK and we can stop iterating\n release = candidateRelease;\n break;\n }\n\n if (candidateVersionsWithoutReleaseTimestamp['timestamp-required'].length) {\n logger.once.debug(\n {\n depName,\n versions:\n candidateVersionsWithoutReleaseTimestamp['timestamp-required'],\n check: 'minimumReleaseAge',\n },\n `Marking ${candidateVersionsWithoutReleaseTimestamp['timestamp-required'].length} release(s) as pending, as they do not have a releaseTimestamp and we're running with minimumReleaseAgeBehaviour=timestamp-required`,\n );\n }\n\n if (candidateVersionsWithoutReleaseTimestamp['timestamp-optional'].length) {\n logger.once.warn(\n \"Some release(s) did not have a releaseTimestamp, but as we're running with minimumReleaseAgeBehaviour=timestamp-optional, proceeding. See debug logs for more information\",\n );\n logger.once.debug(\n {\n depName,\n versions:\n candidateVersionsWithoutReleaseTimestamp['timestamp-optional'],\n check: 'minimumReleaseAge',\n },\n `${candidateVersionsWithoutReleaseTimestamp['timestamp-optional'].length} release(s) did not have a releaseTimestamp, but as we're running with minimumReleaseAgeBehaviour=timestamp-optional, proceeding`,\n );\n }\n\n // v8 ignore else -- TODO: add test #40625\n if (!release && pendingReleases.length) {\n // If all releases were pending then just take the highest\n logger.trace(\n { depName, bucket },\n 'All releases are pending - using latest',\n );\n release = pendingReleases.pop();\n // None are pending anymore because we took the latest, so empty the array\n pendingReleases = [];\n if (internalChecksFilter === 'strict') {\n pendingChecks = true;\n }\n }\n }\n\n return { release, pendingChecks, pendingReleases };\n}\n"],"mappings":";;;;;;;;;;;;;;AAqEA,eAAsB,uBACpB,QAKA,gBACA,kBACA,YACuC;CACvC,MAAM,EAAE,mBAAmB,YAAY,gBAAgB;CACvD,IAAI,CAAC,wBAAwB,iBAAkB,GAC7C,OAAO,EAAE,WAAW,MAAM;CAW5B,OAAO,EACL,WAAW,CAAC,yBARX,MAAM,wBACL,YACA,aACA,gBACA,kBACA,UACF,KAAM,WAEgD,iBAAkB,EAC1E;AACF;AAEA,eAAsB,qBACpB,QACA,eACA,QACA,gBAC+B;CAC/B,MAAM,EAAE,gBAAgB,SAAS,yBAAyB;CAC1D,IAAI,UAA+B,KAAA;CACnC,IAAI,gBAAgB;CACpB,IAAI,kBAA6B,CAAC;CAClC,IAAI,yBAAyB,QAE3B,UAAU,eAAe,IAAI;MACxB;EACL,MAAM,2CAGF;GACF,sBAAsB,CAAC;GACvB,sBAAsB,CAAC;EACzB;EAGA,KAAK,IAAI,oBAAoB,eAAe,QAAQ,GAAG;GAErD,IAAI,gBAAgB,iBAAiB,QAAQ,gBAAgB;GAE7D,cAAc,aAAa,cACzB,eACA,eAEA,gBACA,iBAAiB,OACnB;GACA,gBAAgB,iBACd,eACA,cAAc,cAAc,WAC9B;GAEA,gBAAgB,MAAM,kBAAkB,eAAe,aAAa;GAEpE,MAAM,0BAA0B,MAAM,mBACpC,eACA,gBACF;GACA,IAAI,CAAC,yBACH;GAEF,mBAAmB;GAGnB,MAAM,EAAE,eAAe;GAEvB,MAAM,WAAW,uBACf,eACA,iBAAiB,gBACnB;GACA,IAAI,SAAS,qBAAqB;IAChC,IAAI,CAAC,SAAS,cAAc;KAC1B,MAAM,6BACJ,cAAc;;KAEhB,IACE,+BAA+B,wBAC/B,+BAA+B,sBAE/B,yCACE,2BACD,CAAC,KAAK,iBAAiB,OAAO;IAEnC;IAEA,IAAI,SAAS,WAAW;;KAEtB,IAAI,SAAS,cAEX,OAAO,MACL;MAAE;MAAS,OAAO;KAAoB,GACtC,WAAW,iBAAiB,QAAQ,0BACtC;KAEF,gBAAgB,QAAQ,gBAAgB;KACxC;IACF;GACF;GAQA,KAAI,MAN0B,uBAC5B,eACA,gBACA,iBAAiB,SACjB,UACF,EAAA,CACoB,WAAW;IAC7B,OAAO,MACL;KAAE;KAAS,OAAO;IAAoB,GACtC,WAAW,iBAAiB,QAAQ,0BACtC;IACA,gBAAgB,QAAQ,gBAAgB;IACxC;GACF;GAEA,UAAU;GACV;EACF;EAEA,IAAI,yCAAyC,qBAAqB,CAAC,QACjE,OAAO,KAAK,MACV;GACE;GACA,UACE,yCAAyC;GAC3C,OAAO;EACT,GACA,WAAW,yCAAyC,qBAAqB,CAAC,OAAO,oIACnF;EAGF,IAAI,yCAAyC,qBAAqB,CAAC,QAAQ;GACzE,OAAO,KAAK,KACV,2KACF;GACA,OAAO,KAAK,MACV;IACE;IACA,UACE,yCAAyC;IAC3C,OAAO;GACT,GACA,GAAG,yCAAyC,qBAAqB,CAAC,OAAO,iIAC3E;EACF;;EAGA,IAAI,CAAC,WAAW,gBAAgB,QAAQ;GAEtC,OAAO,MACL;IAAE;IAAS;GAAO,GAClB,yCACF;GACA,UAAU,gBAAgB,IAAI;GAE9B,kBAAkB,CAAC;GACnB,IAAI,yBAAyB,UAC3B,gBAAgB;EAEpB;CACF;CAEA,OAAO;EAAE;EAAS;EAAe;CAAgB;AACnD"}
1
+ {"version":3,"file":"filter-checks.js","names":[],"sources":["../../../../../lib/workers/repository/process/lookup/filter-checks.ts"],"sourcesContent":["import { mergeChildConfig } from '../../../../config/index.ts';\nimport type {\n MinimumReleaseAgeBehaviour,\n UpdateType,\n} from '../../../../config/types.ts';\nimport { logger } from '../../../../logger/index.ts';\nimport type { Release } from '../../../../modules/datasource/index.ts';\nimport { postprocessRelease } from '../../../../modules/datasource/postprocess-release.ts';\nimport type { VersioningApi } from '../../../../modules/versioning/index.ts';\nimport {\n getMergeConfidenceLevel,\n isActiveConfidenceLevel,\n satisfiesConfidenceLevel,\n} from '../../../../util/merge-confidence/index.ts';\nimport type { MergeConfidence } from '../../../../util/merge-confidence/types.ts';\nimport { checkMinimumReleaseAge } from '../../../../util/minimum-release-age.ts';\nimport { applyPackageRules } from '../../../../util/package-rules/index.ts';\nimport type { LookupUpdateConfig, UpdateResult } from './types.ts';\nimport { getUpdateType } from './update-type.ts';\n\nexport interface InternalChecksResult {\n release?: Release;\n pendingChecks: boolean;\n pendingReleases: Release[];\n}\n\n/** Given an UpdateType, should `minimumReleaseAge` apply to it? **/\nexport function isMinimumReleaseAgeApplicable(\n updateType: UpdateType | undefined,\n): boolean {\n return (\n // Possible, but not wanted, as this is intentionally rolling back to a previous (generally older) release to unblock the build\n updateType !== 'rollback' &&\n // Not yet supported: TODO #40288\n updateType !== 'pin' &&\n // Not yet supported: TODO #44820\n updateType !== 'pinDigest' &&\n // Not yet supported: TODO #39400\n updateType !== 'replacement' &&\n // Not possible, as we delegate to the package manager to perform the required changes to update package(s).\n updateType !== 'lockFileMaintenance' &&\n // Not supported\n updateType !== 'bump' &&\n // Not supported\n updateType !== 'lockfileUpdate'\n );\n}\n\n/** Given an UpdateType, should `minimumConfidence` apply to it? **/\nexport function isMinimumConfidenceApplicable(\n updateType: UpdateType | undefined,\n): boolean {\n return (\n // data collection doesn't include digest updates\n updateType !== 'digest' &&\n // data collection doesn't include digest updates\n updateType !== 'pinDigest'\n );\n}\n\nexport interface MinimumConfidenceCheckResult {\n isPending: boolean;\n}\n\n/**\n * Checks whether a release satisfies `minimumConfidence`.\n *\n * Separate from `internalChecksFilter` to allow reuse.\n */\nexport async function checkMinimumConfidence(\n config: {\n minimumConfidence?: MergeConfidence;\n datasource?: string;\n packageName?: string;\n },\n currentVersion: string,\n candidateVersion: string,\n updateType: UpdateType,\n): Promise<MinimumConfidenceCheckResult> {\n const { minimumConfidence, datasource, packageName } = config;\n if (!isActiveConfidenceLevel(minimumConfidence!)) {\n return { isPending: false };\n }\n\n const confidenceLevel =\n (await getMergeConfidenceLevel(\n datasource!,\n packageName!,\n currentVersion,\n candidateVersion,\n updateType,\n )) ?? 'neutral';\n return {\n isPending: !satisfiesConfidenceLevel(confidenceLevel, minimumConfidence!),\n };\n}\n\n/*\n * NOTE that this should be kept in sync with `applyMinimumReleaseAgeToDigestUpdate`()\n */\nexport async function filterInternalChecks(\n config: Partial<LookupUpdateConfig & UpdateResult>,\n versioningApi: VersioningApi,\n bucket: string,\n sortedReleases: Release[],\n): Promise<InternalChecksResult> {\n const { currentVersion, depName, internalChecksFilter } = config;\n let release: Release | undefined = undefined;\n let pendingChecks = false;\n let pendingReleases: Release[] = [];\n if (internalChecksFilter === 'none') {\n // Don't care if minimumReleaseAge or minimumConfidence are unmet\n release = sortedReleases.pop();\n } else {\n const candidateVersionsWithoutReleaseTimestamp: Record<\n MinimumReleaseAgeBehaviour,\n string[]\n > = {\n 'timestamp-required': [],\n 'timestamp-optional': [],\n };\n\n // iterate through releases from highest to lowest, looking for the first which will pass checks if present\n for (let candidateRelease of sortedReleases.reverse()) {\n // merge the release data into dependency config\n let releaseConfig = mergeChildConfig(config, candidateRelease);\n // calculate updateType and then apply it\n releaseConfig.updateType = getUpdateType(\n releaseConfig,\n versioningApi,\n // TODO #22198\n currentVersion!,\n candidateRelease.version,\n );\n releaseConfig = mergeChildConfig(\n releaseConfig,\n releaseConfig[releaseConfig.updateType]!,\n );\n // Apply packageRules in case any apply to updateType\n releaseConfig = await applyPackageRules(releaseConfig, 'update-type');\n\n const updatedCandidateRelease = await postprocessRelease(\n releaseConfig,\n candidateRelease,\n );\n if (!updatedCandidateRelease) {\n continue;\n }\n candidateRelease = updatedCandidateRelease;\n\n // Now check for a minimumReleaseAge config\n const { updateType } = releaseConfig;\n\n const ageCheck = checkMinimumReleaseAge(\n releaseConfig,\n candidateRelease.releaseTimestamp,\n );\n if (ageCheck.minimumReleaseAgeMs) {\n if (!ageCheck.hasTimestamp) {\n const minimumReleaseAgeBehaviour =\n releaseConfig.minimumReleaseAgeBehaviour;\n // v8 ignore else -- TODO: add test #40625\n if (\n minimumReleaseAgeBehaviour === 'timestamp-required' ||\n minimumReleaseAgeBehaviour === 'timestamp-optional'\n ) {\n candidateVersionsWithoutReleaseTimestamp[\n minimumReleaseAgeBehaviour\n ].push(candidateRelease.version);\n }\n }\n\n if (ageCheck.isPending) {\n // v8 ignore else -- TODO: add test #40625\n if (ageCheck.hasTimestamp) {\n // Skip it if it doesn't pass checks\n logger.trace(\n { depName, check: 'minimumReleaseAge' },\n `Release ${candidateRelease.version} is pending status checks`,\n );\n } // or if there is no timestamp, and we're running in `minimumReleaseAgeBehaviour=timestamp-required`, skip it as we require a timestamp\n pendingReleases.unshift(candidateRelease);\n continue;\n }\n }\n\n const confidenceCheck = await checkMinimumConfidence(\n releaseConfig,\n currentVersion!,\n candidateRelease.version,\n updateType!,\n );\n if (confidenceCheck.isPending) {\n logger.trace(\n { depName, check: 'minimumConfidence' },\n `Release ${candidateRelease.version} is pending status checks`,\n );\n pendingReleases.unshift(candidateRelease);\n continue;\n }\n // If we get to here, then the release is OK and we can stop iterating\n release = candidateRelease;\n break;\n }\n\n if (candidateVersionsWithoutReleaseTimestamp['timestamp-required'].length) {\n logger.once.debug(\n {\n depName,\n versions:\n candidateVersionsWithoutReleaseTimestamp['timestamp-required'],\n check: 'minimumReleaseAge',\n },\n `Marking ${candidateVersionsWithoutReleaseTimestamp['timestamp-required'].length} release(s) as pending, as they do not have a releaseTimestamp and we're running with minimumReleaseAgeBehaviour=timestamp-required`,\n );\n }\n\n if (candidateVersionsWithoutReleaseTimestamp['timestamp-optional'].length) {\n logger.once.warn(\n \"Some release(s) did not have a releaseTimestamp, but as we're running with minimumReleaseAgeBehaviour=timestamp-optional, proceeding. See debug logs for more information\",\n );\n logger.once.debug(\n {\n depName,\n versions:\n candidateVersionsWithoutReleaseTimestamp['timestamp-optional'],\n check: 'minimumReleaseAge',\n },\n `${candidateVersionsWithoutReleaseTimestamp['timestamp-optional'].length} release(s) did not have a releaseTimestamp, but as we're running with minimumReleaseAgeBehaviour=timestamp-optional, proceeding`,\n );\n }\n\n // v8 ignore else -- TODO: add test #40625\n if (!release && pendingReleases.length) {\n // If all releases were pending then just take the highest\n logger.trace(\n { depName, bucket },\n 'All releases are pending - using latest',\n );\n release = pendingReleases.pop();\n // None are pending anymore because we took the latest, so empty the array\n pendingReleases = [];\n if (internalChecksFilter === 'strict') {\n pendingChecks = true;\n }\n }\n }\n\n return { release, pendingChecks, pendingReleases };\n}\n"],"mappings":";;;;;;;;;;;;;;AAqEA,eAAsB,uBACpB,QAKA,gBACA,kBACA,YACuC;CACvC,MAAM,EAAE,mBAAmB,YAAY,gBAAgB;CACvD,IAAI,CAAC,wBAAwB,iBAAkB,GAC7C,OAAO,EAAE,WAAW,MAAM;CAW5B,OAAO,EACL,WAAW,CAAC,yBARX,MAAM,wBACL,YACA,aACA,gBACA,kBACA,UACF,KAAM,WAEgD,iBAAkB,EAC1E;AACF;AAKA,eAAsB,qBACpB,QACA,eACA,QACA,gBAC+B;CAC/B,MAAM,EAAE,gBAAgB,SAAS,yBAAyB;CAC1D,IAAI,UAA+B,KAAA;CACnC,IAAI,gBAAgB;CACpB,IAAI,kBAA6B,CAAC;CAClC,IAAI,yBAAyB,QAE3B,UAAU,eAAe,IAAI;MACxB;EACL,MAAM,2CAGF;GACF,sBAAsB,CAAC;GACvB,sBAAsB,CAAC;EACzB;EAGA,KAAK,IAAI,oBAAoB,eAAe,QAAQ,GAAG;GAErD,IAAI,gBAAgB,iBAAiB,QAAQ,gBAAgB;GAE7D,cAAc,aAAa,cACzB,eACA,eAEA,gBACA,iBAAiB,OACnB;GACA,gBAAgB,iBACd,eACA,cAAc,cAAc,WAC9B;GAEA,gBAAgB,MAAM,kBAAkB,eAAe,aAAa;GAEpE,MAAM,0BAA0B,MAAM,mBACpC,eACA,gBACF;GACA,IAAI,CAAC,yBACH;GAEF,mBAAmB;GAGnB,MAAM,EAAE,eAAe;GAEvB,MAAM,WAAW,uBACf,eACA,iBAAiB,gBACnB;GACA,IAAI,SAAS,qBAAqB;IAChC,IAAI,CAAC,SAAS,cAAc;KAC1B,MAAM,6BACJ,cAAc;;KAEhB,IACE,+BAA+B,wBAC/B,+BAA+B,sBAE/B,yCACE,2BACD,CAAC,KAAK,iBAAiB,OAAO;IAEnC;IAEA,IAAI,SAAS,WAAW;;KAEtB,IAAI,SAAS,cAEX,OAAO,MACL;MAAE;MAAS,OAAO;KAAoB,GACtC,WAAW,iBAAiB,QAAQ,0BACtC;KAEF,gBAAgB,QAAQ,gBAAgB;KACxC;IACF;GACF;GAQA,KAAI,MAN0B,uBAC5B,eACA,gBACA,iBAAiB,SACjB,UACF,EAAA,CACoB,WAAW;IAC7B,OAAO,MACL;KAAE;KAAS,OAAO;IAAoB,GACtC,WAAW,iBAAiB,QAAQ,0BACtC;IACA,gBAAgB,QAAQ,gBAAgB;IACxC;GACF;GAEA,UAAU;GACV;EACF;EAEA,IAAI,yCAAyC,qBAAqB,CAAC,QACjE,OAAO,KAAK,MACV;GACE;GACA,UACE,yCAAyC;GAC3C,OAAO;EACT,GACA,WAAW,yCAAyC,qBAAqB,CAAC,OAAO,oIACnF;EAGF,IAAI,yCAAyC,qBAAqB,CAAC,QAAQ;GACzE,OAAO,KAAK,KACV,2KACF;GACA,OAAO,KAAK,MACV;IACE;IACA,UACE,yCAAyC;IAC3C,OAAO;GACT,GACA,GAAG,yCAAyC,qBAAqB,CAAC,OAAO,iIAC3E;EACF;;EAGA,IAAI,CAAC,WAAW,gBAAgB,QAAQ;GAEtC,OAAO,MACL;IAAE;IAAS;GAAO,GAClB,yCACF;GACA,UAAU,gBAAgB,IAAI;GAE9B,kBAAkB,CAAC;GACnB,IAAI,yBAAyB,UAC3B,gBAAgB;EAEpB;CACF;CAEA,OAAO;EAAE;EAAS;EAAe;CAAgB;AACnD"}
@@ -14,6 +14,7 @@ import { getRangeStrategy } from "../../../../modules/manager/index.js";
14
14
  import "../../../../config/index.js";
15
15
  import { applyPackageRules } from "../../../../util/package-rules/index.js";
16
16
  import { postprocessRelease } from "../../../../modules/datasource/postprocess-release.js";
17
+ import { checkMinimumReleaseAge } from "../../../../util/minimum-release-age.js";
17
18
  import { calculateAbandonment } from "./abandonment.js";
18
19
  import { getBucket } from "./bucket.js";
19
20
  import { getCurrentVersion } from "./current.js";
@@ -31,6 +32,48 @@ async function getTimestamp(config, versions, version, versioningApi) {
31
32
  if (currentRelease.releaseTimestamp) return currentRelease.releaseTimestamp;
32
33
  return (await postprocessRelease(config, currentRelease))?.releaseTimestamp;
33
34
  }
35
+ /**
36
+ * A helper function to allow a short-circuit for `minimumReleaseAge` functionality if a package may have config that applies it.
37
+ *
38
+ * Allows avoiding unnecessary calls to more expensive checks like merge + `applyPackageRules()` and `getTimestamp()`.
39
+ */
40
+ function couldApplyMinimumReleaseAgeToDigest(config) {
41
+ if (config.internalChecksFilter === "none") return false;
42
+ return isNonEmptyString(config.minimumReleaseAge) || isNonEmptyString(config.digest?.minimumReleaseAge) || !!config.packageRules?.some((rule) => isNonEmptyString(rule.minimumReleaseAge));
43
+ }
44
+ /**
45
+ * Ensure `minimumReleaseAge`/`internalChecksFilter` applies to digest updates, as they don't currently get run through `filterInternalChecks()`.
46
+ *
47
+ * NOTE that this should be kept in sync with `filterInternalChecks`()
48
+ */
49
+ async function applyMinimumReleaseAgeToDigestUpdate(update, config, res, newestMatchingVersionTimestamp) {
50
+ if (!couldApplyMinimumReleaseAgeToDigest(config)) return;
51
+ let releaseConfig = {
52
+ ...mergeChildConfig(config, res),
53
+ updateType: update.updateType
54
+ };
55
+ releaseConfig = mergeChildConfig(releaseConfig, releaseConfig[update.updateType]);
56
+ releaseConfig = await applyPackageRules(releaseConfig, "update-type");
57
+ const ageCheck = checkMinimumReleaseAge(releaseConfig, newestMatchingVersionTimestamp);
58
+ if (ageCheck.minimumReleaseAgeMs && !ageCheck.hasTimestamp) {
59
+ if (releaseConfig.minimumReleaseAgeBehaviour === "timestamp-optional") logger.once.warn("Some release(s) did not have a releaseTimestamp, but as we're running with minimumReleaseAgeBehaviour=timestamp-optional, proceeding. See debug logs for more information");
60
+ logger.once.debug({
61
+ depName: config.depName,
62
+ updateType: update.updateType,
63
+ minimumReleaseAgeBehaviour: releaseConfig.minimumReleaseAgeBehaviour,
64
+ check: "minimumReleaseAge"
65
+ }, `${update.updateType} update of ${config.depName} has no releaseTimestamp to age against`);
66
+ }
67
+ if (ageCheck.isPending) {
68
+ logger.trace({
69
+ depName: config.depName,
70
+ updateType: update.updateType,
71
+ releaseTimestamp: newestMatchingVersionTimestamp,
72
+ check: "minimumReleaseAge"
73
+ }, `${update.updateType} update is pending minimumReleaseAge status checks`);
74
+ if (config.internalChecksFilter === "strict") update.pendingChecks = true;
75
+ }
76
+ }
34
77
  async function lookupUpdates(inconfig) {
35
78
  let config = { ...inconfig };
36
79
  config.versioning ??= getDefaultVersioning(config.datasource);
@@ -41,6 +84,8 @@ async function lookupUpdates(inconfig) {
41
84
  updates: [],
42
85
  warnings: []
43
86
  };
87
+ let newestMatchingVersionTimestamp;
88
+ let digestUpdate;
44
89
  try {
45
90
  logger.trace({
46
91
  dependency: config.packageName,
@@ -180,6 +225,10 @@ async function lookupUpdates(inconfig) {
180
225
  currentVersionTimestamp
181
226
  }, "current-timestamp");
182
227
  }
228
+ if (config.currentDigest && couldApplyMinimumReleaseAgeToDigest(config)) {
229
+ const newestMatchingVersion = getCurrentVersion(compareValue, "", versioningApi, "replace", latestVersion, allVersions.filter((v) => !v.isDeprecated).map((v) => v.version)) ?? getCurrentVersion(compareValue, "", versioningApi, "replace", latestVersion, allVersions.map((v) => v.version));
230
+ if (newestMatchingVersion) newestMatchingVersionTimestamp = await getTimestamp(config, allVersions, newestMatchingVersion, versioningApi);
231
+ }
183
232
  if (compareValue && currentVersion && rangeStrategy === "pin" && !versioningApi.isSingleVersion(compareValue)) {
184
233
  const newValue = versioningApi.getPinnedValue?.(currentVersion) ?? currentVersion;
185
234
  res.updates.push({
@@ -238,7 +287,10 @@ async function lookupUpdates(inconfig) {
238
287
  if (!release) return Result.ok(res);
239
288
  const newVersion = release.version;
240
289
  const update = await generateUpdate(config, compareValue, versioningApi, rangeStrategy, config.lockedVersion ?? currentVersion, bucket, release, allReleaseVersions);
241
- if (config.manager === "gomod" && compareValue?.startsWith("v0.0.0-") && update.newValue?.startsWith("v0.0.0-") && config.currentDigest !== update.newDigest) update.updateType = "digest";
290
+ if (config.manager === "gomod" && compareValue?.startsWith("v0.0.0-") && update.newValue?.startsWith("v0.0.0-") && config.currentDigest !== update.newDigest) {
291
+ update.updateType = "digest";
292
+ await applyMinimumReleaseAgeToDigestUpdate(update, config, res, release.releaseTimestamp);
293
+ }
242
294
  if (pendingChecks) update.pendingChecks = pendingChecks;
243
295
  if (pendingReleases.length) update.pendingVersions = pendingReleases.map((r) => r.version);
244
296
  if (!update.newValue || update.newValue === compareValue) {
@@ -293,10 +345,13 @@ async function lookupUpdates(inconfig) {
293
345
  }
294
346
  if (supportsDigests(config.datasource)) {
295
347
  if (config.currentDigest) {
296
- if (!config.digestOneAndOnly || !res.updates.length) res.updates.push({
297
- updateType: "digest",
298
- newValue: config.currentValue
299
- });
348
+ if (!config.digestOneAndOnly || !res.updates.length) {
349
+ digestUpdate = {
350
+ updateType: "digest",
351
+ newValue: config.currentValue
352
+ };
353
+ res.updates.push(digestUpdate);
354
+ }
300
355
  } else if (config.pinDigests && !res.updates.some((update) => update.updateType === "pin")) res.updates.push({
301
356
  isPinDigest: true,
302
357
  updateType: "pinDigest",
@@ -346,6 +401,7 @@ async function lookupUpdates(inconfig) {
346
401
  res.updates = res.updates.filter((update) => update.newValue !== null || config.currentValue === null).filter((update) => update.newDigest !== null).filter((update) => isString(update.newName) && update.newName !== config.packageName || update.isReplacement === true || update.newValue !== config.currentValue || update.isLockfileUpdate === true || update.newDigest && !update.newDigest.startsWith(config.currentDigest));
347
402
  if (config.rangeStrategy === "in-range-only") res.updates = res.updates.filter((update) => update.newValue === config.currentValue);
348
403
  if (config.rollbackPrs && config.followTag) res.updates = res.updates.filter((update) => update.updateType !== "rollback" || res.updates.length === 1);
404
+ if (digestUpdate && res.updates.includes(digestUpdate)) await applyMinimumReleaseAgeToDigestUpdate(digestUpdate, config, res, newestMatchingVersionTimestamp);
349
405
  const release = res.updates.length > 0 ? dependency?.releases.find((r) => r.version === res.updates[0].newValue) ?? dependency?.releases.find((r) => r.version === res.updates[0].newVersion) : null;
350
406
  if (release?.changelogContent) {
351
407
  res.changelogContent = release.changelogContent;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["allVersioning.get"],"sources":["../../../../../lib/workers/repository/process/lookup/index.ts"],"sourcesContent":["import { isNonEmptyString, isString, isUndefined } from '@sindresorhus/is';\nimport { mergeChildConfig } from '../../../../config/index.ts';\nimport type { ValidationMessage } from '../../../../config/types.ts';\nimport { CONFIG_VALIDATION } from '../../../../constants/error-messages.ts';\nimport { logger } from '../../../../logger/index.ts';\nimport {\n getDatasourceFor,\n getDefaultVersioning,\n} from '../../../../modules/datasource/common.ts';\nimport type {\n GetDigestInputConfig,\n Release,\n ReleaseResult,\n} from '../../../../modules/datasource/index.ts';\nimport {\n applyDatasourceFilters,\n getDigest,\n getRawPkgReleases,\n isGetPkgReleasesConfig,\n supportsDigests,\n} from '../../../../modules/datasource/index.ts';\nimport { postprocessRelease } from '../../../../modules/datasource/postprocess-release.ts';\nimport { getRangeStrategy } from '../../../../modules/manager/index.ts';\nimport { id as dockerVersioningId } from '../../../../modules/versioning/docker/index.ts';\nimport * as allVersioning from '../../../../modules/versioning/index.ts';\nimport { ExternalHostError } from '../../../../types/errors/external-host-error.ts';\nimport { assignKeys } from '../../../../util/assign-keys.ts';\nimport { getElapsedDays } from '../../../../util/date.ts';\nimport { applyPackageRules } from '../../../../util/package-rules/index.ts';\nimport { regEx } from '../../../../util/regex.ts';\nimport { Result } from '../../../../util/result.ts';\nimport type { Timestamp } from '../../../../util/timestamp.ts';\nimport { calculateAbandonment } from './abandonment.ts';\nimport { getBucket } from './bucket.ts';\nimport { getCurrentVersion } from './current.ts';\nimport { filterVersions } from './filter.ts';\nimport { filterInternalChecks } from './filter-checks.ts';\nimport { generateUpdate } from './generate.ts';\nimport { getRollbackUpdate } from './rollback.ts';\nimport { calculateMostRecentTimestamp } from './timestamps.ts';\nimport type { LookupUpdateConfig, UpdateResult } from './types.ts';\nimport {\n addReplacementUpdateIfValid,\n isReplacementRulesConfigured,\n} from './utils.ts';\n\nasync function getTimestamp(\n config: LookupUpdateConfig,\n versions: Release[],\n version: string,\n versioningApi: allVersioning.VersioningApi,\n): Promise<Timestamp | null | undefined> {\n const currentRelease = versions.find(\n (v) =>\n versioningApi.isValid(v.version) &&\n versioningApi.equals(v.version, version),\n );\n\n if (!currentRelease) {\n return null;\n }\n\n if (currentRelease.releaseTimestamp) {\n return currentRelease.releaseTimestamp;\n }\n\n const remoteRelease = await postprocessRelease(config, currentRelease);\n return remoteRelease?.releaseTimestamp;\n}\n\nexport async function lookupUpdates(\n inconfig: LookupUpdateConfig,\n): Promise<Result<UpdateResult>> {\n let config: LookupUpdateConfig = { ...inconfig };\n config.versioning ??= getDefaultVersioning(config.datasource);\n\n const versioningApi = allVersioning.get(config.versioning);\n\n let dependency: ReleaseResult | null = null;\n const res: UpdateResult = {\n versioning: config.versioning,\n updates: [],\n warnings: [],\n };\n\n try {\n logger.trace(\n {\n dependency: config.packageName,\n currentValue: config.currentValue,\n },\n 'lookupUpdates',\n );\n if (config.currentValue && !isString(config.currentValue)) {\n // If currentValue is not a string, then it's invalid\n // v8 ignore else -- TODO: add test #40625\n if (config.currentValue) {\n logger.debug(\n `Invalid currentValue for ${config.packageName}: ${JSON.stringify(config.currentValue)} (${typeof config.currentValue})`,\n );\n }\n res.skipReason = 'invalid-value';\n return Result.ok(res);\n }\n if (\n !isGetPkgReleasesConfig(config) ||\n !getDatasourceFor(config.datasource)\n ) {\n res.skipReason = 'invalid-config';\n return Result.ok(res);\n }\n let compareValue = config.currentValue;\n if (\n isString(config.currentValue) &&\n isString(config.versionCompatibility)\n ) {\n const versionCompatbilityRegEx = regEx(config.versionCompatibility);\n const regexMatch = versionCompatbilityRegEx.exec(config.currentValue);\n if (regexMatch?.groups) {\n logger.debug(\n {\n versionCompatibility: config.versionCompatibility,\n currentValue: config.currentValue,\n packageName: config.packageName,\n groups: regexMatch.groups,\n },\n 'version compatibility regex match',\n );\n config.currentCompatibility = regexMatch.groups.compatibility;\n compareValue = regexMatch.groups.version;\n } else {\n logger.debug(\n {\n versionCompatibility: config.versionCompatibility,\n currentValue: config.currentValue,\n packageName: config.packageName,\n },\n 'version compatibility regex mismatch',\n );\n }\n }\n\n const isValid =\n isString(compareValue) && versioningApi.isValid(compareValue);\n\n const unconstrainedValue =\n !!config.lockedVersion && isUndefined(config.currentValue);\n\n if (isValid || unconstrainedValue) {\n if (\n !config.updatePinnedDependencies &&\n // TODO #22198\n versioningApi.isSingleVersion(compareValue!)\n ) {\n res.skipReason = 'is-pinned';\n return Result.ok(res);\n }\n\n const { val: releaseResult, err: lookupError } = await getRawPkgReleases(\n config,\n )\n .transform((res) => calculateMostRecentTimestamp(versioningApi, res))\n .transform((res) => calculateAbandonment(res, config))\n .transform((res) => applyDatasourceFilters(res, config))\n .unwrap();\n\n if (lookupError instanceof Error) {\n throw lookupError;\n }\n\n if (lookupError) {\n // If dependency lookup fails then warn and return\n const warning: ValidationMessage = {\n topic: config.packageName,\n message: `Failed to look up ${config.datasource} package ${config.packageName}: ${lookupError}`,\n };\n logger.debug(\n {\n dependency: config.packageName,\n packageFile: config.packageFile,\n },\n warning.message,\n );\n // TODO: return warnings in own field\n res.warnings.push(warning);\n return Result.ok(res);\n }\n\n dependency = releaseResult;\n\n if (dependency.deprecationMessage) {\n logger.debug(\n `Found deprecationMessage for ${config.datasource} package ${config.packageName}`,\n );\n }\n\n assignKeys(res, dependency, [\n 'deprecationMessage',\n 'sourceUrl',\n 'registryUrl',\n 'sourceDirectory',\n 'homepage',\n 'changelogUrl',\n 'dependencyUrl',\n 'lookupName',\n 'packageScope',\n 'mostRecentTimestamp',\n 'isAbandoned',\n 'respectLatest',\n ]);\n\n const latestVersion = dependency.tags?.latest;\n // Filter out any results from datasource that don't comply with our versioning\n let allVersions = dependency.releases.filter((release) =>\n versioningApi.isVersion(release.version),\n );\n const allReleaseVersions = new Set(allVersions.map((r) => r.version));\n // istanbul ignore if\n if (allVersions.length === 0) {\n const message = `Found no results from datasource that look like a version`;\n logger.info(\n {\n dependency: config.packageName,\n result: dependency,\n },\n message,\n );\n if (!config.currentDigest) {\n return Result.ok(res);\n }\n }\n // Reapply package rules in case we missed something from sourceUrl\n config = await applyPackageRules(\n { ...config, sourceUrl: res.sourceUrl },\n 'source-url',\n );\n if (config.followTag) {\n const taggedVersion = dependency.tags?.[config.followTag];\n if (!taggedVersion) {\n res.warnings.push({\n topic: config.packageName,\n message: `Can't find version with tag ${config.followTag} for ${config.datasource} package ${config.packageName}`,\n });\n return Result.ok(res);\n }\n allVersions = allVersions.filter(\n (v) =>\n v.version === taggedVersion ||\n (v.version === compareValue &&\n versioningApi.isGreaterThan(taggedVersion, compareValue)),\n );\n }\n\n const inRangeOnlyStrategy = config.rangeStrategy === 'in-range-only';\n // Check that existing constraint can be satisfied\n const allSatisfyingVersions =\n (inRangeOnlyStrategy || config.rollbackPrs) && !unconstrainedValue\n ? allVersions.filter((v) =>\n // TODO #22198\n versioningApi.matches(v.version, compareValue!),\n )\n : allVersions;\n if (!allSatisfyingVersions.length) {\n logger.debug(\n `Found no satisfying versions with '${config.versioning}' versioning`,\n );\n }\n\n if (config.rollbackPrs && !allSatisfyingVersions.length) {\n const rollback = getRollbackUpdate(config, allVersions, versioningApi);\n // istanbul ignore if\n if (!rollback) {\n res.warnings.push({\n topic: config.packageName,\n // TODO: types (#22198)\n message: `Can't find version matching ${compareValue!} for ${\n config.datasource\n } package ${config.packageName}`,\n });\n return Result.ok(res);\n }\n res.updates.push(rollback);\n }\n let rangeStrategy = getRangeStrategy(config);\n\n // istanbul ignore next\n if (\n config.isVulnerabilityAlert &&\n rangeStrategy === 'update-lockfile' &&\n !config.lockedVersion\n ) {\n rangeStrategy = 'bump';\n }\n // unconstrained deps with lockedVersion\n if (\n config.isVulnerabilityAlert &&\n !config.currentValue &&\n config.lockedVersion\n ) {\n rangeStrategy = 'update-lockfile';\n }\n const nonDeprecatedVersions = dependency.releases\n .filter((release) => !release.isDeprecated)\n .map((release) => release.version);\n let currentVersion: string;\n if (rangeStrategy === 'update-lockfile') {\n currentVersion = config.lockedVersion!;\n } else if (\n compareValue &&\n versioningApi.isSingleVersion(compareValue) &&\n allVersions.find((v) => v.version === compareValue)\n ) {\n currentVersion = compareValue;\n }\n // TODO #22198\n currentVersion ??=\n getCurrentVersion(\n compareValue!,\n config.lockedVersion!,\n versioningApi,\n rangeStrategy!,\n latestVersion!,\n nonDeprecatedVersions,\n ) ??\n getCurrentVersion(\n compareValue!,\n config.lockedVersion!,\n versioningApi,\n rangeStrategy!,\n latestVersion!,\n allVersions.map((v) => v.version),\n )!;\n\n if (!currentVersion) {\n // v8 ignore else -- TODO: add test #40625\n if (!config.lockedVersion) {\n logger.debug(\n `No currentVersion or lockedVersion found for ${config.packageName}`,\n );\n res.skipReason = 'invalid-value';\n }\n return Result.ok(res);\n }\n\n res.currentVersion = currentVersion;\n\n // Use lockedVersion for the timestamp lookup when available, because\n // res.currentVersion is later overwritten to lockedVersion (see below).\n // Without this, strategies like \"replace\" would compute the timestamp\n // for the highest satisfying version (e.g. 1.4.1) while the reported\n // currentVersion ends up being the locked one (e.g. 1.0.0).\n const versionForTimestamp = config.lockedVersion ?? currentVersion;\n const currentVersionTimestamp = await getTimestamp(\n config,\n allVersions,\n versionForTimestamp,\n versioningApi,\n );\n\n if (isNonEmptyString(currentVersionTimestamp)) {\n res.currentVersionTimestamp = currentVersionTimestamp;\n res.currentVersionAgeInDays = getElapsedDays(currentVersionTimestamp);\n\n if (\n config.packageRules?.some((rule) =>\n isNonEmptyString(rule.matchCurrentAge),\n )\n ) {\n // Reapply package rules to check matches for matchCurrentAge\n config = await applyPackageRules(\n { ...config, currentVersionTimestamp },\n 'current-timestamp',\n );\n }\n }\n\n if (\n compareValue &&\n currentVersion &&\n rangeStrategy === 'pin' &&\n !versioningApi.isSingleVersion(compareValue)\n ) {\n const newValue =\n versioningApi.getPinnedValue?.(currentVersion) ?? currentVersion;\n res.updates.push({\n updateType: 'pin',\n isPin: true,\n newValue,\n newVersion: currentVersion,\n newMajor: versioningApi.getMajor(currentVersion)!,\n });\n }\n if (rangeStrategy === 'pin') {\n // Fall back to replace once pinning logic is done\n rangeStrategy = 'replace';\n }\n // istanbul ignore if\n if (!versioningApi.isVersion(currentVersion!)) {\n res.skipReason = 'invalid-version';\n return Result.ok(res);\n }\n // Filter latest, unstable, etc\n // TODO #22198\n let filteredReleases = filterVersions(\n config,\n currentVersion!,\n latestVersion!,\n inRangeOnlyStrategy ? allSatisfyingVersions : allVersions,\n versioningApi,\n ).filter(\n (v) =>\n // Leave only compatible versions\n unconstrainedValue ||\n versioningApi.isCompatible(v.version, compareValue),\n );\n let shrinkedViaVulnerability = false;\n if (config.isVulnerabilityAlert) {\n if (config.vulnerabilityFixVersion) {\n res.vulnerabilityFixVersion = config.vulnerabilityFixVersion;\n res.vulnerabilityFixStrategy = config.vulnerabilityFixStrategy;\n if (versioningApi.isValid(config.vulnerabilityFixVersion)) {\n let fixedFilteredReleases;\n if (versioningApi.isVersion(config.vulnerabilityFixVersion)) {\n // Retain only releases greater than or equal to the fix version\n fixedFilteredReleases = filteredReleases.filter(\n (release) =>\n !versioningApi.isGreaterThan(\n config.vulnerabilityFixVersion!,\n release.version,\n ),\n );\n } else {\n // Retain only releases which max the fix constraint\n fixedFilteredReleases = filteredReleases.filter((release) =>\n versioningApi.matches(\n release.version,\n config.vulnerabilityFixVersion!,\n ),\n );\n }\n // Warn if this filtering results caused zero releases\n if (fixedFilteredReleases.length === 0 && filteredReleases.length) {\n logger.warn(\n {\n releases: filteredReleases,\n vulnerabilityFixVersion: config.vulnerabilityFixVersion,\n packageName: config.packageName,\n },\n 'No releases satisfy vulnerabilityFixVersion',\n );\n }\n // Use the additionally filtered releases\n filteredReleases = fixedFilteredReleases;\n } else {\n logger.warn(\n {\n vulnerabilityFixVersion: config.vulnerabilityFixVersion,\n packageName: config.packageName,\n },\n 'vulnerabilityFixVersion is not valid',\n );\n }\n }\n if (config.vulnerabilityFixStrategy === 'highest') {\n // Don't shrink the list of releases - let Renovate use its normal logic\n logger.once.debug(\n `Using vulnerabilityFixStrategy=highest for ${config.packageName}`,\n );\n } else {\n // Shrink the list of releases to the lowest fixed version\n logger.once.debug(\n `Using vulnerabilityFixStrategy=lowest for ${config.packageName}`,\n );\n filteredReleases = filteredReleases.slice(0, 1);\n shrinkedViaVulnerability = true;\n }\n }\n const buckets: Record<string, [Release]> = {};\n for (const release of filteredReleases) {\n const bucket = getBucket(\n config,\n // TODO #22198\n currentVersion!,\n release.version,\n versioningApi,\n );\n // v8 ignore else -- TODO: add test #40625\n if (isString(bucket)) {\n if (buckets[bucket]) {\n buckets[bucket].push(release);\n } else {\n buckets[bucket] = [release];\n }\n }\n }\n const depResultConfig = mergeChildConfig(config, res);\n for (const [bucket, releases] of Object.entries(buckets)) {\n const sortedReleases = releases.sort((r1, r2) =>\n versioningApi.sortVersions(r1.version, r2.version),\n );\n const { release, pendingChecks, pendingReleases } =\n await filterInternalChecks(\n depResultConfig,\n versioningApi,\n bucket,\n sortedReleases,\n );\n // istanbul ignore next\n if (!release) {\n return Result.ok(res);\n }\n const newVersion = release.version;\n const update = await generateUpdate(\n config,\n compareValue,\n versioningApi,\n // TODO #22198\n\n rangeStrategy!,\n config.lockedVersion ?? currentVersion!,\n bucket,\n release,\n allReleaseVersions,\n );\n\n // #29034\n if (\n config.manager === 'gomod' &&\n compareValue?.startsWith('v0.0.0-') &&\n update.newValue?.startsWith('v0.0.0-') &&\n config.currentDigest !== update.newDigest\n ) {\n update.updateType = 'digest';\n }\n\n if (pendingChecks) {\n update.pendingChecks = pendingChecks;\n }\n\n if (pendingReleases.length) {\n update.pendingVersions = pendingReleases.map((r) => r.version);\n }\n if (!update.newValue || update.newValue === compareValue) {\n if (!config.lockedVersion) {\n continue;\n }\n // istanbul ignore if\n if (rangeStrategy === 'bump') {\n logger.trace(\n {\n packageName: config.packageName,\n currentValue: config.currentValue,\n lockedVersion: config.lockedVersion,\n newVersion,\n },\n 'Skipping bump because newValue is the same',\n );\n continue;\n }\n res.isSingleVersion = true;\n }\n res.isSingleVersion ??=\n isString(update.newValue) &&\n versioningApi.isSingleVersion(update.newValue);\n // istanbul ignore if\n if (\n config.versioning === dockerVersioningId &&\n update.updateType !== 'rollback' &&\n update.newValue &&\n versioningApi.isVersion(update.newValue) &&\n compareValue &&\n versioningApi.isVersion(compareValue) &&\n versioningApi.isGreaterThan(compareValue, update.newValue)\n ) {\n logger.warn(\n {\n packageName: config.packageName,\n currentValue: config.currentValue,\n compareValue,\n currentVersion: config.currentVersion,\n update,\n allVersionsLength: allVersions.length,\n filteredReleaseVersions: filteredReleases.map((r) => r.version),\n shrinkedViaVulnerability,\n },\n 'Unexpected downgrade detected: skipping',\n );\n } else {\n res.updates.push(update);\n }\n }\n } else if (compareValue) {\n logger.debug(\n `Dependency ${config.packageName} has unsupported/unversioned value ${compareValue} (versioning=${config.versioning})`,\n );\n\n if (!config.pinDigests && !config.currentDigest) {\n logger.debug(\n `Skipping ${config.packageName} because no currentDigest or pinDigests`,\n );\n res.skipReason = 'invalid-value';\n } else {\n delete res.skipReason;\n }\n } else {\n res.skipReason = 'invalid-value';\n }\n\n if (isReplacementRulesConfigured(config)) {\n addReplacementUpdateIfValid(res.updates, config);\n } else if (dependency?.replacementName && dependency.replacementVersion) {\n res.updates.push({\n updateType: 'replacement',\n newName: dependency.replacementName,\n newValue: dependency.replacementVersion,\n });\n }\n\n // Record if the dep is fixed to a version\n if (config.lockedVersion) {\n res.currentVersion = config.lockedVersion;\n res.fixedVersion = config.lockedVersion;\n } else if (compareValue && versioningApi.isSingleVersion(compareValue)) {\n res.fixedVersion = compareValue.replace(regEx(/^=+/), '');\n }\n\n // massage versionCompatibility\n if (\n isString(config.currentValue) &&\n isString(compareValue) &&\n isString(config.versionCompatibility)\n ) {\n for (const update of res.updates) {\n logger.debug({ update });\n // v8 ignore else -- TODO: add test #40625\n if (isString(config.currentValue) && isString(update.newValue)) {\n update.newValue = config.currentValue.replace(\n compareValue,\n update.newValue,\n );\n }\n }\n }\n\n // Add digests if necessary\n if (supportsDigests(config.datasource)) {\n if (config.currentDigest) {\n if (!config.digestOneAndOnly || !res.updates.length) {\n // digest update\n res.updates.push({\n updateType: 'digest',\n newValue: config.currentValue,\n });\n }\n } else if (\n config.pinDigests &&\n // Create a pin only if one doesn't already exists\n // v8 ignore else -- TODO: add test #40625\n !res.updates.some((update) => update.updateType === 'pin')\n ) {\n // pin digest\n res.updates.push({\n isPinDigest: true,\n updateType: 'pinDigest',\n newValue: config.currentValue,\n });\n }\n if (versioningApi.valueToVersion) {\n // TODO #22198\n res.currentVersion = versioningApi.valueToVersion(res.currentVersion!);\n for (const update of res.updates) {\n // TODO #22198\n update.newVersion = versioningApi.valueToVersion(update.newVersion!);\n }\n }\n if (res.registryUrl) {\n config.registryUrls = [res.registryUrl];\n }\n\n // update digest for all\n for (const update of res.updates) {\n if (config.pinDigests === true || config.currentDigest) {\n const getDigestConfig: GetDigestInputConfig = {\n ...config,\n registryUrl: update.registryUrl ?? res.registryUrl,\n lookupName: res.lookupName,\n };\n\n // #20304 only pass it for replacement updates, otherwise we get wrong or invalid digest\n if (update.updateType !== 'replacement') {\n delete getDigestConfig.replacementName;\n }\n\n // #20304 don't use lookupName and currentDigest when we replace image name\n if (\n update.updateType === 'replacement' &&\n update.newName !== config.packageName\n ) {\n delete getDigestConfig.lookupName;\n delete getDigestConfig.currentDigest;\n getDigestConfig.replacementName = update.newName;\n }\n\n // Don't use current releases if replacement changes name, otherwise we use the wrong new digest.\n // This happens on datasources which return the digest in release info like `github-tags`.\n // We can still use it when only version is changing.\n if (\n update.updateType !== 'replacement' ||\n update.newName === config.packageName\n ) {\n update.newDigest ??= dependency?.releases.find(\n (r) => r.version === update.newValue,\n )?.newDigest;\n }\n\n update.newDigest ??= await getDigest(\n getDigestConfig,\n update.newValue,\n );\n\n // If the digest could not be determined, report this as otherwise the\n // update will be omitted later on without notice.\n if (update.newDigest === null) {\n logger.debug(\n {\n packageName: config.packageName,\n currentValue: config.currentValue,\n datasource: config.datasource,\n newValue: update.newValue,\n bucket: update.bucket,\n },\n 'Could not determine new digest for update.',\n );\n\n // Only report a warning if there is a current digest.\n // Context: https://github.com/renovatebot/renovate/pull/20175#discussion_r1102615059.\n if (config.currentDigest) {\n res.warnings.push({\n message: `Could not determine new digest for update (${config.datasource} package ${config.packageName})`,\n topic: config.packageName,\n });\n }\n }\n } else {\n delete update.newDigest;\n }\n if (update.newVersion) {\n const registryUrl = dependency?.releases?.find(\n (release) => release.version === update.newVersion,\n )?.registryUrl;\n if (registryUrl && registryUrl !== res.registryUrl) {\n update.registryUrl = registryUrl;\n }\n }\n }\n }\n\n if (res.updates.length) {\n delete res.skipReason;\n }\n // Strip out any non-changed ones\n res.updates = res.updates\n .filter(\n (update) => update.newValue !== null || config.currentValue === null,\n )\n .filter((update) => update.newDigest !== null)\n .filter(\n (update) =>\n (isString(update.newName) && update.newName !== config.packageName) ||\n update.isReplacement === true ||\n update.newValue !== config.currentValue ||\n update.isLockfileUpdate === true ||\n // TODO #22198\n (update.newDigest &&\n !update.newDigest.startsWith(config.currentDigest!)),\n );\n // If range strategy specified in config is 'in-range-only', also strip out updates where currentValue !== newValue\n if (config.rangeStrategy === 'in-range-only') {\n res.updates = res.updates.filter(\n (update) => update.newValue === config.currentValue,\n );\n }\n // Handle a weird edge case involving followTag and fallbacks\n if (config.rollbackPrs && config.followTag) {\n res.updates = res.updates.filter(\n (update) =>\n update.updateType !== 'rollback' || res.updates.length === 1,\n );\n }\n\n const release =\n res.updates.length > 0\n ? (dependency?.releases.find(\n (r) => r.version === res.updates[0].newValue,\n ) ??\n dependency?.releases.find(\n (r) => r.version === res.updates[0].newVersion,\n ))\n : null;\n\n if (release?.changelogContent) {\n res.changelogContent = release.changelogContent;\n res.changelogUrl = release.changelogUrl;\n }\n } catch (err) /* istanbul ignore next */ {\n if (err instanceof ExternalHostError) {\n return Result.err(err);\n }\n\n if (err instanceof Error && err.message === CONFIG_VALIDATION) {\n return Result.err(err);\n }\n\n logger.error(\n {\n currentDigest: config.currentDigest,\n currentValue: config.currentValue,\n datasource: config.datasource,\n packageName: config.packageName,\n digestOneAndOnly: config.digestOneAndOnly,\n followTag: config.followTag,\n lockedVersion: config.lockedVersion,\n packageFile: config.packageFile,\n pinDigests: config.pinDigests,\n rollbackPrs: config.rollbackPrs,\n isVulnerabilityAlert: config.isVulnerabilityAlert,\n updatePinnedDependencies: config.updatePinnedDependencies,\n err,\n },\n 'lookupUpdates error',\n );\n res.skipReason = 'internal-error';\n }\n return Result.ok(res);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["allVersioning.get"],"sources":["../../../../../lib/workers/repository/process/lookup/index.ts"],"sourcesContent":["import { isNonEmptyString, isString, isUndefined } from '@sindresorhus/is';\nimport { mergeChildConfig } from '../../../../config/index.ts';\nimport type { ValidationMessage } from '../../../../config/types.ts';\nimport { CONFIG_VALIDATION } from '../../../../constants/error-messages.ts';\nimport { logger } from '../../../../logger/index.ts';\nimport {\n getDatasourceFor,\n getDefaultVersioning,\n} from '../../../../modules/datasource/common.ts';\nimport type {\n GetDigestInputConfig,\n Release,\n ReleaseResult,\n} from '../../../../modules/datasource/index.ts';\nimport {\n applyDatasourceFilters,\n getDigest,\n getRawPkgReleases,\n isGetPkgReleasesConfig,\n supportsDigests,\n} from '../../../../modules/datasource/index.ts';\nimport { postprocessRelease } from '../../../../modules/datasource/postprocess-release.ts';\nimport { getRangeStrategy } from '../../../../modules/manager/index.ts';\nimport type { LookupUpdate } from '../../../../modules/manager/types.ts';\nimport { id as dockerVersioningId } from '../../../../modules/versioning/docker/index.ts';\nimport * as allVersioning from '../../../../modules/versioning/index.ts';\nimport { ExternalHostError } from '../../../../types/errors/external-host-error.ts';\nimport { assignKeys } from '../../../../util/assign-keys.ts';\nimport { getElapsedDays } from '../../../../util/date.ts';\nimport { checkMinimumReleaseAge } from '../../../../util/minimum-release-age.ts';\nimport { applyPackageRules } from '../../../../util/package-rules/index.ts';\nimport { regEx } from '../../../../util/regex.ts';\nimport { Result } from '../../../../util/result.ts';\nimport type { Timestamp } from '../../../../util/timestamp.ts';\nimport { calculateAbandonment } from './abandonment.ts';\nimport { getBucket } from './bucket.ts';\nimport { getCurrentVersion } from './current.ts';\nimport { filterVersions } from './filter.ts';\nimport { filterInternalChecks } from './filter-checks.ts';\nimport { generateUpdate } from './generate.ts';\nimport { getRollbackUpdate } from './rollback.ts';\nimport { calculateMostRecentTimestamp } from './timestamps.ts';\nimport type { LookupUpdateConfig, UpdateResult } from './types.ts';\nimport {\n addReplacementUpdateIfValid,\n isReplacementRulesConfigured,\n} from './utils.ts';\n\nasync function getTimestamp(\n config: LookupUpdateConfig,\n versions: Release[],\n version: string,\n versioningApi: allVersioning.VersioningApi,\n): Promise<Timestamp | null | undefined> {\n const currentRelease = versions.find(\n (v) =>\n versioningApi.isValid(v.version) &&\n versioningApi.equals(v.version, version),\n );\n\n if (!currentRelease) {\n return null;\n }\n\n if (currentRelease.releaseTimestamp) {\n return currentRelease.releaseTimestamp;\n }\n\n const remoteRelease = await postprocessRelease(config, currentRelease);\n return remoteRelease?.releaseTimestamp;\n}\n\n/** The only `updateType` that `applyMinimumReleaseAgeToDigestUpdate()` can be called with */\ntype DigestLikeUpdate = LookupUpdate & { updateType: 'digest' };\n\n/**\n * A helper function to allow a short-circuit for `minimumReleaseAge` functionality if a package may have config that applies it.\n *\n * Allows avoiding unnecessary calls to more expensive checks like merge + `applyPackageRules()` and `getTimestamp()`.\n */\nfunction couldApplyMinimumReleaseAgeToDigest(\n config: LookupUpdateConfig,\n): boolean {\n // Match filterInternalChecks(): under `none` the user opted out of internal\n // checks entirely, so do no merging, no package rules, no age check and no\n // logging claiming an age check ran.\n if (config.internalChecksFilter === 'none') {\n return false;\n }\n\n return (\n isNonEmptyString(config.minimumReleaseAge) ||\n isNonEmptyString(config.digest?.minimumReleaseAge) ||\n !!config.packageRules?.some((rule) =>\n isNonEmptyString(rule.minimumReleaseAge),\n )\n );\n}\n\n/**\n * Ensure `minimumReleaseAge`/`internalChecksFilter` applies to digest updates, as they don't currently get run through `filterInternalChecks()`.\n *\n * NOTE that this should be kept in sync with `filterInternalChecks`()\n */\nasync function applyMinimumReleaseAgeToDigestUpdate(\n update: DigestLikeUpdate,\n config: LookupUpdateConfig,\n res: UpdateResult,\n newestMatchingVersionTimestamp: Timestamp | null | undefined,\n): Promise<void> {\n if (!couldApplyMinimumReleaseAgeToDigest(config)) {\n return;\n }\n\n let releaseConfig: LookupUpdateConfig = {\n ...mergeChildConfig(config, res),\n updateType: update.updateType,\n };\n releaseConfig = mergeChildConfig(\n releaseConfig,\n releaseConfig[update.updateType]!,\n );\n releaseConfig = await applyPackageRules(releaseConfig, 'update-type');\n\n const ageCheck = checkMinimumReleaseAge(\n releaseConfig,\n // intentionally used instead of `update.releaseTimestamp`\n newestMatchingVersionTimestamp,\n );\n\n // Mirror filterInternalChecks()'s logging so a held/passed digest update is diagnosable.\n if (ageCheck.minimumReleaseAgeMs && !ageCheck.hasTimestamp) {\n if (releaseConfig.minimumReleaseAgeBehaviour === 'timestamp-optional') {\n logger.once.warn(\n \"Some release(s) did not have a releaseTimestamp, but as we're running with minimumReleaseAgeBehaviour=timestamp-optional, proceeding. See debug logs for more information\",\n );\n }\n\n logger.once.debug(\n {\n depName: config.depName,\n updateType: update.updateType,\n minimumReleaseAgeBehaviour: releaseConfig.minimumReleaseAgeBehaviour,\n check: 'minimumReleaseAge',\n },\n `${update.updateType} update of ${config.depName} has no releaseTimestamp to age against`,\n );\n }\n if (ageCheck.isPending) {\n logger.trace(\n {\n depName: config.depName,\n updateType: update.updateType,\n releaseTimestamp: newestMatchingVersionTimestamp,\n check: 'minimumReleaseAge',\n },\n `${update.updateType} update is pending minimumReleaseAge status checks`,\n );\n\n // internalChecksFilter is read from the unmerged top-level config, like filterInternalChecks().\n if (config.internalChecksFilter === 'strict') {\n update.pendingChecks = true;\n }\n }\n}\n\nexport async function lookupUpdates(\n inconfig: LookupUpdateConfig,\n): Promise<Result<UpdateResult>> {\n let config: LookupUpdateConfig = { ...inconfig };\n config.versioning ??= getDefaultVersioning(config.datasource);\n\n const versioningApi = allVersioning.get(config.versioning);\n\n let dependency: ReleaseResult | null = null;\n const res: UpdateResult = {\n versioning: config.versioning,\n updates: [],\n warnings: [],\n };\n // Timestamp of the release a `digest` update repoints to (the newest version matching the current value), as opposed to `res.currentVersionTimestamp` which tracks whatever the configured rangeStrategy resolves `currentVersion` to (e.g. the oldest for `bump`)\n let newestMatchingVersionTimestamp: Timestamp | null | undefined;\n // The `digest` update for `config.currentDigest` (if one is added), so its age check can run after `newDigest` is fetched and no-op updates are stripped.\n let digestUpdate: DigestLikeUpdate | undefined;\n\n try {\n logger.trace(\n {\n dependency: config.packageName,\n currentValue: config.currentValue,\n },\n 'lookupUpdates',\n );\n if (config.currentValue && !isString(config.currentValue)) {\n // If currentValue is not a string, then it's invalid\n // v8 ignore else -- TODO: add test #40625\n if (config.currentValue) {\n logger.debug(\n `Invalid currentValue for ${config.packageName}: ${JSON.stringify(config.currentValue)} (${typeof config.currentValue})`,\n );\n }\n res.skipReason = 'invalid-value';\n return Result.ok(res);\n }\n if (\n !isGetPkgReleasesConfig(config) ||\n !getDatasourceFor(config.datasource)\n ) {\n res.skipReason = 'invalid-config';\n return Result.ok(res);\n }\n let compareValue = config.currentValue;\n if (\n isString(config.currentValue) &&\n isString(config.versionCompatibility)\n ) {\n const versionCompatbilityRegEx = regEx(config.versionCompatibility);\n const regexMatch = versionCompatbilityRegEx.exec(config.currentValue);\n if (regexMatch?.groups) {\n logger.debug(\n {\n versionCompatibility: config.versionCompatibility,\n currentValue: config.currentValue,\n packageName: config.packageName,\n groups: regexMatch.groups,\n },\n 'version compatibility regex match',\n );\n config.currentCompatibility = regexMatch.groups.compatibility;\n compareValue = regexMatch.groups.version;\n } else {\n logger.debug(\n {\n versionCompatibility: config.versionCompatibility,\n currentValue: config.currentValue,\n packageName: config.packageName,\n },\n 'version compatibility regex mismatch',\n );\n }\n }\n\n const isValid =\n isString(compareValue) && versioningApi.isValid(compareValue);\n\n const unconstrainedValue =\n !!config.lockedVersion && isUndefined(config.currentValue);\n\n if (isValid || unconstrainedValue) {\n if (\n !config.updatePinnedDependencies &&\n // TODO #22198\n versioningApi.isSingleVersion(compareValue!)\n ) {\n res.skipReason = 'is-pinned';\n return Result.ok(res);\n }\n\n const { val: releaseResult, err: lookupError } = await getRawPkgReleases(\n config,\n )\n .transform((res) => calculateMostRecentTimestamp(versioningApi, res))\n .transform((res) => calculateAbandonment(res, config))\n .transform((res) => applyDatasourceFilters(res, config))\n .unwrap();\n\n if (lookupError instanceof Error) {\n throw lookupError;\n }\n\n if (lookupError) {\n // If dependency lookup fails then warn and return\n const warning: ValidationMessage = {\n topic: config.packageName,\n message: `Failed to look up ${config.datasource} package ${config.packageName}: ${lookupError}`,\n };\n logger.debug(\n {\n dependency: config.packageName,\n packageFile: config.packageFile,\n },\n warning.message,\n );\n // TODO: return warnings in own field\n res.warnings.push(warning);\n return Result.ok(res);\n }\n\n dependency = releaseResult;\n\n if (dependency.deprecationMessage) {\n logger.debug(\n `Found deprecationMessage for ${config.datasource} package ${config.packageName}`,\n );\n }\n\n assignKeys(res, dependency, [\n 'deprecationMessage',\n 'sourceUrl',\n 'registryUrl',\n 'sourceDirectory',\n 'homepage',\n 'changelogUrl',\n 'dependencyUrl',\n 'lookupName',\n 'packageScope',\n 'mostRecentTimestamp',\n 'isAbandoned',\n 'respectLatest',\n ]);\n\n const latestVersion = dependency.tags?.latest;\n // Filter out any results from datasource that don't comply with our versioning\n let allVersions = dependency.releases.filter((release) =>\n versioningApi.isVersion(release.version),\n );\n const allReleaseVersions = new Set(allVersions.map((r) => r.version));\n // istanbul ignore if\n if (allVersions.length === 0) {\n const message = `Found no results from datasource that look like a version`;\n logger.info(\n {\n dependency: config.packageName,\n result: dependency,\n },\n message,\n );\n if (!config.currentDigest) {\n return Result.ok(res);\n }\n }\n // Reapply package rules in case we missed something from sourceUrl\n config = await applyPackageRules(\n { ...config, sourceUrl: res.sourceUrl },\n 'source-url',\n );\n if (config.followTag) {\n const taggedVersion = dependency.tags?.[config.followTag];\n if (!taggedVersion) {\n res.warnings.push({\n topic: config.packageName,\n message: `Can't find version with tag ${config.followTag} for ${config.datasource} package ${config.packageName}`,\n });\n return Result.ok(res);\n }\n allVersions = allVersions.filter(\n (v) =>\n v.version === taggedVersion ||\n (v.version === compareValue &&\n versioningApi.isGreaterThan(taggedVersion, compareValue)),\n );\n }\n\n const inRangeOnlyStrategy = config.rangeStrategy === 'in-range-only';\n // Check that existing constraint can be satisfied\n const allSatisfyingVersions =\n (inRangeOnlyStrategy || config.rollbackPrs) && !unconstrainedValue\n ? allVersions.filter((v) =>\n // TODO #22198\n versioningApi.matches(v.version, compareValue!),\n )\n : allVersions;\n if (!allSatisfyingVersions.length) {\n logger.debug(\n `Found no satisfying versions with '${config.versioning}' versioning`,\n );\n }\n\n if (config.rollbackPrs && !allSatisfyingVersions.length) {\n const rollback = getRollbackUpdate(config, allVersions, versioningApi);\n // istanbul ignore if\n if (!rollback) {\n res.warnings.push({\n topic: config.packageName,\n // TODO: types (#22198)\n message: `Can't find version matching ${compareValue!} for ${\n config.datasource\n } package ${config.packageName}`,\n });\n return Result.ok(res);\n }\n res.updates.push(rollback);\n }\n let rangeStrategy = getRangeStrategy(config);\n\n // istanbul ignore next\n if (\n config.isVulnerabilityAlert &&\n rangeStrategy === 'update-lockfile' &&\n !config.lockedVersion\n ) {\n rangeStrategy = 'bump';\n }\n // unconstrained deps with lockedVersion\n if (\n config.isVulnerabilityAlert &&\n !config.currentValue &&\n config.lockedVersion\n ) {\n rangeStrategy = 'update-lockfile';\n }\n const nonDeprecatedVersions = dependency.releases\n .filter((release) => !release.isDeprecated)\n .map((release) => release.version);\n let currentVersion: string;\n if (rangeStrategy === 'update-lockfile') {\n currentVersion = config.lockedVersion!;\n } else if (\n compareValue &&\n versioningApi.isSingleVersion(compareValue) &&\n allVersions.find((v) => v.version === compareValue)\n ) {\n currentVersion = compareValue;\n }\n // TODO #22198\n currentVersion ??=\n getCurrentVersion(\n compareValue!,\n config.lockedVersion!,\n versioningApi,\n rangeStrategy!,\n latestVersion!,\n nonDeprecatedVersions,\n ) ??\n getCurrentVersion(\n compareValue!,\n config.lockedVersion!,\n versioningApi,\n rangeStrategy!,\n latestVersion!,\n allVersions.map((v) => v.version),\n )!;\n\n if (!currentVersion) {\n // v8 ignore else -- TODO: add test #40625\n if (!config.lockedVersion) {\n logger.debug(\n `No currentVersion or lockedVersion found for ${config.packageName}`,\n );\n res.skipReason = 'invalid-value';\n }\n return Result.ok(res);\n }\n\n res.currentVersion = currentVersion;\n\n // Use lockedVersion for the timestamp lookup when available, because\n // res.currentVersion is later overwritten to lockedVersion (see below).\n // Without this, strategies like \"replace\" would compute the timestamp\n // for the highest satisfying version (e.g. 1.4.1) while the reported\n // currentVersion ends up being the locked one (e.g. 1.0.0).\n const versionForTimestamp = config.lockedVersion ?? currentVersion;\n const currentVersionTimestamp = await getTimestamp(\n config,\n allVersions,\n versionForTimestamp,\n versioningApi,\n );\n\n if (isNonEmptyString(currentVersionTimestamp)) {\n res.currentVersionTimestamp = currentVersionTimestamp;\n res.currentVersionAgeInDays = getElapsedDays(currentVersionTimestamp);\n\n if (\n config.packageRules?.some((rule) =>\n isNonEmptyString(rule.matchCurrentAge),\n )\n ) {\n // Reapply package rules to check matches for matchCurrentAge\n config = await applyPackageRules(\n { ...config, currentVersionTimestamp },\n 'current-timestamp',\n );\n }\n }\n\n if (config.currentDigest && couldApplyMinimumReleaseAgeToDigest(config)) {\n // Resolve from `allVersions` (not `dependency.releases`) so that filters like followTag apply, preferring non-deprecated versions with a fallback - both like the `currentVersion` resolution above.\n const newestMatchingVersion =\n getCurrentVersion(\n compareValue!,\n '',\n versioningApi,\n 'replace',\n latestVersion!,\n allVersions.filter((v) => !v.isDeprecated).map((v) => v.version),\n ) ??\n getCurrentVersion(\n compareValue!,\n '',\n versioningApi,\n 'replace',\n latestVersion!,\n allVersions.map((v) => v.version),\n );\n if (newestMatchingVersion) {\n newestMatchingVersionTimestamp = await getTimestamp(\n config,\n allVersions,\n newestMatchingVersion,\n versioningApi,\n );\n }\n }\n\n if (\n compareValue &&\n currentVersion &&\n rangeStrategy === 'pin' &&\n !versioningApi.isSingleVersion(compareValue)\n ) {\n const newValue =\n versioningApi.getPinnedValue?.(currentVersion) ?? currentVersion;\n res.updates.push({\n updateType: 'pin',\n isPin: true,\n newValue,\n newVersion: currentVersion,\n newMajor: versioningApi.getMajor(currentVersion)!,\n });\n }\n if (rangeStrategy === 'pin') {\n // Fall back to replace once pinning logic is done\n rangeStrategy = 'replace';\n }\n // istanbul ignore if\n if (!versioningApi.isVersion(currentVersion!)) {\n res.skipReason = 'invalid-version';\n return Result.ok(res);\n }\n // Filter latest, unstable, etc\n // TODO #22198\n let filteredReleases = filterVersions(\n config,\n currentVersion!,\n latestVersion!,\n inRangeOnlyStrategy ? allSatisfyingVersions : allVersions,\n versioningApi,\n ).filter(\n (v) =>\n // Leave only compatible versions\n unconstrainedValue ||\n versioningApi.isCompatible(v.version, compareValue),\n );\n let shrinkedViaVulnerability = false;\n if (config.isVulnerabilityAlert) {\n if (config.vulnerabilityFixVersion) {\n res.vulnerabilityFixVersion = config.vulnerabilityFixVersion;\n res.vulnerabilityFixStrategy = config.vulnerabilityFixStrategy;\n if (versioningApi.isValid(config.vulnerabilityFixVersion)) {\n let fixedFilteredReleases;\n if (versioningApi.isVersion(config.vulnerabilityFixVersion)) {\n // Retain only releases greater than or equal to the fix version\n fixedFilteredReleases = filteredReleases.filter(\n (release) =>\n !versioningApi.isGreaterThan(\n config.vulnerabilityFixVersion!,\n release.version,\n ),\n );\n } else {\n // Retain only releases which max the fix constraint\n fixedFilteredReleases = filteredReleases.filter((release) =>\n versioningApi.matches(\n release.version,\n config.vulnerabilityFixVersion!,\n ),\n );\n }\n // Warn if this filtering results caused zero releases\n if (fixedFilteredReleases.length === 0 && filteredReleases.length) {\n logger.warn(\n {\n releases: filteredReleases,\n vulnerabilityFixVersion: config.vulnerabilityFixVersion,\n packageName: config.packageName,\n },\n 'No releases satisfy vulnerabilityFixVersion',\n );\n }\n // Use the additionally filtered releases\n filteredReleases = fixedFilteredReleases;\n } else {\n logger.warn(\n {\n vulnerabilityFixVersion: config.vulnerabilityFixVersion,\n packageName: config.packageName,\n },\n 'vulnerabilityFixVersion is not valid',\n );\n }\n }\n if (config.vulnerabilityFixStrategy === 'highest') {\n // Don't shrink the list of releases - let Renovate use its normal logic\n logger.once.debug(\n `Using vulnerabilityFixStrategy=highest for ${config.packageName}`,\n );\n } else {\n // Shrink the list of releases to the lowest fixed version\n logger.once.debug(\n `Using vulnerabilityFixStrategy=lowest for ${config.packageName}`,\n );\n filteredReleases = filteredReleases.slice(0, 1);\n shrinkedViaVulnerability = true;\n }\n }\n const buckets: Record<string, [Release]> = {};\n for (const release of filteredReleases) {\n const bucket = getBucket(\n config,\n // TODO #22198\n currentVersion!,\n release.version,\n versioningApi,\n );\n // v8 ignore else -- TODO: add test #40625\n if (isString(bucket)) {\n if (buckets[bucket]) {\n buckets[bucket].push(release);\n } else {\n buckets[bucket] = [release];\n }\n }\n }\n const depResultConfig = mergeChildConfig(config, res);\n for (const [bucket, releases] of Object.entries(buckets)) {\n const sortedReleases = releases.sort((r1, r2) =>\n versioningApi.sortVersions(r1.version, r2.version),\n );\n const { release, pendingChecks, pendingReleases } =\n await filterInternalChecks(\n depResultConfig,\n versioningApi,\n bucket,\n sortedReleases,\n );\n // istanbul ignore next\n if (!release) {\n return Result.ok(res);\n }\n const newVersion = release.version;\n const update = await generateUpdate(\n config,\n compareValue,\n versioningApi,\n // TODO #22198\n\n rangeStrategy!,\n config.lockedVersion ?? currentVersion!,\n bucket,\n release,\n allReleaseVersions,\n );\n\n // #29034\n if (\n config.manager === 'gomod' &&\n compareValue?.startsWith('v0.0.0-') &&\n update.newValue?.startsWith('v0.0.0-') &&\n config.currentDigest !== update.newDigest\n ) {\n update.updateType = 'digest';\n\n // As this has already been processed by `filterInternalChecks()`, but we're changing the `updateType`, we need to apply the digest-scoped minimumReleaseAge rules\n await applyMinimumReleaseAgeToDigestUpdate(\n update as DigestLikeUpdate,\n config,\n res,\n release.releaseTimestamp,\n );\n }\n\n if (pendingChecks) {\n update.pendingChecks = pendingChecks;\n }\n\n if (pendingReleases.length) {\n update.pendingVersions = pendingReleases.map((r) => r.version);\n }\n if (!update.newValue || update.newValue === compareValue) {\n if (!config.lockedVersion) {\n continue;\n }\n // istanbul ignore if\n if (rangeStrategy === 'bump') {\n logger.trace(\n {\n packageName: config.packageName,\n currentValue: config.currentValue,\n lockedVersion: config.lockedVersion,\n newVersion,\n },\n 'Skipping bump because newValue is the same',\n );\n continue;\n }\n res.isSingleVersion = true;\n }\n res.isSingleVersion ??=\n isString(update.newValue) &&\n versioningApi.isSingleVersion(update.newValue);\n // istanbul ignore if\n if (\n config.versioning === dockerVersioningId &&\n update.updateType !== 'rollback' &&\n update.newValue &&\n versioningApi.isVersion(update.newValue) &&\n compareValue &&\n versioningApi.isVersion(compareValue) &&\n versioningApi.isGreaterThan(compareValue, update.newValue)\n ) {\n logger.warn(\n {\n packageName: config.packageName,\n currentValue: config.currentValue,\n compareValue,\n currentVersion: config.currentVersion,\n update,\n allVersionsLength: allVersions.length,\n filteredReleaseVersions: filteredReleases.map((r) => r.version),\n shrinkedViaVulnerability,\n },\n 'Unexpected downgrade detected: skipping',\n );\n } else {\n res.updates.push(update);\n }\n }\n } else if (compareValue) {\n logger.debug(\n `Dependency ${config.packageName} has unsupported/unversioned value ${compareValue} (versioning=${config.versioning})`,\n );\n\n if (!config.pinDigests && !config.currentDigest) {\n logger.debug(\n `Skipping ${config.packageName} because no currentDigest or pinDigests`,\n );\n res.skipReason = 'invalid-value';\n } else {\n delete res.skipReason;\n }\n } else {\n res.skipReason = 'invalid-value';\n }\n\n if (isReplacementRulesConfigured(config)) {\n addReplacementUpdateIfValid(res.updates, config);\n } else if (dependency?.replacementName && dependency.replacementVersion) {\n res.updates.push({\n updateType: 'replacement',\n newName: dependency.replacementName,\n newValue: dependency.replacementVersion,\n });\n }\n\n // Record if the dep is fixed to a version\n if (config.lockedVersion) {\n res.currentVersion = config.lockedVersion;\n res.fixedVersion = config.lockedVersion;\n } else if (compareValue && versioningApi.isSingleVersion(compareValue)) {\n res.fixedVersion = compareValue.replace(regEx(/^=+/), '');\n }\n\n // massage versionCompatibility\n if (\n isString(config.currentValue) &&\n isString(compareValue) &&\n isString(config.versionCompatibility)\n ) {\n for (const update of res.updates) {\n logger.debug({ update });\n // v8 ignore else -- TODO: add test #40625\n if (isString(config.currentValue) && isString(update.newValue)) {\n update.newValue = config.currentValue.replace(\n compareValue,\n update.newValue,\n );\n }\n }\n }\n\n // Add digests if necessary\n if (supportsDigests(config.datasource)) {\n if (config.currentDigest) {\n if (!config.digestOneAndOnly || !res.updates.length) {\n // digest update - age-checked after the strip below, once newDigest is known\n digestUpdate = {\n updateType: 'digest',\n newValue: config.currentValue,\n };\n res.updates.push(digestUpdate);\n }\n } else if (\n config.pinDigests &&\n // Create a pin only if one doesn't already exists\n // v8 ignore else -- TODO: add test #40625\n !res.updates.some((update) => update.updateType === 'pin')\n ) {\n // pin digest\n res.updates.push({\n isPinDigest: true,\n updateType: 'pinDigest',\n newValue: config.currentValue,\n });\n }\n if (versioningApi.valueToVersion) {\n // TODO #22198\n res.currentVersion = versioningApi.valueToVersion(res.currentVersion!);\n for (const update of res.updates) {\n // TODO #22198\n update.newVersion = versioningApi.valueToVersion(update.newVersion!);\n }\n }\n if (res.registryUrl) {\n config.registryUrls = [res.registryUrl];\n }\n\n // update digest for all\n for (const update of res.updates) {\n if (config.pinDigests === true || config.currentDigest) {\n const getDigestConfig: GetDigestInputConfig = {\n ...config,\n registryUrl: update.registryUrl ?? res.registryUrl,\n lookupName: res.lookupName,\n };\n\n // #20304 only pass it for replacement updates, otherwise we get wrong or invalid digest\n if (update.updateType !== 'replacement') {\n delete getDigestConfig.replacementName;\n }\n\n // #20304 don't use lookupName and currentDigest when we replace image name\n if (\n update.updateType === 'replacement' &&\n update.newName !== config.packageName\n ) {\n delete getDigestConfig.lookupName;\n delete getDigestConfig.currentDigest;\n getDigestConfig.replacementName = update.newName;\n }\n\n // Don't use current releases if replacement changes name, otherwise we use the wrong new digest.\n // This happens on datasources which return the digest in release info like `github-tags`.\n // We can still use it when only version is changing.\n if (\n update.updateType !== 'replacement' ||\n update.newName === config.packageName\n ) {\n update.newDigest ??= dependency?.releases.find(\n (r) => r.version === update.newValue,\n )?.newDigest;\n }\n\n update.newDigest ??= await getDigest(\n getDigestConfig,\n update.newValue,\n );\n\n // If the digest could not be determined, report this as otherwise the\n // update will be omitted later on without notice.\n if (update.newDigest === null) {\n logger.debug(\n {\n packageName: config.packageName,\n currentValue: config.currentValue,\n datasource: config.datasource,\n newValue: update.newValue,\n bucket: update.bucket,\n },\n 'Could not determine new digest for update.',\n );\n\n // Only report a warning if there is a current digest.\n // Context: https://github.com/renovatebot/renovate/pull/20175#discussion_r1102615059.\n if (config.currentDigest) {\n res.warnings.push({\n message: `Could not determine new digest for update (${config.datasource} package ${config.packageName})`,\n topic: config.packageName,\n });\n }\n }\n } else {\n delete update.newDigest;\n }\n if (update.newVersion) {\n const registryUrl = dependency?.releases?.find(\n (release) => release.version === update.newVersion,\n )?.registryUrl;\n if (registryUrl && registryUrl !== res.registryUrl) {\n update.registryUrl = registryUrl;\n }\n }\n }\n }\n\n if (res.updates.length) {\n delete res.skipReason;\n }\n // Strip out any non-changed ones\n res.updates = res.updates\n .filter(\n (update) => update.newValue !== null || config.currentValue === null,\n )\n .filter((update) => update.newDigest !== null)\n .filter(\n (update) =>\n (isString(update.newName) && update.newName !== config.packageName) ||\n update.isReplacement === true ||\n update.newValue !== config.currentValue ||\n update.isLockfileUpdate === true ||\n // TODO #22198\n (update.newDigest &&\n !update.newDigest.startsWith(config.currentDigest!)),\n );\n // If range strategy specified in config is 'in-range-only', also strip out updates where currentValue !== newValue\n if (config.rangeStrategy === 'in-range-only') {\n res.updates = res.updates.filter(\n (update) => update.newValue === config.currentValue,\n );\n }\n // Handle a weird edge case involving followTag and fallbacks\n if (config.rollbackPrs && config.followTag) {\n res.updates = res.updates.filter(\n (update) =>\n update.updateType !== 'rollback' || res.updates.length === 1,\n );\n }\n\n // If there is a digest update proposed which is in the pending updates for this dependency, ensure that `minimumReleaseAge` is applied\n if (digestUpdate && res.updates.includes(digestUpdate)) {\n await applyMinimumReleaseAgeToDigestUpdate(\n digestUpdate,\n config,\n res,\n newestMatchingVersionTimestamp,\n );\n }\n\n const release =\n res.updates.length > 0\n ? (dependency?.releases.find(\n (r) => r.version === res.updates[0].newValue,\n ) ??\n dependency?.releases.find(\n (r) => r.version === res.updates[0].newVersion,\n ))\n : null;\n\n if (release?.changelogContent) {\n res.changelogContent = release.changelogContent;\n res.changelogUrl = release.changelogUrl;\n }\n } catch (err) /* istanbul ignore next */ {\n if (err instanceof ExternalHostError) {\n return Result.err(err);\n }\n\n if (err instanceof Error && err.message === CONFIG_VALIDATION) {\n return Result.err(err);\n }\n\n logger.error(\n {\n currentDigest: config.currentDigest,\n currentValue: config.currentValue,\n datasource: config.datasource,\n packageName: config.packageName,\n digestOneAndOnly: config.digestOneAndOnly,\n followTag: config.followTag,\n lockedVersion: config.lockedVersion,\n packageFile: config.packageFile,\n pinDigests: config.pinDigests,\n rollbackPrs: config.rollbackPrs,\n isVulnerabilityAlert: config.isVulnerabilityAlert,\n updatePinnedDependencies: config.updatePinnedDependencies,\n err,\n },\n 'lookupUpdates error',\n );\n res.skipReason = 'internal-error';\n }\n return Result.ok(res);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgDA,eAAe,aACb,QACA,UACA,SACA,eACuC;CACvC,MAAM,iBAAiB,SAAS,MAC7B,MACC,cAAc,QAAQ,EAAE,OAAO,KAC/B,cAAc,OAAO,EAAE,SAAS,OAAO,CAC3C;CAEA,IAAI,CAAC,gBACH,OAAO;CAGT,IAAI,eAAe,kBACjB,OAAO,eAAe;CAIxB,QAAO,MADqB,mBAAmB,QAAQ,cAAc,EAAA,EAC/C;AACxB;;;;;;AAUA,SAAS,oCACP,QACS;CAIT,IAAI,OAAO,yBAAyB,QAClC,OAAO;CAGT,OACE,iBAAiB,OAAO,iBAAiB,KACzC,iBAAiB,OAAO,QAAQ,iBAAiB,KACjD,CAAC,CAAC,OAAO,cAAc,MAAM,SAC3B,iBAAiB,KAAK,iBAAiB,CACzC;AAEJ;;;;;;AAOA,eAAe,qCACb,QACA,QACA,KACA,gCACe;CACf,IAAI,CAAC,oCAAoC,MAAM,GAC7C;CAGF,IAAI,gBAAoC;EACtC,GAAG,iBAAiB,QAAQ,GAAG;EAC/B,YAAY,OAAO;CACrB;CACA,gBAAgB,iBACd,eACA,cAAc,OAAO,WACvB;CACA,gBAAgB,MAAM,kBAAkB,eAAe,aAAa;CAEpE,MAAM,WAAW,uBACf,eAEA,8BACF;CAGA,IAAI,SAAS,uBAAuB,CAAC,SAAS,cAAc;EAC1D,IAAI,cAAc,+BAA+B,sBAC/C,OAAO,KAAK,KACV,2KACF;EAGF,OAAO,KAAK,MACV;GACE,SAAS,OAAO;GAChB,YAAY,OAAO;GACnB,4BAA4B,cAAc;GAC1C,OAAO;EACT,GACA,GAAG,OAAO,WAAW,aAAa,OAAO,QAAQ,wCACnD;CACF;CACA,IAAI,SAAS,WAAW;EACtB,OAAO,MACL;GACE,SAAS,OAAO;GAChB,YAAY,OAAO;GACnB,kBAAkB;GAClB,OAAO;EACT,GACA,GAAG,OAAO,WAAW,mDACvB;EAGA,IAAI,OAAO,yBAAyB,UAClC,OAAO,gBAAgB;CAE3B;AACF;AAEA,eAAsB,cACpB,UAC+B;CAC/B,IAAI,SAA6B,EAAE,GAAG,SAAS;CAC/C,OAAO,eAAe,qBAAqB,OAAO,UAAU;CAE5D,MAAM,gBAAgBA,IAAkB,OAAO,UAAU;CAEzD,IAAI,aAAmC;CACvC,MAAM,MAAoB;EACxB,YAAY,OAAO;EACnB,SAAS,CAAC;EACV,UAAU,CAAC;CACb;CAEA,IAAI;CAEJ,IAAI;CAEJ,IAAI;EACF,OAAO,MACL;GACE,YAAY,OAAO;GACnB,cAAc,OAAO;EACvB,GACA,eACF;EACA,IAAI,OAAO,gBAAgB,CAAC,SAAS,OAAO,YAAY,GAAG;;GAGzD,IAAI,OAAO,cACT,OAAO,MACL,4BAA4B,OAAO,YAAY,IAAI,KAAK,UAAU,OAAO,YAAY,EAAE,IAAI,OAAO,OAAO,aAAa,EACxH;GAEF,IAAI,aAAa;GACjB,OAAO,OAAO,GAAG,GAAG;EACtB;EACA,IACE,CAAC,uBAAuB,MAAM,KAC9B,CAAC,iBAAiB,OAAO,UAAU,GACnC;GACA,IAAI,aAAa;GACjB,OAAO,OAAO,GAAG,GAAG;EACtB;EACA,IAAI,eAAe,OAAO;EAC1B,IACE,SAAS,OAAO,YAAY,KAC5B,SAAS,OAAO,oBAAoB,GACpC;GAEA,MAAM,aAD2B,MAAM,OAAO,oBACJ,CAAC,CAAC,KAAK,OAAO,YAAY;GACpE,IAAI,YAAY,QAAQ;IACtB,OAAO,MACL;KACE,sBAAsB,OAAO;KAC7B,cAAc,OAAO;KACrB,aAAa,OAAO;KACpB,QAAQ,WAAW;IACrB,GACA,mCACF;IACA,OAAO,uBAAuB,WAAW,OAAO;IAChD,eAAe,WAAW,OAAO;GACnC,OACE,OAAO,MACL;IACE,sBAAsB,OAAO;IAC7B,cAAc,OAAO;IACrB,aAAa,OAAO;GACtB,GACA,sCACF;EAEJ;EAEA,MAAM,UACJ,SAAS,YAAY,KAAK,cAAc,QAAQ,YAAY;EAE9D,MAAM,qBACJ,CAAC,CAAC,OAAO,iBAAiB,YAAY,OAAO,YAAY;EAE3D,IAAI,WAAW,oBAAoB;GACjC,IACE,CAAC,OAAO,4BAER,cAAc,gBAAgB,YAAa,GAC3C;IACA,IAAI,aAAa;IACjB,OAAO,OAAO,GAAG,GAAG;GACtB;GAEA,MAAM,EAAE,KAAK,eAAe,KAAK,gBAAgB,MAAM,kBACrD,MACF,CAAC,CACE,WAAW,QAAQ,6BAA6B,eAAe,GAAG,CAAC,CAAC,CACpE,WAAW,QAAQ,qBAAqB,KAAK,MAAM,CAAC,CAAC,CACrD,WAAW,QAAQ,uBAAuB,KAAK,MAAM,CAAC,CAAC,CACvD,OAAO;GAEV,IAAI,uBAAuB,OACzB,MAAM;GAGR,IAAI,aAAa;IAEf,MAAM,UAA6B;KACjC,OAAO,OAAO;KACd,SAAS,qBAAqB,OAAO,WAAW,WAAW,OAAO,YAAY,IAAI;IACpF;IACA,OAAO,MACL;KACE,YAAY,OAAO;KACnB,aAAa,OAAO;IACtB,GACA,QAAQ,OACV;IAEA,IAAI,SAAS,KAAK,OAAO;IACzB,OAAO,OAAO,GAAG,GAAG;GACtB;GAEA,aAAa;GAEb,IAAI,WAAW,oBACb,OAAO,MACL,gCAAgC,OAAO,WAAW,WAAW,OAAO,aACtE;GAGF,WAAW,KAAK,YAAY;IAC1B;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;GACF,CAAC;GAED,MAAM,gBAAgB,WAAW,MAAM;GAEvC,IAAI,cAAc,WAAW,SAAS,QAAQ,YAC5C,cAAc,UAAU,QAAQ,OAAO,CACzC;GACA,MAAM,qBAAqB,IAAI,IAAI,YAAY,KAAK,MAAM,EAAE,OAAO,CAAC;;GAEpE,IAAI,YAAY,WAAW,GAAG;IAE5B,OAAO,KACL;KACE,YAAY,OAAO;KACnB,QAAQ;IACV,GACA,2DACF;IACA,IAAI,CAAC,OAAO,eACV,OAAO,OAAO,GAAG,GAAG;GAExB;GAEA,SAAS,MAAM,kBACb;IAAE,GAAG;IAAQ,WAAW,IAAI;GAAU,GACtC,YACF;GACA,IAAI,OAAO,WAAW;IACpB,MAAM,gBAAgB,WAAW,OAAO,OAAO;IAC/C,IAAI,CAAC,eAAe;KAClB,IAAI,SAAS,KAAK;MAChB,OAAO,OAAO;MACd,SAAS,+BAA+B,OAAO,UAAU,OAAO,OAAO,WAAW,WAAW,OAAO;KACtG,CAAC;KACD,OAAO,OAAO,GAAG,GAAG;IACtB;IACA,cAAc,YAAY,QACvB,MACC,EAAE,YAAY,iBACb,EAAE,YAAY,gBACb,cAAc,cAAc,eAAe,YAAY,CAC7D;GACF;GAEA,MAAM,sBAAsB,OAAO,kBAAkB;GAErD,MAAM,yBACH,uBAAuB,OAAO,gBAAgB,CAAC,qBAC5C,YAAY,QAAQ,MAElB,cAAc,QAAQ,EAAE,SAAS,YAAa,CAChD,IACA;GACN,IAAI,CAAC,sBAAsB,QACzB,OAAO,MACL,sCAAsC,OAAO,WAAW,aAC1D;GAGF,IAAI,OAAO,eAAe,CAAC,sBAAsB,QAAQ;IACvD,MAAM,WAAW,kBAAkB,QAAQ,aAAa,aAAa;;IAErE,IAAI,CAAC,UAAU;KACb,IAAI,SAAS,KAAK;MAChB,OAAO,OAAO;MAEd,SAAS,+BAA+B,aAAc,OACpD,OAAO,WACR,WAAW,OAAO;KACrB,CAAC;KACD,OAAO,OAAO,GAAG,GAAG;IACtB;IACA,IAAI,QAAQ,KAAK,QAAQ;GAC3B;GACA,IAAI,gBAAgB,iBAAiB,MAAM;;GAG3C,IACE,OAAO,wBACP,kBAAkB,qBAClB,CAAC,OAAO,eAER,gBAAgB;GAGlB,IACE,OAAO,wBACP,CAAC,OAAO,gBACR,OAAO,eAEP,gBAAgB;GAElB,MAAM,wBAAwB,WAAW,SACtC,QAAQ,YAAY,CAAC,QAAQ,YAAY,CAAC,CAC1C,KAAK,YAAY,QAAQ,OAAO;GACnC,IAAI;GACJ,IAAI,kBAAkB,mBACpB,iBAAiB,OAAO;QACnB,IACL,gBACA,cAAc,gBAAgB,YAAY,KAC1C,YAAY,MAAM,MAAM,EAAE,YAAY,YAAY,GAElD,iBAAiB;GAGnB,mBACE,kBACE,cACA,OAAO,eACP,eACA,eACA,eACA,qBACF,KACA,kBACE,cACA,OAAO,eACP,eACA,eACA,eACA,YAAY,KAAK,MAAM,EAAE,OAAO,CAClC;GAEF,IAAI,CAAC,gBAAgB;;IAEnB,IAAI,CAAC,OAAO,eAAe;KACzB,OAAO,MACL,gDAAgD,OAAO,aACzD;KACA,IAAI,aAAa;IACnB;IACA,OAAO,OAAO,GAAG,GAAG;GACtB;GAEA,IAAI,iBAAiB;GAOrB,MAAM,sBAAsB,OAAO,iBAAiB;GACpD,MAAM,0BAA0B,MAAM,aACpC,QACA,aACA,qBACA,aACF;GAEA,IAAI,iBAAiB,uBAAuB,GAAG;IAC7C,IAAI,0BAA0B;IAC9B,IAAI,0BAA0B,eAAe,uBAAuB;IAEpE,IACE,OAAO,cAAc,MAAM,SACzB,iBAAiB,KAAK,eAAe,CACvC,GAGA,SAAS,MAAM,kBACb;KAAE,GAAG;KAAQ;IAAwB,GACrC,mBACF;GAEJ;GAEA,IAAI,OAAO,iBAAiB,oCAAoC,MAAM,GAAG;IAEvE,MAAM,wBACJ,kBACE,cACA,IACA,eACA,WACA,eACA,YAAY,QAAQ,MAAM,CAAC,EAAE,YAAY,CAAC,CAAC,KAAK,MAAM,EAAE,OAAO,CACjE,KACA,kBACE,cACA,IACA,eACA,WACA,eACA,YAAY,KAAK,MAAM,EAAE,OAAO,CAClC;IACF,IAAI,uBACF,iCAAiC,MAAM,aACrC,QACA,aACA,uBACA,aACF;GAEJ;GAEA,IACE,gBACA,kBACA,kBAAkB,SAClB,CAAC,cAAc,gBAAgB,YAAY,GAC3C;IACA,MAAM,WACJ,cAAc,iBAAiB,cAAc,KAAK;IACpD,IAAI,QAAQ,KAAK;KACf,YAAY;KACZ,OAAO;KACP;KACA,YAAY;KACZ,UAAU,cAAc,SAAS,cAAc;IACjD,CAAC;GACH;GACA,IAAI,kBAAkB,OAEpB,gBAAgB;;GAGlB,IAAI,CAAC,cAAc,UAAU,cAAe,GAAG;IAC7C,IAAI,aAAa;IACjB,OAAO,OAAO,GAAG,GAAG;GACtB;GAGA,IAAI,mBAAmB,eACrB,QACA,gBACA,eACA,sBAAsB,wBAAwB,aAC9C,aACF,CAAC,CAAC,QACC,MAEC,sBACA,cAAc,aAAa,EAAE,SAAS,YAAY,CACtD;GACA,IAAI,2BAA2B;GAC/B,IAAI,OAAO,sBAAsB;IAC/B,IAAI,OAAO,yBAAyB;KAClC,IAAI,0BAA0B,OAAO;KACrC,IAAI,2BAA2B,OAAO;KACtC,IAAI,cAAc,QAAQ,OAAO,uBAAuB,GAAG;MACzD,IAAI;MACJ,IAAI,cAAc,UAAU,OAAO,uBAAuB,GAExD,wBAAwB,iBAAiB,QACtC,YACC,CAAC,cAAc,cACb,OAAO,yBACP,QAAQ,OACV,CACJ;WAGA,wBAAwB,iBAAiB,QAAQ,YAC/C,cAAc,QACZ,QAAQ,SACR,OAAO,uBACT,CACF;MAGF,IAAI,sBAAsB,WAAW,KAAK,iBAAiB,QACzD,OAAO,KACL;OACE,UAAU;OACV,yBAAyB,OAAO;OAChC,aAAa,OAAO;MACtB,GACA,6CACF;MAGF,mBAAmB;KACrB,OACE,OAAO,KACL;MACE,yBAAyB,OAAO;MAChC,aAAa,OAAO;KACtB,GACA,sCACF;IAEJ;IACA,IAAI,OAAO,6BAA6B,WAEtC,OAAO,KAAK,MACV,8CAA8C,OAAO,aACvD;SACK;KAEL,OAAO,KAAK,MACV,6CAA6C,OAAO,aACtD;KACA,mBAAmB,iBAAiB,MAAM,GAAG,CAAC;KAC9C,2BAA2B;IAC7B;GACF;GACA,MAAM,UAAqC,CAAC;GAC5C,KAAK,MAAM,WAAW,kBAAkB;IACtC,MAAM,SAAS,UACb,QAEA,gBACA,QAAQ,SACR,aACF;;IAEA,IAAI,SAAS,MAAM,GACjB,IAAI,QAAQ,SACV,QAAQ,OAAO,CAAC,KAAK,OAAO;SAE5B,QAAQ,UAAU,CAAC,OAAO;GAGhC;GACA,MAAM,kBAAkB,iBAAiB,QAAQ,GAAG;GACpD,KAAK,MAAM,CAAC,QAAQ,aAAa,OAAO,QAAQ,OAAO,GAAG;IAIxD,MAAM,EAAE,SAAS,eAAe,oBAC9B,MAAM,qBACJ,iBACA,eACA,QAPmB,SAAS,MAAM,IAAI,OACxC,cAAc,aAAa,GAAG,SAAS,GAAG,OAAO,CAOlC,CACf;;IAEF,IAAI,CAAC,SACH,OAAO,OAAO,GAAG,GAAG;IAEtB,MAAM,aAAa,QAAQ;IAC3B,MAAM,SAAS,MAAM,eACnB,QACA,cACA,eAGA,eACA,OAAO,iBAAiB,gBACxB,QACA,SACA,kBACF;IAGA,IACE,OAAO,YAAY,WACnB,cAAc,WAAW,SAAS,KAClC,OAAO,UAAU,WAAW,SAAS,KACrC,OAAO,kBAAkB,OAAO,WAChC;KACA,OAAO,aAAa;KAGpB,MAAM,qCACJ,QACA,QACA,KACA,QAAQ,gBACV;IACF;IAEA,IAAI,eACF,OAAO,gBAAgB;IAGzB,IAAI,gBAAgB,QAClB,OAAO,kBAAkB,gBAAgB,KAAK,MAAM,EAAE,OAAO;IAE/D,IAAI,CAAC,OAAO,YAAY,OAAO,aAAa,cAAc;KACxD,IAAI,CAAC,OAAO,eACV;;KAGF,IAAI,kBAAkB,QAAQ;MAC5B,OAAO,MACL;OACE,aAAa,OAAO;OACpB,cAAc,OAAO;OACrB,eAAe,OAAO;OACtB;MACF,GACA,4CACF;MACA;KACF;KACA,IAAI,kBAAkB;IACxB;IACA,IAAI,oBACF,SAAS,OAAO,QAAQ,KACxB,cAAc,gBAAgB,OAAO,QAAQ;;IAE/C,IACE,OAAO,eAAA,YACP,OAAO,eAAe,cACtB,OAAO,YACP,cAAc,UAAU,OAAO,QAAQ,KACvC,gBACA,cAAc,UAAU,YAAY,KACpC,cAAc,cAAc,cAAc,OAAO,QAAQ,GAEzD,OAAO,KACL;KACE,aAAa,OAAO;KACpB,cAAc,OAAO;KACrB;KACA,gBAAgB,OAAO;KACvB;KACA,mBAAmB,YAAY;KAC/B,yBAAyB,iBAAiB,KAAK,MAAM,EAAE,OAAO;KAC9D;IACF,GACA,yCACF;SAEA,IAAI,QAAQ,KAAK,MAAM;GAE3B;EACF,OAAO,IAAI,cAAc;GACvB,OAAO,MACL,cAAc,OAAO,YAAY,qCAAqC,aAAa,eAAe,OAAO,WAAW,EACtH;GAEA,IAAI,CAAC,OAAO,cAAc,CAAC,OAAO,eAAe;IAC/C,OAAO,MACL,YAAY,OAAO,YAAY,wCACjC;IACA,IAAI,aAAa;GACnB,OACE,OAAO,IAAI;EAEf,OACE,IAAI,aAAa;EAGnB,IAAI,6BAA6B,MAAM,GACrC,4BAA4B,IAAI,SAAS,MAAM;OAC1C,IAAI,YAAY,mBAAmB,WAAW,oBACnD,IAAI,QAAQ,KAAK;GACf,YAAY;GACZ,SAAS,WAAW;GACpB,UAAU,WAAW;EACvB,CAAC;EAIH,IAAI,OAAO,eAAe;GACxB,IAAI,iBAAiB,OAAO;GAC5B,IAAI,eAAe,OAAO;EAC5B,OAAO,IAAI,gBAAgB,cAAc,gBAAgB,YAAY,GACnE,IAAI,eAAe,aAAa,QAAQ,MAAM,KAAK,GAAG,EAAE;EAI1D,IACE,SAAS,OAAO,YAAY,KAC5B,SAAS,YAAY,KACrB,SAAS,OAAO,oBAAoB,GAEpC,KAAK,MAAM,UAAU,IAAI,SAAS;GAChC,OAAO,MAAM,EAAE,OAAO,CAAC;;GAEvB,IAAI,SAAS,OAAO,YAAY,KAAK,SAAS,OAAO,QAAQ,GAC3D,OAAO,WAAW,OAAO,aAAa,QACpC,cACA,OAAO,QACT;EAEJ;EAIF,IAAI,gBAAgB,OAAO,UAAU,GAAG;GACtC,IAAI,OAAO,eACL;QAAA,CAAC,OAAO,oBAAoB,CAAC,IAAI,QAAQ,QAAQ;KAEnD,eAAe;MACb,YAAY;MACZ,UAAU,OAAO;KACnB;KACA,IAAI,QAAQ,KAAK,YAAY;IAC/B;UACK,IACL,OAAO,cAGP,CAAC,IAAI,QAAQ,MAAM,WAAW,OAAO,eAAe,KAAK,GAGzD,IAAI,QAAQ,KAAK;IACf,aAAa;IACb,YAAY;IACZ,UAAU,OAAO;GACnB,CAAC;GAEH,IAAI,cAAc,gBAAgB;IAEhC,IAAI,iBAAiB,cAAc,eAAe,IAAI,cAAe;IACrE,KAAK,MAAM,UAAU,IAAI,SAEvB,OAAO,aAAa,cAAc,eAAe,OAAO,UAAW;GAEvE;GACA,IAAI,IAAI,aACN,OAAO,eAAe,CAAC,IAAI,WAAW;GAIxC,KAAK,MAAM,UAAU,IAAI,SAAS;IAChC,IAAI,OAAO,eAAe,QAAQ,OAAO,eAAe;KACtD,MAAM,kBAAwC;MAC5C,GAAG;MACH,aAAa,OAAO,eAAe,IAAI;MACvC,YAAY,IAAI;KAClB;KAGA,IAAI,OAAO,eAAe,eACxB,OAAO,gBAAgB;KAIzB,IACE,OAAO,eAAe,iBACtB,OAAO,YAAY,OAAO,aAC1B;MACA,OAAO,gBAAgB;MACvB,OAAO,gBAAgB;MACvB,gBAAgB,kBAAkB,OAAO;KAC3C;KAKA,IACE,OAAO,eAAe,iBACtB,OAAO,YAAY,OAAO,aAE1B,OAAO,cAAc,YAAY,SAAS,MACvC,MAAM,EAAE,YAAY,OAAO,QAC9B,CAAC,EAAE;KAGL,OAAO,cAAc,MAAM,UACzB,iBACA,OAAO,QACT;KAIA,IAAI,OAAO,cAAc,MAAM;MAC7B,OAAO,MACL;OACE,aAAa,OAAO;OACpB,cAAc,OAAO;OACrB,YAAY,OAAO;OACnB,UAAU,OAAO;OACjB,QAAQ,OAAO;MACjB,GACA,4CACF;MAIA,IAAI,OAAO,eACT,IAAI,SAAS,KAAK;OAChB,SAAS,8CAA8C,OAAO,WAAW,WAAW,OAAO,YAAY;OACvG,OAAO,OAAO;MAChB,CAAC;KAEL;IACF,OACE,OAAO,OAAO;IAEhB,IAAI,OAAO,YAAY;KACrB,MAAM,cAAc,YAAY,UAAU,MACvC,YAAY,QAAQ,YAAY,OAAO,UAC1C,CAAC,EAAE;KACH,IAAI,eAAe,gBAAgB,IAAI,aACrC,OAAO,cAAc;IAEzB;GACF;EACF;EAEA,IAAI,IAAI,QAAQ,QACd,OAAO,IAAI;EAGb,IAAI,UAAU,IAAI,QACf,QACE,WAAW,OAAO,aAAa,QAAQ,OAAO,iBAAiB,IAClE,CAAC,CACA,QAAQ,WAAW,OAAO,cAAc,IAAI,CAAC,CAC7C,QACE,WACE,SAAS,OAAO,OAAO,KAAK,OAAO,YAAY,OAAO,eACvD,OAAO,kBAAkB,QACzB,OAAO,aAAa,OAAO,gBAC3B,OAAO,qBAAqB,QAE3B,OAAO,aACN,CAAC,OAAO,UAAU,WAAW,OAAO,aAAc,CACxD;EAEF,IAAI,OAAO,kBAAkB,iBAC3B,IAAI,UAAU,IAAI,QAAQ,QACvB,WAAW,OAAO,aAAa,OAAO,YACzC;EAGF,IAAI,OAAO,eAAe,OAAO,WAC/B,IAAI,UAAU,IAAI,QAAQ,QACvB,WACC,OAAO,eAAe,cAAc,IAAI,QAAQ,WAAW,CAC/D;EAIF,IAAI,gBAAgB,IAAI,QAAQ,SAAS,YAAY,GACnD,MAAM,qCACJ,cACA,QACA,KACA,8BACF;EAGF,MAAM,UACJ,IAAI,QAAQ,SAAS,IAChB,YAAY,SAAS,MACnB,MAAM,EAAE,YAAY,IAAI,QAAQ,EAAE,CAAC,QACtC,KACA,YAAY,SAAS,MAClB,MAAM,EAAE,YAAY,IAAI,QAAQ,EAAE,CAAC,UACtC,IACA;EAEN,IAAI,SAAS,kBAAkB;GAC7B,IAAI,mBAAmB,QAAQ;GAC/B,IAAI,eAAe,QAAQ;EAC7B;CACF,SAAS,iCAAgC;EACvC,IAAI,eAAe,mBACjB,OAAO,OAAO,IAAI,GAAG;EAGvB,IAAI,eAAe,SAAS,IAAI,YAAA,qBAC9B,OAAO,OAAO,IAAI,GAAG;EAGvB,OAAO,MACL;GACE,eAAe,OAAO;GACtB,cAAc,OAAO;GACrB,YAAY,OAAO;GACnB,aAAa,OAAO;GACpB,kBAAkB,OAAO;GACzB,WAAW,OAAO;GAClB,eAAe,OAAO;GACtB,aAAa,OAAO;GACpB,YAAY,OAAO;GACnB,aAAa,OAAO;GACpB,sBAAsB,OAAO;GAC7B,0BAA0B,OAAO;GACjC;EACF,GACA,qBACF;EACA,IAAI,aAAa;CACnB;CACA,OAAO,OAAO,GAAG,GAAG;AACtB"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "renovate",
3
3
  "description": "Automated dependency updates. Flexible so you don't need to be.",
4
- "version": "44.3.0",
4
+ "version": "44.3.1",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "renovate": "dist/renovate.js",
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "$id": "https://docs.renovatebot.com/renovate-schema.json",
3
- "title": "JSON schema for Renovate 44.3.0 config files (https://renovatebot.com/)",
3
+ "title": "JSON schema for Renovate 44.3.1 config files (https://renovatebot.com/)",
4
4
  "$schema": "http://json-schema.org/draft-07/schema#",
5
- "x-renovate-version": "44.3.0",
5
+ "x-renovate-version": "44.3.1",
6
6
  "allowComments": true,
7
7
  "type": "object",
8
8
  "definitions": {
@@ -6558,7 +6558,7 @@
6558
6558
  "description": "Text added here will be placed last in the PR body, with a divider separator before it.\nSee also: https://docs.renovatebot.com/configuration-options/#prfooter",
6559
6559
  "markdownDescription": "Text added here will be placed last in the PR body, with a divider separator before it.\n\nSee also: [prFooter](https://docs.renovatebot.com/configuration-options/#prfooter)",
6560
6560
  "type": "string",
6561
- "default": "This PR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate)."
6561
+ "default": "This PR has been generated by [Mend Renovate CLI](https://github.com/renovatebot/renovate)."
6562
6562
  },
6563
6563
  "prHeader": {
6564
6564
  "description": "Text added here will be placed first in the PR body.\nSee also: https://docs.renovatebot.com/configuration-options/#prheader",