renovate 44.78.0 → 44.79.0

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.
Files changed (53) hide show
  1. package/dist/config/global.d.ts +1 -1
  2. package/dist/config/global.js +2 -0
  3. package/dist/config/global.js.map +1 -1
  4. package/dist/config/options/index.js +35 -0
  5. package/dist/config/options/index.js.map +1 -1
  6. package/dist/config/presets/http/index.js +3 -1
  7. package/dist/config/presets/http/index.js.map +1 -1
  8. package/dist/config/presets/index.js +7 -1
  9. package/dist/config/presets/index.js.map +1 -1
  10. package/dist/config/presets/npm/index.js +4 -2
  11. package/dist/config/presets/npm/index.js.map +1 -1
  12. package/dist/config/types.d.ts +4 -1
  13. package/dist/config/types.js.map +1 -1
  14. package/dist/config/validation.js +18 -0
  15. package/dist/config/validation.js.map +1 -1
  16. package/dist/constants/error-messages.d.ts +2 -1
  17. package/dist/constants/error-messages.js +2 -1
  18. package/dist/constants/error-messages.js.map +1 -1
  19. package/dist/global-config-option-defaults.generated.js +2 -0
  20. package/dist/global-config-option-defaults.generated.js.map +1 -1
  21. package/dist/modules/datasource/docker/common.js +3 -2
  22. package/dist/modules/datasource/docker/common.js.map +1 -1
  23. package/dist/modules/datasource/index.js +1 -1
  24. package/dist/modules/datasource/index.js.map +1 -1
  25. package/dist/modules/datasource/maven/util.js +3 -2
  26. package/dist/modules/datasource/maven/util.js.map +1 -1
  27. package/dist/modules/datasource/npm/get.js +1 -1
  28. package/dist/modules/datasource/npm/get.js.map +1 -1
  29. package/dist/modules/datasource/pod/index.js +2 -1
  30. package/dist/modules/datasource/pod/index.js.map +1 -1
  31. package/dist/modules/datasource/repology/index.js +3 -2
  32. package/dist/modules/datasource/repology/index.js.map +1 -1
  33. package/dist/types/host-rules.d.ts +35 -2
  34. package/dist/types/index.d.ts +2 -2
  35. package/dist/util/host-rules.d.ts +8 -2
  36. package/dist/util/host-rules.js +54 -6
  37. package/dist/util/host-rules.js.map +1 -1
  38. package/dist/util/http/host-guard.js +279 -0
  39. package/dist/util/http/host-guard.js.map +1 -0
  40. package/dist/util/http/host-rules.js.map +1 -1
  41. package/dist/util/http/http.d.ts +8 -0
  42. package/dist/util/http/http.js +37 -21
  43. package/dist/util/http/http.js.map +1 -1
  44. package/dist/util/http/types.d.ts +6 -0
  45. package/dist/util/http/types.js.map +1 -1
  46. package/dist/util/http/util.js +10 -1
  47. package/dist/util/http/util.js.map +1 -1
  48. package/dist/workers/repository/init/inherited.js +28 -4
  49. package/dist/workers/repository/init/inherited.js.map +1 -1
  50. package/dist/workers/repository/init/merge.js +28 -12
  51. package/dist/workers/repository/init/merge.js.map +1 -1
  52. package/package.json +1 -1
  53. package/renovate-schema.json +17 -2
@@ -37,7 +37,7 @@ import { getOnboardingConfig } from "../onboarding/branch/config.js";
37
37
  import { getOnboardingConfigFromCache, getOnboardingFileNameFromCache, setOnboardingConfigDetails } from "../onboarding/branch/onboarding-branch-cache.js";
38
38
  import { OnboardingState, getDefaultConfigFileName } from "../onboarding/common.js";
39
39
  import { filterAllowedEnv } from "./filter-allowed-env.js";
40
- import { isNonEmptyArray, isNonEmptyObject, isNonEmptyString, isString } from "@sindresorhus/is";
40
+ import { isNonEmptyArray, isNonEmptyObject, isNonEmptyString, isString, isUndefined } from "@sindresorhus/is";
41
41
  import { dequal } from "dequal";
42
42
  //#region lib/workers/repository/init/merge.ts
43
43
  async function detectConfigFile() {
@@ -237,17 +237,26 @@ function migratedHostRules(rules) {
237
237
  function adminSuppliedValues(adminConfigs) {
238
238
  const env = /* @__PURE__ */ new Set();
239
239
  const headers = /* @__PURE__ */ new Map();
240
+ const internalGrants = /* @__PURE__ */ new Map();
240
241
  for (const adminConfig of adminConfigs) for (const source of [adminConfig, adminConfig.force]) {
241
242
  for (const [name, value] of Object.entries(coerceObject(source?.env))) env.add(nameValueIdentity(name, value));
242
- for (const [identity, matchHosts] of headersByIdentity(migratedHostRules(source?.hostRules))) {
243
+ const rules = migratedHostRules(source?.hostRules);
244
+ for (const [identity, matchHosts] of headersByIdentity(rules)) {
243
245
  const hosts = headers.get(identity) ?? /* @__PURE__ */ new Set();
244
246
  for (const matchHost of matchHosts) hosts.add(matchHost);
245
247
  headers.set(identity, hosts);
246
248
  }
249
+ for (const rule of rules) if (!isUndefined(rule.allowInternal)) {
250
+ const key = rule.allowInternal.toString();
251
+ const hosts = internalGrants.get(key) ?? /* @__PURE__ */ new Set();
252
+ hosts.add(rule.matchHost ?? null);
253
+ internalGrants.set(key, hosts);
254
+ }
247
255
  }
248
256
  return {
249
257
  env,
250
- headers
258
+ headers,
259
+ internalGrants
251
260
  };
252
261
  }
253
262
  /**
@@ -260,15 +269,22 @@ function adminSuppliedValues(adminConfigs) {
260
269
  function withoutAdminSuppliedValues(resolved, admin) {
261
270
  const result = { ...resolved };
262
271
  if (result.env) result.env = Object.fromEntries(Object.entries(result.env).filter(([name, value]) => !admin.env.has(nameValueIdentity(name, value))));
263
- if (result.hostRules) result.hostRules = result.hostRules.map((rule) => ({
264
- ...rule,
265
- headers: Object.fromEntries(Object.entries(coerceObject(rule.headers)).filter(([name, value]) => {
266
- const adminHosts = admin.headers.get(nameValueIdentity(name, value));
267
- if (!adminHosts) return true;
268
- if (adminHosts.has(null)) return false;
269
- return !(rule.matchHost && [...adminHosts].some((adminHost) => adminHost !== null && isWithinHost(rule.matchHost, adminHost)));
270
- }))
271
- }));
272
+ if (result.hostRules) result.hostRules = result.hostRules.map((rule) => {
273
+ const filtered = {
274
+ ...rule,
275
+ headers: Object.fromEntries(Object.entries(coerceObject(rule.headers)).filter(([name, value]) => {
276
+ const adminHosts = admin.headers.get(nameValueIdentity(name, value));
277
+ if (!adminHosts) return true;
278
+ if (adminHosts.has(null)) return false;
279
+ return !(rule.matchHost && [...adminHosts].some((adminHost) => adminHost !== null && isWithinHost(rule.matchHost, adminHost)));
280
+ }))
281
+ };
282
+ if (!isUndefined(filtered.allowInternal)) {
283
+ const adminHosts = admin.internalGrants.get(filtered.allowInternal.toString());
284
+ if (adminHosts && (adminHosts.has(null) || !!filtered.matchHost && [...adminHosts].some((adminHost) => adminHost !== null && isWithinHost(filtered.matchHost, adminHost)))) delete filtered.allowInternal;
285
+ }
286
+ return filtered;
287
+ });
272
288
  if (result.force) result.force = withoutAdminSuppliedValues(result.force, admin);
273
289
  return result;
274
290
  }
@@ -1 +1 @@
1
- {"version":3,"file":"merge.js","names":["configValidation.validateConfig","hostRules.matchesHost","presets.resolveConfigPresets"],"sources":["../../../../lib/workers/repository/init/merge.ts"],"sourcesContent":["import {\n isNonEmptyArray,\n isNonEmptyObject,\n isNonEmptyString,\n isString,\n} from '@sindresorhus/is';\nimport { dequal } from 'dequal';\nimport { getConfigFileNames } from '../../../config/app-strings.ts';\nimport { decryptConfig } from '../../../config/decrypt.ts';\nimport { mergeChildConfig } from '../../../config/index.ts';\nimport { massageConfig } from '../../../config/massage.ts';\nimport { migrateAndValidate } from '../../../config/migrate-validate.ts';\nimport { migrateConfig } from '../../../config/migration.ts';\nimport { parseFileConfig } from '../../../config/parse.ts';\nimport * as presets from '../../../config/presets/index.ts';\nimport { applySecretsAndVariablesToConfig } from '../../../config/secrets.ts';\nimport type {\n AllConfig,\n MigratedConfig,\n RenovateConfig,\n ValidationMessage,\n} from '../../../config/types.ts';\nimport * as configValidation from '../../../config/validation.ts';\nimport { ConfigValidationTopic } from '../../../config/validation-helpers/types.ts';\nimport {\n CONFIG_VALIDATION,\n REPOSITORY_CHANGED,\n} from '../../../constants/error-messages.ts';\nimport { pkg } from '../../../expose.ts';\nimport { logger } from '../../../logger/index.ts';\nimport * as npmApi from '../../../modules/datasource/npm/index.ts';\nimport { platform } from '../../../modules/platform/index.ts';\nimport { scm } from '../../../modules/platform/scm.ts';\nimport { ExternalHostError } from '../../../types/errors/external-host-error.ts';\nimport type { HostRule } from '../../../types/index.ts';\nimport { coerceArray } from '../../../util/array.ts';\nimport { getCache } from '../../../util/cache/repository/index.ts';\nimport { clone } from '../../../util/clone.ts';\nimport { getInheritedOrGlobal, parseJson } from '../../../util/common.ts';\nimport { setUserEnv } from '../../../util/env.ts';\nimport { readLocalFile, readSystemFile } from '../../../util/fs/index.ts';\nimport * as hostRules from '../../../util/host-rules.ts';\nimport * as queue from '../../../util/http/queue.ts';\nimport * as throttle from '../../../util/http/throttle.ts';\nimport { maskToken } from '../../../util/mask.ts';\nimport { coerceObject } from '../../../util/object.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport { coerceString } from '../../../util/string.ts';\nimport { safeStringify } from '../../../util/stringify.ts';\nimport { parseUrl } from '../../../util/url.ts';\nimport { getOnboardingConfig } from '../onboarding/branch/config.ts';\nimport {\n getOnboardingConfigFromCache,\n getOnboardingFileNameFromCache,\n setOnboardingConfigDetails,\n} from '../onboarding/branch/onboarding-branch-cache.ts';\nimport {\n OnboardingState,\n getDefaultConfigFileName,\n} from '../onboarding/common.ts';\nimport { filterAllowedEnv } from './filter-allowed-env.ts';\nimport type { RepoFileConfig, RepositoryWorkerConfig } from './types.ts';\n\nexport async function detectConfigFile(): Promise<string | null> {\n const fileList = await scm.getFileList();\n for (const fileName of getConfigFileNames()) {\n if (fileName === 'package.json') {\n try {\n const pJson = JSON.parse(\n (await readLocalFile('package.json', 'utf8'))!,\n );\n if (pJson.renovate) {\n logger.warn(\n 'Using package.json for Renovate config is deprecated - please use a dedicated configuration file instead',\n );\n return 'package.json';\n }\n } catch {\n // Do nothing\n }\n } else if (fileList.includes(fileName)) {\n return fileName;\n }\n }\n return null;\n}\n\nexport async function detectRepoFileConfig(\n branchName?: string,\n): Promise<RepoFileConfig> {\n const cache = getCache();\n let { configFileName } = cache;\n if (isNonEmptyString(configFileName)) {\n let configFileRaw: string | null;\n try {\n configFileRaw = await platform.getRawFile(\n configFileName,\n undefined,\n branchName,\n );\n } catch (err) {\n // istanbul ignore if\n if (err instanceof ExternalHostError) {\n throw err;\n }\n configFileRaw = null;\n }\n if (configFileRaw) {\n let configFileParsed = parseJson(configFileRaw, configFileName) as any;\n if (configFileName === 'package.json') {\n configFileParsed = configFileParsed.renovate;\n }\n return { configFileName, configFileParsed };\n }\n logger.debug('Existing config file no longer exists');\n delete cache.configFileName;\n }\n\n if (OnboardingState.onboardingCacheValid) {\n configFileName = getOnboardingFileNameFromCache();\n } else {\n configFileName = coerceString(await detectConfigFile());\n }\n\n if (!configFileName) {\n logger.debug('No renovate config file found');\n cache.configFileName = '';\n return {};\n }\n cache.configFileName = configFileName;\n logger.debug(`Found ${configFileName} config file`);\n // TODO #22198\n let configFileParsed: any;\n let configFileRaw: string | undefined | null;\n\n if (OnboardingState.onboardingCacheValid) {\n const cachedConfig = getOnboardingConfigFromCache();\n const parsedConfig = cachedConfig ? JSON.parse(cachedConfig) : undefined;\n if (parsedConfig) {\n setOnboardingConfigDetails(configFileName, JSON.stringify(parsedConfig));\n return { configFileName, configFileParsed: parsedConfig };\n }\n }\n\n if (configFileName === 'package.json') {\n // We already know it parses\n configFileParsed = JSON.parse(\n // TODO #22198\n (await readLocalFile('package.json', 'utf8'))!,\n ).renovate;\n if (isString(configFileParsed)) {\n logger.debug('Massaging string renovate config to extends array');\n configFileParsed = { extends: [configFileParsed] };\n }\n logger.debug({ config: configFileParsed }, 'package.json>renovate config');\n } else {\n configFileRaw = await readLocalFile(configFileName, 'utf8');\n // istanbul ignore if\n if (!isString(configFileRaw)) {\n logger.warn({ configFileName }, 'Null contents when reading config file');\n throw new Error(REPOSITORY_CHANGED);\n }\n // istanbul ignore if\n if (!configFileRaw.length) {\n configFileRaw = '{}';\n }\n\n const parseResult = parseFileConfig(configFileName, configFileRaw);\n\n if (!parseResult.success) {\n return {\n configFileName,\n configFileParseError: {\n validationError: parseResult.validationError,\n validationMessage: parseResult.validationMessage,\n },\n };\n }\n configFileParsed = parseResult.parsedContents;\n logger.debug(\n { fileName: configFileName, config: configFileParsed },\n 'Repository config',\n );\n }\n\n setOnboardingConfigDetails(configFileName, JSON.stringify(configFileParsed));\n return { configFileName, configFileParsed };\n}\n\nexport function checkForRepoConfigError(repoConfig: RepoFileConfig): void {\n if (!repoConfig.configFileParseError) {\n return;\n }\n const error = new Error(CONFIG_VALIDATION);\n error.validationSource = repoConfig.configFileName;\n error.validationError = repoConfig.configFileParseError.validationError;\n error.validationMessage = repoConfig.configFileParseError.validationMessage;\n throw error;\n}\n\n/**\n * Validation source for `repositories[]` object-entry config.\n *\n * As these are managed by the self-hosted admin's global config (`config.js`, or through environment variables, CLI options) we shouldn't report this as an issue the repo owner has introduced.\n */\nconst repositoriesEntrySource = 'Self-hosted config (`repositories[]`)';\n\nconst repoFileValidationError =\n 'The Renovate configuration file contains some invalid settings';\n\nconst repositoriesEntryValidationError =\n 'The self-hosted `repositories[]` config contains some invalid settings';\n\nfunction throwConfigValidationError(\n validationSource: string | undefined,\n errors: ValidationMessage[],\n validationError = repoFileValidationError,\n): never {\n const error = new Error(CONFIG_VALIDATION);\n error.validationSource = validationSource;\n error.validationError = validationError;\n error.validationMessage = errors.map((e) => e.message).join(', ');\n throw error;\n}\n\n/**\n * Validate a fully-resolved config (i.e. after `resolveConfigPresets`).\n *\n * If there are top-level `allowedEnv`/`allowedHeaders` violations, these are reported with `ConfigValidationTopic.Security` and always fail a validation, as they are sensitive config options that need to be blocked.\n *\n * All other issues will be a WARN, unless `configValidationError=true`, because these are resolved config options and may not be in control of the repository owner.\n *\n * `validationSource` is reported to the user; use `repositoriesEntrySource` and `repositoriesEntryValidationError` for admin-controlled object entries so a fault is not blamed on the repo owner.\n */\nasync function validateResolvedConfig(\n resolved: RenovateConfig,\n validationSource: string | undefined,\n strict: boolean,\n validationError?: string,\n): Promise<void> {\n const { errors, warnings } = await configValidation.validateConfig(\n 'repo',\n // `validateConfig` expects massaged input\n massageConfig(resolved),\n );\n\n // Security findings are collected from the warnings too: `validateConfig` folds the results of the sub-validations it runs (notably `onboardingConfig`) into its warnings, and a finding is no less real for having been reported from within one\n const securityErrors = [...errors, ...warnings].filter(\n (err) => err.topic === ConfigValidationTopic.Security,\n );\n const otherErrors = errors.filter(\n (err) => err.topic !== ConfigValidationTopic.Security,\n );\n const otherWarnings = warnings.filter(\n (err) => err.topic !== ConfigValidationTopic.Security,\n );\n\n // before throwing, make sure that any other errors or warnings are logged, as there may be important findings\n if (otherErrors.length || otherWarnings.length) {\n logger.debug(\n { errors: otherErrors, warnings: otherWarnings },\n 'Config validation failed on resolved config, for non-security-sensitive reasons',\n );\n }\n\n if (securityErrors.length) {\n throwConfigValidationError(\n validationSource,\n securityErrors,\n validationError,\n );\n }\n if (strict && otherErrors.length) {\n throwConfigValidationError(validationSource, otherErrors, validationError);\n }\n}\n\n/**\n * Identify a single `env` variable, or a single header of a host rule, by name and value.\n *\n * As `env` is replaced wholesale and `hostRules` is `mergeable`, self-hosted config and repo config end up indistinguishable in the resolved config, so we need a stable way to look a given name and value up.\n */\nfunction nameValueIdentity(name: string, value: string): string {\n // use safeStringify to avoid any potential for an attacker-controlled value to attempt to try and fake the separator and inject in their value as priority\n return safeStringify([name, value]);\n}\n\n/**\n * Index a set of host rules' headers by {@link nameValueIdentity}, recording the `matchHost` values each is set for (`null` for a host-less rule, which matches every host).\n */\nfunction headersByIdentity(\n rules: HostRule[] | undefined,\n): Map<string, Set<string | null>> {\n const result = new Map<string, Set<string | null>>();\n for (const rule of coerceArray(rules)) {\n for (const [name, value] of Object.entries(coerceObject(rule.headers))) {\n const identity = nameValueIdentity(name, value);\n const hosts = result.get(identity) ?? new Set<string | null>();\n hosts.add(rule.matchHost ?? null);\n result.set(identity, hosts);\n }\n }\n return result;\n}\n\n/**\n * Whether every request matched by `matchHost` is also matched by `adminMatchHost` - i.e. a rule scoped to `matchHost` cannot reach any host the admin's own rule does not already reach.\n *\n * A bare hostname is compared as its `https://` URL. `matchesHost` treats a bare `adminMatchHost` as also covering its subdomains, which errs on the admin-friendly side: those hosts sit within the admin's own domain.\n */\nfunction isWithinHost(matchHost: string, adminMatchHost: string): boolean {\n const url = parseUrl(matchHost) ? matchHost : `https://${matchHost}`;\n return hostRules.matchesHost(url, adminMatchHost);\n}\n\n/**\n * Migrate a config, tolerating a migration which throws.\n *\n * `hostRules` migration throws when a rule carries more than one host-matching field. That is per-rule invalid config which {@link applyHostRules} logs and skips over, keeping the rest of the run going, so migrating a whole config here must not escalate it into an error which aborts the repository.\n */\nfunction migrateConfigOrWarn(config: RenovateConfig): MigratedConfig {\n try {\n return migrateConfig(config);\n } catch (err) {\n logger.warn({ err }, 'Error migrating config');\n return { isMigrated: false, migratedConfig: config };\n }\n}\n\n/**\n * The security-sensitive values (`env`, and `hostRules[].headers`) the self-hosted admin supplied, indexed by {@link nameValueIdentity}; the headers additionally record the `matchHost` values each was set for.\n *\n * `mergeChildConfig` promotes `force` values to the top level, so each config contributes its `force` alongside its top-level values.\n */\ninterface AdminSuppliedValues {\n env: Set<string>;\n headers: Map<string, Set<string | null>>;\n}\n\n/**\n * Migrate a set of host rules, so that their `matchHost` compares like for like against the resolved config's own: migration rewrites them (e.g. a legacy `hostName` becoming a `matchHost`, or a bare `matchHost` gaining a scheme), and the resolved config only ever contains the migrated spellings.\n */\nfunction migratedHostRules(rules: HostRule[] | undefined): HostRule[] {\n if (!isNonEmptyArray(rules)) {\n return [];\n }\n return coerceArray(\n migrateConfigOrWarn({ hostRules: rules }).migratedConfig.hostRules,\n );\n}\n\n/**\n * Collect the {@link AdminSuppliedValues} of every config the self-hosted admin supplied.\n *\n * A preset is only ever resolved into the config which extends it, so a config here is the *resolved* form of an admin config: whatever the presets the admin chose to extend contribute is as much theirs as a value they wrote inline.\n */\nfunction adminSuppliedValues(\n adminConfigs: RenovateConfig[],\n): AdminSuppliedValues {\n const env = new Set<string>();\n const headers = new Map<string, Set<string | null>>();\n\n for (const adminConfig of adminConfigs) {\n for (const source of [adminConfig, adminConfig.force]) {\n for (const [name, value] of Object.entries(coerceObject(source?.env))) {\n env.add(nameValueIdentity(name, value));\n }\n for (const [identity, matchHosts] of headersByIdentity(\n migratedHostRules(source?.hostRules),\n )) {\n const hosts = headers.get(identity) ?? new Set<string | null>();\n for (const matchHost of matchHosts) {\n hosts.add(matchHost);\n }\n headers.set(identity, hosts);\n }\n }\n }\n\n return { env, headers };\n}\n\n/**\n * Return `resolved` without the security-sensitive (`env` and `hostRules[].headers`) values the self-hosted admin supplied themselves.\n *\n * `allowedEnv`/`allowedHeaders` exist to constrain what repository config, and the presets it extends, may inject; the self-hosted admin is who sets those allowlists, so their own values are not violations of them.\n *\n * Reporting them would abort the repository and file a \"Fix Renovate Configuration\" issue whose cause the repository's owners can neither see nor fix.\n */\nfunction withoutAdminSuppliedValues(\n resolved: RenovateConfig,\n admin: AdminSuppliedValues,\n): RenovateConfig {\n const result = { ...resolved };\n\n if (result.env) {\n result.env = Object.fromEntries(\n Object.entries(result.env).filter(\n ([name, value]) => !admin.env.has(nameValueIdentity(name, value)),\n ),\n );\n }\n\n // A header is the admin's own when its name and value match one the admin set for hosts that already cover this rule's hosts - the exact `matchHost` spelling must not matter, as migration and presets can re-spell (e.g. add a scheme) or narrow (e.g. a subpath) it\n if (result.hostRules) {\n result.hostRules = result.hostRules.map((rule) => ({\n ...rule,\n headers: Object.fromEntries(\n Object.entries(coerceObject(rule.headers)).filter(([name, value]) => {\n const adminHosts = admin.headers.get(nameValueIdentity(name, value));\n if (!adminHosts) {\n // not a header the admin set - report it\n return true;\n }\n if (adminHosts.has(null)) {\n // the admin already sends it to every host\n return false;\n }\n // a host-less rule reaches every host, so only a host-less admin header (above) can exempt it\n return !(\n rule.matchHost &&\n [...adminHosts].some(\n (adminHost) =>\n adminHost !== null && isWithinHost(rule.matchHost!, adminHost),\n )\n );\n }),\n ),\n }));\n }\n\n // `mergeChildConfig` promotes `force` values into the config it returns, so the admin's own `force.env`/`force.hostRules[].headers` are applied - and exempted - the same way their top-level equivalents are\n if (result.force) {\n result.force = withoutAdminSuppliedValues(result.force, admin);\n }\n\n return result;\n}\n\n// Check for repository config\nexport async function mergeRenovateConfig(\n config: RepositoryWorkerConfig,\n branchName?: string,\n): Promise<RenovateConfig> {\n let returnConfig: RepositoryWorkerConfig = { ...config };\n let repoConfig: RepoFileConfig = {};\n if (getInheritedOrGlobal('requireConfig') !== 'ignored') {\n repoConfig = await detectRepoFileConfig(branchName);\n }\n if (!repoConfig.configFileParsed && config.mode === 'silent') {\n logger.debug(\n 'When mode=silent and repo has no config file, we use the onboarding config as repo config',\n );\n const configFileName = getDefaultConfigFileName();\n repoConfig = {\n configFileName,\n configFileParsed: await getOnboardingConfig(config),\n };\n }\n const configFileParsed = coerceObject(repoConfig?.configFileParsed);\n const resolvedRepoConfig = await resolveStaticRepoConfig(\n configFileParsed,\n process.env.RENOVATE_X_STATIC_REPO_CONFIG_FILE,\n );\n\n // Apply the repositories[] object-entry config between global config and\n // repository file config.\n // Must run after repository file config is loaded so its `ignorePresets` can\n // be included when resolving object-entry presets.\n const repoEntryConfig = returnConfig.repositoryEntryConfig;\n delete returnConfig.repositoryEntryConfig;\n\n // The presets the self-hosted admin's own config extends are their config too - a repository which merely inherits them must neither be blamed for what they contribute, nor have it filtered out from under it.\n // They are resolved separately because below they are resolved together with the repository's own presets, leaving no way to tell one from the other; a failure here is left to that resolution to report, as it is the one whose result is used.\n let adminPresetConfig: AllConfig = {};\n if (isNonEmptyArray(returnConfig.extends)) {\n try {\n ({ config: adminPresetConfig } = await presets.resolveConfigPresets(\n { extends: returnConfig.extends },\n config,\n config.ignorePresets,\n ));\n } catch (err) {\n logger.debug(\n { err },\n 'Error resolving the self-hosted config presets - continuing without their exemption',\n );\n }\n }\n\n // self-hosted configuration is always allowed\n // `force.env` is included because `mergeChildConfig` promotes `force` values to the top level as configs are merged\n const adminSuppliedEnv = {\n // presets the admin extends: as much theirs as anything they set inline, which is why they are listed first - the values they set themselves win\n ...coerceObject(adminPresetConfig.env),\n ...coerceObject(adminPresetConfig.force?.env),\n // `env` settings the self-hosted admin supplied (via `config.js`, etc), `env`, etc\n ...coerceObject(config.env),\n ...coerceObject(config.force?.env),\n // `repositories[]` entry for this repo - refreshed with the resolved values below, once its own presets, secrets and variables have been applied\n ...coerceObject(repoEntryConfig?.env),\n ...coerceObject(repoEntryConfig?.force?.env),\n };\n\n // every config the self-hosted admin supplied, in resolved form, for {@link adminSuppliedValues}\n const adminConfigs: RenovateConfig[] = [config, adminPresetConfig];\n\n if (isNonEmptyObject(repoEntryConfig)) {\n const repoEntry = repoEntryConfig as RenovateConfig;\n const toResolve: RenovateConfig = {\n ...repoEntry,\n extends: [\n ...coerceArray(returnConfig.extends),\n ...coerceArray(repoEntry.extends),\n ],\n ignorePresets: [\n ...coerceArray(returnConfig.ignorePresets),\n ...coerceArray(repoEntry.ignorePresets),\n ...coerceArray(resolvedRepoConfig.ignorePresets),\n ],\n };\n delete returnConfig.extends;\n\n let { config: resolvedRepoEntry } = await presets.resolveConfigPresets(\n toResolve,\n config,\n );\n\n // Migrate before validating so legacy option names contributed by the entry or its presets are migrated rather than reported as invalid options.\n const entryMigration = migrateConfigOrWarn(resolvedRepoEntry);\n if (entryMigration.isMigrated) {\n resolvedRepoEntry = entryMigration.migratedConfig;\n }\n\n // Migrate the entry's own config the same way, so its values compare like for like below: migration can rewrite them (e.g. a legacy `hostName` becoming a `matchHost`, or a bare `matchHost` gaining a scheme), and the resolved config only ever contains the migrated spellings\n const { migratedConfig: migratedEntry } = migrateConfigOrWarn(toResolve);\n // `resolveConfigPresets` removes both of these from its result\n delete migratedEntry.extends;\n delete migratedEntry.ignorePresets;\n\n // The entry, and every preset it extends, is the self-hosted admin's own config, so its `env`/`headers` are exempt from the allowlists the admin set - but the rest of the resolved result is still worth validating before any of it is applied (npmrc, hostRules, env).\n // When resolution and migration changed nothing, the presets contributed nothing and the entry itself was already validated as part of the admin's global config, so skip the (costly) validation walk entirely.\n adminConfigs.push(resolvedRepoEntry);\n if (!dequal(resolvedRepoEntry, migratedEntry)) {\n await validateResolvedConfig(\n withoutAdminSuppliedValues(\n resolvedRepoEntry,\n adminSuppliedValues(adminConfigs),\n ),\n repositoriesEntrySource,\n config.configValidationError === true,\n repositoriesEntryValidationError,\n );\n }\n\n applyNpmrc(resolvedRepoEntry, 'resolvedRepoEntry');\n\n const resolvedRepoEntryWithSecrets = applySecretsAndVariablesToConfig({\n config: resolvedRepoEntry,\n // like the repository config below, the entry can carry its own `secrets`/`variables` - `validateConfigSecretsAndVariables` validates them at startup\n secrets: mergeChildConfig(\n coerceObject(config.secrets),\n coerceObject(resolvedRepoEntry.secrets),\n ),\n variables: mergeChildConfig(\n coerceObject(config.variables),\n coerceObject(resolvedRepoEntry.variables),\n ),\n });\n\n // Refresh the admin-supplied snapshot from the resolved entry: it also carries whatever the presets the entry extends contributed, and its `env` values may contain `{{ secrets.* }}`/`{{ variables.* }}` templates only interpolated here - e.g. when the secrets are defined on the entry itself rather than globally.\n // Interpolation is recursive, so the interpolated `force.env` values stay nested under `force`.\n Object.assign(\n adminSuppliedEnv,\n coerceObject(resolvedRepoEntryWithSecrets.env),\n coerceObject(resolvedRepoEntryWithSecrets.force?.env),\n );\n\n // the `repositories[]` entry is the self-hosted admin's own config - as its `env` is already treated as admin-supplied, its rules are `trusted` too, so that an admin can still override a header they set globally for just this repository\n applyHostRules(resolvedRepoEntryWithSecrets, { trusted: true });\n returnConfig = mergeChildConfig(returnConfig, resolvedRepoEntryWithSecrets);\n }\n\n if (isNonEmptyArray(returnConfig.extends)) {\n resolvedRepoConfig.extends = [\n ...coerceArray(returnConfig.extends),\n ...coerceArray(resolvedRepoConfig.extends),\n ];\n delete returnConfig.extends;\n }\n checkForRepoConfigError(repoConfig);\n const migratedConfig = await migrateAndValidate(config, resolvedRepoConfig);\n if (migratedConfig.errors?.length) {\n throwConfigValidationError(\n repoConfig.configFileName,\n migratedConfig.errors,\n );\n }\n if (migratedConfig.warnings) {\n returnConfig.warnings = [\n ...coerceArray(returnConfig.warnings),\n ...migratedConfig.warnings,\n ];\n }\n delete migratedConfig.errors;\n delete migratedConfig.warnings;\n // TODO #22198\n const repository = config.repository!;\n // Decrypt before resolving in case we need npm authentication for any presets\n const decryptedConfig = await decryptConfig(migratedConfig, repository);\n applyNpmrc(decryptedConfig, 'decrypted');\n\n // NOTE that this should not be used with any other configuration (`resolvedConfig`, etc) below, as they will include addditionally merged configuration\n // Decrypted secrets are sanitised, so should be safe to log\n await logShallowConfig(decryptedConfig, config);\n\n // Decrypt after resolving in case the preset contains npm authentication instead\n const { config: configToDecrypt } = await presets.resolveConfigPresets(\n decryptedConfig,\n config,\n config.ignorePresets,\n );\n let resolvedConfig = await decryptConfig(configToDecrypt, repository);\n logger.trace({ config: resolvedConfig }, 'resolved config');\n const migrationResult = migrateConfig(resolvedConfig);\n if (migrationResult.isMigrated) {\n logger.debug('Resolved config needs migrating');\n logger.trace({ config: resolvedConfig }, 'resolved config after migrating');\n resolvedConfig = migrationResult.migratedConfig;\n }\n\n // Validate the fully-resolved repository config, enforcing validation is applied against all stages of the preset, and providing defence-in-depth for any sensitive config options\n // note that we do not need to re-run `migrateAndValidate` if we're already at the same configuration that we've previously resolved, decrypted and migrated, so we can avoid a costly re-validation\n if (!dequal(resolvedConfig, migratedConfig)) {\n await validateResolvedConfig(\n // the admin's own `extends` are resolved into this config alongside the repository's, so exempt what they contributed: the repository can neither see nor fix it\n withoutAdminSuppliedValues(\n resolvedConfig,\n adminSuppliedValues(adminConfigs),\n ),\n // a repository that is not yet onboarded has no config file to blame; 'config' mirrors other unattributable validation errors (e.g. `decryptConfig`)\n repoConfig.configFileName ?? 'config',\n config.configValidationError === true,\n );\n }\n if (isString(resolvedConfig.npmrc)) {\n logger.debug(\n 'Ignoring any .npmrc files in repository due to configured npmrc',\n );\n }\n applyNpmrc(resolvedConfig, 'resolved');\n resolvedConfig = applySecretsAndVariablesToConfig({\n config: resolvedConfig,\n secrets: mergeChildConfig(\n coerceObject(config.secrets),\n coerceObject(resolvedConfig.secrets),\n ),\n variables: mergeChildConfig(\n coerceObject(config.variables),\n coerceObject(resolvedConfig.variables),\n ),\n });\n\n applyHostRules(resolvedConfig);\n returnConfig = mergeChildConfig(returnConfig, resolvedConfig);\n ({ config: returnConfig } = await presets.resolveConfigPresets(\n returnConfig,\n config,\n ));\n returnConfig.renovateJsonPresent = true;\n // istanbul ignore if\n if (returnConfig.ignorePaths?.length) {\n logger.debug(\n { ignorePaths: returnConfig.ignorePaths },\n `Found repo ignorePaths`,\n );\n }\n\n setUserEnv(filterAllowedEnv(returnConfig.env, adminSuppliedEnv));\n delete returnConfig.env;\n\n return returnConfig;\n}\n\nexport function applyNpmrc(\n config: RenovateConfig,\n configType?: 'resolved' | 'resolvedRepoEntry' | 'decrypted',\n): void {\n setNpmTokenInNpmrc(config);\n if (!isString(config.npmrc)) {\n return;\n }\n logger.debug(\n `Setting npmrc from ${configType ? `${configType} ` : ''}config`,\n );\n npmApi.setNpmrc(config.npmrc);\n}\n\nexport function applyHostRules(\n config: RenovateConfig,\n options?: hostRules.AddHostRuleOptions,\n): void {\n if (!config.hostRules) {\n return;\n }\n\n logger.debug('Setting hostRules from config');\n // `hostRules.add` enforces `allowedHeaders` on every rule it registers\n for (const rule of config.hostRules) {\n try {\n hostRules.add(rule, options);\n } catch (err) {\n logger.warn({ err, config: rule }, 'Error setting hostRule from config');\n }\n }\n // host rules can change concurrency\n queue.clear();\n throttle.clear();\n delete config.hostRules;\n}\n\n/** needed when using portal secrets for npmToken */\nexport function setNpmTokenInNpmrc(config: RenovateConfig): void {\n if (!isString(config.npmToken)) {\n return;\n }\n\n const token = config.npmToken;\n logger.debug({ npmToken: maskToken(token) }, 'Migrating npmToken to npmrc');\n\n if (!isString(config.npmrc)) {\n logger.debug('Adding npmrc to config');\n config.npmrc = `//registry.npmjs.org/:_authToken=${token}\\n`;\n delete config.npmToken;\n return;\n }\n\n if (config.npmrc.includes(`\\${NPM_TOKEN}`)) {\n logger.debug(`Replacing \\${NPM_TOKEN} with npmToken`);\n config.npmrc = config.npmrc.replace(regEx(/\\${NPM_TOKEN}/g), token);\n } else {\n logger.debug('Appending _authToken= to end of existing npmrc');\n config.npmrc = config.npmrc.replace(\n regEx(/\\n?$/),\n `\\n_authToken=${token}\\n`,\n );\n }\n\n delete config.npmToken;\n}\n\nexport async function resolveStaticRepoConfig(\n config: AllConfig,\n filename: string | undefined,\n): Promise<AllConfig> {\n if (!isNonEmptyString(filename)) {\n return config;\n }\n\n let staticRepoConfig: AllConfig;\n\n try {\n staticRepoConfig = await tryReadStaticRepoFileConfig(filename);\n } catch (err) {\n logger.fatal({ err }, 'Failed to load static repository config file');\n process.exit(1);\n }\n\n if (!isNonEmptyObject(staticRepoConfig)) {\n return config;\n }\n\n return mergeStaticConfig(config, staticRepoConfig);\n}\n\nexport async function tryReadStaticRepoFileConfig(\n staticRepoConfigFile: string,\n): Promise<AllConfig> {\n logger.debug(`Reading static repo config file from ${staticRepoConfigFile}`);\n\n let staticRepoConfigRaw: string;\n try {\n staticRepoConfigRaw = await readSystemFile(staticRepoConfigFile, 'utf8');\n } catch (err) {\n throw new Error(\n `Failed to read static repo config file: \"${staticRepoConfigFile}\"`,\n { cause: err },\n );\n }\n\n const staticRepoConfig = parseJson(\n staticRepoConfigRaw,\n staticRepoConfigFile,\n ) as AllConfig;\n\n // validate and log issues here to preserve context, caller handles migration and full validation.\n const { errors, warnings } = await configValidation.validateConfig(\n 'repo',\n staticRepoConfig,\n );\n\n if (isNonEmptyArray(errors) || isNonEmptyArray(warnings)) {\n logger.info(\n { errors, warnings },\n 'Static repo config validation issues detected',\n );\n } else {\n logger.debug(\n { staticRepoConfig },\n 'Static repository config file successfully parsed and validated',\n );\n }\n\n return staticRepoConfig;\n}\n\nexport function mergeStaticConfig(\n config: AllConfig,\n staticRepoConfig: AllConfig,\n): AllConfig {\n // merge extends\n if (isNonEmptyArray(staticRepoConfig.extends)) {\n config.extends = [\n ...staticRepoConfig.extends,\n ...coerceArray(config.extends),\n ];\n delete staticRepoConfig.extends;\n }\n\n // renovate repo config overrides RENOVATE_STATIC_REPO_CONFIG[_FILE]\n return mergeChildConfig(staticRepoConfig, config);\n}\n\n/**\n * Resolve everything but internal Renovate presets and log it out.\n *\n* This allows users to understand the fully resolved configuration, including any `github>`, `local>`, etc presets, but excluding anything that's internal to Renovate (which can be verbose and/or less relevant), and provides useful output for debugging purposes.\n\n* This is also known as the \"shallow\" config.\n\n* Due to caching, this doesn't add any additional requests.\n */\nasync function logShallowConfig(\n _decryptedConfig: RenovateConfig,\n _config: RepositoryWorkerConfig,\n): Promise<void> {\n // make sure we clone the existing config, so we don't modify the existing settings when resolving this in a shallow fashion\n const decryptedConfig = clone(_decryptedConfig);\n const config = clone(_config);\n\n const { config: resolvedConfig, visitedPresets } =\n await presets.resolveConfigPresets(\n clone(decryptedConfig),\n clone(config),\n [],\n [],\n false,\n );\n logger.debug(\n {\n renovateVersion: pkg.version,\n config: resolvedConfig,\n visitedPresets,\n },\n 'Resolved shallow config, without merging internal presets',\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"merge.js","names":["configValidation.validateConfig","hostRules.matchesHost","presets.resolveConfigPresets"],"sources":["../../../../lib/workers/repository/init/merge.ts"],"sourcesContent":["import {\n isNonEmptyArray,\n isNonEmptyObject,\n isNonEmptyString,\n isString,\n isUndefined,\n} from '@sindresorhus/is';\nimport { dequal } from 'dequal';\nimport { getConfigFileNames } from '../../../config/app-strings.ts';\nimport { decryptConfig } from '../../../config/decrypt.ts';\nimport { mergeChildConfig } from '../../../config/index.ts';\nimport { massageConfig } from '../../../config/massage.ts';\nimport { migrateAndValidate } from '../../../config/migrate-validate.ts';\nimport { migrateConfig } from '../../../config/migration.ts';\nimport { parseFileConfig } from '../../../config/parse.ts';\nimport * as presets from '../../../config/presets/index.ts';\nimport { applySecretsAndVariablesToConfig } from '../../../config/secrets.ts';\nimport type {\n AllConfig,\n MigratedConfig,\n RenovateConfig,\n ValidationMessage,\n} from '../../../config/types.ts';\nimport * as configValidation from '../../../config/validation.ts';\nimport { ConfigValidationTopic } from '../../../config/validation-helpers/types.ts';\nimport {\n CONFIG_VALIDATION,\n REPOSITORY_CHANGED,\n} from '../../../constants/error-messages.ts';\nimport { pkg } from '../../../expose.ts';\nimport { logger } from '../../../logger/index.ts';\nimport * as npmApi from '../../../modules/datasource/npm/index.ts';\nimport { platform } from '../../../modules/platform/index.ts';\nimport { scm } from '../../../modules/platform/scm.ts';\nimport { ExternalHostError } from '../../../types/errors/external-host-error.ts';\nimport type { HostRule } from '../../../types/index.ts';\nimport { coerceArray } from '../../../util/array.ts';\nimport { getCache } from '../../../util/cache/repository/index.ts';\nimport { clone } from '../../../util/clone.ts';\nimport { getInheritedOrGlobal, parseJson } from '../../../util/common.ts';\nimport { setUserEnv } from '../../../util/env.ts';\nimport { readLocalFile, readSystemFile } from '../../../util/fs/index.ts';\nimport * as hostRules from '../../../util/host-rules.ts';\nimport * as queue from '../../../util/http/queue.ts';\nimport * as throttle from '../../../util/http/throttle.ts';\nimport { maskToken } from '../../../util/mask.ts';\nimport { coerceObject } from '../../../util/object.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport { coerceString } from '../../../util/string.ts';\nimport { safeStringify } from '../../../util/stringify.ts';\nimport { parseUrl } from '../../../util/url.ts';\nimport { getOnboardingConfig } from '../onboarding/branch/config.ts';\nimport {\n getOnboardingConfigFromCache,\n getOnboardingFileNameFromCache,\n setOnboardingConfigDetails,\n} from '../onboarding/branch/onboarding-branch-cache.ts';\nimport {\n OnboardingState,\n getDefaultConfigFileName,\n} from '../onboarding/common.ts';\nimport { filterAllowedEnv } from './filter-allowed-env.ts';\nimport type { RepoFileConfig, RepositoryWorkerConfig } from './types.ts';\n\nexport async function detectConfigFile(): Promise<string | null> {\n const fileList = await scm.getFileList();\n for (const fileName of getConfigFileNames()) {\n if (fileName === 'package.json') {\n try {\n const pJson = JSON.parse(\n (await readLocalFile('package.json', 'utf8'))!,\n );\n if (pJson.renovate) {\n logger.warn(\n 'Using package.json for Renovate config is deprecated - please use a dedicated configuration file instead',\n );\n return 'package.json';\n }\n } catch {\n // Do nothing\n }\n } else if (fileList.includes(fileName)) {\n return fileName;\n }\n }\n return null;\n}\n\nexport async function detectRepoFileConfig(\n branchName?: string,\n): Promise<RepoFileConfig> {\n const cache = getCache();\n let { configFileName } = cache;\n if (isNonEmptyString(configFileName)) {\n let configFileRaw: string | null;\n try {\n configFileRaw = await platform.getRawFile(\n configFileName,\n undefined,\n branchName,\n );\n } catch (err) {\n // istanbul ignore if\n if (err instanceof ExternalHostError) {\n throw err;\n }\n configFileRaw = null;\n }\n if (configFileRaw) {\n let configFileParsed = parseJson(configFileRaw, configFileName) as any;\n if (configFileName === 'package.json') {\n configFileParsed = configFileParsed.renovate;\n }\n return { configFileName, configFileParsed };\n }\n logger.debug('Existing config file no longer exists');\n delete cache.configFileName;\n }\n\n if (OnboardingState.onboardingCacheValid) {\n configFileName = getOnboardingFileNameFromCache();\n } else {\n configFileName = coerceString(await detectConfigFile());\n }\n\n if (!configFileName) {\n logger.debug('No renovate config file found');\n cache.configFileName = '';\n return {};\n }\n cache.configFileName = configFileName;\n logger.debug(`Found ${configFileName} config file`);\n // TODO #22198\n let configFileParsed: any;\n let configFileRaw: string | undefined | null;\n\n if (OnboardingState.onboardingCacheValid) {\n const cachedConfig = getOnboardingConfigFromCache();\n const parsedConfig = cachedConfig ? JSON.parse(cachedConfig) : undefined;\n if (parsedConfig) {\n setOnboardingConfigDetails(configFileName, JSON.stringify(parsedConfig));\n return { configFileName, configFileParsed: parsedConfig };\n }\n }\n\n if (configFileName === 'package.json') {\n // We already know it parses\n configFileParsed = JSON.parse(\n // TODO #22198\n (await readLocalFile('package.json', 'utf8'))!,\n ).renovate;\n if (isString(configFileParsed)) {\n logger.debug('Massaging string renovate config to extends array');\n configFileParsed = { extends: [configFileParsed] };\n }\n logger.debug({ config: configFileParsed }, 'package.json>renovate config');\n } else {\n configFileRaw = await readLocalFile(configFileName, 'utf8');\n // istanbul ignore if\n if (!isString(configFileRaw)) {\n logger.warn({ configFileName }, 'Null contents when reading config file');\n throw new Error(REPOSITORY_CHANGED);\n }\n // istanbul ignore if\n if (!configFileRaw.length) {\n configFileRaw = '{}';\n }\n\n const parseResult = parseFileConfig(configFileName, configFileRaw);\n\n if (!parseResult.success) {\n return {\n configFileName,\n configFileParseError: {\n validationError: parseResult.validationError,\n validationMessage: parseResult.validationMessage,\n },\n };\n }\n configFileParsed = parseResult.parsedContents;\n logger.debug(\n { fileName: configFileName, config: configFileParsed },\n 'Repository config',\n );\n }\n\n setOnboardingConfigDetails(configFileName, JSON.stringify(configFileParsed));\n return { configFileName, configFileParsed };\n}\n\nexport function checkForRepoConfigError(repoConfig: RepoFileConfig): void {\n if (!repoConfig.configFileParseError) {\n return;\n }\n const error = new Error(CONFIG_VALIDATION);\n error.validationSource = repoConfig.configFileName;\n error.validationError = repoConfig.configFileParseError.validationError;\n error.validationMessage = repoConfig.configFileParseError.validationMessage;\n throw error;\n}\n\n/**\n * Validation source for `repositories[]` object-entry config.\n *\n * As these are managed by the self-hosted admin's global config (`config.js`, or through environment variables, CLI options) we shouldn't report this as an issue the repo owner has introduced.\n */\nconst repositoriesEntrySource = 'Self-hosted config (`repositories[]`)';\n\nconst repoFileValidationError =\n 'The Renovate configuration file contains some invalid settings';\n\nconst repositoriesEntryValidationError =\n 'The self-hosted `repositories[]` config contains some invalid settings';\n\nfunction throwConfigValidationError(\n validationSource: string | undefined,\n errors: ValidationMessage[],\n validationError = repoFileValidationError,\n): never {\n const error = new Error(CONFIG_VALIDATION);\n error.validationSource = validationSource;\n error.validationError = validationError;\n error.validationMessage = errors.map((e) => e.message).join(', ');\n throw error;\n}\n\n/**\n * Validate a fully-resolved config (i.e. after `resolveConfigPresets`).\n *\n * If there are top-level `allowedEnv`/`allowedHeaders` violations, these are reported with `ConfigValidationTopic.Security` and always fail a validation, as they are sensitive config options that need to be blocked.\n *\n * All other issues will be a WARN, unless `configValidationError=true`, because these are resolved config options and may not be in control of the repository owner.\n *\n * `validationSource` is reported to the user; use `repositoriesEntrySource` and `repositoriesEntryValidationError` for admin-controlled object entries so a fault is not blamed on the repo owner.\n */\nasync function validateResolvedConfig(\n resolved: RenovateConfig,\n validationSource: string | undefined,\n strict: boolean,\n validationError?: string,\n): Promise<void> {\n const { errors, warnings } = await configValidation.validateConfig(\n 'repo',\n // `validateConfig` expects massaged input\n massageConfig(resolved),\n );\n\n // Security findings are collected from the warnings too: `validateConfig` folds the results of the sub-validations it runs (notably `onboardingConfig`) into its warnings, and a finding is no less real for having been reported from within one\n const securityErrors = [...errors, ...warnings].filter(\n (err) => err.topic === ConfigValidationTopic.Security,\n );\n const otherErrors = errors.filter(\n (err) => err.topic !== ConfigValidationTopic.Security,\n );\n const otherWarnings = warnings.filter(\n (err) => err.topic !== ConfigValidationTopic.Security,\n );\n\n // before throwing, make sure that any other errors or warnings are logged, as there may be important findings\n if (otherErrors.length || otherWarnings.length) {\n logger.debug(\n { errors: otherErrors, warnings: otherWarnings },\n 'Config validation failed on resolved config, for non-security-sensitive reasons',\n );\n }\n\n if (securityErrors.length) {\n throwConfigValidationError(\n validationSource,\n securityErrors,\n validationError,\n );\n }\n if (strict && otherErrors.length) {\n throwConfigValidationError(validationSource, otherErrors, validationError);\n }\n}\n\n/**\n * Identify a single `env` variable, or a single header of a host rule, by name and value.\n *\n * As `env` is replaced wholesale and `hostRules` is `mergeable`, self-hosted config and repo config end up indistinguishable in the resolved config, so we need a stable way to look a given name and value up.\n */\nfunction nameValueIdentity(name: string, value: string): string {\n // use safeStringify to avoid any potential for an attacker-controlled value to attempt to try and fake the separator and inject in their value as priority\n return safeStringify([name, value]);\n}\n\n/**\n * Index a set of host rules' headers by {@link nameValueIdentity}, recording the `matchHost` values each is set for (`null` for a host-less rule, which matches every host).\n */\nfunction headersByIdentity(\n rules: HostRule[] | undefined,\n): Map<string, Set<string | null>> {\n const result = new Map<string, Set<string | null>>();\n for (const rule of coerceArray(rules)) {\n for (const [name, value] of Object.entries(coerceObject(rule.headers))) {\n const identity = nameValueIdentity(name, value);\n const hosts = result.get(identity) ?? new Set<string | null>();\n hosts.add(rule.matchHost ?? null);\n result.set(identity, hosts);\n }\n }\n return result;\n}\n\n/**\n * Whether every request matched by `matchHost` is also matched by `adminMatchHost` - i.e. a rule scoped to `matchHost` cannot reach any host the admin's own rule does not already reach.\n *\n * A bare hostname is compared as its `https://` URL. `matchesHost` treats a bare `adminMatchHost` as also covering its subdomains, which errs on the admin-friendly side: those hosts sit within the admin's own domain.\n */\nfunction isWithinHost(matchHost: string, adminMatchHost: string): boolean {\n const url = parseUrl(matchHost) ? matchHost : `https://${matchHost}`;\n return hostRules.matchesHost(url, adminMatchHost);\n}\n\n/**\n * Migrate a config, tolerating a migration which throws.\n *\n * `hostRules` migration throws when a rule carries more than one host-matching field. That is per-rule invalid config which {@link applyHostRules} logs and skips over, keeping the rest of the run going, so migrating a whole config here must not escalate it into an error which aborts the repository.\n */\nfunction migrateConfigOrWarn(config: RenovateConfig): MigratedConfig {\n try {\n return migrateConfig(config);\n } catch (err) {\n logger.warn({ err }, 'Error migrating config');\n return { isMigrated: false, migratedConfig: config };\n }\n}\n\n/**\n * The security-sensitive values (`env`, and `hostRules[].headers`) the self-hosted admin supplied, indexed by {@link nameValueIdentity}; the headers additionally record the `matchHost` values each was set for.\n *\n * `mergeChildConfig` promotes `force` values to the top level, so each config contributes its `force` alongside its top-level values.\n */\ninterface AdminSuppliedValues {\n env: Set<string>;\n headers: Map<string, Set<string | null>>;\n /** the `allowInternal` values ('true'/'false') the admin set, recording the `matchHost` values each is set for (`null` for a host-less rule) */\n internalGrants: Map<string, Set<string | null>>;\n}\n\n/**\n * Migrate a set of host rules, so that their `matchHost` compares like for like against the resolved config's own: migration rewrites them (e.g. a legacy `hostName` becoming a `matchHost`, or a bare `matchHost` gaining a scheme), and the resolved config only ever contains the migrated spellings.\n */\nfunction migratedHostRules(rules: HostRule[] | undefined): HostRule[] {\n if (!isNonEmptyArray(rules)) {\n return [];\n }\n return coerceArray(\n migrateConfigOrWarn({ hostRules: rules }).migratedConfig.hostRules,\n );\n}\n\n/**\n * Collect the {@link AdminSuppliedValues} of every config the self-hosted admin supplied.\n *\n * A preset is only ever resolved into the config which extends it, so a config here is the *resolved* form of an admin config: whatever the presets the admin chose to extend contribute is as much theirs as a value they wrote inline.\n */\nfunction adminSuppliedValues(\n adminConfigs: RenovateConfig[],\n): AdminSuppliedValues {\n const env = new Set<string>();\n const headers = new Map<string, Set<string | null>>();\n const internalGrants = new Map<string, Set<string | null>>();\n\n for (const adminConfig of adminConfigs) {\n for (const source of [adminConfig, adminConfig.force]) {\n for (const [name, value] of Object.entries(coerceObject(source?.env))) {\n env.add(nameValueIdentity(name, value));\n }\n const rules = migratedHostRules(source?.hostRules);\n for (const [identity, matchHosts] of headersByIdentity(rules)) {\n const hosts = headers.get(identity) ?? new Set<string | null>();\n for (const matchHost of matchHosts) {\n hosts.add(matchHost);\n }\n headers.set(identity, hosts);\n }\n for (const rule of rules) {\n if (!isUndefined(rule.allowInternal)) {\n const key = rule.allowInternal.toString();\n const hosts = internalGrants.get(key) ?? new Set<string | null>();\n hosts.add(rule.matchHost ?? null);\n internalGrants.set(key, hosts);\n }\n }\n }\n }\n\n return { env, headers, internalGrants };\n}\n\n/**\n * Return `resolved` without the security-sensitive (`env` and `hostRules[].headers`) values the self-hosted admin supplied themselves.\n *\n * `allowedEnv`/`allowedHeaders` exist to constrain what repository config, and the presets it extends, may inject; the self-hosted admin is who sets those allowlists, so their own values are not violations of them.\n *\n * Reporting them would abort the repository and file a \"Fix Renovate Configuration\" issue whose cause the repository's owners can neither see nor fix.\n */\nfunction withoutAdminSuppliedValues(\n resolved: RenovateConfig,\n admin: AdminSuppliedValues,\n): RenovateConfig {\n const result = { ...resolved };\n\n if (result.env) {\n result.env = Object.fromEntries(\n Object.entries(result.env).filter(\n ([name, value]) => !admin.env.has(nameValueIdentity(name, value)),\n ),\n );\n }\n\n // A header is the admin's own when its name and value match one the admin set for hosts that already cover this rule's hosts - the exact `matchHost` spelling must not matter, as migration and presets can re-spell (e.g. add a scheme) or narrow (e.g. a subpath) it\n if (result.hostRules) {\n result.hostRules = result.hostRules.map((rule) => {\n const filtered: HostRule = {\n ...rule,\n headers: Object.fromEntries(\n Object.entries(coerceObject(rule.headers)).filter(([name, value]) => {\n const adminHosts = admin.headers.get(\n nameValueIdentity(name, value),\n );\n if (!adminHosts) {\n // not a header the admin set - report it\n return true;\n }\n if (adminHosts.has(null)) {\n // the admin already sends it to every host\n return false;\n }\n // a host-less rule reaches every host, so only a host-less admin header (above) can exempt it\n return !(\n rule.matchHost &&\n [...adminHosts].some(\n (adminHost) =>\n adminHost !== null &&\n isWithinHost(rule.matchHost!, adminHost),\n )\n );\n }),\n ),\n };\n\n // same principle for `allowInternal`: the admin's own value, for hosts their own rules already cover, is not a violation\n if (!isUndefined(filtered.allowInternal)) {\n const adminHosts = admin.internalGrants.get(\n filtered.allowInternal.toString(),\n );\n const covered =\n adminHosts &&\n (adminHosts.has(null) ||\n (!!filtered.matchHost &&\n [...adminHosts].some(\n (adminHost) =>\n adminHost !== null &&\n isWithinHost(filtered.matchHost!, adminHost),\n )));\n if (covered) {\n delete filtered.allowInternal;\n }\n }\n\n return filtered;\n });\n }\n\n // `mergeChildConfig` promotes `force` values into the config it returns, so the admin's own `force.env`/`force.hostRules[].headers` are applied - and exempted - the same way their top-level equivalents are\n if (result.force) {\n result.force = withoutAdminSuppliedValues(result.force, admin);\n }\n\n return result;\n}\n\n// Check for repository config\nexport async function mergeRenovateConfig(\n config: RepositoryWorkerConfig,\n branchName?: string,\n): Promise<RenovateConfig> {\n let returnConfig: RepositoryWorkerConfig = { ...config };\n let repoConfig: RepoFileConfig = {};\n if (getInheritedOrGlobal('requireConfig') !== 'ignored') {\n repoConfig = await detectRepoFileConfig(branchName);\n }\n if (!repoConfig.configFileParsed && config.mode === 'silent') {\n logger.debug(\n 'When mode=silent and repo has no config file, we use the onboarding config as repo config',\n );\n const configFileName = getDefaultConfigFileName();\n repoConfig = {\n configFileName,\n configFileParsed: await getOnboardingConfig(config),\n };\n }\n const configFileParsed = coerceObject(repoConfig?.configFileParsed);\n const resolvedRepoConfig = await resolveStaticRepoConfig(\n configFileParsed,\n process.env.RENOVATE_X_STATIC_REPO_CONFIG_FILE,\n );\n\n // Apply the repositories[] object-entry config between global config and\n // repository file config.\n // Must run after repository file config is loaded so its `ignorePresets` can\n // be included when resolving object-entry presets.\n const repoEntryConfig = returnConfig.repositoryEntryConfig;\n delete returnConfig.repositoryEntryConfig;\n\n // The presets the self-hosted admin's own config extends are their config too - a repository which merely inherits them must neither be blamed for what they contribute, nor have it filtered out from under it.\n // They are resolved separately because below they are resolved together with the repository's own presets, leaving no way to tell one from the other; a failure here is left to that resolution to report, as it is the one whose result is used.\n let adminPresetConfig: AllConfig = {};\n if (isNonEmptyArray(returnConfig.extends)) {\n try {\n ({ config: adminPresetConfig } = await presets.resolveConfigPresets(\n { extends: returnConfig.extends },\n config,\n config.ignorePresets,\n ));\n } catch (err) {\n logger.debug(\n { err },\n 'Error resolving the self-hosted config presets - continuing without their exemption',\n );\n }\n }\n\n // self-hosted configuration is always allowed\n // `force.env` is included because `mergeChildConfig` promotes `force` values to the top level as configs are merged\n const adminSuppliedEnv = {\n // presets the admin extends: as much theirs as anything they set inline, which is why they are listed first - the values they set themselves win\n ...coerceObject(adminPresetConfig.env),\n ...coerceObject(adminPresetConfig.force?.env),\n // `env` settings the self-hosted admin supplied (via `config.js`, etc), `env`, etc\n ...coerceObject(config.env),\n ...coerceObject(config.force?.env),\n // `repositories[]` entry for this repo - refreshed with the resolved values below, once its own presets, secrets and variables have been applied\n ...coerceObject(repoEntryConfig?.env),\n ...coerceObject(repoEntryConfig?.force?.env),\n };\n\n // every config the self-hosted admin supplied, in resolved form, for {@link adminSuppliedValues}\n const adminConfigs: RenovateConfig[] = [config, adminPresetConfig];\n\n if (isNonEmptyObject(repoEntryConfig)) {\n const repoEntry = repoEntryConfig as RenovateConfig;\n const toResolve: RenovateConfig = {\n ...repoEntry,\n extends: [\n ...coerceArray(returnConfig.extends),\n ...coerceArray(repoEntry.extends),\n ],\n ignorePresets: [\n ...coerceArray(returnConfig.ignorePresets),\n ...coerceArray(repoEntry.ignorePresets),\n ...coerceArray(resolvedRepoConfig.ignorePresets),\n ],\n };\n delete returnConfig.extends;\n\n let { config: resolvedRepoEntry } = await presets.resolveConfigPresets(\n toResolve,\n config,\n );\n\n // Migrate before validating so legacy option names contributed by the entry or its presets are migrated rather than reported as invalid options.\n const entryMigration = migrateConfigOrWarn(resolvedRepoEntry);\n if (entryMigration.isMigrated) {\n resolvedRepoEntry = entryMigration.migratedConfig;\n }\n\n // Migrate the entry's own config the same way, so its values compare like for like below: migration can rewrite them (e.g. a legacy `hostName` becoming a `matchHost`, or a bare `matchHost` gaining a scheme), and the resolved config only ever contains the migrated spellings\n const { migratedConfig: migratedEntry } = migrateConfigOrWarn(toResolve);\n // `resolveConfigPresets` removes both of these from its result\n delete migratedEntry.extends;\n delete migratedEntry.ignorePresets;\n\n // The entry, and every preset it extends, is the self-hosted admin's own config, so its `env`/`headers` are exempt from the allowlists the admin set - but the rest of the resolved result is still worth validating before any of it is applied (npmrc, hostRules, env).\n // When resolution and migration changed nothing, the presets contributed nothing and the entry itself was already validated as part of the admin's global config, so skip the (costly) validation walk entirely.\n adminConfigs.push(resolvedRepoEntry);\n if (!dequal(resolvedRepoEntry, migratedEntry)) {\n await validateResolvedConfig(\n withoutAdminSuppliedValues(\n resolvedRepoEntry,\n adminSuppliedValues(adminConfigs),\n ),\n repositoriesEntrySource,\n config.configValidationError === true,\n repositoriesEntryValidationError,\n );\n }\n\n applyNpmrc(resolvedRepoEntry, 'resolvedRepoEntry');\n\n const resolvedRepoEntryWithSecrets = applySecretsAndVariablesToConfig({\n config: resolvedRepoEntry,\n // like the repository config below, the entry can carry its own `secrets`/`variables` - `validateConfigSecretsAndVariables` validates them at startup\n secrets: mergeChildConfig(\n coerceObject(config.secrets),\n coerceObject(resolvedRepoEntry.secrets),\n ),\n variables: mergeChildConfig(\n coerceObject(config.variables),\n coerceObject(resolvedRepoEntry.variables),\n ),\n });\n\n // Refresh the admin-supplied snapshot from the resolved entry: it also carries whatever the presets the entry extends contributed, and its `env` values may contain `{{ secrets.* }}`/`{{ variables.* }}` templates only interpolated here - e.g. when the secrets are defined on the entry itself rather than globally.\n // Interpolation is recursive, so the interpolated `force.env` values stay nested under `force`.\n Object.assign(\n adminSuppliedEnv,\n coerceObject(resolvedRepoEntryWithSecrets.env),\n coerceObject(resolvedRepoEntryWithSecrets.force?.env),\n );\n\n // the `repositories[]` entry is the self-hosted admin's own config - as its `env` is already treated as admin-supplied, its rules are `trusted` too, so that an admin can still override a header they set globally for just this repository\n applyHostRules(resolvedRepoEntryWithSecrets, { trusted: true });\n returnConfig = mergeChildConfig(returnConfig, resolvedRepoEntryWithSecrets);\n }\n\n if (isNonEmptyArray(returnConfig.extends)) {\n resolvedRepoConfig.extends = [\n ...coerceArray(returnConfig.extends),\n ...coerceArray(resolvedRepoConfig.extends),\n ];\n delete returnConfig.extends;\n }\n checkForRepoConfigError(repoConfig);\n const migratedConfig = await migrateAndValidate(config, resolvedRepoConfig);\n if (migratedConfig.errors?.length) {\n throwConfigValidationError(\n repoConfig.configFileName,\n migratedConfig.errors,\n );\n }\n if (migratedConfig.warnings) {\n returnConfig.warnings = [\n ...coerceArray(returnConfig.warnings),\n ...migratedConfig.warnings,\n ];\n }\n delete migratedConfig.errors;\n delete migratedConfig.warnings;\n // TODO #22198\n const repository = config.repository!;\n // Decrypt before resolving in case we need npm authentication for any presets\n const decryptedConfig = await decryptConfig(migratedConfig, repository);\n applyNpmrc(decryptedConfig, 'decrypted');\n\n // NOTE that this should not be used with any other configuration (`resolvedConfig`, etc) below, as they will include addditionally merged configuration\n // Decrypted secrets are sanitised, so should be safe to log\n await logShallowConfig(decryptedConfig, config);\n\n // Decrypt after resolving in case the preset contains npm authentication instead\n const { config: configToDecrypt } = await presets.resolveConfigPresets(\n decryptedConfig,\n config,\n config.ignorePresets,\n );\n let resolvedConfig = await decryptConfig(configToDecrypt, repository);\n logger.trace({ config: resolvedConfig }, 'resolved config');\n const migrationResult = migrateConfig(resolvedConfig);\n if (migrationResult.isMigrated) {\n logger.debug('Resolved config needs migrating');\n logger.trace({ config: resolvedConfig }, 'resolved config after migrating');\n resolvedConfig = migrationResult.migratedConfig;\n }\n\n // Validate the fully-resolved repository config, enforcing validation is applied against all stages of the preset, and providing defence-in-depth for any sensitive config options\n // note that we do not need to re-run `migrateAndValidate` if we're already at the same configuration that we've previously resolved, decrypted and migrated, so we can avoid a costly re-validation\n if (!dequal(resolvedConfig, migratedConfig)) {\n await validateResolvedConfig(\n // the admin's own `extends` are resolved into this config alongside the repository's, so exempt what they contributed: the repository can neither see nor fix it\n withoutAdminSuppliedValues(\n resolvedConfig,\n adminSuppliedValues(adminConfigs),\n ),\n // a repository that is not yet onboarded has no config file to blame; 'config' mirrors other unattributable validation errors (e.g. `decryptConfig`)\n repoConfig.configFileName ?? 'config',\n config.configValidationError === true,\n );\n }\n if (isString(resolvedConfig.npmrc)) {\n logger.debug(\n 'Ignoring any .npmrc files in repository due to configured npmrc',\n );\n }\n applyNpmrc(resolvedConfig, 'resolved');\n resolvedConfig = applySecretsAndVariablesToConfig({\n config: resolvedConfig,\n secrets: mergeChildConfig(\n coerceObject(config.secrets),\n coerceObject(resolvedConfig.secrets),\n ),\n variables: mergeChildConfig(\n coerceObject(config.variables),\n coerceObject(resolvedConfig.variables),\n ),\n });\n\n applyHostRules(resolvedConfig);\n returnConfig = mergeChildConfig(returnConfig, resolvedConfig);\n ({ config: returnConfig } = await presets.resolveConfigPresets(\n returnConfig,\n config,\n ));\n returnConfig.renovateJsonPresent = true;\n // istanbul ignore if\n if (returnConfig.ignorePaths?.length) {\n logger.debug(\n { ignorePaths: returnConfig.ignorePaths },\n `Found repo ignorePaths`,\n );\n }\n\n setUserEnv(filterAllowedEnv(returnConfig.env, adminSuppliedEnv));\n delete returnConfig.env;\n\n return returnConfig;\n}\n\nexport function applyNpmrc(\n config: RenovateConfig,\n configType?: 'resolved' | 'resolvedRepoEntry' | 'decrypted',\n): void {\n setNpmTokenInNpmrc(config);\n if (!isString(config.npmrc)) {\n return;\n }\n logger.debug(\n `Setting npmrc from ${configType ? `${configType} ` : ''}config`,\n );\n npmApi.setNpmrc(config.npmrc);\n}\n\nexport function applyHostRules(\n config: RenovateConfig,\n options?: hostRules.AddHostRuleOptions,\n): void {\n if (!config.hostRules) {\n return;\n }\n\n logger.debug('Setting hostRules from config');\n // `hostRules.add` enforces `allowedHeaders` on every rule it registers\n for (const rule of config.hostRules) {\n try {\n hostRules.add(rule, options);\n } catch (err) {\n logger.warn({ err, config: rule }, 'Error setting hostRule from config');\n }\n }\n // host rules can change concurrency\n queue.clear();\n throttle.clear();\n delete config.hostRules;\n}\n\n/** needed when using portal secrets for npmToken */\nexport function setNpmTokenInNpmrc(config: RenovateConfig): void {\n if (!isString(config.npmToken)) {\n return;\n }\n\n const token = config.npmToken;\n logger.debug({ npmToken: maskToken(token) }, 'Migrating npmToken to npmrc');\n\n if (!isString(config.npmrc)) {\n logger.debug('Adding npmrc to config');\n config.npmrc = `//registry.npmjs.org/:_authToken=${token}\\n`;\n delete config.npmToken;\n return;\n }\n\n if (config.npmrc.includes(`\\${NPM_TOKEN}`)) {\n logger.debug(`Replacing \\${NPM_TOKEN} with npmToken`);\n config.npmrc = config.npmrc.replace(regEx(/\\${NPM_TOKEN}/g), token);\n } else {\n logger.debug('Appending _authToken= to end of existing npmrc');\n config.npmrc = config.npmrc.replace(\n regEx(/\\n?$/),\n `\\n_authToken=${token}\\n`,\n );\n }\n\n delete config.npmToken;\n}\n\nexport async function resolveStaticRepoConfig(\n config: AllConfig,\n filename: string | undefined,\n): Promise<AllConfig> {\n if (!isNonEmptyString(filename)) {\n return config;\n }\n\n let staticRepoConfig: AllConfig;\n\n try {\n staticRepoConfig = await tryReadStaticRepoFileConfig(filename);\n } catch (err) {\n logger.fatal({ err }, 'Failed to load static repository config file');\n process.exit(1);\n }\n\n if (!isNonEmptyObject(staticRepoConfig)) {\n return config;\n }\n\n return mergeStaticConfig(config, staticRepoConfig);\n}\n\nexport async function tryReadStaticRepoFileConfig(\n staticRepoConfigFile: string,\n): Promise<AllConfig> {\n logger.debug(`Reading static repo config file from ${staticRepoConfigFile}`);\n\n let staticRepoConfigRaw: string;\n try {\n staticRepoConfigRaw = await readSystemFile(staticRepoConfigFile, 'utf8');\n } catch (err) {\n throw new Error(\n `Failed to read static repo config file: \"${staticRepoConfigFile}\"`,\n { cause: err },\n );\n }\n\n const staticRepoConfig = parseJson(\n staticRepoConfigRaw,\n staticRepoConfigFile,\n ) as AllConfig;\n\n // validate and log issues here to preserve context, caller handles migration and full validation.\n const { errors, warnings } = await configValidation.validateConfig(\n 'repo',\n staticRepoConfig,\n );\n\n if (isNonEmptyArray(errors) || isNonEmptyArray(warnings)) {\n logger.info(\n { errors, warnings },\n 'Static repo config validation issues detected',\n );\n } else {\n logger.debug(\n { staticRepoConfig },\n 'Static repository config file successfully parsed and validated',\n );\n }\n\n return staticRepoConfig;\n}\n\nexport function mergeStaticConfig(\n config: AllConfig,\n staticRepoConfig: AllConfig,\n): AllConfig {\n // merge extends\n if (isNonEmptyArray(staticRepoConfig.extends)) {\n config.extends = [\n ...staticRepoConfig.extends,\n ...coerceArray(config.extends),\n ];\n delete staticRepoConfig.extends;\n }\n\n // renovate repo config overrides RENOVATE_STATIC_REPO_CONFIG[_FILE]\n return mergeChildConfig(staticRepoConfig, config);\n}\n\n/**\n * Resolve everything but internal Renovate presets and log it out.\n *\n* This allows users to understand the fully resolved configuration, including any `github>`, `local>`, etc presets, but excluding anything that's internal to Renovate (which can be verbose and/or less relevant), and provides useful output for debugging purposes.\n\n* This is also known as the \"shallow\" config.\n\n* Due to caching, this doesn't add any additional requests.\n */\nasync function logShallowConfig(\n _decryptedConfig: RenovateConfig,\n _config: RepositoryWorkerConfig,\n): Promise<void> {\n // make sure we clone the existing config, so we don't modify the existing settings when resolving this in a shallow fashion\n const decryptedConfig = clone(_decryptedConfig);\n const config = clone(_config);\n\n const { config: resolvedConfig, visitedPresets } =\n await presets.resolveConfigPresets(\n clone(decryptedConfig),\n clone(config),\n [],\n [],\n false,\n );\n logger.debug(\n {\n renovateVersion: pkg.version,\n config: resolvedConfig,\n visitedPresets,\n },\n 'Resolved shallow config, without merging internal presets',\n );\n}\n"],"mappings":"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"}
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.78.0",
4
+ "version": "44.79.0",
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.78.0 config files (https://renovatebot.com/)",
3
+ "title": "JSON schema for Renovate 44.79.0 config files (https://renovatebot.com/)",
4
4
  "$schema": "http://json-schema.org/draft-07/schema#",
5
- "x-renovate-version": "44.78.0",
5
+ "x-renovate-version": "44.79.0",
6
6
  "allowComments": true,
7
7
  "type": "object",
8
8
  "definitions": {
@@ -11517,6 +11517,11 @@
11517
11517
  "mergeConfidenceDatasources"
11518
11518
  ]
11519
11519
  },
11520
+ {
11521
+ "required": [
11522
+ "internalHostAccess"
11523
+ ]
11524
+ },
11520
11525
  {
11521
11526
  "required": [
11522
11527
  "useCloudMetadataServices"
@@ -11767,6 +11772,11 @@
11767
11772
  "inheritConfigStrict"
11768
11773
  ]
11769
11774
  },
11775
+ {
11776
+ "required": [
11777
+ "inheritConfigTrusted"
11778
+ ]
11779
+ },
11770
11780
  {
11771
11781
  "required": [
11772
11782
  "requireConfig"
@@ -11922,6 +11932,11 @@
11922
11932
  "bbUseDevelopmentBranch"
11923
11933
  ]
11924
11934
  },
11935
+ {
11936
+ "required": [
11937
+ "allowInternal"
11938
+ ]
11939
+ },
11925
11940
  {
11926
11941
  "required": [
11927
11942
  "cacheHardTtlMinutes"