renovate 43.115.1 → 43.116.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.
- package/dist/config/global.js +1 -0
- package/dist/config/global.js.map +1 -1
- package/dist/config/inherit.js +2 -1
- package/dist/config/inherit.js.map +1 -1
- package/dist/config/types.d.ts +1 -0
- package/dist/config/types.js.map +1 -1
- package/dist/modules/platform/github/schema.d.ts +2 -2
- package/dist/workers/repository/init/merge.js +2 -2
- package/dist/workers/repository/init/merge.js.map +1 -1
- package/dist/workers/repository/onboarding/branch/check.js +4 -4
- package/dist/workers/repository/onboarding/branch/check.js.map +1 -1
- package/dist/workers/repository/onboarding/pr/index.js +1 -1
- package/dist/workers/repository/onboarding/pr/index.js.map +1 -1
- package/dist/workers/repository/process/extract-update.js +1 -0
- package/dist/workers/repository/process/extract-update.js.map +1 -1
- package/dist/workers/repository/process/vulnerabilities.js +33 -0
- package/dist/workers/repository/process/vulnerabilities.js.map +1 -1
- package/package.json +2 -2
- package/renovate-schema.json +2 -2
package/dist/config/global.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"global.js","names":[],"sources":["../../lib/config/global.ts"],"sourcesContent":["import type { RenovateConfig, RepoGlobalConfig } from './types.ts';\n\nexport class GlobalConfig {\n // TODO: once global config work is complete, add a test to make sure this list includes all options with globalOnly=true (#9603)\n static OPTIONS: readonly (keyof RepoGlobalConfig)[] = [\n 'allowCustomCrateRegistries',\n 'allowPlugins',\n 'allowScripts',\n 'allowShellExecutorForPostUpgradeCommands',\n 'allowedCommands',\n 'allowedEnv',\n 'allowedHeaders',\n 'allowedUnsafeExecutions',\n 'autodiscoverRepoOrder',\n 'autodiscoverRepoSort',\n 'bbUseDevelopmentBranch',\n 'binarySource',\n 'cacheDir',\n 'cacheHardTtlMinutes',\n 'cachePrivatePackages',\n 'cacheTtlOverride',\n 'configFileNames',\n 'containerbaseDir',\n 'customEnvVariables',\n 'dockerChildPrefix',\n 'dockerCliOptions',\n 'dockerMaxPages',\n 'dockerSidecarImage',\n 'dockerUser',\n 'dryRun',\n 'encryptedWarning',\n 'endpoint',\n 'executionTimeout',\n 'exposeAllEnv',\n 'gitTimeout',\n 'githubTokenWarn',\n 'httpCacheTtlDays',\n 'ignorePrAuthor',\n 'includeMirrors',\n 'localDir',\n 'migratePresets',\n 'onboarding',\n 'onboardingAutoCloseAge',\n 'onboardingBranch',\n 'onboardingCommitMessage',\n 'onboardingConfig',\n 'onboardingConfigFileName',\n 'onboardingNoDeps',\n 'onboardingPrTitle',\n 'platform',\n 'prCacheSyncMaxPages',\n 'presetCachePersistence',\n 'repositoryCacheForceLocal',\n 's3Endpoint',\n 's3PathStyle',\n 'toolSettings',\n 'userAgent',\n ];\n\n private static config: RepoGlobalConfig = {};\n\n static get(): RepoGlobalConfig;\n static get<Key extends keyof RepoGlobalConfig>(\n key: Key,\n ): RepoGlobalConfig[Key];\n static get<Key extends keyof RepoGlobalConfig>(\n key: Key,\n defaultValue: Required<RepoGlobalConfig>[Key],\n ): Required<RepoGlobalConfig>[Key];\n static get<Key extends keyof RepoGlobalConfig>(\n key?: Key,\n defaultValue?: RepoGlobalConfig[Key],\n ): RepoGlobalConfig | RepoGlobalConfig[Key] {\n return key\n ? (GlobalConfig.config[key] ?? defaultValue)\n : GlobalConfig.config;\n }\n\n static set(config: RenovateConfig & RepoGlobalConfig): RenovateConfig {\n GlobalConfig.reset();\n\n const result = { ...config };\n for (const option of GlobalConfig.OPTIONS) {\n GlobalConfig.config[option] = config[option] as never;\n delete result[option];\n }\n\n return result;\n }\n\n static reset(): void {\n GlobalConfig.config = {};\n }\n}\n"],"mappings":";AAEA,IAAa,eAAb,MAAa,aAAa;CAExB,OAAO,UAA+C;EACpD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;CAED,OAAe,SAA2B,EAAE;CAU5C,OAAO,IACL,KACA,cAC0C;AAC1C,SAAO,MACF,aAAa,OAAO,QAAQ,eAC7B,aAAa;;CAGnB,OAAO,IAAI,QAA2D;AACpE,eAAa,OAAO;EAEpB,MAAM,SAAS,EAAE,GAAG,QAAQ;AAC5B,OAAK,MAAM,UAAU,aAAa,SAAS;AACzC,gBAAa,OAAO,UAAU,OAAO;AACrC,UAAO,OAAO;;AAGhB,SAAO;;CAGT,OAAO,QAAc;AACnB,eAAa,SAAS,EAAE"}
|
|
1
|
+
{"version":3,"file":"global.js","names":[],"sources":["../../lib/config/global.ts"],"sourcesContent":["import type { RenovateConfig, RepoGlobalConfig } from './types.ts';\n\nexport class GlobalConfig {\n // TODO: once global config work is complete, add a test to make sure this list includes all options with globalOnly=true (#9603)\n static OPTIONS: readonly (keyof RepoGlobalConfig)[] = [\n 'allowCustomCrateRegistries',\n 'allowPlugins',\n 'allowScripts',\n 'allowShellExecutorForPostUpgradeCommands',\n 'allowedCommands',\n 'allowedEnv',\n 'allowedHeaders',\n 'allowedUnsafeExecutions',\n 'autodiscoverRepoOrder',\n 'autodiscoverRepoSort',\n 'bbUseDevelopmentBranch',\n 'binarySource',\n 'cacheDir',\n 'cacheHardTtlMinutes',\n 'cachePrivatePackages',\n 'cacheTtlOverride',\n 'configFileNames',\n 'containerbaseDir',\n 'customEnvVariables',\n 'dockerChildPrefix',\n 'dockerCliOptions',\n 'dockerMaxPages',\n 'dockerSidecarImage',\n 'dockerUser',\n 'dryRun',\n 'encryptedWarning',\n 'endpoint',\n 'executionTimeout',\n 'exposeAllEnv',\n 'gitTimeout',\n 'githubTokenWarn',\n 'httpCacheTtlDays',\n 'ignorePrAuthor',\n 'includeMirrors',\n 'localDir',\n 'migratePresets',\n 'onboarding',\n 'onboardingAutoCloseAge',\n 'onboardingBranch',\n 'onboardingCommitMessage',\n 'onboardingConfig',\n 'onboardingConfigFileName',\n 'onboardingNoDeps',\n 'onboardingPrTitle',\n 'platform',\n 'prCacheSyncMaxPages',\n 'presetCachePersistence',\n 'repositoryCacheForceLocal',\n 'requireConfig',\n 's3Endpoint',\n 's3PathStyle',\n 'toolSettings',\n 'userAgent',\n ];\n\n private static config: RepoGlobalConfig = {};\n\n static get(): RepoGlobalConfig;\n static get<Key extends keyof RepoGlobalConfig>(\n key: Key,\n ): RepoGlobalConfig[Key];\n static get<Key extends keyof RepoGlobalConfig>(\n key: Key,\n defaultValue: Required<RepoGlobalConfig>[Key],\n ): Required<RepoGlobalConfig>[Key];\n static get<Key extends keyof RepoGlobalConfig>(\n key?: Key,\n defaultValue?: RepoGlobalConfig[Key],\n ): RepoGlobalConfig | RepoGlobalConfig[Key] {\n return key\n ? (GlobalConfig.config[key] ?? defaultValue)\n : GlobalConfig.config;\n }\n\n static set(config: RenovateConfig & RepoGlobalConfig): RenovateConfig {\n GlobalConfig.reset();\n\n const result = { ...config };\n for (const option of GlobalConfig.OPTIONS) {\n GlobalConfig.config[option] = config[option] as never;\n delete result[option];\n }\n\n return result;\n }\n\n static reset(): void {\n GlobalConfig.config = {};\n }\n}\n"],"mappings":";AAEA,IAAa,eAAb,MAAa,aAAa;CAExB,OAAO,UAA+C;EACpD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;CAED,OAAe,SAA2B,EAAE;CAU5C,OAAO,IACL,KACA,cAC0C;AAC1C,SAAO,MACF,aAAa,OAAO,QAAQ,eAC7B,aAAa;;CAGnB,OAAO,IAAI,QAA2D;AACpE,eAAa,OAAO;EAEpB,MAAM,SAAS,EAAE,GAAG,QAAQ;AAC5B,OAAK,MAAM,UAAU,aAAa,SAAS;AACzC,gBAAa,OAAO,UAAU,OAAO;AACrC,UAAO,OAAO;;AAGhB,SAAO;;CAGT,OAAO,QAAc;AACnB,eAAa,SAAS,EAAE"}
|
package/dist/config/inherit.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inherit.js","names":[],"sources":["../../lib/config/inherit.ts"],"sourcesContent":["import type { GlobalInheritableConfig, RenovateConfig } from './types.ts';\n\nexport const NOT_PRESENT = Symbol('not-present');\n\nexport class InheritConfig {\n static OPTIONS: readonly (keyof GlobalInheritableConfig)[] = [\n 'bbUseDevelopmentBranch',\n 'configFileNames',\n 'onboarding',\n 'onboardingAutoCloseAge',\n 'onboardingBranch',\n 'onboardingCommitMessage',\n 'onboardingConfig',\n 'onboardingConfigFileName',\n 'onboardingNoDeps',\n 'onboardingPrTitle',\n ];\n\n private static config: GlobalInheritableConfig = {};\n\n static get<Key extends keyof GlobalInheritableConfig>(\n key: Key,\n ): GlobalInheritableConfig[Key] | typeof NOT_PRESENT {\n if (key in InheritConfig.config) {\n return InheritConfig.config[key];\n }\n\n return NOT_PRESENT;\n }\n\n static set(config: RenovateConfig & GlobalInheritableConfig): RenovateConfig {\n InheritConfig.reset();\n\n const result = { ...config };\n for (const option of InheritConfig.OPTIONS) {\n if (option in config) {\n InheritConfig.config[option] = config[option] as never;\n }\n delete result[option];\n }\n\n return result;\n }\n\n static reset(): void {\n InheritConfig.config = {};\n }\n}\n"],"mappings":";AAEA,MAAa,cAAc,OAAO,cAAc;AAEhD,IAAa,gBAAb,MAAa,cAAc;CACzB,OAAO,UAAsD;EAC3D;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;CAED,OAAe,SAAkC,EAAE;CAEnD,OAAO,IACL,KACmD;AACnD,MAAI,OAAO,cAAc,OACvB,QAAO,cAAc,OAAO;AAG9B,SAAO;;CAGT,OAAO,IAAI,QAAkE;AAC3E,gBAAc,OAAO;EAErB,MAAM,SAAS,EAAE,GAAG,QAAQ;AAC5B,OAAK,MAAM,UAAU,cAAc,SAAS;AAC1C,OAAI,UAAU,OACZ,eAAc,OAAO,UAAU,OAAO;AAExC,UAAO,OAAO;;AAGhB,SAAO;;CAGT,OAAO,QAAc;AACnB,gBAAc,SAAS,EAAE"}
|
|
1
|
+
{"version":3,"file":"inherit.js","names":[],"sources":["../../lib/config/inherit.ts"],"sourcesContent":["import type { GlobalInheritableConfig, RenovateConfig } from './types.ts';\n\nexport const NOT_PRESENT = Symbol('not-present');\n\nexport class InheritConfig {\n static OPTIONS: readonly (keyof GlobalInheritableConfig)[] = [\n 'bbUseDevelopmentBranch',\n 'configFileNames',\n 'onboarding',\n 'onboardingAutoCloseAge',\n 'onboardingBranch',\n 'onboardingCommitMessage',\n 'onboardingConfig',\n 'onboardingConfigFileName',\n 'onboardingNoDeps',\n 'onboardingPrTitle',\n 'requireConfig',\n ];\n\n private static config: GlobalInheritableConfig = {};\n\n static get<Key extends keyof GlobalInheritableConfig>(\n key: Key,\n ): GlobalInheritableConfig[Key] | typeof NOT_PRESENT {\n if (key in InheritConfig.config) {\n return InheritConfig.config[key];\n }\n\n return NOT_PRESENT;\n }\n\n static set(config: RenovateConfig & GlobalInheritableConfig): RenovateConfig {\n InheritConfig.reset();\n\n const result = { ...config };\n for (const option of InheritConfig.OPTIONS) {\n if (option in config) {\n InheritConfig.config[option] = config[option] as never;\n }\n delete result[option];\n }\n\n return result;\n }\n\n static reset(): void {\n InheritConfig.config = {};\n }\n}\n"],"mappings":";AAEA,MAAa,cAAc,OAAO,cAAc;AAEhD,IAAa,gBAAb,MAAa,cAAc;CACzB,OAAO,UAAsD;EAC3D;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;CAED,OAAe,SAAkC,EAAE;CAEnD,OAAO,IACL,KACmD;AACnD,MAAI,OAAO,cAAc,OACvB,QAAO,cAAc,OAAO;AAG9B,SAAO;;CAGT,OAAO,IAAI,QAAkE;AAC3E,gBAAc,OAAO;EAErB,MAAM,SAAS,EAAE,GAAG,QAAQ;AAC5B,OAAK,MAAM,UAAU,cAAc,SAAS;AAC1C,OAAI,UAAU,OACZ,eAAc,OAAO,UAAU,OAAO;AAExC,UAAO,OAAO;;AAGhB,SAAO;;CAGT,OAAO,QAAc;AACnB,gBAAc,SAAS,EAAE"}
|
package/dist/config/types.d.ts
CHANGED
|
@@ -152,6 +152,7 @@ interface GlobalInheritableConfig {
|
|
|
152
152
|
onboardingConfigFileName?: string;
|
|
153
153
|
onboardingNoDeps?: 'auto' | 'enabled' | 'disabled';
|
|
154
154
|
onboardingPrTitle?: string;
|
|
155
|
+
requireConfig?: RequiredConfig;
|
|
155
156
|
}
|
|
156
157
|
/** @deprecated use `RepoGlobalConfig` instead **/
|
|
157
158
|
interface GlobalOnlyConfigLegacy {
|
package/dist/config/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","names":[],"sources":["../../lib/config/types.ts"],"sourcesContent":["import type { Category, PlatformId } from '../constants/index.ts';\nimport type { LogLevelRemap } from '../logger/types.ts';\nimport type { ManagerName } from '../manager-list.generated.ts';\nimport type { CustomManager } from '../modules/manager/custom/types.ts';\nimport type { RepoSortMethod, SortMethod } from '../modules/platform/types.ts';\nimport type {\n AutoMergeType,\n HostRule,\n Nullish,\n RangeStrategy,\n SkipReason,\n} from '../types/index.ts';\nimport type { StageName } from '../types/skip-reason.ts';\nimport type { ConstraintName, ToolName } from '../util/exec/types.ts';\nimport type { GitNoVerifyOption } from '../util/git/types.ts';\nimport type { MergeConfidence } from '../util/merge-confidence/types.ts';\nimport type { Timestamp } from '../util/timestamp.ts';\n\nexport type RenovateConfigStage =\n | 'global'\n | 'inherit'\n | 'repository'\n | 'package'\n | 'branch'\n | 'pr';\n\nexport type RenovateSplit =\n | 'init'\n | 'onboarding'\n | 'extract'\n | 'lookup'\n | 'update';\n\nexport type RepositoryCacheConfig = 'disabled' | 'enabled' | 'reset';\nexport type RepositoryCacheType = 'local' | (string & {});\nexport type DryRunConfig = 'extract' | 'lookup' | 'full';\nexport type RequiredConfig = 'required' | 'optional' | 'ignored';\n\nexport interface GroupConfig extends Record<string, unknown> {\n branchName?: string;\n branchTopic?: string;\n}\n\nexport type RecreateWhen = 'auto' | 'never' | 'always';\nexport type PlatformCommitOptions = 'auto' | 'disabled' | 'enabled';\n\nexport type BinarySource = 'docker' | 'global' | 'install' | 'hermit';\n\n// TODO: Proper typings\n/**\n * Any configuration that could be used either top-level in a repository config (or Global, Inherited or Shareable Preset configuration), or:\n *\n * - in a datasource-specific configuration\n * - in a manager-specific configuration\n * - in a Package Rule\n *\n * @see RenovateConfig for the superset of all configuration allowed in a given repository\n *\n */\nexport interface RenovateSharedConfig {\n $schema?: string;\n abandonmentThreshold?: Nullish<string>;\n addLabels?: string[];\n assignAutomerge?: boolean;\n autoApprove?: boolean;\n autoReplaceGlobalMatch?: boolean;\n automerge?: boolean;\n automergeSchedule?: string[];\n automergeStrategy?: MergeStrategy;\n automergeType?: AutoMergeType;\n azureWorkItemId?: number;\n branchName?: string;\n branchNameStrict?: boolean;\n branchPrefix?: string;\n branchPrefixOld?: string;\n bumpVersions?: BumpVersionConfig[];\n commitBody?: string;\n commitBodyTable?: boolean;\n commitMessage?: string;\n commitMessageAction?: string;\n commitMessageExtra?: string;\n commitMessageLowerCase?: 'auto' | 'never';\n commitMessagePrefix?: string;\n commitMessageTopic?: string;\n confidential?: boolean;\n configValidationError?: boolean;\n changelogUrl?: string;\n dependencyDashboardApproval?: boolean;\n draftPR?: boolean;\n enabled?: boolean;\n enabledManagers?: string[];\n encrypted?: Record<string, string>;\n extends?: string[];\n extractVersion?: string;\n managerFilePatterns?: string[];\n followTag?: string;\n force?: RenovateConfig;\n gitIgnoredAuthors?: string[];\n group?: GroupConfig;\n groupName?: string;\n groupSlug?: string;\n hashedBranchLength?: number;\n ignoreDeps?: string[];\n ignorePaths?: string[];\n ignoreTests?: boolean;\n ignoreUnstable?: boolean;\n includePaths?: string[];\n internalChecksAsSuccess?: boolean;\n internalChecksFilter?: 'strict' | 'flexible' | 'none';\n keepUpdatedLabel?: string;\n labels?: string[];\n manager?: string;\n milestone?: number;\n minimumReleaseAge?: Nullish<string>;\n npmrc?: string;\n npmrcMerge?: boolean;\n npmToken?: string;\n\n pinDigests?: boolean;\n platformAutomerge?: boolean;\n platformCommit?: PlatformCommitOptions;\n postUpgradeTasks?: PostUpgradeTasks;\n prBodyColumns?: string[];\n prBodyDefinitions?: Record<string, string>;\n prBodyHeadingDefinitions?: Record<string, string>;\n prBodyNotes?: string[];\n prCreation?: 'immediate' | 'not-pending' | 'status-success' | 'approval';\n prFooter?: string;\n prHeader?: string;\n prPriority?: number;\n prTitle?: string;\n prTitleStrict?: boolean;\n productLinks?: Record<string, string>;\n pruneBranchAfterAutomerge?: boolean;\n rangeStrategy?: RangeStrategy;\n rebaseLabel?: string;\n rebaseWhen?: string;\n recreateClosed?: boolean;\n recreateWhen?: RecreateWhen;\n repository?: string;\n repositoryCache?: RepositoryCacheConfig;\n repositoryCacheType?: RepositoryCacheType;\n respectLatest?: boolean;\n rollbackPrs?: boolean;\n schedule?: string[];\n semanticCommitScope?: string | null;\n semanticCommitType?: string;\n semanticCommits?: 'auto' | 'enabled' | 'disabled';\n separateMajorMinor?: boolean;\n separateMinorPatch?: boolean;\n separateMultipleMajor?: boolean;\n separateMultipleMinor?: boolean;\n skipArtifactsUpdate?: boolean;\n stopUpdatingLabel?: string;\n suppressNotifications?: string[];\n timezone?: string;\n unicodeEmoji?: boolean;\n updateNotScheduled?: boolean;\n versioning?: string;\n versionCompatibility?: string;\n}\n\n/**\n * Contains all options with globalOnly=true && inheritConfigSupport=true\n */\nexport interface GlobalInheritableConfig {\n bbUseDevelopmentBranch?: boolean;\n configFileNames?: string[];\n onboarding?: boolean;\n onboardingAutoCloseAge?: number;\n onboardingBranch?: string;\n onboardingCommitMessage?: string;\n onboardingConfig?: RenovateConfig;\n onboardingConfigFileName?: string;\n onboardingNoDeps?: 'auto' | 'enabled' | 'disabled';\n onboardingPrTitle?: string;\n}\n\n// Config options used only within the global worker\n// The below should contain config options where stage=global\n/** @deprecated use `RepoGlobalConfig` instead **/\nexport interface GlobalOnlyConfigLegacy {\n autodiscover?: boolean;\n autodiscoverFilter?: string[] | string;\n autodiscoverNamespaces?: string[];\n autodiscoverProjects?: string[];\n autodiscoverTopics?: string[];\n baseDir?: string;\n cacheDir?: string;\n containerbaseDir?: string;\n detectHostRulesFromEnv?: boolean;\n dockerCliOptions?: string;\n endpoint?: string;\n forceCli?: boolean;\n gitNoVerify?: GitNoVerifyOption[];\n gitPrivateKey?: string;\n gitPrivateKeyPassphrase?: string;\n globalExtends?: string[];\n mergeConfidenceDatasources?: string[];\n mergeConfidenceEndpoint?: string;\n platform?: PlatformId;\n processEnv?: Record<string, string>;\n prCommitsPerRunLimit?: number;\n privateKey?: string;\n privateKeyOld?: string;\n privateKeyPath?: string;\n privateKeyPathOld?: string;\n redisPrefix?: string;\n redisUrl?: string;\n repositories?: RenovateRepository[];\n useCloudMetadataServices?: boolean;\n deleteConfigFile?: boolean;\n deleteAdditionalConfigFile?: boolean;\n}\n\n/**\n * Any global-only configuration set by self-hosted administrators.\n *\n * Used within the repository worker.\n *\n * Should only contain config options where globalOnly=true.\n */\nexport interface RepoGlobalConfig extends GlobalInheritableConfig {\n allowedCommands?: string[];\n allowCustomCrateRegistries?: boolean;\n allowPlugins?: boolean;\n allowScripts?: boolean;\n allowShellExecutorForPostUpgradeCommands?: boolean;\n allowedEnv?: string[];\n allowedHeaders?: string[];\n binarySource?: BinarySource;\n cacheDir?: string;\n cacheHardTtlMinutes?: number;\n cacheTtlOverride?: Record<string, number>;\n containerbaseDir?: string;\n customEnvVariables?: Record<string, string>;\n dockerChildPrefix?: string;\n dockerCliOptions?: string;\n dockerSidecarImage?: string;\n dockerUser?: string;\n dryRun?: DryRunConfig;\n encryptedWarning?: string;\n endpoint?: string;\n executionTimeout?: number;\n exposeAllEnv?: boolean;\n gitTimeout?: number;\n githubTokenWarn?: boolean;\n includeMirrors?: boolean;\n localDir?: string;\n migratePresets?: Record<string, string>;\n platform?: PlatformId;\n prCacheSyncMaxPages?: number;\n presetCachePersistence?: boolean;\n httpCacheTtlDays?: number;\n autodiscoverRepoSort?: RepoSortMethod;\n autodiscoverRepoOrder?: SortMethod;\n userAgent?: string;\n dockerMaxPages?: number;\n s3Endpoint?: string;\n s3PathStyle?: boolean;\n cachePrivatePackages?: boolean;\n repositoryCacheForceLocal?: boolean;\n configFileNames?: string[];\n ignorePrAuthor?: boolean;\n allowedUnsafeExecutions?: AllowedUnsafeExecution[];\n onboardingAutoCloseAge?: number;\n toolSettings?: ToolSettingsOptions;\n}\n\n/**\n * Those options are global only but still passed into the repository worker config.\n *\n * @deprecated https://github.com/renovatebot/renovate/issues/39693\n */\nexport interface LegacyAdminConfig {\n baseDir?: string;\n localDir?: string;\n\n logContext?: string;\n\n onboarding?: boolean;\n onboardingBranch?: string;\n onboardingNoDeps?: 'auto' | 'enabled' | 'disabled';\n onboardingRebaseCheckbox?: boolean;\n onboardingConfig?: RenovateConfig;\n onboardingConfigFileName?: string;\n\n optimizeForDisabled?: boolean;\n\n persistRepoData?: boolean;\n\n prCommitsPerRunLimit?: number;\n\n requireConfig?: RequiredConfig;\n\n useCloudMetadataServices?: boolean;\n\n writeDiscoveredRepos?: string;\n}\n\nexport type ExecutionMode = 'branch' | 'update';\n\nexport interface PostUpgradeTasks {\n commands?: string[];\n workingDirTemplate?: string;\n dataFileTemplate?: string;\n fileFilters?: string[];\n executionMode: ExecutionMode;\n installTools?: Partial<Record<ToolName, Record<never, never>>>;\n}\n\nexport type UpdateConfig<\n T extends RenovateSharedConfig = RenovateSharedConfig,\n> = Partial<Record<UpdateType, T | null>>;\n\nexport type RenovateRepository =\n | string\n | (RenovateConfig & {\n repository: string;\n });\n\nexport type UseBaseBranchConfigType = 'merge' | 'none';\nexport type ConstraintsFilter = 'strict' | 'none';\nexport type MinimumReleaseAgeBehaviour =\n | 'timestamp-required'\n | 'timestamp-optional';\n\nexport const allowedStatusCheckStrings = [\n 'minimumReleaseAge',\n 'mergeConfidence',\n 'configValidation',\n 'artifactError',\n] as const;\nexport type StatusCheckKey = (typeof allowedStatusCheckStrings)[number];\ntype UserEnv = Record<string, string>;\n\n/**\n * Computed properties, for internal use only\n */\nexport interface RenovateInternalConfig {\n /** computed base branch from patterns - for internal use only */\n baseBranches?: string[];\n currentCompatibility?: string;\n datasource?: string;\n hasBaseBranches?: boolean;\n isFork?: boolean;\n isVulnerabilityAlert?: boolean;\n\n /** What is this used for? */\n remediations?: unknown;\n /** What is this used for? */\n vulnerabilityAlertsOnly?: boolean;\n}\n\n// TODO: Proper typings\n/**\n * Configuration that could be used either top-level in a repository config (or Global, Inherited or Shareable Preset configuration).\n *\n * This is a superset of any configuration that a Renovate user (not self-hosted administrator) can set.\n */\nexport interface RenovateConfig\n extends\n LegacyAdminConfig,\n RenovateSharedConfig,\n UpdateConfig<PackageRule>,\n AssigneesAndReviewersConfig,\n ConfigMigration,\n RenovateInternalConfig {\n s3Endpoint?: string;\n s3PathStyle?: boolean;\n reportFormatting?: boolean;\n reportPath?: string;\n reportType?: 'logging' | 'file' | 's3' | null;\n depName?: string;\n /** user configurable base branch patterns*/\n baseBranchPatterns?: string[];\n useBaseBranchConfig?: UseBaseBranchConfigType;\n baseBranch?: string;\n defaultBranch?: string;\n branchList?: string[];\n cloneSubmodules?: boolean;\n cloneSubmodulesFilter?: string[];\n description?: string | string[];\n detectGlobalManagerConfig?: boolean;\n errors?: ValidationMessage[];\n forkModeDisallowMaintainerEdits?: boolean;\n forkProcessing?: 'auto' | 'enabled' | 'disabled';\n forkToken?: string;\n\n gitAuthor?: string;\n\n hostRules?: HostRule[];\n\n inheritConfig?: boolean;\n inheritConfigFileName?: string;\n inheritConfigRepoName?: string;\n inheritConfigStrict?: boolean;\n\n ignorePresets?: string[];\n\n fileList?: string[];\n configWarningReuseIssue?: boolean;\n dependencyDashboard?: boolean;\n dependencyDashboardAutoclose?: boolean;\n dependencyDashboardChecks?: Record<string, string>;\n dependencyDashboardIssue?: number;\n dependencyDashboardTitle?: string;\n dependencyDashboardHeader?: string;\n dependencyDashboardFooter?: string;\n dependencyDashboardLabels?: string[];\n dependencyDashboardOSVVulnerabilitySummary?: 'none' | 'all' | 'unresolved';\n dependencyDashboardReportAbandonment?: boolean;\n mode?: 'silent' | 'full';\n packageFile?: string;\n packageRules?: PackageRule[];\n postUpdateOptions?: string[];\n branchConcurrentLimit?: number | null;\n parentOrg?: string;\n prConcurrentLimit?: number;\n commitHourlyLimit?: number;\n prHourlyLimit?: number;\n\n printConfig?: boolean;\n\n pruneStaleBranches?: boolean;\n\n defaultRegistryUrls?: string[];\n registryUrls?: string[] | null;\n registryAliases?: Record<string, string>;\n\n /**\n * What is this used for?\n * @deprecated\n */\n renovateJsonPresent?: boolean;\n\n repoIsOnboarded?: boolean;\n repoIsActivated?: boolean;\n\n topLevelOrg?: string;\n updateInternalDeps?: boolean;\n updateType?: UpdateType;\n\n warnings?: ValidationMessage[];\n vulnerabilityAlerts?: RenovateSharedConfig;\n osvVulnerabilityAlerts?: boolean;\n vulnerabilitySeverity?: string;\n customManagers?: CustomManager[];\n customDatasources?: Record<string, CustomDatasourceConfig>;\n\n fetchChangeLogs?: FetchChangeLogsOptions;\n secrets?: Record<string, string>;\n variables?: Record<string, string>;\n\n constraints?: Partial<Record<ConstraintName, string>>;\n skipInstalls?: boolean | null;\n\n constraintsFiltering?: ConstraintsFilter;\n\n checkedBranches?: string[];\n customizeDashboard?: Record<string, string>;\n\n statusCheckNames?: Record<StatusCheckKey, string | null>;\n /**\n * User configured environment variables that Renovate uses when executing package manager commands\n */\n env?: UserEnv;\n logLevelRemap?: LogLevelRemap[];\n\n branchTopic?: string;\n additionalBranchPrefix?: string;\n sharedVariableName?: string;\n minimumGroupSize?: number;\n configFileNames?: string[];\n minimumReleaseAgeBehaviour?: MinimumReleaseAgeBehaviour;\n toolSettings?: ToolSettingsOptions;\n}\n\nconst CustomDatasourceFormats = [\n 'html',\n 'json',\n 'plain',\n 'toml',\n 'yaml',\n] as const;\nexport type CustomDatasourceFormats = (typeof CustomDatasourceFormats)[number];\n\nexport interface CustomDatasourceConfig {\n defaultRegistryUrlTemplate?: string;\n format?: CustomDatasourceFormats;\n transformTemplates?: string[];\n}\n\n/**\n * The superset of all configuration that a self-hosted administrator can set, alongside all repository-level configuration.\n *\n */\nexport interface AllConfig\n extends RenovateConfig, GlobalOnlyConfigLegacy, RepoGlobalConfig {\n password?: string;\n token?: string;\n username?: string;\n}\n\nexport interface AssigneesAndReviewersConfig {\n assigneesFromCodeOwners?: boolean;\n expandCodeOwnersGroups?: boolean;\n assignees?: string[];\n assigneesSampleSize?: number;\n ignoreReviewers?: string[];\n reviewersFromCodeOwners?: boolean;\n reviewers?: string[];\n reviewersSampleSize?: number;\n additionalReviewers?: string[];\n filterUnavailableUsers?: boolean;\n}\n\nexport type UpdateType =\n | 'major'\n | 'minor'\n | 'patch'\n | 'pin'\n | 'digest'\n | 'pinDigest'\n | 'lockFileMaintenance'\n | 'lockfileUpdate'\n | 'rollback'\n | 'bump'\n | 'replacement';\n\n// These are the update types which can have configuration\nexport const UpdateTypesOptions = [\n 'major',\n 'minor',\n 'patch',\n 'pin',\n 'digest',\n 'pinDigest',\n 'lockFileMaintenance',\n 'rollback',\n 'replacement',\n] as const;\n\nexport type UpdateTypeOptions = (typeof UpdateTypesOptions)[number];\n\nexport type FetchChangeLogsOptions = 'off' | 'branch' | 'pr';\n\nexport type MatchStringsStrategy = 'any' | 'recursive' | 'combination';\n\nexport type MergeStrategy =\n | 'auto'\n | 'fast-forward'\n | 'merge-commit'\n | 'rebase'\n | 'rebase-merge'\n | 'squash';\n\n// This list should be added to as any new unsafe execution commands should be permitted\nexport type AllowedUnsafeExecution =\n | 'bazelModDeps'\n | 'goGenerate'\n | 'gradleWrapper';\n\n// TODO: Proper typings\nexport interface PackageRule\n extends RenovateSharedConfig, RenovateInternalConfig, UpdateConfig {\n allowedVersions?: string;\n description?: string | string[];\n matchBaseBranches?: string[];\n matchCategories?: string[];\n matchConfidence?: MergeConfidence[];\n matchCurrentAge?: string;\n matchCurrentValue?: string;\n matchCurrentVersion?: string;\n matchDatasources?: string[];\n matchDepNames?: string[];\n matchDepTypes?: string[];\n matchFileNames?: string[];\n matchManagers?: string[];\n matchNewValue?: string;\n matchPackageNames?: string[];\n matchRepositories?: string[];\n matchSourceUrls?: string[];\n matchRegistryUrls?: string[];\n matchUpdateTypes?: UpdateType[];\n matchJsonata?: string[];\n overrideDatasource?: string;\n overrideDepName?: string;\n overridePackageName?: string;\n registryUrls?: string[] | null;\n replacementName?: string;\n replacementVersion?: string;\n sourceUrl?: string;\n sourceDirectory?: string;\n vulnerabilitySeverity?: string;\n vulnerabilityFixVersion?: string;\n}\n\nexport interface ValidationMessage {\n topic: string;\n message: string;\n}\n\nexport type AllowedParents =\n | '.'\n | 'bumpVersions'\n | 'customDatasources'\n | 'customManagers'\n | 'hostRules'\n | 'logLevelRemap'\n | 'packageRules'\n | 'postUpgradeTasks'\n | 'vulnerabilityAlerts'\n | 'toolSettings'\n | ManagerName\n | UpdateTypeOptions;\nexport interface RenovateOptionBase {\n /**\n * If true, the option can only be configured by people with access to the Renovate instance.\n * Furthermore, the option should be documented in docs/usage/self-hosted-configuration.md.\n */\n globalOnly?: boolean;\n\n inheritConfigSupport?: boolean;\n\n allowedValues?: string[];\n\n allowString?: boolean;\n\n cli?: boolean;\n\n description: string;\n\n env?: false | string;\n\n /**\n * Do not validate object children\n */\n freeChoice?: boolean;\n\n mergeable?: boolean;\n\n autogenerated?: boolean;\n\n name: string;\n\n parents?: AllowedParents[];\n\n stage?: RenovateConfigStage;\n\n experimental?: boolean;\n\n experimentalDescription?: string;\n\n experimentalIssues?: number[];\n\n advancedUse?: boolean;\n\n /**\n * This is used to add a deprecation message in the docs\n */\n deprecationMsg?: string;\n\n /**\n * For internal use only: add it to any config option that supports regex or glob matching\n */\n patternMatch?: boolean;\n\n /**\n * For internal use only: add it to any config option of type integer that supports negative integers\n */\n allowNegative?: boolean;\n\n /**\n * Managers which support this option, leave undefined if all managers support it.\n */\n supportedManagers?: string[];\n\n /**\n * Platforms which support this option, leave undefined if all platforms support it.\n */\n supportedPlatforms?: PlatformId[];\n\n /**\n * Conditions that must be met for this option to be required.\n */\n requiredIf?: RenovateRequiredOption[];\n}\n\nexport interface RenovateRequiredOption {\n siblingProperties: { property: string; value: string }[];\n}\n\nexport interface RenovateArrayOption<\n T extends string | number | Record<string, unknown> = Record<string, unknown>,\n> extends RenovateOptionBase {\n default?: T[] | null;\n mergeable?: boolean;\n type: 'array';\n subType?: 'string' | 'object' | 'number';\n}\n\nexport interface RenovateStringArrayOption extends RenovateArrayOption<string> {\n format?: 'regex';\n subType: 'string';\n}\n\nexport interface RenovateNumberArrayOption extends RenovateArrayOption<number> {\n subType: 'number';\n}\n\nexport interface RenovateBooleanOption extends RenovateOptionBase {\n default?: boolean | null;\n type: 'boolean';\n}\n\nexport interface RenovateIntegerOption extends RenovateOptionBase {\n default?: number | null;\n type: 'integer';\n}\n\nexport interface RenovateStringOption extends RenovateOptionBase {\n default?: string | null;\n format?: 'regex';\n\n // Not used\n replaceLineReturns?: boolean;\n type: 'string';\n}\n\nexport interface RenovateObjectOption extends RenovateOptionBase {\n default?: any;\n additionalProperties?: Record<string, unknown> | boolean;\n mergeable?: boolean;\n type: 'object';\n}\n\nexport type RenovateOptions =\n | RenovateStringOption\n | RenovateNumberArrayOption\n | RenovateStringArrayOption\n | RenovateIntegerOption\n | RenovateBooleanOption\n | RenovateArrayOption\n | RenovateObjectOption;\n\nexport interface PackageRuleInputConfig extends RenovateConfig {\n versioning?: string;\n packageFile?: string;\n lockFiles?: string[];\n depType?: string;\n depTypes?: string[];\n depName?: string;\n packageName?: string | null;\n newValue?: string | null;\n currentValue?: string | null;\n currentVersion?: string;\n lockedVersion?: string;\n updateType?: UpdateType;\n mergeConfidenceLevel?: MergeConfidence | undefined;\n isBump?: boolean;\n sourceUrl?: string | null;\n categories?: string[];\n baseBranch?: string;\n manager?: string;\n datasource?: string;\n packageRules?: (PackageRule & PackageRuleInputConfig)[];\n releaseTimestamp?: Timestamp | null;\n repository?: string;\n currentVersionAgeInDays?: number;\n currentVersionTimestamp?: string;\n enabled?: boolean;\n skipReason?: SkipReason;\n skipStage?: StageName;\n}\n\nexport interface ConfigMigration {\n configMigration?: boolean;\n}\n\nexport interface MigratedConfig {\n /**\n * Indicates whether there was a migration applied to the configuration.\n *\n * @returns\n * `false` if the configuration does not need migrating, and `migratedConfig` can be ignored\n * `true` if the configuration was migrated, and if so, `migratedConfig` should be used instead of the provided config\n */\n isMigrated: boolean;\n migratedConfig: RenovateConfig;\n}\n\nexport interface MigratedRenovateConfig extends RenovateConfig {\n endpoints?: HostRule[];\n pathRules: PackageRule[];\n packages: PackageRule[];\n\n node?: RenovateConfig;\n travis?: RenovateConfig;\n gradle?: RenovateConfig;\n}\n\nexport interface ManagerConfig extends RenovateConfig {\n manager: string;\n categories?: Category[];\n}\n\nexport interface ValidationResult {\n errors: ValidationMessage[];\n warnings: ValidationMessage[];\n}\n\nexport interface BumpVersionConfig {\n bumpType?: string;\n filePatterns: string[];\n matchStrings: string[];\n name?: string;\n}\n\nexport interface ToolSettingsOptions {\n jvmMaxMemory?: number;\n jvmMemory?: number;\n nodeMaxMemory?: number;\n}\n"],"mappings":";AAuUA,MAAa,4BAA4B;CACvC;CACA;CACA;CACA;CACD;AAuMD,MAAa,qBAAqB;CAChC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD"}
|
|
1
|
+
{"version":3,"file":"types.js","names":[],"sources":["../../lib/config/types.ts"],"sourcesContent":["import type { Category, PlatformId } from '../constants/index.ts';\nimport type { LogLevelRemap } from '../logger/types.ts';\nimport type { ManagerName } from '../manager-list.generated.ts';\nimport type { CustomManager } from '../modules/manager/custom/types.ts';\nimport type { RepoSortMethod, SortMethod } from '../modules/platform/types.ts';\nimport type {\n AutoMergeType,\n HostRule,\n Nullish,\n RangeStrategy,\n SkipReason,\n} from '../types/index.ts';\nimport type { StageName } from '../types/skip-reason.ts';\nimport type { ConstraintName, ToolName } from '../util/exec/types.ts';\nimport type { GitNoVerifyOption } from '../util/git/types.ts';\nimport type { MergeConfidence } from '../util/merge-confidence/types.ts';\nimport type { Timestamp } from '../util/timestamp.ts';\n\nexport type RenovateConfigStage =\n | 'global'\n | 'inherit'\n | 'repository'\n | 'package'\n | 'branch'\n | 'pr';\n\nexport type RenovateSplit =\n | 'init'\n | 'onboarding'\n | 'extract'\n | 'lookup'\n | 'update';\n\nexport type RepositoryCacheConfig = 'disabled' | 'enabled' | 'reset';\nexport type RepositoryCacheType = 'local' | (string & {});\nexport type DryRunConfig = 'extract' | 'lookup' | 'full';\nexport type RequiredConfig = 'required' | 'optional' | 'ignored';\n\nexport interface GroupConfig extends Record<string, unknown> {\n branchName?: string;\n branchTopic?: string;\n}\n\nexport type RecreateWhen = 'auto' | 'never' | 'always';\nexport type PlatformCommitOptions = 'auto' | 'disabled' | 'enabled';\n\nexport type BinarySource = 'docker' | 'global' | 'install' | 'hermit';\n\n// TODO: Proper typings\n/**\n * Any configuration that could be used either top-level in a repository config (or Global, Inherited or Shareable Preset configuration), or:\n *\n * - in a datasource-specific configuration\n * - in a manager-specific configuration\n * - in a Package Rule\n *\n * @see RenovateConfig for the superset of all configuration allowed in a given repository\n *\n */\nexport interface RenovateSharedConfig {\n $schema?: string;\n abandonmentThreshold?: Nullish<string>;\n addLabels?: string[];\n assignAutomerge?: boolean;\n autoApprove?: boolean;\n autoReplaceGlobalMatch?: boolean;\n automerge?: boolean;\n automergeSchedule?: string[];\n automergeStrategy?: MergeStrategy;\n automergeType?: AutoMergeType;\n azureWorkItemId?: number;\n branchName?: string;\n branchNameStrict?: boolean;\n branchPrefix?: string;\n branchPrefixOld?: string;\n bumpVersions?: BumpVersionConfig[];\n commitBody?: string;\n commitBodyTable?: boolean;\n commitMessage?: string;\n commitMessageAction?: string;\n commitMessageExtra?: string;\n commitMessageLowerCase?: 'auto' | 'never';\n commitMessagePrefix?: string;\n commitMessageTopic?: string;\n confidential?: boolean;\n configValidationError?: boolean;\n changelogUrl?: string;\n dependencyDashboardApproval?: boolean;\n draftPR?: boolean;\n enabled?: boolean;\n enabledManagers?: string[];\n encrypted?: Record<string, string>;\n extends?: string[];\n extractVersion?: string;\n managerFilePatterns?: string[];\n followTag?: string;\n force?: RenovateConfig;\n gitIgnoredAuthors?: string[];\n group?: GroupConfig;\n groupName?: string;\n groupSlug?: string;\n hashedBranchLength?: number;\n ignoreDeps?: string[];\n ignorePaths?: string[];\n ignoreTests?: boolean;\n ignoreUnstable?: boolean;\n includePaths?: string[];\n internalChecksAsSuccess?: boolean;\n internalChecksFilter?: 'strict' | 'flexible' | 'none';\n keepUpdatedLabel?: string;\n labels?: string[];\n manager?: string;\n milestone?: number;\n minimumReleaseAge?: Nullish<string>;\n npmrc?: string;\n npmrcMerge?: boolean;\n npmToken?: string;\n\n pinDigests?: boolean;\n platformAutomerge?: boolean;\n platformCommit?: PlatformCommitOptions;\n postUpgradeTasks?: PostUpgradeTasks;\n prBodyColumns?: string[];\n prBodyDefinitions?: Record<string, string>;\n prBodyHeadingDefinitions?: Record<string, string>;\n prBodyNotes?: string[];\n prCreation?: 'immediate' | 'not-pending' | 'status-success' | 'approval';\n prFooter?: string;\n prHeader?: string;\n prPriority?: number;\n prTitle?: string;\n prTitleStrict?: boolean;\n productLinks?: Record<string, string>;\n pruneBranchAfterAutomerge?: boolean;\n rangeStrategy?: RangeStrategy;\n rebaseLabel?: string;\n rebaseWhen?: string;\n recreateClosed?: boolean;\n recreateWhen?: RecreateWhen;\n repository?: string;\n repositoryCache?: RepositoryCacheConfig;\n repositoryCacheType?: RepositoryCacheType;\n respectLatest?: boolean;\n rollbackPrs?: boolean;\n schedule?: string[];\n semanticCommitScope?: string | null;\n semanticCommitType?: string;\n semanticCommits?: 'auto' | 'enabled' | 'disabled';\n separateMajorMinor?: boolean;\n separateMinorPatch?: boolean;\n separateMultipleMajor?: boolean;\n separateMultipleMinor?: boolean;\n skipArtifactsUpdate?: boolean;\n stopUpdatingLabel?: string;\n suppressNotifications?: string[];\n timezone?: string;\n unicodeEmoji?: boolean;\n updateNotScheduled?: boolean;\n versioning?: string;\n versionCompatibility?: string;\n}\n\n/**\n * Contains all options with globalOnly=true && inheritConfigSupport=true\n */\nexport interface GlobalInheritableConfig {\n bbUseDevelopmentBranch?: boolean;\n configFileNames?: string[];\n onboarding?: boolean;\n onboardingAutoCloseAge?: number;\n onboardingBranch?: string;\n onboardingCommitMessage?: string;\n onboardingConfig?: RenovateConfig;\n onboardingConfigFileName?: string;\n onboardingNoDeps?: 'auto' | 'enabled' | 'disabled';\n onboardingPrTitle?: string;\n requireConfig?: RequiredConfig;\n}\n\n// Config options used only within the global worker\n// The below should contain config options where stage=global\n/** @deprecated use `RepoGlobalConfig` instead **/\nexport interface GlobalOnlyConfigLegacy {\n autodiscover?: boolean;\n autodiscoverFilter?: string[] | string;\n autodiscoverNamespaces?: string[];\n autodiscoverProjects?: string[];\n autodiscoverTopics?: string[];\n baseDir?: string;\n cacheDir?: string;\n containerbaseDir?: string;\n detectHostRulesFromEnv?: boolean;\n dockerCliOptions?: string;\n endpoint?: string;\n forceCli?: boolean;\n gitNoVerify?: GitNoVerifyOption[];\n gitPrivateKey?: string;\n gitPrivateKeyPassphrase?: string;\n globalExtends?: string[];\n mergeConfidenceDatasources?: string[];\n mergeConfidenceEndpoint?: string;\n platform?: PlatformId;\n processEnv?: Record<string, string>;\n prCommitsPerRunLimit?: number;\n privateKey?: string;\n privateKeyOld?: string;\n privateKeyPath?: string;\n privateKeyPathOld?: string;\n redisPrefix?: string;\n redisUrl?: string;\n repositories?: RenovateRepository[];\n useCloudMetadataServices?: boolean;\n deleteConfigFile?: boolean;\n deleteAdditionalConfigFile?: boolean;\n}\n\n/**\n * Any global-only configuration set by self-hosted administrators.\n *\n * Used within the repository worker.\n *\n * Should only contain config options where globalOnly=true.\n */\nexport interface RepoGlobalConfig extends GlobalInheritableConfig {\n allowedCommands?: string[];\n allowCustomCrateRegistries?: boolean;\n allowPlugins?: boolean;\n allowScripts?: boolean;\n allowShellExecutorForPostUpgradeCommands?: boolean;\n allowedEnv?: string[];\n allowedHeaders?: string[];\n binarySource?: BinarySource;\n cacheDir?: string;\n cacheHardTtlMinutes?: number;\n cacheTtlOverride?: Record<string, number>;\n containerbaseDir?: string;\n customEnvVariables?: Record<string, string>;\n dockerChildPrefix?: string;\n dockerCliOptions?: string;\n dockerSidecarImage?: string;\n dockerUser?: string;\n dryRun?: DryRunConfig;\n encryptedWarning?: string;\n endpoint?: string;\n executionTimeout?: number;\n exposeAllEnv?: boolean;\n gitTimeout?: number;\n githubTokenWarn?: boolean;\n includeMirrors?: boolean;\n localDir?: string;\n migratePresets?: Record<string, string>;\n platform?: PlatformId;\n prCacheSyncMaxPages?: number;\n presetCachePersistence?: boolean;\n httpCacheTtlDays?: number;\n autodiscoverRepoSort?: RepoSortMethod;\n autodiscoverRepoOrder?: SortMethod;\n userAgent?: string;\n dockerMaxPages?: number;\n s3Endpoint?: string;\n s3PathStyle?: boolean;\n cachePrivatePackages?: boolean;\n repositoryCacheForceLocal?: boolean;\n configFileNames?: string[];\n ignorePrAuthor?: boolean;\n allowedUnsafeExecutions?: AllowedUnsafeExecution[];\n onboardingAutoCloseAge?: number;\n toolSettings?: ToolSettingsOptions;\n}\n\n/**\n * Those options are global only but still passed into the repository worker config.\n *\n * @deprecated https://github.com/renovatebot/renovate/issues/39693\n */\nexport interface LegacyAdminConfig {\n baseDir?: string;\n localDir?: string;\n\n logContext?: string;\n\n onboarding?: boolean;\n onboardingBranch?: string;\n onboardingNoDeps?: 'auto' | 'enabled' | 'disabled';\n onboardingRebaseCheckbox?: boolean;\n onboardingConfig?: RenovateConfig;\n onboardingConfigFileName?: string;\n\n optimizeForDisabled?: boolean;\n\n persistRepoData?: boolean;\n\n prCommitsPerRunLimit?: number;\n\n requireConfig?: RequiredConfig;\n\n useCloudMetadataServices?: boolean;\n\n writeDiscoveredRepos?: string;\n}\n\nexport type ExecutionMode = 'branch' | 'update';\n\nexport interface PostUpgradeTasks {\n commands?: string[];\n workingDirTemplate?: string;\n dataFileTemplate?: string;\n fileFilters?: string[];\n executionMode: ExecutionMode;\n installTools?: Partial<Record<ToolName, Record<never, never>>>;\n}\n\nexport type UpdateConfig<\n T extends RenovateSharedConfig = RenovateSharedConfig,\n> = Partial<Record<UpdateType, T | null>>;\n\nexport type RenovateRepository =\n | string\n | (RenovateConfig & {\n repository: string;\n });\n\nexport type UseBaseBranchConfigType = 'merge' | 'none';\nexport type ConstraintsFilter = 'strict' | 'none';\nexport type MinimumReleaseAgeBehaviour =\n | 'timestamp-required'\n | 'timestamp-optional';\n\nexport const allowedStatusCheckStrings = [\n 'minimumReleaseAge',\n 'mergeConfidence',\n 'configValidation',\n 'artifactError',\n] as const;\nexport type StatusCheckKey = (typeof allowedStatusCheckStrings)[number];\ntype UserEnv = Record<string, string>;\n\n/**\n * Computed properties, for internal use only\n */\nexport interface RenovateInternalConfig {\n /** computed base branch from patterns - for internal use only */\n baseBranches?: string[];\n currentCompatibility?: string;\n datasource?: string;\n hasBaseBranches?: boolean;\n isFork?: boolean;\n isVulnerabilityAlert?: boolean;\n\n /** What is this used for? */\n remediations?: unknown;\n /** What is this used for? */\n vulnerabilityAlertsOnly?: boolean;\n}\n\n// TODO: Proper typings\n/**\n * Configuration that could be used either top-level in a repository config (or Global, Inherited or Shareable Preset configuration).\n *\n * This is a superset of any configuration that a Renovate user (not self-hosted administrator) can set.\n */\nexport interface RenovateConfig\n extends\n LegacyAdminConfig,\n RenovateSharedConfig,\n UpdateConfig<PackageRule>,\n AssigneesAndReviewersConfig,\n ConfigMigration,\n RenovateInternalConfig {\n s3Endpoint?: string;\n s3PathStyle?: boolean;\n reportFormatting?: boolean;\n reportPath?: string;\n reportType?: 'logging' | 'file' | 's3' | null;\n depName?: string;\n /** user configurable base branch patterns*/\n baseBranchPatterns?: string[];\n useBaseBranchConfig?: UseBaseBranchConfigType;\n baseBranch?: string;\n defaultBranch?: string;\n branchList?: string[];\n cloneSubmodules?: boolean;\n cloneSubmodulesFilter?: string[];\n description?: string | string[];\n detectGlobalManagerConfig?: boolean;\n errors?: ValidationMessage[];\n forkModeDisallowMaintainerEdits?: boolean;\n forkProcessing?: 'auto' | 'enabled' | 'disabled';\n forkToken?: string;\n\n gitAuthor?: string;\n\n hostRules?: HostRule[];\n\n inheritConfig?: boolean;\n inheritConfigFileName?: string;\n inheritConfigRepoName?: string;\n inheritConfigStrict?: boolean;\n\n ignorePresets?: string[];\n\n fileList?: string[];\n configWarningReuseIssue?: boolean;\n dependencyDashboard?: boolean;\n dependencyDashboardAutoclose?: boolean;\n dependencyDashboardChecks?: Record<string, string>;\n dependencyDashboardIssue?: number;\n dependencyDashboardTitle?: string;\n dependencyDashboardHeader?: string;\n dependencyDashboardFooter?: string;\n dependencyDashboardLabels?: string[];\n dependencyDashboardOSVVulnerabilitySummary?: 'none' | 'all' | 'unresolved';\n dependencyDashboardReportAbandonment?: boolean;\n mode?: 'silent' | 'full';\n packageFile?: string;\n packageRules?: PackageRule[];\n postUpdateOptions?: string[];\n branchConcurrentLimit?: number | null;\n parentOrg?: string;\n prConcurrentLimit?: number;\n commitHourlyLimit?: number;\n prHourlyLimit?: number;\n\n printConfig?: boolean;\n\n pruneStaleBranches?: boolean;\n\n defaultRegistryUrls?: string[];\n registryUrls?: string[] | null;\n registryAliases?: Record<string, string>;\n\n /**\n * What is this used for?\n * @deprecated\n */\n renovateJsonPresent?: boolean;\n\n repoIsOnboarded?: boolean;\n repoIsActivated?: boolean;\n\n topLevelOrg?: string;\n updateInternalDeps?: boolean;\n updateType?: UpdateType;\n\n warnings?: ValidationMessage[];\n vulnerabilityAlerts?: RenovateSharedConfig;\n osvVulnerabilityAlerts?: boolean;\n vulnerabilitySeverity?: string;\n customManagers?: CustomManager[];\n customDatasources?: Record<string, CustomDatasourceConfig>;\n\n fetchChangeLogs?: FetchChangeLogsOptions;\n secrets?: Record<string, string>;\n variables?: Record<string, string>;\n\n constraints?: Partial<Record<ConstraintName, string>>;\n skipInstalls?: boolean | null;\n\n constraintsFiltering?: ConstraintsFilter;\n\n checkedBranches?: string[];\n customizeDashboard?: Record<string, string>;\n\n statusCheckNames?: Record<StatusCheckKey, string | null>;\n /**\n * User configured environment variables that Renovate uses when executing package manager commands\n */\n env?: UserEnv;\n logLevelRemap?: LogLevelRemap[];\n\n branchTopic?: string;\n additionalBranchPrefix?: string;\n sharedVariableName?: string;\n minimumGroupSize?: number;\n configFileNames?: string[];\n minimumReleaseAgeBehaviour?: MinimumReleaseAgeBehaviour;\n toolSettings?: ToolSettingsOptions;\n}\n\nconst CustomDatasourceFormats = [\n 'html',\n 'json',\n 'plain',\n 'toml',\n 'yaml',\n] as const;\nexport type CustomDatasourceFormats = (typeof CustomDatasourceFormats)[number];\n\nexport interface CustomDatasourceConfig {\n defaultRegistryUrlTemplate?: string;\n format?: CustomDatasourceFormats;\n transformTemplates?: string[];\n}\n\n/**\n * The superset of all configuration that a self-hosted administrator can set, alongside all repository-level configuration.\n *\n */\nexport interface AllConfig\n extends RenovateConfig, GlobalOnlyConfigLegacy, RepoGlobalConfig {\n password?: string;\n token?: string;\n username?: string;\n}\n\nexport interface AssigneesAndReviewersConfig {\n assigneesFromCodeOwners?: boolean;\n expandCodeOwnersGroups?: boolean;\n assignees?: string[];\n assigneesSampleSize?: number;\n ignoreReviewers?: string[];\n reviewersFromCodeOwners?: boolean;\n reviewers?: string[];\n reviewersSampleSize?: number;\n additionalReviewers?: string[];\n filterUnavailableUsers?: boolean;\n}\n\nexport type UpdateType =\n | 'major'\n | 'minor'\n | 'patch'\n | 'pin'\n | 'digest'\n | 'pinDigest'\n | 'lockFileMaintenance'\n | 'lockfileUpdate'\n | 'rollback'\n | 'bump'\n | 'replacement';\n\n// These are the update types which can have configuration\nexport const UpdateTypesOptions = [\n 'major',\n 'minor',\n 'patch',\n 'pin',\n 'digest',\n 'pinDigest',\n 'lockFileMaintenance',\n 'rollback',\n 'replacement',\n] as const;\n\nexport type UpdateTypeOptions = (typeof UpdateTypesOptions)[number];\n\nexport type FetchChangeLogsOptions = 'off' | 'branch' | 'pr';\n\nexport type MatchStringsStrategy = 'any' | 'recursive' | 'combination';\n\nexport type MergeStrategy =\n | 'auto'\n | 'fast-forward'\n | 'merge-commit'\n | 'rebase'\n | 'rebase-merge'\n | 'squash';\n\n// This list should be added to as any new unsafe execution commands should be permitted\nexport type AllowedUnsafeExecution =\n | 'bazelModDeps'\n | 'goGenerate'\n | 'gradleWrapper';\n\n// TODO: Proper typings\nexport interface PackageRule\n extends RenovateSharedConfig, RenovateInternalConfig, UpdateConfig {\n allowedVersions?: string;\n description?: string | string[];\n matchBaseBranches?: string[];\n matchCategories?: string[];\n matchConfidence?: MergeConfidence[];\n matchCurrentAge?: string;\n matchCurrentValue?: string;\n matchCurrentVersion?: string;\n matchDatasources?: string[];\n matchDepNames?: string[];\n matchDepTypes?: string[];\n matchFileNames?: string[];\n matchManagers?: string[];\n matchNewValue?: string;\n matchPackageNames?: string[];\n matchRepositories?: string[];\n matchSourceUrls?: string[];\n matchRegistryUrls?: string[];\n matchUpdateTypes?: UpdateType[];\n matchJsonata?: string[];\n overrideDatasource?: string;\n overrideDepName?: string;\n overridePackageName?: string;\n registryUrls?: string[] | null;\n replacementName?: string;\n replacementVersion?: string;\n sourceUrl?: string;\n sourceDirectory?: string;\n vulnerabilitySeverity?: string;\n vulnerabilityFixVersion?: string;\n}\n\nexport interface ValidationMessage {\n topic: string;\n message: string;\n}\n\nexport type AllowedParents =\n | '.'\n | 'bumpVersions'\n | 'customDatasources'\n | 'customManagers'\n | 'hostRules'\n | 'logLevelRemap'\n | 'packageRules'\n | 'postUpgradeTasks'\n | 'vulnerabilityAlerts'\n | 'toolSettings'\n | ManagerName\n | UpdateTypeOptions;\nexport interface RenovateOptionBase {\n /**\n * If true, the option can only be configured by people with access to the Renovate instance.\n * Furthermore, the option should be documented in docs/usage/self-hosted-configuration.md.\n */\n globalOnly?: boolean;\n\n inheritConfigSupport?: boolean;\n\n allowedValues?: string[];\n\n allowString?: boolean;\n\n cli?: boolean;\n\n description: string;\n\n env?: false | string;\n\n /**\n * Do not validate object children\n */\n freeChoice?: boolean;\n\n mergeable?: boolean;\n\n autogenerated?: boolean;\n\n name: string;\n\n parents?: AllowedParents[];\n\n stage?: RenovateConfigStage;\n\n experimental?: boolean;\n\n experimentalDescription?: string;\n\n experimentalIssues?: number[];\n\n advancedUse?: boolean;\n\n /**\n * This is used to add a deprecation message in the docs\n */\n deprecationMsg?: string;\n\n /**\n * For internal use only: add it to any config option that supports regex or glob matching\n */\n patternMatch?: boolean;\n\n /**\n * For internal use only: add it to any config option of type integer that supports negative integers\n */\n allowNegative?: boolean;\n\n /**\n * Managers which support this option, leave undefined if all managers support it.\n */\n supportedManagers?: string[];\n\n /**\n * Platforms which support this option, leave undefined if all platforms support it.\n */\n supportedPlatforms?: PlatformId[];\n\n /**\n * Conditions that must be met for this option to be required.\n */\n requiredIf?: RenovateRequiredOption[];\n}\n\nexport interface RenovateRequiredOption {\n siblingProperties: { property: string; value: string }[];\n}\n\nexport interface RenovateArrayOption<\n T extends string | number | Record<string, unknown> = Record<string, unknown>,\n> extends RenovateOptionBase {\n default?: T[] | null;\n mergeable?: boolean;\n type: 'array';\n subType?: 'string' | 'object' | 'number';\n}\n\nexport interface RenovateStringArrayOption extends RenovateArrayOption<string> {\n format?: 'regex';\n subType: 'string';\n}\n\nexport interface RenovateNumberArrayOption extends RenovateArrayOption<number> {\n subType: 'number';\n}\n\nexport interface RenovateBooleanOption extends RenovateOptionBase {\n default?: boolean | null;\n type: 'boolean';\n}\n\nexport interface RenovateIntegerOption extends RenovateOptionBase {\n default?: number | null;\n type: 'integer';\n}\n\nexport interface RenovateStringOption extends RenovateOptionBase {\n default?: string | null;\n format?: 'regex';\n\n // Not used\n replaceLineReturns?: boolean;\n type: 'string';\n}\n\nexport interface RenovateObjectOption extends RenovateOptionBase {\n default?: any;\n additionalProperties?: Record<string, unknown> | boolean;\n mergeable?: boolean;\n type: 'object';\n}\n\nexport type RenovateOptions =\n | RenovateStringOption\n | RenovateNumberArrayOption\n | RenovateStringArrayOption\n | RenovateIntegerOption\n | RenovateBooleanOption\n | RenovateArrayOption\n | RenovateObjectOption;\n\nexport interface PackageRuleInputConfig extends RenovateConfig {\n versioning?: string;\n packageFile?: string;\n lockFiles?: string[];\n depType?: string;\n depTypes?: string[];\n depName?: string;\n packageName?: string | null;\n newValue?: string | null;\n currentValue?: string | null;\n currentVersion?: string;\n lockedVersion?: string;\n updateType?: UpdateType;\n mergeConfidenceLevel?: MergeConfidence | undefined;\n isBump?: boolean;\n sourceUrl?: string | null;\n categories?: string[];\n baseBranch?: string;\n manager?: string;\n datasource?: string;\n packageRules?: (PackageRule & PackageRuleInputConfig)[];\n releaseTimestamp?: Timestamp | null;\n repository?: string;\n currentVersionAgeInDays?: number;\n currentVersionTimestamp?: string;\n enabled?: boolean;\n skipReason?: SkipReason;\n skipStage?: StageName;\n}\n\nexport interface ConfigMigration {\n configMigration?: boolean;\n}\n\nexport interface MigratedConfig {\n /**\n * Indicates whether there was a migration applied to the configuration.\n *\n * @returns\n * `false` if the configuration does not need migrating, and `migratedConfig` can be ignored\n * `true` if the configuration was migrated, and if so, `migratedConfig` should be used instead of the provided config\n */\n isMigrated: boolean;\n migratedConfig: RenovateConfig;\n}\n\nexport interface MigratedRenovateConfig extends RenovateConfig {\n endpoints?: HostRule[];\n pathRules: PackageRule[];\n packages: PackageRule[];\n\n node?: RenovateConfig;\n travis?: RenovateConfig;\n gradle?: RenovateConfig;\n}\n\nexport interface ManagerConfig extends RenovateConfig {\n manager: string;\n categories?: Category[];\n}\n\nexport interface ValidationResult {\n errors: ValidationMessage[];\n warnings: ValidationMessage[];\n}\n\nexport interface BumpVersionConfig {\n bumpType?: string;\n filePatterns: string[];\n matchStrings: string[];\n name?: string;\n}\n\nexport interface ToolSettingsOptions {\n jvmMaxMemory?: number;\n jvmMemory?: number;\n nodeMaxMemory?: number;\n}\n"],"mappings":";AAwUA,MAAa,4BAA4B;CACvC;CACA;CACA;CACA;CACD;AAuMD,MAAa,qBAAqB;CAChC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD"}
|
|
@@ -14,7 +14,7 @@ declare const GithubVulnerabilityAlerts: z.ZodEffects<z.ZodEffects<z.ZodArray<z.
|
|
|
14
14
|
};
|
|
15
15
|
security_vulnerability: {
|
|
16
16
|
package: {
|
|
17
|
-
ecosystem: "composer" | "maven" | "npm" | "rust" | "go" | "
|
|
17
|
+
ecosystem: "composer" | "maven" | "npm" | "rust" | "go" | "nuget" | "actions" | "pip" | "rubygems";
|
|
18
18
|
name: string;
|
|
19
19
|
};
|
|
20
20
|
vulnerable_version_range: string;
|
|
@@ -39,7 +39,7 @@ declare const GithubVulnerabilityAlerts: z.ZodEffects<z.ZodEffects<z.ZodArray<z.
|
|
|
39
39
|
};
|
|
40
40
|
security_vulnerability: {
|
|
41
41
|
package: {
|
|
42
|
-
ecosystem: "composer" | "maven" | "npm" | "rust" | "go" | "
|
|
42
|
+
ecosystem: "composer" | "maven" | "npm" | "rust" | "go" | "nuget" | "actions" | "pip" | "rubygems";
|
|
43
43
|
name: string;
|
|
44
44
|
};
|
|
45
45
|
vulnerable_version_range: string;
|
|
@@ -4,7 +4,7 @@ import { regEx } from "../../../util/regex.js";
|
|
|
4
4
|
import { getConfigFileNames } from "../../../config/app-strings.js";
|
|
5
5
|
import { logger } from "../../../logger/index.js";
|
|
6
6
|
import { add } from "../../../util/host-rules.js";
|
|
7
|
-
import { parseJson } from "../../../util/common.js";
|
|
7
|
+
import { getInheritedOrGlobal, parseJson } from "../../../util/common.js";
|
|
8
8
|
import { ExternalHostError } from "../../../types/errors/external-host-error.js";
|
|
9
9
|
import { readLocalFile, readSystemFile } from "../../../util/fs/index.js";
|
|
10
10
|
import { clear } from "../../../util/http/queue.js";
|
|
@@ -133,7 +133,7 @@ function checkForRepoConfigError(repoConfig) {
|
|
|
133
133
|
async function mergeRenovateConfig(config, branchName) {
|
|
134
134
|
let returnConfig = { ...config };
|
|
135
135
|
let repoConfig = {};
|
|
136
|
-
if (
|
|
136
|
+
if (getInheritedOrGlobal("requireConfig") !== "ignored") repoConfig = await detectRepoFileConfig(branchName);
|
|
137
137
|
if (!repoConfig.configFileParsed && config.mode === "silent") {
|
|
138
138
|
logger.debug("When mode=silent and repo has no config file, we use the onboarding config as repo config");
|
|
139
139
|
repoConfig = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"merge.js","names":["presets.resolveConfigPresets","configValidation.validateConfig"],"sources":["../../../../lib/workers/repository/init/merge.ts"],"sourcesContent":["import {\n isNonEmptyArray,\n isNonEmptyObject,\n isNonEmptyString,\n isString,\n} from '@sindresorhus/is';\nimport { getConfigFileNames } from '../../../config/app-strings.ts';\nimport { decryptConfig } from '../../../config/decrypt.ts';\nimport { mergeChildConfig } from '../../../config/index.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 { AllConfig, RenovateConfig } from '../../../config/types.ts';\nimport * as configValidation from '../../../config/validation.ts';\nimport {\n CONFIG_VALIDATION,\n REPOSITORY_CHANGED,\n} from '../../../constants/error-messages.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 { getCache } from '../../../util/cache/repository/index.ts';\nimport { 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 { regEx } from '../../../util/regex.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 type { RepoFileConfig } 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 } else {\n logger.debug('Existing config file no longer exists');\n delete cache.configFileName;\n }\n }\n\n if (OnboardingState.onboardingCacheValid) {\n configFileName = getOnboardingFileNameFromCache();\n } else {\n configFileName = (await detectConfigFile()) ?? undefined;\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// Check for repository config\nexport async function mergeRenovateConfig(\n config: RenovateConfig,\n branchName?: string,\n): Promise<RenovateConfig> {\n let returnConfig = { ...config };\n let repoConfig: RepoFileConfig = {};\n if (config.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 = repoConfig?.configFileParsed ?? {};\n const resolvedRepoConfig = await resolveStaticRepoConfig(\n configFileParsed,\n process.env.RENOVATE_X_STATIC_REPO_CONFIG_FILE,\n );\n\n if (isNonEmptyArray(returnConfig.extends)) {\n resolvedRepoConfig.extends = [\n ...returnConfig.extends,\n ...(resolvedRepoConfig.extends ?? []),\n ];\n delete returnConfig.extends;\n }\n checkForRepoConfigError(repoConfig);\n const migratedConfig = await migrateAndValidate(config, resolvedRepoConfig);\n if (migratedConfig.errors?.length) {\n const error = new Error(CONFIG_VALIDATION);\n error.validationSource = repoConfig.configFileName;\n error.validationError =\n 'The renovate configuration file contains some invalid settings';\n error.validationMessage = migratedConfig.errors\n .map((e) => e.message)\n .join(', ');\n throw error;\n }\n if (migratedConfig.warnings) {\n returnConfig.warnings = [\n ...(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 // 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 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 config.secrets ?? {},\n resolvedConfig.secrets ?? {},\n ),\n variables: mergeChildConfig(\n config.variables ?? {},\n 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(returnConfig.env);\n delete returnConfig.env;\n\n return returnConfig;\n}\n\nexport function applyNpmrc(\n config: RenovateConfig,\n configType?: 'resolved' | '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(config: RenovateConfig): void {\n if (!config.hostRules) {\n return;\n }\n\n logger.debug('Setting hostRules from config');\n for (const rule of config.hostRules) {\n try {\n hostRules.add(rule);\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 = [...staticRepoConfig.extends, ...(config.extends ?? [])];\n delete staticRepoConfig.extends;\n }\n\n // renovate repo config overrides RENOVATE_STATIC_REPO_CONFIG[_FILE]\n return mergeChildConfig(staticRepoConfig, config);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"merge.js","names":["presets.resolveConfigPresets","configValidation.validateConfig"],"sources":["../../../../lib/workers/repository/init/merge.ts"],"sourcesContent":["import {\n isNonEmptyArray,\n isNonEmptyObject,\n isNonEmptyString,\n isString,\n} from '@sindresorhus/is';\nimport { getConfigFileNames } from '../../../config/app-strings.ts';\nimport { decryptConfig } from '../../../config/decrypt.ts';\nimport { mergeChildConfig } from '../../../config/index.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 { AllConfig, RenovateConfig } from '../../../config/types.ts';\nimport * as configValidation from '../../../config/validation.ts';\nimport {\n CONFIG_VALIDATION,\n REPOSITORY_CHANGED,\n} from '../../../constants/error-messages.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 { getCache } from '../../../util/cache/repository/index.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 { regEx } from '../../../util/regex.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 type { RepoFileConfig } 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 } else {\n logger.debug('Existing config file no longer exists');\n delete cache.configFileName;\n }\n }\n\n if (OnboardingState.onboardingCacheValid) {\n configFileName = getOnboardingFileNameFromCache();\n } else {\n configFileName = (await detectConfigFile()) ?? undefined;\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// Check for repository config\nexport async function mergeRenovateConfig(\n config: RenovateConfig,\n branchName?: string,\n): Promise<RenovateConfig> {\n let returnConfig = { ...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 = repoConfig?.configFileParsed ?? {};\n const resolvedRepoConfig = await resolveStaticRepoConfig(\n configFileParsed,\n process.env.RENOVATE_X_STATIC_REPO_CONFIG_FILE,\n );\n\n if (isNonEmptyArray(returnConfig.extends)) {\n resolvedRepoConfig.extends = [\n ...returnConfig.extends,\n ...(resolvedRepoConfig.extends ?? []),\n ];\n delete returnConfig.extends;\n }\n checkForRepoConfigError(repoConfig);\n const migratedConfig = await migrateAndValidate(config, resolvedRepoConfig);\n if (migratedConfig.errors?.length) {\n const error = new Error(CONFIG_VALIDATION);\n error.validationSource = repoConfig.configFileName;\n error.validationError =\n 'The renovate configuration file contains some invalid settings';\n error.validationMessage = migratedConfig.errors\n .map((e) => e.message)\n .join(', ');\n throw error;\n }\n if (migratedConfig.warnings) {\n returnConfig.warnings = [\n ...(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 // 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 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 config.secrets ?? {},\n resolvedConfig.secrets ?? {},\n ),\n variables: mergeChildConfig(\n config.variables ?? {},\n 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(returnConfig.env);\n delete returnConfig.env;\n\n return returnConfig;\n}\n\nexport function applyNpmrc(\n config: RenovateConfig,\n configType?: 'resolved' | '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(config: RenovateConfig): void {\n if (!config.hostRules) {\n return;\n }\n\n logger.debug('Setting hostRules from config');\n for (const rule of config.hostRules) {\n try {\n hostRules.add(rule);\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 = [...staticRepoConfig.extends, ...(config.extends ?? [])];\n delete staticRepoConfig.extends;\n }\n\n // renovate repo config overrides RENOVATE_STATIC_REPO_CONFIG[_FILE]\n return mergeChildConfig(staticRepoConfig, config);\n}\n"],"mappings":"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"}
|
|
@@ -49,8 +49,8 @@ async function isOnboarded(config) {
|
|
|
49
49
|
logger.debug("Silent mode enabled so repo is considered onboarded");
|
|
50
50
|
return true;
|
|
51
51
|
}
|
|
52
|
-
if (
|
|
53
|
-
if (
|
|
52
|
+
if (getInheritedOrGlobal("requireConfig") === "optional" && getInheritedOrGlobal("onboarding") === false) return true;
|
|
53
|
+
if (getInheritedOrGlobal("requireConfig") === "ignored") {
|
|
54
54
|
logger.debug("Config file will be ignored");
|
|
55
55
|
return true;
|
|
56
56
|
}
|
|
@@ -89,13 +89,13 @@ async function isOnboarded(config) {
|
|
|
89
89
|
await platform.ensureIssueClosing(title);
|
|
90
90
|
return true;
|
|
91
91
|
}
|
|
92
|
-
if (
|
|
92
|
+
if (getInheritedOrGlobal("requireConfig") === "required" && getInheritedOrGlobal("onboarding") === false) throw new Error(REPOSITORY_NO_CONFIG);
|
|
93
93
|
if (!closedOnboardingPr) {
|
|
94
94
|
logger.debug("Found no closed onboarding PR");
|
|
95
95
|
return false;
|
|
96
96
|
}
|
|
97
97
|
logger.debug("Found closed onboarding PR");
|
|
98
|
-
if (
|
|
98
|
+
if (getInheritedOrGlobal("requireConfig") === "optional") {
|
|
99
99
|
logger.debug("Config not mandatory so repo is considered onboarded");
|
|
100
100
|
return true;
|
|
101
101
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check.js","names":[],"sources":["../../../../../lib/workers/repository/onboarding/branch/check.ts"],"sourcesContent":["import { isNonEmptyObject } from '@sindresorhus/is';\nimport { getConfigFileNames } from '../../../../config/app-strings.ts';\nimport type { RenovateConfig } from '../../../../config/types.ts';\nimport {\n REPOSITORY_CLOSED_ONBOARDING,\n REPOSITORY_NO_CONFIG,\n} from '../../../../constants/error-messages.ts';\nimport { logger } from '../../../../logger/index.ts';\nimport { ensureComment } from '../../../../modules/platform/comment.ts';\nimport type { Pr } from '../../../../modules/platform/index.ts';\nimport { platform } from '../../../../modules/platform/index.ts';\nimport { scm } from '../../../../modules/platform/scm.ts';\nimport { getCache } from '../../../../util/cache/repository/index.ts';\nimport { getInheritedOrGlobal } from '../../../../util/common.ts';\nimport { getElapsedDays } from '../../../../util/date.ts';\nimport { readLocalFile } from '../../../../util/fs/index.ts';\nimport { getBranchCommit } from '../../../../util/git/index.ts';\nimport { getSemanticCommitPrTitle } from '../common.ts';\n\nasync function findFile(fileName: string): Promise<boolean> {\n logger.debug(`findFile(${fileName})`);\n const fileList = await scm.getFileList();\n return fileList.includes(fileName);\n}\n\nasync function configFileExists(): Promise<boolean> {\n for (const fileName of getConfigFileNames()) {\n if (fileName !== 'package.json' && (await findFile(fileName))) {\n logger.debug(`Config file exists, fileName: ${fileName}`);\n return true;\n }\n }\n return false;\n}\n\nasync function packageJsonConfigExists(): Promise<boolean> {\n try {\n // TODO #22198\n const pJson = JSON.parse((await readLocalFile('package.json', 'utf8'))!);\n if (pJson.renovate) {\n return true;\n }\n } catch {\n // Do nothing\n }\n return false;\n}\n\nasync function closedPrExists(config: RenovateConfig): Promise<Pr | null> {\n return (\n (await platform.findPr({\n branchName: getInheritedOrGlobal('onboardingBranch')!,\n prTitle: getInheritedOrGlobal('onboardingPrTitle'),\n state: '!open',\n targetBranch: config.baseBranch,\n })) ??\n (await platform.findPr({\n branchName: getInheritedOrGlobal('onboardingBranch')!,\n prTitle: getSemanticCommitPrTitle(config),\n state: '!open',\n targetBranch: config.baseBranch,\n }))\n );\n}\n\nexport async function isOnboarded(config: RenovateConfig): Promise<boolean> {\n logger.debug('isOnboarded()');\n const title = `Action required: Add a Renovate config`;\n\n // Repo is onboarded if in silent mode\n if (config.mode === 'silent') {\n logger.debug('Silent mode enabled so repo is considered onboarded');\n return true;\n }\n\n // Repo is onboarded if global config is bypassing onboarding and does not require a\n // configuration file.\n // The repo is considered \"not onboarded\" if:\n // - An onboarding cache is present, and\n // - The current default branch SHA matches the default SHA found in the cache\n // Also if there is a closed pr skip using cache as it is outdated\n if (\n config.requireConfig === 'optional' &&\n getInheritedOrGlobal('onboarding') === false\n ) {\n // Return early and avoid checking for config files\n return true;\n }\n if (config.requireConfig === 'ignored') {\n logger.debug('Config file will be ignored');\n return true;\n }\n\n const closedOnboardingPr = await closedPrExists(config);\n const cache = getCache();\n const onboardingBranchCache = cache?.onboardingBranchCache;\n // if onboarding cache is present and base branch has not been updated; branch is not onboarded\n // if closed pr exists then presence of onboarding cache doesn't matter as we need to skip onboarding\n if (\n getInheritedOrGlobal('onboarding') &&\n !closedOnboardingPr &&\n isNonEmptyObject(onboardingBranchCache) &&\n onboardingBranchCache.defaultBranchSha ===\n getBranchCommit(config.defaultBranch!)\n ) {\n logger.debug('Onboarding cache is valid. Repo is not onboarded');\n return false;\n }\n\n // when bot is ran is fork mode ... do not fetch file using api call instead use the git.fileList so we get sync first and get the latest config\n // prevents https://github.com/renovatebot/renovate/discussions/37328\n if (cache.configFileName && !config.forkToken) {\n logger.debug('Checking cached config file name');\n try {\n const configFileContent = await platform.getJsonFile(\n cache.configFileName,\n );\n if (configFileContent) {\n if (\n cache.configFileName !== 'package.json' ||\n configFileContent.renovate\n ) {\n logger.debug('Existing config file confirmed');\n logger.debug(\n { fileName: cache.configFileName, config: configFileContent },\n 'Repository config',\n );\n return true;\n }\n }\n } catch {\n // probably file doesn't exist\n }\n logger.debug('Existing config file no longer exists');\n delete cache.configFileName;\n }\n if (await configFileExists()) {\n await platform.ensureIssueClosing(title);\n return true;\n }\n logger.debug('config file not found');\n if (await packageJsonConfigExists()) {\n logger.debug('package.json contains config');\n await platform.ensureIssueClosing(title);\n return true;\n }\n\n // If onboarding has been disabled and config files are required then the\n // repository has not been onboarded yet\n if (\n config.requireConfig === 'required' &&\n getInheritedOrGlobal('onboarding') === false\n ) {\n throw new Error(REPOSITORY_NO_CONFIG);\n }\n\n if (!closedOnboardingPr) {\n logger.debug('Found no closed onboarding PR');\n return false;\n }\n logger.debug('Found closed onboarding PR');\n if (config.requireConfig === 'optional') {\n logger.debug('Config not mandatory so repo is considered onboarded');\n return true;\n }\n logger.debug('Repo is not onboarded and no merged PRs exist');\n if (!config.suppressNotifications!.includes('onboardingClose')) {\n const ageOfOnboardingPr = getElapsedDays(\n closedOnboardingPr.createdAt!,\n false,\n );\n const onboardingAutoCloseAge = getInheritedOrGlobal(\n 'onboardingAutoCloseAge',\n );\n if (onboardingAutoCloseAge) {\n logger.debug(\n {\n onboardingAutoCloseAge,\n createdAt: closedOnboardingPr.createdAt!,\n ageOfOnboardingPr,\n },\n `Determining that the closed onboarding PR was created at \\`${closedOnboardingPr.createdAt!}\\` was created ${ageOfOnboardingPr.toFixed(2)} days ago`,\n );\n }\n // if we have onboardingAutoCloseAge, and it hasn't yet passed onboardingAutoCloseAge, add a comment\n // if it /has/ passed, we'll comment this appropriately in `ensureOnboardingPr`, so there doesn't need to be a comment here\n if (\n !onboardingAutoCloseAge ||\n ageOfOnboardingPr <= onboardingAutoCloseAge\n ) {\n // ensure PR comment\n await ensureComment({\n number: closedOnboardingPr.number,\n topic: `Renovate is disabled`,\n content: `Renovate is disabled because there is no Renovate configuration file. To enable Renovate, you can either (a) change this PR's title to get a new onboarding PR, and merge the new onboarding PR, or (b) create a Renovate config file, and commit that file to your base branch.`,\n });\n }\n }\n throw new Error(REPOSITORY_CLOSED_ONBOARDING);\n}\n\nexport async function getOnboardingPr(\n config: RenovateConfig,\n): Promise<Pr | null> {\n return await platform.getBranchPr(\n getInheritedOrGlobal('onboardingBranch')!,\n config.baseBranch,\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"check.js","names":[],"sources":["../../../../../lib/workers/repository/onboarding/branch/check.ts"],"sourcesContent":["import { isNonEmptyObject } from '@sindresorhus/is';\nimport { getConfigFileNames } from '../../../../config/app-strings.ts';\nimport type { RenovateConfig } from '../../../../config/types.ts';\nimport {\n REPOSITORY_CLOSED_ONBOARDING,\n REPOSITORY_NO_CONFIG,\n} from '../../../../constants/error-messages.ts';\nimport { logger } from '../../../../logger/index.ts';\nimport { ensureComment } from '../../../../modules/platform/comment.ts';\nimport type { Pr } from '../../../../modules/platform/index.ts';\nimport { platform } from '../../../../modules/platform/index.ts';\nimport { scm } from '../../../../modules/platform/scm.ts';\nimport { getCache } from '../../../../util/cache/repository/index.ts';\nimport { getInheritedOrGlobal } from '../../../../util/common.ts';\nimport { getElapsedDays } from '../../../../util/date.ts';\nimport { readLocalFile } from '../../../../util/fs/index.ts';\nimport { getBranchCommit } from '../../../../util/git/index.ts';\nimport { getSemanticCommitPrTitle } from '../common.ts';\n\nasync function findFile(fileName: string): Promise<boolean> {\n logger.debug(`findFile(${fileName})`);\n const fileList = await scm.getFileList();\n return fileList.includes(fileName);\n}\n\nasync function configFileExists(): Promise<boolean> {\n for (const fileName of getConfigFileNames()) {\n if (fileName !== 'package.json' && (await findFile(fileName))) {\n logger.debug(`Config file exists, fileName: ${fileName}`);\n return true;\n }\n }\n return false;\n}\n\nasync function packageJsonConfigExists(): Promise<boolean> {\n try {\n // TODO #22198\n const pJson = JSON.parse((await readLocalFile('package.json', 'utf8'))!);\n if (pJson.renovate) {\n return true;\n }\n } catch {\n // Do nothing\n }\n return false;\n}\n\nasync function closedPrExists(config: RenovateConfig): Promise<Pr | null> {\n return (\n (await platform.findPr({\n branchName: getInheritedOrGlobal('onboardingBranch')!,\n prTitle: getInheritedOrGlobal('onboardingPrTitle'),\n state: '!open',\n targetBranch: config.baseBranch,\n })) ??\n (await platform.findPr({\n branchName: getInheritedOrGlobal('onboardingBranch')!,\n prTitle: getSemanticCommitPrTitle(config),\n state: '!open',\n targetBranch: config.baseBranch,\n }))\n );\n}\n\nexport async function isOnboarded(config: RenovateConfig): Promise<boolean> {\n logger.debug('isOnboarded()');\n const title = `Action required: Add a Renovate config`;\n\n // Repo is onboarded if in silent mode\n if (config.mode === 'silent') {\n logger.debug('Silent mode enabled so repo is considered onboarded');\n return true;\n }\n\n // Repo is onboarded if global config is bypassing onboarding and does not require a\n // configuration file.\n // The repo is considered \"not onboarded\" if:\n // - An onboarding cache is present, and\n // - The current default branch SHA matches the default SHA found in the cache\n // Also if there is a closed pr skip using cache as it is outdated\n if (\n getInheritedOrGlobal('requireConfig') === 'optional' &&\n getInheritedOrGlobal('onboarding') === false\n ) {\n // Return early and avoid checking for config files\n return true;\n }\n if (getInheritedOrGlobal('requireConfig') === 'ignored') {\n logger.debug('Config file will be ignored');\n return true;\n }\n\n const closedOnboardingPr = await closedPrExists(config);\n const cache = getCache();\n const onboardingBranchCache = cache?.onboardingBranchCache;\n // if onboarding cache is present and base branch has not been updated; branch is not onboarded\n // if closed pr exists then presence of onboarding cache doesn't matter as we need to skip onboarding\n if (\n getInheritedOrGlobal('onboarding') &&\n !closedOnboardingPr &&\n isNonEmptyObject(onboardingBranchCache) &&\n onboardingBranchCache.defaultBranchSha ===\n getBranchCommit(config.defaultBranch!)\n ) {\n logger.debug('Onboarding cache is valid. Repo is not onboarded');\n return false;\n }\n\n // when bot is ran is fork mode ... do not fetch file using api call instead use the git.fileList so we get sync first and get the latest config\n // prevents https://github.com/renovatebot/renovate/discussions/37328\n if (cache.configFileName && !config.forkToken) {\n logger.debug('Checking cached config file name');\n try {\n const configFileContent = await platform.getJsonFile(\n cache.configFileName,\n );\n if (configFileContent) {\n if (\n cache.configFileName !== 'package.json' ||\n configFileContent.renovate\n ) {\n logger.debug('Existing config file confirmed');\n logger.debug(\n { fileName: cache.configFileName, config: configFileContent },\n 'Repository config',\n );\n return true;\n }\n }\n } catch {\n // probably file doesn't exist\n }\n logger.debug('Existing config file no longer exists');\n delete cache.configFileName;\n }\n if (await configFileExists()) {\n await platform.ensureIssueClosing(title);\n return true;\n }\n logger.debug('config file not found');\n if (await packageJsonConfigExists()) {\n logger.debug('package.json contains config');\n await platform.ensureIssueClosing(title);\n return true;\n }\n\n // If onboarding has been disabled and config files are required then the\n // repository has not been onboarded yet\n if (\n getInheritedOrGlobal('requireConfig') === 'required' &&\n getInheritedOrGlobal('onboarding') === false\n ) {\n throw new Error(REPOSITORY_NO_CONFIG);\n }\n\n if (!closedOnboardingPr) {\n logger.debug('Found no closed onboarding PR');\n return false;\n }\n logger.debug('Found closed onboarding PR');\n if (getInheritedOrGlobal('requireConfig') === 'optional') {\n logger.debug('Config not mandatory so repo is considered onboarded');\n return true;\n }\n logger.debug('Repo is not onboarded and no merged PRs exist');\n if (!config.suppressNotifications!.includes('onboardingClose')) {\n const ageOfOnboardingPr = getElapsedDays(\n closedOnboardingPr.createdAt!,\n false,\n );\n const onboardingAutoCloseAge = getInheritedOrGlobal(\n 'onboardingAutoCloseAge',\n );\n if (onboardingAutoCloseAge) {\n logger.debug(\n {\n onboardingAutoCloseAge,\n createdAt: closedOnboardingPr.createdAt!,\n ageOfOnboardingPr,\n },\n `Determining that the closed onboarding PR was created at \\`${closedOnboardingPr.createdAt!}\\` was created ${ageOfOnboardingPr.toFixed(2)} days ago`,\n );\n }\n // if we have onboardingAutoCloseAge, and it hasn't yet passed onboardingAutoCloseAge, add a comment\n // if it /has/ passed, we'll comment this appropriately in `ensureOnboardingPr`, so there doesn't need to be a comment here\n if (\n !onboardingAutoCloseAge ||\n ageOfOnboardingPr <= onboardingAutoCloseAge\n ) {\n // ensure PR comment\n await ensureComment({\n number: closedOnboardingPr.number,\n topic: `Renovate is disabled`,\n content: `Renovate is disabled because there is no Renovate configuration file. To enable Renovate, you can either (a) change this PR's title to get a new onboarding PR, and merge the new onboarding PR, or (b) create a Renovate config file, and commit that file to your base branch.`,\n });\n }\n }\n throw new Error(REPOSITORY_CLOSED_ONBOARDING);\n}\n\nexport async function getOnboardingPr(\n config: RenovateConfig,\n): Promise<Pr | null> {\n return await platform.getBranchPr(\n getInheritedOrGlobal('onboardingBranch')!,\n config.baseBranch,\n );\n}\n"],"mappings":"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"}
|
|
@@ -80,7 +80,7 @@ async function ensureOnboardingPr(config, packageFiles, branches) {
|
|
|
80
80
|
const rebaseCheckBox = getRebaseCheckbox(config.onboardingRebaseCheckbox);
|
|
81
81
|
logger.debug("Filling in onboarding PR template");
|
|
82
82
|
let prTemplate = `Welcome to [Renovate](${config.productLinks.homepage})! This is an onboarding PR to help you understand and configure settings before regular Pull Requests begin.\n\n`;
|
|
83
|
-
prTemplate +=
|
|
83
|
+
prTemplate += getInheritedOrGlobal("requireConfig") === "required" ? emojify(`:vertical_traffic_light: To activate Renovate, merge this Pull Request. To disable Renovate, simply close this Pull Request unmerged.\n\n`) : emojify(`:vertical_traffic_light: Renovate will begin keeping your dependencies up-to-date only once you merge or close this Pull Request.\n\n`);
|
|
84
84
|
prTemplate += emojify(`:books: See our [Reading List](https://docs.renovatebot.com/reading-list/) for relevant documentation you may be interested in reading.\n\n`);
|
|
85
85
|
const configFile = getDefaultConfigFileName();
|
|
86
86
|
prTemplate += emojify(`:abcd: Do you want to change how Renovate upgrades your dependencies?`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["template.compile"],"sources":["../../../../../lib/workers/repository/onboarding/pr/index.ts"],"sourcesContent":["import { isNumber, isString } from '@sindresorhus/is';\nimport { GlobalConfig } from '../../../../config/global.ts';\nimport type { RenovateConfig } from '../../../../config/types.ts';\nimport { REPOSITORY_CLOSED_ONBOARDING } from '../../../../constants/error-messages.ts';\nimport { logger } from '../../../../logger/index.ts';\nimport type { PackageFile } from '../../../../modules/manager/types.ts';\nimport { ensureComment } from '../../../../modules/platform/comment.ts';\nimport type { Pr } from '../../../../modules/platform/index.ts';\nimport { platform } from '../../../../modules/platform/index.ts';\nimport { hashBody } from '../../../../modules/platform/pr-body.ts';\nimport { scm } from '../../../../modules/platform/scm.ts';\nimport { getInheritedOrGlobal } from '../../../../util/common.ts';\nimport { getElapsedDays } from '../../../../util/date.ts';\nimport { emojify } from '../../../../util/emoji.ts';\nimport { getFile } from '../../../../util/git/index.ts';\nimport { toSha256 } from '../../../../util/hash.ts';\nimport * as template from '../../../../util/template/index.ts';\nimport type { BranchConfig } from '../../../types.ts';\nimport {\n getDepWarningsOnboardingPR,\n getErrors,\n getWarnings,\n} from '../../errors-warnings.ts';\nimport { getPlatformPrOptions } from '../../update/pr/index.ts';\nimport { prepareLabels } from '../../update/pr/labels.ts';\nimport { addParticipants } from '../../update/pr/participants.ts';\nimport { isOnboardingBranchConflicted } from '../branch/onboarding-branch-cache.ts';\nimport {\n OnboardingState,\n getDefaultConfigFileName,\n getSemanticCommitPrTitle,\n} from '../common.ts';\nimport { getBaseBranchDesc } from './base-branch.ts';\nimport { getConfigDesc } from './config-description.ts';\nimport { getExpectedPrList } from './pr-list.ts';\n\n/**\n * Given an existing PR, if onboardingAutoCloseAge has passed, close the PR.\n *\n * Returns true if the PR was closed.\n */\nasync function ensureOnboardingAutoCloseAge(existingPr: Pr): Promise<boolean> {\n // check if the existing pr crosses the onboarding autoclose age\n const ageOfOnboardingPr = getElapsedDays(existingPr.createdAt!, false);\n const onboardingAutoCloseAge = getInheritedOrGlobal('onboardingAutoCloseAge');\n if (onboardingAutoCloseAge) {\n logger.debug(\n {\n onboardingAutoCloseAge,\n createdAt: existingPr.createdAt!,\n ageOfOnboardingPr,\n },\n `Determining that the onboarding PR created at \\`${existingPr.createdAt!}\\` was created ${ageOfOnboardingPr.toFixed(2)} days ago`,\n );\n }\n if (\n isNumber(onboardingAutoCloseAge) &&\n ageOfOnboardingPr > onboardingAutoCloseAge\n ) {\n // close the pr\n await platform.updatePr({\n number: existingPr.number,\n state: 'closed',\n prTitle: existingPr.title,\n });\n // ensure comment\n await ensureComment({\n number: existingPr.number,\n topic: `Renovate is disabled`,\n content: `Renovate is disabled because the onboarding PR has been unmerged for more than ${onboardingAutoCloseAge} days. To enable Renovate, you can either (a) change this PR's title to get a new onboarding PR, and merge the new onboarding PR, or (b) create a Renovate config file, and commit that file to your base branch.`,\n });\n logger.debug(\n {\n ageOfOnboardingPr,\n onboardingAutoCloseAge,\n },\n `Renovate is being disabled for this repository as the onboarding PR has been unmerged for more than ${onboardingAutoCloseAge} days`,\n );\n return true;\n }\n return false;\n}\n\nexport async function ensureOnboardingPr(\n config: RenovateConfig,\n packageFiles: Record<string, PackageFile[]> | null,\n branches: BranchConfig[],\n): Promise<void> {\n if (\n config.repoIsOnboarded === true ||\n (config.onboardingRebaseCheckbox && !OnboardingState.prUpdateRequested)\n ) {\n return;\n }\n logger.debug('ensureOnboardingPr()');\n logger.trace({ config });\n // TODO #22198\n const onboardingBranch = getInheritedOrGlobal('onboardingBranch')!;\n const existingPr = await platform.getBranchPr(\n onboardingBranch,\n config.defaultBranch,\n );\n if (existingPr) {\n const wasClosed = await ensureOnboardingAutoCloseAge(existingPr);\n if (wasClosed) {\n throw new Error(REPOSITORY_CLOSED_ONBOARDING);\n }\n\n // skip pr-update if branch is conflicted\n if (\n await isOnboardingBranchConflicted(\n config.defaultBranch!,\n onboardingBranch,\n )\n ) {\n if (GlobalConfig.get('dryRun')) {\n logger.info(\n 'DRY-RUN: Would comment that Onboarding PR is conflicted and needs manual resolving',\n );\n return;\n }\n await ensureComment({\n number: existingPr.number,\n topic: 'Branch Conflicted',\n content: emojify(\n `:warning: This PR has a merge conflict which Renovate is unable to automatically resolve, so updates to this PR description are now paused. Please resolve the merge conflict manually.\\n\\n`,\n ),\n });\n return;\n }\n }\n\n if (OnboardingState.onboardingCacheValid) {\n return;\n }\n\n const onboardingConfigHashComment = await getOnboardingConfigHashComment();\n const rebaseCheckBox = getRebaseCheckbox(config.onboardingRebaseCheckbox);\n logger.debug('Filling in onboarding PR template');\n let prTemplate = `Welcome to [Renovate](${\n config.productLinks!.homepage\n })! This is an onboarding PR to help you understand and configure settings before regular Pull Requests begin.\\n\\n`;\n prTemplate +=\n config.requireConfig === 'required'\n ? emojify(\n `:vertical_traffic_light: To activate Renovate, merge this Pull Request. To disable Renovate, simply close this Pull Request unmerged.\\n\\n`,\n )\n : emojify(\n `:vertical_traffic_light: Renovate will begin keeping your dependencies up-to-date only once you merge or close this Pull Request.\\n\\n`,\n );\n\n prTemplate += emojify(\n `:books: See our [Reading List](https://docs.renovatebot.com/reading-list/) for relevant documentation you may be interested in reading.\\n\\n`,\n );\n\n const configFile = getDefaultConfigFileName();\n prTemplate += emojify(\n `:abcd: Do you want to change how Renovate upgrades your dependencies?`,\n );\n prTemplate += ` Add your custom config to \\`${configFile}\\` in this branch${\n config.onboardingRebaseCheckbox\n ? ' and select the Retry/Rebase checkbox below'\n : ''\n }. Renovate will update the Pull Request description the next time it runs.`;\n prTemplate += '\\n\\n';\n // TODO #22198\n prTemplate += emojify(\n `\n\n---\n{{PACKAGE FILES}}\n{{CONFIG}}\n{{BASEBRANCH}}\n{{PRLIST}}\n{{WARNINGS}}\n{{ERRORS}}\n\n---\n\n:question: Got questions? Check out Renovate's [Docs](${\n config.productLinks!.documentation\n }), particularly the Getting Started section.\nIf you need any further assistance then you can also [request help here](${\n config.productLinks!.help\n }).\n`,\n );\n prTemplate += rebaseCheckBox;\n let prBody = prTemplate;\n if (packageFiles && Object.entries(packageFiles).length) {\n let files: string[] = [];\n for (const [manager, managerFiles] of Object.entries(packageFiles)) {\n files = files.concat(\n managerFiles.map((file) => ` * \\`${file.packageFile}\\` (${manager})`),\n );\n }\n prBody =\n prBody.replace(\n '{{PACKAGE FILES}}',\n '### Detected Package Files\\n\\n' + files.join('\\n'),\n ) + '\\n';\n } else {\n prBody = prBody.replace('{{PACKAGE FILES}}\\n', '');\n }\n let configDesc = '';\n if (GlobalConfig.get('dryRun')) {\n // TODO: types (#22198)\n logger.info(`DRY-RUN: Would check branch ${onboardingBranch}`);\n } else {\n configDesc = getConfigDesc(config, packageFiles!);\n }\n prBody = prBody.replace('{{CONFIG}}\\n', configDesc);\n prBody = prBody.replace(\n '{{WARNINGS}}\\n',\n getWarnings(config) + getDepWarningsOnboardingPR(packageFiles!, config),\n );\n prBody = prBody.replace('{{ERRORS}}\\n', getErrors(config));\n prBody = prBody.replace('{{BASEBRANCH}}\\n', getBaseBranchDesc(config));\n prBody = prBody.replace('{{PRLIST}}\\n', getExpectedPrList(config, branches));\n if (isString(config.prHeader)) {\n prBody = `${template.compile(config.prHeader, config)}\\n\\n${prBody}`;\n }\n if (isString(config.prFooter)) {\n prBody = `${prBody}\\n---\\n\\n${template.compile(config.prFooter, config)}\\n`;\n }\n\n prBody += onboardingConfigHashComment;\n\n logger.trace('prBody:\\n' + prBody);\n\n prBody = platform.massageMarkdown(prBody, config.rebaseLabel);\n\n if (existingPr) {\n logger.debug('Found open onboarding PR');\n // Check if existing PR needs updating\n const prBodyHash = hashBody(prBody);\n if (existingPr.bodyStruct?.hash === prBodyHash) {\n logger.debug(`Pull Request #${existingPr.number} does not need updating`);\n return;\n }\n // PR must need updating\n if (GlobalConfig.get('dryRun')) {\n logger.info('DRY-RUN: Would update onboarding PR');\n } else {\n await platform.updatePr({\n number: existingPr.number,\n prTitle: existingPr.title,\n prBody,\n });\n logger.info({ pr: existingPr.number }, 'Onboarding PR updated');\n }\n return;\n }\n logger.debug('Creating onboarding PR');\n const labels: string[] = prepareLabels(config);\n try {\n if (GlobalConfig.get('dryRun')) {\n logger.info('DRY-RUN: Would create onboarding PR');\n } else {\n // TODO #22198\n const prTitle =\n config.semanticCommits === 'enabled'\n ? getSemanticCommitPrTitle(config)\n : getInheritedOrGlobal('onboardingPrTitle')!;\n const pr = await platform.createPr({\n sourceBranch: onboardingBranch,\n targetBranch: config.defaultBranch!,\n prTitle,\n prBody,\n labels,\n platformPrOptions: getPlatformPrOptions({\n ...config,\n automerge: false,\n }),\n });\n logger.info(\n { pr: `Pull Request #${pr!.number}` },\n 'Onboarding PR created',\n );\n await addParticipants(config, pr!);\n }\n } catch (err) {\n if (\n err.response?.statusCode === 422 &&\n err.response?.body?.errors?.[0]?.message?.startsWith(\n 'A pull request already exists',\n )\n ) {\n logger.warn(\n 'Onboarding PR already exists but cannot find it. It was probably created by a different user.',\n );\n await scm.deleteBranch(onboardingBranch);\n return;\n }\n throw err;\n }\n}\n\nfunction getRebaseCheckbox(onboardingRebaseCheckbox?: boolean): string {\n let rebaseCheckBox = '';\n if (onboardingRebaseCheckbox) {\n // Create markdown checkbox\n rebaseCheckBox = `\\n\\n---\\n\\n - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, click this checkbox.\\n`;\n }\n\n return rebaseCheckBox;\n}\n\nasync function getOnboardingConfigHashComment(): Promise<string> {\n const configFile = getDefaultConfigFileName();\n const existingContents =\n (await getFile(configFile, getInheritedOrGlobal('onboardingBranch'))) ?? '';\n const hash = toSha256(existingContents);\n\n return `\\n<!--renovate-config-hash:${hash}-->\\n`;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["template.compile"],"sources":["../../../../../lib/workers/repository/onboarding/pr/index.ts"],"sourcesContent":["import { isNumber, isString } from '@sindresorhus/is';\nimport { GlobalConfig } from '../../../../config/global.ts';\nimport type { RenovateConfig } from '../../../../config/types.ts';\nimport { REPOSITORY_CLOSED_ONBOARDING } from '../../../../constants/error-messages.ts';\nimport { logger } from '../../../../logger/index.ts';\nimport type { PackageFile } from '../../../../modules/manager/types.ts';\nimport { ensureComment } from '../../../../modules/platform/comment.ts';\nimport type { Pr } from '../../../../modules/platform/index.ts';\nimport { platform } from '../../../../modules/platform/index.ts';\nimport { hashBody } from '../../../../modules/platform/pr-body.ts';\nimport { scm } from '../../../../modules/platform/scm.ts';\nimport { getInheritedOrGlobal } from '../../../../util/common.ts';\nimport { getElapsedDays } from '../../../../util/date.ts';\nimport { emojify } from '../../../../util/emoji.ts';\nimport { getFile } from '../../../../util/git/index.ts';\nimport { toSha256 } from '../../../../util/hash.ts';\nimport * as template from '../../../../util/template/index.ts';\nimport type { BranchConfig } from '../../../types.ts';\nimport {\n getDepWarningsOnboardingPR,\n getErrors,\n getWarnings,\n} from '../../errors-warnings.ts';\nimport { getPlatformPrOptions } from '../../update/pr/index.ts';\nimport { prepareLabels } from '../../update/pr/labels.ts';\nimport { addParticipants } from '../../update/pr/participants.ts';\nimport { isOnboardingBranchConflicted } from '../branch/onboarding-branch-cache.ts';\nimport {\n OnboardingState,\n getDefaultConfigFileName,\n getSemanticCommitPrTitle,\n} from '../common.ts';\nimport { getBaseBranchDesc } from './base-branch.ts';\nimport { getConfigDesc } from './config-description.ts';\nimport { getExpectedPrList } from './pr-list.ts';\n\n/**\n * Given an existing PR, if onboardingAutoCloseAge has passed, close the PR.\n *\n * Returns true if the PR was closed.\n */\nasync function ensureOnboardingAutoCloseAge(existingPr: Pr): Promise<boolean> {\n // check if the existing pr crosses the onboarding autoclose age\n const ageOfOnboardingPr = getElapsedDays(existingPr.createdAt!, false);\n const onboardingAutoCloseAge = getInheritedOrGlobal('onboardingAutoCloseAge');\n if (onboardingAutoCloseAge) {\n logger.debug(\n {\n onboardingAutoCloseAge,\n createdAt: existingPr.createdAt!,\n ageOfOnboardingPr,\n },\n `Determining that the onboarding PR created at \\`${existingPr.createdAt!}\\` was created ${ageOfOnboardingPr.toFixed(2)} days ago`,\n );\n }\n if (\n isNumber(onboardingAutoCloseAge) &&\n ageOfOnboardingPr > onboardingAutoCloseAge\n ) {\n // close the pr\n await platform.updatePr({\n number: existingPr.number,\n state: 'closed',\n prTitle: existingPr.title,\n });\n // ensure comment\n await ensureComment({\n number: existingPr.number,\n topic: `Renovate is disabled`,\n content: `Renovate is disabled because the onboarding PR has been unmerged for more than ${onboardingAutoCloseAge} days. To enable Renovate, you can either (a) change this PR's title to get a new onboarding PR, and merge the new onboarding PR, or (b) create a Renovate config file, and commit that file to your base branch.`,\n });\n logger.debug(\n {\n ageOfOnboardingPr,\n onboardingAutoCloseAge,\n },\n `Renovate is being disabled for this repository as the onboarding PR has been unmerged for more than ${onboardingAutoCloseAge} days`,\n );\n return true;\n }\n return false;\n}\n\nexport async function ensureOnboardingPr(\n config: RenovateConfig,\n packageFiles: Record<string, PackageFile[]> | null,\n branches: BranchConfig[],\n): Promise<void> {\n if (\n config.repoIsOnboarded === true ||\n (config.onboardingRebaseCheckbox && !OnboardingState.prUpdateRequested)\n ) {\n return;\n }\n logger.debug('ensureOnboardingPr()');\n logger.trace({ config });\n // TODO #22198\n const onboardingBranch = getInheritedOrGlobal('onboardingBranch')!;\n const existingPr = await platform.getBranchPr(\n onboardingBranch,\n config.defaultBranch,\n );\n if (existingPr) {\n const wasClosed = await ensureOnboardingAutoCloseAge(existingPr);\n if (wasClosed) {\n throw new Error(REPOSITORY_CLOSED_ONBOARDING);\n }\n\n // skip pr-update if branch is conflicted\n if (\n await isOnboardingBranchConflicted(\n config.defaultBranch!,\n onboardingBranch,\n )\n ) {\n if (GlobalConfig.get('dryRun')) {\n logger.info(\n 'DRY-RUN: Would comment that Onboarding PR is conflicted and needs manual resolving',\n );\n return;\n }\n await ensureComment({\n number: existingPr.number,\n topic: 'Branch Conflicted',\n content: emojify(\n `:warning: This PR has a merge conflict which Renovate is unable to automatically resolve, so updates to this PR description are now paused. Please resolve the merge conflict manually.\\n\\n`,\n ),\n });\n return;\n }\n }\n\n if (OnboardingState.onboardingCacheValid) {\n return;\n }\n\n const onboardingConfigHashComment = await getOnboardingConfigHashComment();\n const rebaseCheckBox = getRebaseCheckbox(config.onboardingRebaseCheckbox);\n logger.debug('Filling in onboarding PR template');\n let prTemplate = `Welcome to [Renovate](${\n config.productLinks!.homepage\n })! This is an onboarding PR to help you understand and configure settings before regular Pull Requests begin.\\n\\n`;\n prTemplate +=\n getInheritedOrGlobal('requireConfig') === 'required'\n ? emojify(\n `:vertical_traffic_light: To activate Renovate, merge this Pull Request. To disable Renovate, simply close this Pull Request unmerged.\\n\\n`,\n )\n : emojify(\n `:vertical_traffic_light: Renovate will begin keeping your dependencies up-to-date only once you merge or close this Pull Request.\\n\\n`,\n );\n\n prTemplate += emojify(\n `:books: See our [Reading List](https://docs.renovatebot.com/reading-list/) for relevant documentation you may be interested in reading.\\n\\n`,\n );\n\n const configFile = getDefaultConfigFileName();\n prTemplate += emojify(\n `:abcd: Do you want to change how Renovate upgrades your dependencies?`,\n );\n prTemplate += ` Add your custom config to \\`${configFile}\\` in this branch${\n config.onboardingRebaseCheckbox\n ? ' and select the Retry/Rebase checkbox below'\n : ''\n }. Renovate will update the Pull Request description the next time it runs.`;\n prTemplate += '\\n\\n';\n // TODO #22198\n prTemplate += emojify(\n `\n\n---\n{{PACKAGE FILES}}\n{{CONFIG}}\n{{BASEBRANCH}}\n{{PRLIST}}\n{{WARNINGS}}\n{{ERRORS}}\n\n---\n\n:question: Got questions? Check out Renovate's [Docs](${\n config.productLinks!.documentation\n }), particularly the Getting Started section.\nIf you need any further assistance then you can also [request help here](${\n config.productLinks!.help\n }).\n`,\n );\n prTemplate += rebaseCheckBox;\n let prBody = prTemplate;\n if (packageFiles && Object.entries(packageFiles).length) {\n let files: string[] = [];\n for (const [manager, managerFiles] of Object.entries(packageFiles)) {\n files = files.concat(\n managerFiles.map((file) => ` * \\`${file.packageFile}\\` (${manager})`),\n );\n }\n prBody =\n prBody.replace(\n '{{PACKAGE FILES}}',\n '### Detected Package Files\\n\\n' + files.join('\\n'),\n ) + '\\n';\n } else {\n prBody = prBody.replace('{{PACKAGE FILES}}\\n', '');\n }\n let configDesc = '';\n if (GlobalConfig.get('dryRun')) {\n // TODO: types (#22198)\n logger.info(`DRY-RUN: Would check branch ${onboardingBranch}`);\n } else {\n configDesc = getConfigDesc(config, packageFiles!);\n }\n prBody = prBody.replace('{{CONFIG}}\\n', configDesc);\n prBody = prBody.replace(\n '{{WARNINGS}}\\n',\n getWarnings(config) + getDepWarningsOnboardingPR(packageFiles!, config),\n );\n prBody = prBody.replace('{{ERRORS}}\\n', getErrors(config));\n prBody = prBody.replace('{{BASEBRANCH}}\\n', getBaseBranchDesc(config));\n prBody = prBody.replace('{{PRLIST}}\\n', getExpectedPrList(config, branches));\n if (isString(config.prHeader)) {\n prBody = `${template.compile(config.prHeader, config)}\\n\\n${prBody}`;\n }\n if (isString(config.prFooter)) {\n prBody = `${prBody}\\n---\\n\\n${template.compile(config.prFooter, config)}\\n`;\n }\n\n prBody += onboardingConfigHashComment;\n\n logger.trace('prBody:\\n' + prBody);\n\n prBody = platform.massageMarkdown(prBody, config.rebaseLabel);\n\n if (existingPr) {\n logger.debug('Found open onboarding PR');\n // Check if existing PR needs updating\n const prBodyHash = hashBody(prBody);\n if (existingPr.bodyStruct?.hash === prBodyHash) {\n logger.debug(`Pull Request #${existingPr.number} does not need updating`);\n return;\n }\n // PR must need updating\n if (GlobalConfig.get('dryRun')) {\n logger.info('DRY-RUN: Would update onboarding PR');\n } else {\n await platform.updatePr({\n number: existingPr.number,\n prTitle: existingPr.title,\n prBody,\n });\n logger.info({ pr: existingPr.number }, 'Onboarding PR updated');\n }\n return;\n }\n logger.debug('Creating onboarding PR');\n const labels: string[] = prepareLabels(config);\n try {\n if (GlobalConfig.get('dryRun')) {\n logger.info('DRY-RUN: Would create onboarding PR');\n } else {\n // TODO #22198\n const prTitle =\n config.semanticCommits === 'enabled'\n ? getSemanticCommitPrTitle(config)\n : getInheritedOrGlobal('onboardingPrTitle')!;\n const pr = await platform.createPr({\n sourceBranch: onboardingBranch,\n targetBranch: config.defaultBranch!,\n prTitle,\n prBody,\n labels,\n platformPrOptions: getPlatformPrOptions({\n ...config,\n automerge: false,\n }),\n });\n logger.info(\n { pr: `Pull Request #${pr!.number}` },\n 'Onboarding PR created',\n );\n await addParticipants(config, pr!);\n }\n } catch (err) {\n if (\n err.response?.statusCode === 422 &&\n err.response?.body?.errors?.[0]?.message?.startsWith(\n 'A pull request already exists',\n )\n ) {\n logger.warn(\n 'Onboarding PR already exists but cannot find it. It was probably created by a different user.',\n );\n await scm.deleteBranch(onboardingBranch);\n return;\n }\n throw err;\n }\n}\n\nfunction getRebaseCheckbox(onboardingRebaseCheckbox?: boolean): string {\n let rebaseCheckBox = '';\n if (onboardingRebaseCheckbox) {\n // Create markdown checkbox\n rebaseCheckBox = `\\n\\n---\\n\\n - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, click this checkbox.\\n`;\n }\n\n return rebaseCheckBox;\n}\n\nasync function getOnboardingConfigHashComment(): Promise<string> {\n const configFile = getDefaultConfigFileName();\n const existingContents =\n (await getFile(configFile, getInheritedOrGlobal('onboardingBranch'))) ?? '';\n const hash = toSha256(existingContents);\n\n return `\\n<!--renovate-config-hash:${hash}-->\\n`;\n}\n"],"mappings":"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"}
|
|
@@ -129,6 +129,7 @@ async function fetchVulnerabilities(config, packageFiles) {
|
|
|
129
129
|
async function lookup(config, packageFiles) {
|
|
130
130
|
await fetchVulnerabilities(config, packageFiles);
|
|
131
131
|
await fetchUpdates(config, packageFiles);
|
|
132
|
+
await fetchVulnerabilities(config, packageFiles);
|
|
132
133
|
cleanDatasourceKeys();
|
|
133
134
|
calculateLibYears(config, packageFiles);
|
|
134
135
|
const { branches, branchList } = await branchifyUpgrades(config, packageFiles);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extract-update.js","names":[],"sources":["../../../../lib/workers/repository/process/extract-update.ts"],"sourcesContent":["import { isNonEmptyArray } from '@sindresorhus/is';\nimport type { RenovateConfig } from '../../../config/types.ts';\nimport { instrument } from '../../../instrumentation/index.ts';\nimport { logger } from '../../../logger/index.ts';\nimport { hashMap } from '../../../modules/manager/index.ts';\nimport type { PackageFile } from '../../../modules/manager/types.ts';\nimport { scm } from '../../../modules/platform/scm.ts';\nimport { isNotNullOrUndefined } from '../../../util/array.ts';\nimport * as memCache from '../../../util/cache/memory/index.ts';\nimport { getCache } from '../../../util/cache/repository/index.ts';\nimport type { BaseBranchCache } from '../../../util/cache/repository/types.ts';\nimport { checkGithubToken as ensureGithubToken } from '../../../util/check-token.ts';\nimport { fingerprint } from '../../../util/fingerprint.ts';\nimport type { BranchConfig } from '../../types.ts';\nimport { generateFingerprintConfig } from '../extract/extract-fingerprint-config.ts';\nimport { extractAllDependencies } from '../extract/index.ts';\nimport { branchifyUpgrades } from '../updates/branchify.ts';\nimport { fetchUpdates } from './fetch.ts';\nimport { calculateLibYears } from './libyear.ts';\nimport { sortBranches } from './sort.ts';\nimport { Vulnerabilities } from './vulnerabilities.ts';\nimport type { WriteUpdateResult } from './write.ts';\nimport { writeUpdates } from './write.ts';\n\n// Increment this if needing to cache bust ALL extract caches\nexport const EXTRACT_CACHE_REVISION = 1;\n\nexport interface ExtractResult {\n branches: BranchConfig[];\n branchList: string[];\n packageFiles: Record<string, PackageFile[]>;\n}\n\nexport interface StatsResult {\n fileCount: number;\n depCount: number;\n}\n\nexport interface Stats {\n managers: Record<string, StatsResult>;\n total: StatsResult;\n}\n\n// istanbul ignore next\nfunction extractStats(\n packageFiles: Record<string, PackageFile[]>,\n): Stats | null {\n if (!packageFiles) {\n return null;\n }\n const stats: Stats = {\n managers: {},\n total: {\n fileCount: 0,\n depCount: 0,\n },\n };\n for (const [manager, managerPackageFiles] of Object.entries(packageFiles)) {\n const fileCount = managerPackageFiles.length;\n let depCount = 0;\n for (const file of managerPackageFiles) {\n depCount += file.deps.length;\n }\n stats.managers[manager] = {\n fileCount,\n depCount,\n };\n stats.total.fileCount += fileCount;\n stats.total.depCount += depCount;\n }\n return stats;\n}\n\nexport function isCacheExtractValid(\n baseBranchSha: string,\n configHash: string,\n cachedExtract?: BaseBranchCache,\n): boolean {\n if (!cachedExtract) {\n return false;\n }\n\n if (!cachedExtract.revision) {\n logger.debug('Cached extract is missing revision, so cannot be used');\n return false;\n }\n\n if (cachedExtract.revision !== EXTRACT_CACHE_REVISION) {\n logger.debug(\n `Extract cache revision has changed (old=${cachedExtract.revision}, new=${EXTRACT_CACHE_REVISION})`,\n );\n return false;\n }\n\n if (!(cachedExtract.sha && cachedExtract.configHash)) {\n return false;\n }\n if (cachedExtract.sha !== baseBranchSha) {\n logger.debug(\n `Cached extract result cannot be used due to base branch SHA change (old=${cachedExtract.sha}, new=${baseBranchSha})`,\n );\n return false;\n }\n if (cachedExtract.configHash !== configHash) {\n logger.debug('Cached extract result cannot be used due to config change');\n return false;\n }\n if (!cachedExtract.extractionFingerprints) {\n logger.debug(\n 'Cached extract is missing extractionFingerprints, so cannot be used',\n );\n return false;\n }\n const changedManagers = new Set();\n for (const [manager, fingerprint] of Object.entries(\n cachedExtract.extractionFingerprints,\n )) {\n if (fingerprint !== hashMap.get(manager)) {\n changedManagers.add(manager);\n }\n }\n if (changedManagers.size > 0) {\n logger.debug(\n { changedManagers: [...changedManagers] },\n 'Manager fingerprint(s) have changed, extract cache cannot be reused',\n );\n return false;\n }\n logger.debug(\n `Cached extract for sha=${baseBranchSha} is valid and can be used`,\n );\n return true;\n}\n\nexport async function extract(\n config: RenovateConfig,\n overwriteCache = true,\n): Promise<Record<string, PackageFile[]>> {\n logger.debug('extract()');\n const { baseBranch } = config;\n const baseBranchSha = await scm.getBranchCommit(baseBranch!);\n let packageFiles: Record<string, PackageFile[]>;\n const cache = getCache();\n cache.scan ??= {};\n const cachedExtract = cache.scan[baseBranch!];\n const configHash = instrument('fingerprint', () =>\n fingerprint(generateFingerprintConfig(config)),\n );\n // istanbul ignore if\n if (\n overwriteCache &&\n isCacheExtractValid(baseBranchSha!, configHash, cachedExtract)\n ) {\n packageFiles = cachedExtract.packageFiles;\n try {\n for (const files of Object.values(packageFiles)) {\n for (const file of files) {\n for (const dep of file.deps) {\n delete dep.updates;\n }\n }\n }\n logger.debug('Deleted cached dep updates');\n } catch (err) {\n logger.info({ err }, 'Error deleting cached dep updates');\n }\n } else {\n await instrument(\n 'checkoutBranch',\n async () => await scm.checkoutBranch(baseBranch!),\n );\n const extractResult = await instrument(\n 'extractAllDependencies',\n async () => (await extractAllDependencies(config)) || {},\n );\n packageFiles = extractResult.packageFiles;\n const { extractionFingerprints } = extractResult;\n\n if (overwriteCache) {\n // TODO: fix types (#22198)\n cache.scan[baseBranch!] = {\n revision: EXTRACT_CACHE_REVISION,\n sha: baseBranchSha!,\n configHash,\n extractionFingerprints,\n packageFiles,\n };\n }\n\n // Clean up cached branch extracts\n const baseBranches = isNonEmptyArray(config.baseBranches)\n ? config.baseBranches\n : [baseBranch];\n Object.keys(cache.scan).forEach((branchName) => {\n if (!baseBranches.includes(branchName)) {\n delete cache.scan![branchName];\n }\n });\n }\n const stats = extractStats(packageFiles);\n logger.info(\n { baseBranch: config.baseBranch, stats },\n `Dependency extraction complete`,\n );\n logger.trace({ config: packageFiles }, 'packageFiles');\n ensureGithubToken(packageFiles);\n return packageFiles;\n}\n\nasync function fetchVulnerabilities(\n config: RenovateConfig,\n packageFiles: Record<string, PackageFile[]>,\n): Promise<void> {\n if (config.osvVulnerabilityAlerts) {\n logger.debug('fetchVulnerabilities() - osvVulnerabilityAlerts=true');\n try {\n const vulnerabilities = await Vulnerabilities.create();\n await vulnerabilities.appendVulnerabilityPackageRules(\n config,\n packageFiles,\n );\n } catch (err) {\n logger.warn({ err }, 'Unable to read vulnerability information');\n }\n }\n}\n\nexport async function lookup(\n config: RenovateConfig,\n packageFiles: Record<string, PackageFile[]>,\n): Promise<ExtractResult> {\n await fetchVulnerabilities(config, packageFiles);\n await fetchUpdates(config, packageFiles);\n memCache.cleanDatasourceKeys();\n calculateLibYears(config, packageFiles);\n const { branches, branchList } = await branchifyUpgrades(\n config,\n packageFiles,\n );\n reportMaliciousSkippedDependencies(packageFiles);\n logger.debug(\n { baseBranch: config.baseBranch, config: packageFiles },\n 'packageFiles with updates',\n );\n sortBranches(branches);\n return { branches, branchList, packageFiles };\n}\n\nexport function reportMaliciousSkippedDependencies(\n allPackageFiles: Record<string, PackageFile<Record<string, any>>[]>,\n): void {\n if (allPackageFiles === undefined) {\n return;\n }\n\n for (const [manager, packageFiles] of Object.entries(allPackageFiles)) {\n for (const packageFile of packageFiles) {\n for (const dep of packageFile.deps) {\n if (dep.skipReason === 'malicious-version-in-use') {\n logger.warn(\n {\n packageFile: packageFile.packageFile,\n depName: dep.depName,\n packageName: dep.packageName,\n manager: manager,\n datasource: dep.datasource,\n },\n `Dependency ${dep.depName} is currently using a malicious version`,\n );\n\n // and make sure that it then gets updates proposed in the update phase\n delete dep.skipReason;\n delete dep.skipStage;\n } else if (dep.skipReason === 'malicious-update-proposed') {\n const newVersions = dep.updates\n ?.map((u) => u.newVersion ?? u.newValue)\n .filter(isNotNullOrUndefined);\n logger.warn(\n {\n packageFile: packageFile.packageFile,\n depName: dep.depName,\n packageName: dep.packageName,\n manager: manager,\n datasource: dep.datasource,\n newVersions,\n },\n `Dependency ${dep.depName} has update(s) proposed which would update you to a malicious version - skipping`,\n );\n }\n }\n }\n }\n}\n\nexport async function update(\n config: RenovateConfig,\n branches: BranchConfig[],\n): Promise<WriteUpdateResult | undefined> {\n let res: WriteUpdateResult | undefined;\n if (config.repoIsOnboarded) {\n res = await writeUpdates(config, branches);\n }\n\n return res;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"extract-update.js","names":[],"sources":["../../../../lib/workers/repository/process/extract-update.ts"],"sourcesContent":["import { isNonEmptyArray } from '@sindresorhus/is';\nimport type { RenovateConfig } from '../../../config/types.ts';\nimport { instrument } from '../../../instrumentation/index.ts';\nimport { logger } from '../../../logger/index.ts';\nimport { hashMap } from '../../../modules/manager/index.ts';\nimport type { PackageFile } from '../../../modules/manager/types.ts';\nimport { scm } from '../../../modules/platform/scm.ts';\nimport { isNotNullOrUndefined } from '../../../util/array.ts';\nimport * as memCache from '../../../util/cache/memory/index.ts';\nimport { getCache } from '../../../util/cache/repository/index.ts';\nimport type { BaseBranchCache } from '../../../util/cache/repository/types.ts';\nimport { checkGithubToken as ensureGithubToken } from '../../../util/check-token.ts';\nimport { fingerprint } from '../../../util/fingerprint.ts';\nimport type { BranchConfig } from '../../types.ts';\nimport { generateFingerprintConfig } from '../extract/extract-fingerprint-config.ts';\nimport { extractAllDependencies } from '../extract/index.ts';\nimport { branchifyUpgrades } from '../updates/branchify.ts';\nimport { fetchUpdates } from './fetch.ts';\nimport { calculateLibYears } from './libyear.ts';\nimport { sortBranches } from './sort.ts';\nimport { Vulnerabilities } from './vulnerabilities.ts';\nimport type { WriteUpdateResult } from './write.ts';\nimport { writeUpdates } from './write.ts';\n\n// Increment this if needing to cache bust ALL extract caches\nexport const EXTRACT_CACHE_REVISION = 1;\n\nexport interface ExtractResult {\n branches: BranchConfig[];\n branchList: string[];\n packageFiles: Record<string, PackageFile[]>;\n}\n\nexport interface StatsResult {\n fileCount: number;\n depCount: number;\n}\n\nexport interface Stats {\n managers: Record<string, StatsResult>;\n total: StatsResult;\n}\n\n// istanbul ignore next\nfunction extractStats(\n packageFiles: Record<string, PackageFile[]>,\n): Stats | null {\n if (!packageFiles) {\n return null;\n }\n const stats: Stats = {\n managers: {},\n total: {\n fileCount: 0,\n depCount: 0,\n },\n };\n for (const [manager, managerPackageFiles] of Object.entries(packageFiles)) {\n const fileCount = managerPackageFiles.length;\n let depCount = 0;\n for (const file of managerPackageFiles) {\n depCount += file.deps.length;\n }\n stats.managers[manager] = {\n fileCount,\n depCount,\n };\n stats.total.fileCount += fileCount;\n stats.total.depCount += depCount;\n }\n return stats;\n}\n\nexport function isCacheExtractValid(\n baseBranchSha: string,\n configHash: string,\n cachedExtract?: BaseBranchCache,\n): boolean {\n if (!cachedExtract) {\n return false;\n }\n\n if (!cachedExtract.revision) {\n logger.debug('Cached extract is missing revision, so cannot be used');\n return false;\n }\n\n if (cachedExtract.revision !== EXTRACT_CACHE_REVISION) {\n logger.debug(\n `Extract cache revision has changed (old=${cachedExtract.revision}, new=${EXTRACT_CACHE_REVISION})`,\n );\n return false;\n }\n\n if (!(cachedExtract.sha && cachedExtract.configHash)) {\n return false;\n }\n if (cachedExtract.sha !== baseBranchSha) {\n logger.debug(\n `Cached extract result cannot be used due to base branch SHA change (old=${cachedExtract.sha}, new=${baseBranchSha})`,\n );\n return false;\n }\n if (cachedExtract.configHash !== configHash) {\n logger.debug('Cached extract result cannot be used due to config change');\n return false;\n }\n if (!cachedExtract.extractionFingerprints) {\n logger.debug(\n 'Cached extract is missing extractionFingerprints, so cannot be used',\n );\n return false;\n }\n const changedManagers = new Set();\n for (const [manager, fingerprint] of Object.entries(\n cachedExtract.extractionFingerprints,\n )) {\n if (fingerprint !== hashMap.get(manager)) {\n changedManagers.add(manager);\n }\n }\n if (changedManagers.size > 0) {\n logger.debug(\n { changedManagers: [...changedManagers] },\n 'Manager fingerprint(s) have changed, extract cache cannot be reused',\n );\n return false;\n }\n logger.debug(\n `Cached extract for sha=${baseBranchSha} is valid and can be used`,\n );\n return true;\n}\n\nexport async function extract(\n config: RenovateConfig,\n overwriteCache = true,\n): Promise<Record<string, PackageFile[]>> {\n logger.debug('extract()');\n const { baseBranch } = config;\n const baseBranchSha = await scm.getBranchCommit(baseBranch!);\n let packageFiles: Record<string, PackageFile[]>;\n const cache = getCache();\n cache.scan ??= {};\n const cachedExtract = cache.scan[baseBranch!];\n const configHash = instrument('fingerprint', () =>\n fingerprint(generateFingerprintConfig(config)),\n );\n // istanbul ignore if\n if (\n overwriteCache &&\n isCacheExtractValid(baseBranchSha!, configHash, cachedExtract)\n ) {\n packageFiles = cachedExtract.packageFiles;\n try {\n for (const files of Object.values(packageFiles)) {\n for (const file of files) {\n for (const dep of file.deps) {\n delete dep.updates;\n }\n }\n }\n logger.debug('Deleted cached dep updates');\n } catch (err) {\n logger.info({ err }, 'Error deleting cached dep updates');\n }\n } else {\n await instrument(\n 'checkoutBranch',\n async () => await scm.checkoutBranch(baseBranch!),\n );\n const extractResult = await instrument(\n 'extractAllDependencies',\n async () => (await extractAllDependencies(config)) || {},\n );\n packageFiles = extractResult.packageFiles;\n const { extractionFingerprints } = extractResult;\n\n if (overwriteCache) {\n // TODO: fix types (#22198)\n cache.scan[baseBranch!] = {\n revision: EXTRACT_CACHE_REVISION,\n sha: baseBranchSha!,\n configHash,\n extractionFingerprints,\n packageFiles,\n };\n }\n\n // Clean up cached branch extracts\n const baseBranches = isNonEmptyArray(config.baseBranches)\n ? config.baseBranches\n : [baseBranch];\n Object.keys(cache.scan).forEach((branchName) => {\n if (!baseBranches.includes(branchName)) {\n delete cache.scan![branchName];\n }\n });\n }\n const stats = extractStats(packageFiles);\n logger.info(\n { baseBranch: config.baseBranch, stats },\n `Dependency extraction complete`,\n );\n logger.trace({ config: packageFiles }, 'packageFiles');\n ensureGithubToken(packageFiles);\n return packageFiles;\n}\n\nasync function fetchVulnerabilities(\n config: RenovateConfig,\n packageFiles: Record<string, PackageFile[]>,\n): Promise<void> {\n if (config.osvVulnerabilityAlerts) {\n logger.debug('fetchVulnerabilities() - osvVulnerabilityAlerts=true');\n try {\n const vulnerabilities = await Vulnerabilities.create();\n await vulnerabilities.appendVulnerabilityPackageRules(\n config,\n packageFiles,\n );\n } catch (err) {\n logger.warn({ err }, 'Unable to read vulnerability information');\n }\n }\n}\n\nexport async function lookup(\n config: RenovateConfig,\n packageFiles: Record<string, PackageFile[]>,\n): Promise<ExtractResult> {\n await fetchVulnerabilities(config, packageFiles);\n await fetchUpdates(config, packageFiles);\n // call this twice, as the second time, the updates will be availalbe for malicious package checks\n // TODO: this will be refactored as part of #42423\n await fetchVulnerabilities(config, packageFiles);\n memCache.cleanDatasourceKeys();\n calculateLibYears(config, packageFiles);\n const { branches, branchList } = await branchifyUpgrades(\n config,\n packageFiles,\n );\n reportMaliciousSkippedDependencies(packageFiles);\n logger.debug(\n { baseBranch: config.baseBranch, config: packageFiles },\n 'packageFiles with updates',\n );\n sortBranches(branches);\n return { branches, branchList, packageFiles };\n}\n\nexport function reportMaliciousSkippedDependencies(\n allPackageFiles: Record<string, PackageFile<Record<string, any>>[]>,\n): void {\n if (allPackageFiles === undefined) {\n return;\n }\n\n for (const [manager, packageFiles] of Object.entries(allPackageFiles)) {\n for (const packageFile of packageFiles) {\n for (const dep of packageFile.deps) {\n if (dep.skipReason === 'malicious-version-in-use') {\n logger.warn(\n {\n packageFile: packageFile.packageFile,\n depName: dep.depName,\n packageName: dep.packageName,\n manager: manager,\n datasource: dep.datasource,\n },\n `Dependency ${dep.depName} is currently using a malicious version`,\n );\n\n // and make sure that it then gets updates proposed in the update phase\n delete dep.skipReason;\n delete dep.skipStage;\n } else if (dep.skipReason === 'malicious-update-proposed') {\n const newVersions = dep.updates\n ?.map((u) => u.newVersion ?? u.newValue)\n .filter(isNotNullOrUndefined);\n logger.warn(\n {\n packageFile: packageFile.packageFile,\n depName: dep.depName,\n packageName: dep.packageName,\n manager: manager,\n datasource: dep.datasource,\n newVersions,\n },\n `Dependency ${dep.depName} has update(s) proposed which would update you to a malicious version - skipping`,\n );\n }\n }\n }\n }\n}\n\nexport async function update(\n config: RenovateConfig,\n branches: BranchConfig[],\n): Promise<WriteUpdateResult | undefined> {\n let res: WriteUpdateResult | undefined;\n if (config.repoIsOnboarded) {\n res = await writeUpdates(config, branches);\n }\n\n return res;\n}\n"],"mappings":"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"}
|
|
@@ -105,6 +105,7 @@ var Vulnerabilities = class Vulnerabilities {
|
|
|
105
105
|
logger.trace(`Skipping withdrawn vulnerability ${osvVulnerability.id}`);
|
|
106
106
|
continue;
|
|
107
107
|
}
|
|
108
|
+
this.skipMaliciousPackages(ecosystem, packageName, depVersion, versioningApi, dep, packageFileConfig.manager, packageFileConfig.packageFile, osvVulnerability);
|
|
108
109
|
for (const affected of osvVulnerability.affected ?? []) {
|
|
109
110
|
if (!this.isPackageVulnerable(ecosystem, packageName, depVersion, affected, versioningApi)) continue;
|
|
110
111
|
logger.debug(`Vulnerability ${osvVulnerability.id} affects ${packageName} ${depVersion}`);
|
|
@@ -132,6 +133,38 @@ var Vulnerabilities = class Vulnerabilities {
|
|
|
132
133
|
return null;
|
|
133
134
|
}
|
|
134
135
|
}
|
|
136
|
+
skipMaliciousPackages(ecosystem, packageName, depVersion, versioningApi, dep, manager, packageFile, osvVulnerability) {
|
|
137
|
+
if (osvVulnerability.id.startsWith("MAL-")) for (const affected of osvVulnerability.affected ?? []) {
|
|
138
|
+
if (this.isPackageVulnerable(ecosystem, packageName, depVersion, affected, versioningApi)) {
|
|
139
|
+
logger.debug({
|
|
140
|
+
packageFile,
|
|
141
|
+
depName: dep.depName,
|
|
142
|
+
packageName: dep.packageName,
|
|
143
|
+
manager,
|
|
144
|
+
datasource: dep.datasource,
|
|
145
|
+
currentVersion: depVersion
|
|
146
|
+
}, `Marking ${dep.depName} as skipReason=malicious-version-in-use, as it is affected by ${osvVulnerability.id}`);
|
|
147
|
+
dep.skipReason = "malicious-version-in-use";
|
|
148
|
+
dep.skipStage = "lookup";
|
|
149
|
+
}
|
|
150
|
+
for (const update of dep.updates ?? []) {
|
|
151
|
+
const newVersion = update.newVersion ?? update.newValue;
|
|
152
|
+
if (this.isPackageVulnerable(ecosystem, packageName, newVersion, affected, versioningApi)) {
|
|
153
|
+
logger.debug({
|
|
154
|
+
packageFile,
|
|
155
|
+
depName: dep.depName,
|
|
156
|
+
packageName: dep.packageName,
|
|
157
|
+
manager,
|
|
158
|
+
datasource: dep.datasource,
|
|
159
|
+
currentVersion: depVersion,
|
|
160
|
+
newVersion
|
|
161
|
+
}, `Marking ${dep.depName}'s update to ${newVersion} as skipReason=malicious-update-proposed, as it is affected by ${osvVulnerability.id}`);
|
|
162
|
+
dep.skipReason = "malicious-update-proposed";
|
|
163
|
+
dep.skipStage = "lookup";
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
135
168
|
sortByFixedVersion(packageRules, versioningApi) {
|
|
136
169
|
const versionsCleaned = {};
|
|
137
170
|
for (const rule of packageRules) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vulnerabilities.js","names":["p.all","getVersioning"],"sources":["../../../../lib/workers/repository/process/vulnerabilities.ts"],"sourcesContent":["// TODO #22198\nimport type { Ecosystem, Osv } from '@renovatebot/osv-offline';\nimport { OsvOffline } from '@renovatebot/osv-offline';\nimport {\n isEmptyArray,\n isNonEmptyString,\n isNullOrUndefined,\n isTruthy,\n} from '@sindresorhus/is';\nimport type { CvssVector } from 'ae-cvss-calculator';\nimport * as _aeCvss from 'ae-cvss-calculator';\nimport { z } from 'zod/v3';\nimport { getManagerConfig, mergeChildConfig } from '../../../config/index.ts';\nimport type { PackageRule, RenovateConfig } from '../../../config/types.ts';\nimport { instrument } from '../../../instrumentation/index.ts';\nimport { logger } from '../../../logger/index.ts';\nimport { getDefaultVersioning } from '../../../modules/datasource/common.ts';\nimport type {\n PackageDependency,\n PackageFile,\n} from '../../../modules/manager/types.ts';\nimport type { VersioningApi } from '../../../modules/versioning/index.ts';\nimport { get as getVersioning } from '../../../modules/versioning/index.ts';\nimport { sanitizeMarkdown } from '../../../util/markdown.ts';\nimport * as p from '../../../util/promises.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport { titleCase } from '../../../util/string.ts';\nimport { datasourceToOsvEcosystem } from '../../../util/vulnerability/ecosystem.ts';\nimport {\n getFixedVersionConstraint,\n getLastAffectedVersionConstraint,\n} from '../../../util/vulnerability/utils.ts';\nimport type {\n DependencyVulnerabilities,\n SeverityDetails,\n Vulnerability,\n} from './types.ts';\n\nconst { fromVector } = (_aeCvss as unknown as { default: typeof _aeCvss })\n .default;\n\nexport class Vulnerabilities {\n private static osvOffline: Promise<OsvOffline> | undefined;\n\n private osvOffline: OsvOffline;\n\n private static readonly datasourceEcosystemMap = datasourceToOsvEcosystem;\n\n private constructor(osvOffline: OsvOffline) {\n this.osvOffline = osvOffline;\n }\n\n private static initialize(): Promise<OsvOffline> {\n // no async here, so osv promise will only be created once\n Vulnerabilities.osvOffline ??= OsvOffline.create();\n return Vulnerabilities.osvOffline;\n }\n\n static async create(): Promise<Vulnerabilities> {\n // intialize osv only once\n const osvOffline = await Vulnerabilities.initialize();\n\n const instance = new Vulnerabilities(osvOffline);\n return instance;\n }\n\n async appendVulnerabilityPackageRules(\n config: RenovateConfig,\n packageFiles: Record<string, PackageFile[]>,\n ): Promise<void> {\n const dependencyVulnerabilities = await this.fetchDependencyVulnerabilities(\n config,\n packageFiles,\n );\n\n config.packageRules ??= [];\n for (const {\n vulnerabilities,\n versioningApi,\n } of dependencyVulnerabilities) {\n const groupPackageRules: PackageRule[] = [];\n for (const vulnerability of vulnerabilities) {\n const rule = this.vulnerabilityToPackageRules(vulnerability);\n if (isNullOrUndefined(rule)) {\n continue;\n }\n groupPackageRules.push(rule);\n }\n this.sortByFixedVersion(groupPackageRules, versioningApi);\n\n config.packageRules.push(...groupPackageRules);\n }\n }\n\n async fetchVulnerabilities(\n config: RenovateConfig,\n packageFiles: Record<string, PackageFile[]>,\n ): Promise<Vulnerability[]> {\n const groups = await this.fetchDependencyVulnerabilities(\n config,\n packageFiles,\n );\n return groups.flatMap((group) => group.vulnerabilities);\n }\n\n private async fetchDependencyVulnerabilities(\n config: RenovateConfig,\n packageFiles: Record<string, PackageFile[]>,\n ): Promise<DependencyVulnerabilities[]> {\n const managers = Object.keys(packageFiles);\n const allManagerJobs = managers.map((manager) =>\n this.fetchManagerVulnerabilities(config, packageFiles, manager),\n );\n return (await Promise.all(allManagerJobs)).flat();\n }\n\n private async fetchManagerVulnerabilities(\n config: RenovateConfig,\n packageFiles: Record<string, PackageFile[]>,\n manager: string,\n ): Promise<DependencyVulnerabilities[]> {\n const managerConfig = getManagerConfig(config, manager);\n const queue = packageFiles[manager].map(\n (pFile) => (): Promise<DependencyVulnerabilities[]> =>\n this.fetchManagerPackageFileVulnerabilities(managerConfig, pFile),\n );\n logger.trace(\n { manager, queueLength: queue.length },\n 'fetchManagerVulnerabilities starting',\n );\n const result = (await p.all(queue)).flat();\n logger.trace({ manager }, 'fetchManagerVulnerabilities finished');\n return result;\n }\n\n private async fetchManagerPackageFileVulnerabilities(\n managerConfig: RenovateConfig,\n pFile: PackageFile,\n ): Promise<DependencyVulnerabilities[]> {\n const { packageFile } = pFile;\n const packageFileConfig = mergeChildConfig(managerConfig, pFile);\n const { manager } = packageFileConfig;\n const queue = pFile.deps.map(\n (dep) => (): Promise<DependencyVulnerabilities | null> =>\n this.fetchDependencyVulnerability(packageFileConfig, dep),\n );\n logger.trace(\n { manager, packageFile, queueLength: queue.length },\n 'fetchManagerPackageFileVulnerabilities starting with concurrency',\n );\n\n const result = await p.all(queue);\n logger.trace(\n { packageFile },\n 'fetchManagerPackageFileVulnerabilities finished',\n );\n\n return result.filter(isTruthy);\n }\n\n private async fetchDependencyVulnerability(\n packageFileConfig: RenovateConfig & PackageFile,\n dep: PackageDependency,\n ): Promise<DependencyVulnerabilities | null> {\n const ecosystem = Vulnerabilities.datasourceEcosystemMap[dep.datasource!];\n if (!ecosystem) {\n logger.trace(`Cannot map datasource ${dep.datasource!} to OSV ecosystem`);\n return null;\n }\n\n let packageName = dep.packageName ?? dep.depName!;\n if (ecosystem === 'PyPI') {\n // https://peps.python.org/pep-0503/#normalized-names\n packageName = packageName.toLowerCase().replace(regEx(/[_.-]+/g), '-');\n }\n\n try {\n const osvVulnerabilities = await instrument(\n 'get OSV vulnerabilities',\n () => this.osvOffline.getVulnerabilities(ecosystem, packageName),\n {\n attributes: {\n packageName,\n ecosystem,\n },\n },\n );\n if (\n isNullOrUndefined(osvVulnerabilities) ||\n isEmptyArray(osvVulnerabilities)\n ) {\n logger.trace(\n `No vulnerabilities found in OSV database for ${packageName}`,\n );\n return null;\n }\n\n const depVersion =\n dep.lockedVersion ?? dep.currentVersion ?? dep.currentValue!;\n\n const versioning = dep.versioning ?? getDefaultVersioning(dep.datasource);\n const versioningApi = getVersioning(versioning);\n\n if (!versioningApi.isVersion(depVersion)) {\n logger.debug(\n `Skipping vulnerability lookup for package ${packageName} due to unsupported version ${depVersion}`,\n );\n return null;\n }\n\n const vulnerabilities: Vulnerability[] = [];\n for (const osvVulnerability of osvVulnerabilities) {\n if (osvVulnerability.withdrawn) {\n logger.trace(\n `Skipping withdrawn vulnerability ${osvVulnerability.id}`,\n );\n continue;\n }\n\n for (const affected of osvVulnerability.affected ?? []) {\n const isVulnerable = this.isPackageVulnerable(\n ecosystem,\n packageName,\n depVersion,\n affected,\n versioningApi,\n );\n if (!isVulnerable) {\n continue;\n }\n\n logger.debug(\n `Vulnerability ${osvVulnerability.id} affects ${packageName} ${depVersion}`,\n );\n const fixedVersion = this.getFixedVersion(\n ecosystem,\n depVersion,\n affected,\n versioningApi,\n );\n\n vulnerabilities.push({\n packageName,\n vulnerability: osvVulnerability,\n affected,\n depVersion,\n fixedVersion,\n datasource: dep.datasource!,\n packageFileConfig,\n });\n }\n }\n\n return { vulnerabilities, versioningApi };\n } catch (err) {\n logger.warn(\n { err, packageName },\n 'Error fetching vulnerability information for package',\n );\n return null;\n }\n }\n\n private sortByFixedVersion(\n packageRules: PackageRule[],\n versioningApi: VersioningApi,\n ): void {\n const versionsCleaned: Record<string, string> = {};\n for (const rule of packageRules) {\n const version = rule.allowedVersions!;\n versionsCleaned[version] = version.replace(regEx(/[(),=> ]+/g), '');\n }\n packageRules.sort((a, b) =>\n versioningApi.sortVersions(\n versionsCleaned[a.allowedVersions!],\n versionsCleaned[b.allowedVersions!],\n ),\n );\n }\n\n // https://ossf.github.io/osv-schema/#affectedrangesevents-fields\n private sortEvents(\n events: Osv.Event[],\n versioningApi: VersioningApi,\n ): Osv.Event[] {\n const sortedCopy: Osv.Event[] = [];\n let zeroEvent: Osv.Event | null = null;\n\n for (const event of events) {\n if (event.introduced === '0') {\n zeroEvent = event;\n } else if (versioningApi.isVersion(Object.values(event)[0])) {\n sortedCopy.push(event);\n } else {\n logger.debug({ event }, 'Skipping OSV event with invalid version');\n }\n }\n\n sortedCopy.sort((a, b) =>\n // no pre-processing, as there are only very few values to sort\n versioningApi.sortVersions(Object.values(a)[0], Object.values(b)[0]),\n );\n\n if (zeroEvent) {\n sortedCopy.unshift(zeroEvent);\n }\n\n return sortedCopy;\n }\n\n private isPackageAffected(\n ecosystem: Ecosystem,\n packageName: string,\n affected: Osv.Affected,\n ): boolean {\n return (\n affected.package?.name === packageName &&\n affected.package?.ecosystem === ecosystem\n );\n }\n\n private includedInVersions(\n depVersion: string,\n affected: Osv.Affected,\n ): boolean {\n return !!affected.versions?.includes(depVersion);\n }\n\n private includedInRanges(\n depVersion: string,\n affected: Osv.Affected,\n versioningApi: VersioningApi,\n ): boolean {\n for (const range of affected.ranges ?? []) {\n if (range.type === 'GIT') {\n continue;\n }\n\n let vulnerable = false;\n for (const event of this.sortEvents(range.events, versioningApi)) {\n if (\n isNonEmptyString(event.introduced) &&\n (event.introduced === '0' ||\n this.isVersionGtOrEq(depVersion, event.introduced, versioningApi))\n ) {\n vulnerable = true;\n } else if (\n isNonEmptyString(event.fixed) &&\n this.isVersionGtOrEq(depVersion, event.fixed, versioningApi)\n ) {\n vulnerable = false;\n } else if (\n isNonEmptyString(event.last_affected) &&\n this.isVersionGt(depVersion, event.last_affected, versioningApi)\n ) {\n vulnerable = false;\n }\n }\n\n if (vulnerable) {\n return true;\n }\n }\n\n return false;\n }\n\n // https://ossf.github.io/osv-schema/#evaluation\n private isPackageVulnerable(\n ecosystem: Ecosystem,\n packageName: string,\n depVersion: string,\n affected: Osv.Affected,\n versioningApi: VersioningApi,\n ): boolean {\n return (\n this.isPackageAffected(ecosystem, packageName, affected) &&\n (this.includedInVersions(depVersion, affected) ||\n this.includedInRanges(depVersion, affected, versioningApi))\n );\n }\n\n private getFixedVersion(\n ecosystem: Ecosystem,\n depVersion: string,\n affected: Osv.Affected,\n versioningApi: VersioningApi,\n ): string | null {\n const fixedVersions: string[] = [];\n const lastAffectedVersions: string[] = [];\n\n for (const range of affected.ranges ?? []) {\n if (range.type === 'GIT') {\n continue;\n }\n\n for (const event of range.events) {\n if (\n isNonEmptyString(event.fixed) &&\n versioningApi.isVersion(event.fixed)\n ) {\n fixedVersions.push(event.fixed);\n } else if (\n isNonEmptyString(event.last_affected) &&\n versioningApi.isVersion(event.last_affected)\n ) {\n lastAffectedVersions.push(event.last_affected);\n }\n }\n }\n\n fixedVersions.sort((a, b) => versioningApi.sortVersions(a, b));\n const fixedVersion = fixedVersions.find((version) =>\n this.isVersionGt(version, depVersion, versioningApi),\n );\n if (fixedVersion) {\n return this.getFixedVersionByEcosystem(fixedVersion, ecosystem);\n }\n\n lastAffectedVersions.sort((a, b) => versioningApi.sortVersions(a, b));\n const lastAffected = lastAffectedVersions.find((version) =>\n this.isVersionGtOrEq(version, depVersion, versioningApi),\n );\n if (lastAffected) {\n return this.getLastAffectedByEcosystem(lastAffected, ecosystem);\n }\n\n return null;\n }\n\n private getFixedVersionByEcosystem(\n fixedVersion: string,\n ecosystem: Ecosystem,\n ): string {\n return getFixedVersionConstraint(fixedVersion, ecosystem);\n }\n\n private getLastAffectedByEcosystem(\n lastAffected: string,\n ecosystem: Ecosystem,\n ): string {\n return getLastAffectedVersionConstraint(lastAffected, ecosystem);\n }\n\n private isVersionGt(\n version: string,\n other: string,\n versioningApi: VersioningApi,\n ): boolean {\n return (\n versioningApi.isVersion(version) &&\n versioningApi.isVersion(other) &&\n versioningApi.isGreaterThan(version, other)\n );\n }\n\n private isVersionGtOrEq(\n version: string,\n other: string,\n versioningApi: VersioningApi,\n ): boolean {\n return (\n versioningApi.isVersion(version) &&\n versioningApi.isVersion(other) &&\n (versioningApi.equals(version, other) ||\n versioningApi.isGreaterThan(version, other))\n );\n }\n\n private vulnerabilityToPackageRules(vul: Vulnerability): PackageRule | null {\n const {\n vulnerability,\n affected,\n packageName,\n depVersion,\n fixedVersion,\n datasource,\n packageFileConfig,\n } = vul;\n if (isNullOrUndefined(fixedVersion)) {\n logger.debug(\n `No fixed version available for vulnerability ${vulnerability.id} in ${packageName} ${depVersion}`,\n );\n return null;\n }\n\n logger.debug(\n `Setting allowed version ${fixedVersion} to fix vulnerability ${vulnerability.id} in ${packageName} ${depVersion}`,\n );\n\n const severityDetails = this.extractSeverityDetails(\n vulnerability,\n affected,\n );\n\n return {\n matchDatasources: [datasource],\n matchPackageNames: [packageName],\n matchCurrentVersion: depVersion,\n allowedVersions: fixedVersion,\n isVulnerabilityAlert: true,\n vulnerabilitySeverity: severityDetails.severityLevel,\n prBodyNotes: this.generatePrBodyNotes(vulnerability, affected),\n force: {\n ...packageFileConfig.vulnerabilityAlerts,\n },\n };\n }\n\n static evaluateCvssVector(vector: string): [string, string] {\n const CvssJsonSchema = z.object({\n baseScore: z.number().default(0.0),\n baseSeverity: z.string().toUpperCase().default('UNKNOWN'),\n });\n\n try {\n const parsedCvssScore: CvssVector<any> | null = fromVector(vector);\n const res = CvssJsonSchema.parse(parsedCvssScore?.createJsonSchema());\n\n return [res.baseScore.toFixed(1), res.baseSeverity];\n } catch {\n logger.debug(`Error processing CVSS vector ${vector}`);\n }\n\n return ['', ''];\n }\n\n private generatePrBodyNotes(\n vulnerability: Osv.Vulnerability,\n affected: Osv.Affected,\n ): string[] {\n let aliases = [vulnerability.id].concat(vulnerability.aliases ?? []).sort();\n aliases = aliases.map((id) => {\n if (id.startsWith('CVE-')) {\n return `[${id}](https://nvd.nist.gov/vuln/detail/${id})`;\n } else if (id.startsWith('GHSA-')) {\n return `[${id}](https://github.com/advisories/${id})`;\n } else if (id.startsWith('GO-')) {\n return `[${id}](https://pkg.go.dev/vuln/${id})`;\n } else if (id.startsWith('RUSTSEC-')) {\n return `[${id}](https://rustsec.org/advisories/${id}.html)`;\n }\n\n return id;\n });\n\n let content = '\\n\\n---\\n\\n### ';\n content += vulnerability.summary ? `${vulnerability.summary}\\n` : '';\n content += `${aliases.join(' / ')}\\n`;\n content += `\\n<details>\\n<summary>More information</summary>\\n`;\n\n const details = vulnerability.details?.replace(\n regEx(/^#{1,4} /gm),\n '##### ',\n );\n content += `#### Details\\n${details ?? 'No details.'}\\n`;\n\n content += '#### Severity\\n';\n const severityDetails = this.extractSeverityDetails(\n vulnerability,\n affected,\n );\n\n if (severityDetails.cvssVector) {\n content += `- CVSS Score: ${severityDetails.score}\\n`;\n content += `- Vector String: \\`${severityDetails.cvssVector}\\`\\n`;\n } else {\n content += `${titleCase(severityDetails.severityLevel)}\\n`;\n }\n\n content += `\\n#### References\\n${\n vulnerability.references\n ?.map((ref) => {\n return `- [${ref.url}](${ref.url})`;\n })\n .join('\\n') ?? 'No references.'\n }`;\n\n let attribution = '';\n if (vulnerability.id.startsWith('GHSA-')) {\n attribution = ` and the [GitHub Advisory Database](https://github.com/github/advisory-database) ([CC-BY 4.0](https://github.com/github/advisory-database/blob/main/LICENSE.md))`;\n } else if (vulnerability.id.startsWith('GO-')) {\n attribution = ` and the [Go Vulnerability Database](https://github.com/golang/vulndb) ([CC-BY 4.0](https://github.com/golang/vulndb#license))`;\n } else if (vulnerability.id.startsWith('PYSEC-')) {\n attribution = ` and the [PyPI Advisory Database](https://github.com/pypa/advisory-database) ([CC-BY 4.0](https://github.com/pypa/advisory-database/blob/main/LICENSE))`;\n } else if (vulnerability.id.startsWith('RUSTSEC-')) {\n attribution = ` and the [Rust Advisory Database](https://github.com/RustSec/advisory-db) ([CC0 1.0](https://github.com/rustsec/advisory-db/blob/main/LICENSE.txt))`;\n }\n content += `\\n\\nThis data is provided by [OSV](https://osv.dev/vulnerability/${vulnerability.id})${attribution}.\\n`;\n content += `</details>`;\n\n return [sanitizeMarkdown(content)];\n }\n\n private extractSeverityDetails(\n vulnerability: Osv.Vulnerability,\n affected: Osv.Affected,\n ): SeverityDetails {\n let severityLevel = 'UNKNOWN';\n let score = 'Unknown';\n\n const cvssVector =\n vulnerability.severity?.find((e) => e.type === 'CVSS_V4')?.score ??\n vulnerability.severity?.find((e) => e.type === 'CVSS_V3')?.score ??\n (affected.database_specific?.cvss as string); // RUSTSEC\n\n if (cvssVector) {\n const [baseScore, severity] =\n Vulnerabilities.evaluateCvssVector(cvssVector);\n severityLevel = severity ? severity.toUpperCase() : 'UNKNOWN';\n score = baseScore\n ? `${baseScore} / 10 (${titleCase(severityLevel)})`\n : 'Unknown';\n } else if (\n vulnerability.id.startsWith('GHSA-') &&\n vulnerability.database_specific?.severity\n ) {\n const severity = vulnerability.database_specific.severity as string;\n severityLevel = severity.toUpperCase();\n }\n\n return {\n cvssVector,\n score,\n severityLevel,\n };\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"vulnerabilities.js","names":["p.all","getVersioning"],"sources":["../../../../lib/workers/repository/process/vulnerabilities.ts"],"sourcesContent":["// TODO #22198\nimport type { Ecosystem, Osv } from '@renovatebot/osv-offline';\nimport { OsvOffline } from '@renovatebot/osv-offline';\nimport {\n isEmptyArray,\n isNonEmptyString,\n isNullOrUndefined,\n isTruthy,\n} from '@sindresorhus/is';\nimport type { CvssVector } from 'ae-cvss-calculator';\nimport * as _aeCvss from 'ae-cvss-calculator';\nimport { z } from 'zod/v3';\nimport { getManagerConfig, mergeChildConfig } from '../../../config/index.ts';\nimport type { PackageRule, RenovateConfig } from '../../../config/types.ts';\nimport { instrument } from '../../../instrumentation/index.ts';\nimport { logger } from '../../../logger/index.ts';\nimport { getDefaultVersioning } from '../../../modules/datasource/common.ts';\nimport type {\n PackageDependency,\n PackageFile,\n} from '../../../modules/manager/types.ts';\nimport type { VersioningApi } from '../../../modules/versioning/index.ts';\nimport { get as getVersioning } from '../../../modules/versioning/index.ts';\nimport { sanitizeMarkdown } from '../../../util/markdown.ts';\nimport * as p from '../../../util/promises.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport { titleCase } from '../../../util/string.ts';\nimport { datasourceToOsvEcosystem } from '../../../util/vulnerability/ecosystem.ts';\nimport {\n getFixedVersionConstraint,\n getLastAffectedVersionConstraint,\n} from '../../../util/vulnerability/utils.ts';\nimport type {\n DependencyVulnerabilities,\n SeverityDetails,\n Vulnerability,\n} from './types.ts';\n\nconst { fromVector } = (_aeCvss as unknown as { default: typeof _aeCvss })\n .default;\n\nexport class Vulnerabilities {\n private static osvOffline: Promise<OsvOffline> | undefined;\n\n private osvOffline: OsvOffline;\n\n private static readonly datasourceEcosystemMap = datasourceToOsvEcosystem;\n\n private constructor(osvOffline: OsvOffline) {\n this.osvOffline = osvOffline;\n }\n\n private static initialize(): Promise<OsvOffline> {\n // no async here, so osv promise will only be created once\n Vulnerabilities.osvOffline ??= OsvOffline.create();\n return Vulnerabilities.osvOffline;\n }\n\n static async create(): Promise<Vulnerabilities> {\n // intialize osv only once\n const osvOffline = await Vulnerabilities.initialize();\n\n const instance = new Vulnerabilities(osvOffline);\n return instance;\n }\n\n async appendVulnerabilityPackageRules(\n config: RenovateConfig,\n packageFiles: Record<string, PackageFile[]>,\n ): Promise<void> {\n const dependencyVulnerabilities = await this.fetchDependencyVulnerabilities(\n config,\n packageFiles,\n );\n\n config.packageRules ??= [];\n for (const {\n vulnerabilities,\n versioningApi,\n } of dependencyVulnerabilities) {\n const groupPackageRules: PackageRule[] = [];\n for (const vulnerability of vulnerabilities) {\n const rule = this.vulnerabilityToPackageRules(vulnerability);\n if (isNullOrUndefined(rule)) {\n continue;\n }\n groupPackageRules.push(rule);\n }\n this.sortByFixedVersion(groupPackageRules, versioningApi);\n\n config.packageRules.push(...groupPackageRules);\n }\n }\n\n async fetchVulnerabilities(\n config: RenovateConfig,\n packageFiles: Record<string, PackageFile[]>,\n ): Promise<Vulnerability[]> {\n const groups = await this.fetchDependencyVulnerabilities(\n config,\n packageFiles,\n );\n return groups.flatMap((group) => group.vulnerabilities);\n }\n\n private async fetchDependencyVulnerabilities(\n config: RenovateConfig,\n packageFiles: Record<string, PackageFile[]>,\n ): Promise<DependencyVulnerabilities[]> {\n const managers = Object.keys(packageFiles);\n const allManagerJobs = managers.map((manager) =>\n this.fetchManagerVulnerabilities(config, packageFiles, manager),\n );\n return (await Promise.all(allManagerJobs)).flat();\n }\n\n private async fetchManagerVulnerabilities(\n config: RenovateConfig,\n packageFiles: Record<string, PackageFile[]>,\n manager: string,\n ): Promise<DependencyVulnerabilities[]> {\n const managerConfig = getManagerConfig(config, manager);\n const queue = packageFiles[manager].map(\n (pFile) => (): Promise<DependencyVulnerabilities[]> =>\n this.fetchManagerPackageFileVulnerabilities(managerConfig, pFile),\n );\n logger.trace(\n { manager, queueLength: queue.length },\n 'fetchManagerVulnerabilities starting',\n );\n const result = (await p.all(queue)).flat();\n logger.trace({ manager }, 'fetchManagerVulnerabilities finished');\n return result;\n }\n\n private async fetchManagerPackageFileVulnerabilities(\n managerConfig: RenovateConfig,\n pFile: PackageFile,\n ): Promise<DependencyVulnerabilities[]> {\n const { packageFile } = pFile;\n const packageFileConfig = mergeChildConfig(managerConfig, pFile);\n const { manager } = packageFileConfig;\n const queue = pFile.deps.map(\n (dep) => (): Promise<DependencyVulnerabilities | null> =>\n this.fetchDependencyVulnerability(packageFileConfig, dep),\n );\n logger.trace(\n { manager, packageFile, queueLength: queue.length },\n 'fetchManagerPackageFileVulnerabilities starting with concurrency',\n );\n\n const result = await p.all(queue);\n logger.trace(\n { packageFile },\n 'fetchManagerPackageFileVulnerabilities finished',\n );\n\n return result.filter(isTruthy);\n }\n\n private async fetchDependencyVulnerability(\n packageFileConfig: RenovateConfig & PackageFile,\n dep: PackageDependency,\n ): Promise<DependencyVulnerabilities | null> {\n const ecosystem = Vulnerabilities.datasourceEcosystemMap[dep.datasource!];\n if (!ecosystem) {\n logger.trace(`Cannot map datasource ${dep.datasource!} to OSV ecosystem`);\n return null;\n }\n\n let packageName = dep.packageName ?? dep.depName!;\n if (ecosystem === 'PyPI') {\n // https://peps.python.org/pep-0503/#normalized-names\n packageName = packageName.toLowerCase().replace(regEx(/[_.-]+/g), '-');\n }\n\n try {\n const osvVulnerabilities = await instrument(\n 'get OSV vulnerabilities',\n () => this.osvOffline.getVulnerabilities(ecosystem, packageName),\n {\n attributes: {\n packageName,\n ecosystem,\n },\n },\n );\n if (\n isNullOrUndefined(osvVulnerabilities) ||\n isEmptyArray(osvVulnerabilities)\n ) {\n logger.trace(\n `No vulnerabilities found in OSV database for ${packageName}`,\n );\n return null;\n }\n\n const depVersion =\n dep.lockedVersion ?? dep.currentVersion ?? dep.currentValue!;\n\n const versioning = dep.versioning ?? getDefaultVersioning(dep.datasource);\n const versioningApi = getVersioning(versioning);\n\n if (!versioningApi.isVersion(depVersion)) {\n logger.debug(\n `Skipping vulnerability lookup for package ${packageName} due to unsupported version ${depVersion}`,\n );\n return null;\n }\n\n const vulnerabilities: Vulnerability[] = [];\n for (const osvVulnerability of osvVulnerabilities) {\n if (osvVulnerability.withdrawn) {\n logger.trace(\n `Skipping withdrawn vulnerability ${osvVulnerability.id}`,\n );\n continue;\n }\n\n this.skipMaliciousPackages(\n ecosystem,\n packageName,\n depVersion,\n versioningApi,\n dep,\n packageFileConfig.manager,\n packageFileConfig.packageFile,\n osvVulnerability,\n );\n\n for (const affected of osvVulnerability.affected ?? []) {\n const isVulnerable = this.isPackageVulnerable(\n ecosystem,\n packageName,\n depVersion,\n affected,\n versioningApi,\n );\n if (!isVulnerable) {\n continue;\n }\n\n logger.debug(\n `Vulnerability ${osvVulnerability.id} affects ${packageName} ${depVersion}`,\n );\n const fixedVersion = this.getFixedVersion(\n ecosystem,\n depVersion,\n affected,\n versioningApi,\n );\n\n vulnerabilities.push({\n packageName,\n vulnerability: osvVulnerability,\n affected,\n depVersion,\n fixedVersion,\n datasource: dep.datasource!,\n packageFileConfig,\n });\n }\n }\n\n return { vulnerabilities, versioningApi };\n } catch (err) {\n logger.warn(\n { err, packageName },\n 'Error fetching vulnerability information for package',\n );\n return null;\n }\n }\n\n private skipMaliciousPackages(\n ecosystem: Ecosystem,\n packageName: string,\n depVersion: string,\n versioningApi: VersioningApi,\n dep: PackageDependency,\n manager: string | undefined,\n packageFile: string,\n osvVulnerability: Osv.Vulnerability,\n ): void {\n // the OpenSSF's Malicious Packages (https://github.com/ossf/malicious-packages) is a source of advisories through osv.dev, which takes various sources of advisories, and will re-publish them with more specific information about their malicious usage\n if (osvVulnerability.id.startsWith('MAL-')) {\n // is the current dependency vulnerable?\n for (const affected of osvVulnerability.affected ?? []) {\n // is the current dependency vulnerable?\n const isVulnerable = this.isPackageVulnerable(\n ecosystem,\n packageName,\n depVersion,\n affected,\n versioningApi,\n );\n\n if (isVulnerable) {\n logger.debug(\n {\n packageFile: packageFile,\n depName: dep.depName,\n packageName: dep.packageName,\n manager: manager,\n datasource: dep.datasource,\n currentVersion: depVersion,\n },\n `Marking ${dep.depName} as skipReason=malicious-version-in-use, as it is affected by ${osvVulnerability.id}`,\n );\n dep.skipReason = 'malicious-version-in-use';\n dep.skipStage = 'lookup';\n }\n\n // or are any of the updates vulnerable?\n for (const update of dep.updates ?? []) {\n const newVersion = update.newVersion ?? update.newValue!;\n\n const isUpdateVulnerable = this.isPackageVulnerable(\n ecosystem,\n packageName,\n newVersion,\n affected,\n versioningApi,\n );\n\n if (isUpdateVulnerable) {\n logger.debug(\n {\n packageFile: packageFile,\n depName: dep.depName,\n packageName: dep.packageName,\n manager: manager,\n datasource: dep.datasource,\n currentVersion: depVersion,\n newVersion,\n },\n `Marking ${dep.depName}'s update to ${newVersion} as skipReason=malicious-update-proposed, as it is affected by ${osvVulnerability.id}`,\n );\n dep.skipReason = 'malicious-update-proposed';\n dep.skipStage = 'lookup';\n }\n }\n }\n }\n }\n\n private sortByFixedVersion(\n packageRules: PackageRule[],\n versioningApi: VersioningApi,\n ): void {\n const versionsCleaned: Record<string, string> = {};\n for (const rule of packageRules) {\n const version = rule.allowedVersions!;\n versionsCleaned[version] = version.replace(regEx(/[(),=> ]+/g), '');\n }\n packageRules.sort((a, b) =>\n versioningApi.sortVersions(\n versionsCleaned[a.allowedVersions!],\n versionsCleaned[b.allowedVersions!],\n ),\n );\n }\n\n // https://ossf.github.io/osv-schema/#affectedrangesevents-fields\n private sortEvents(\n events: Osv.Event[],\n versioningApi: VersioningApi,\n ): Osv.Event[] {\n const sortedCopy: Osv.Event[] = [];\n let zeroEvent: Osv.Event | null = null;\n\n for (const event of events) {\n if (event.introduced === '0') {\n zeroEvent = event;\n } else if (versioningApi.isVersion(Object.values(event)[0])) {\n sortedCopy.push(event);\n } else {\n logger.debug({ event }, 'Skipping OSV event with invalid version');\n }\n }\n\n sortedCopy.sort((a, b) =>\n // no pre-processing, as there are only very few values to sort\n versioningApi.sortVersions(Object.values(a)[0], Object.values(b)[0]),\n );\n\n if (zeroEvent) {\n sortedCopy.unshift(zeroEvent);\n }\n\n return sortedCopy;\n }\n\n private isPackageAffected(\n ecosystem: Ecosystem,\n packageName: string,\n affected: Osv.Affected,\n ): boolean {\n return (\n affected.package?.name === packageName &&\n affected.package?.ecosystem === ecosystem\n );\n }\n\n private includedInVersions(\n depVersion: string,\n affected: Osv.Affected,\n ): boolean {\n return !!affected.versions?.includes(depVersion);\n }\n\n private includedInRanges(\n depVersion: string,\n affected: Osv.Affected,\n versioningApi: VersioningApi,\n ): boolean {\n for (const range of affected.ranges ?? []) {\n if (range.type === 'GIT') {\n continue;\n }\n\n let vulnerable = false;\n for (const event of this.sortEvents(range.events, versioningApi)) {\n if (\n isNonEmptyString(event.introduced) &&\n (event.introduced === '0' ||\n this.isVersionGtOrEq(depVersion, event.introduced, versioningApi))\n ) {\n vulnerable = true;\n } else if (\n isNonEmptyString(event.fixed) &&\n this.isVersionGtOrEq(depVersion, event.fixed, versioningApi)\n ) {\n vulnerable = false;\n } else if (\n isNonEmptyString(event.last_affected) &&\n this.isVersionGt(depVersion, event.last_affected, versioningApi)\n ) {\n vulnerable = false;\n }\n }\n\n if (vulnerable) {\n return true;\n }\n }\n\n return false;\n }\n\n // https://ossf.github.io/osv-schema/#evaluation\n private isPackageVulnerable(\n ecosystem: Ecosystem,\n packageName: string,\n depVersion: string,\n affected: Osv.Affected,\n versioningApi: VersioningApi,\n ): boolean {\n return (\n this.isPackageAffected(ecosystem, packageName, affected) &&\n (this.includedInVersions(depVersion, affected) ||\n this.includedInRanges(depVersion, affected, versioningApi))\n );\n }\n\n private getFixedVersion(\n ecosystem: Ecosystem,\n depVersion: string,\n affected: Osv.Affected,\n versioningApi: VersioningApi,\n ): string | null {\n const fixedVersions: string[] = [];\n const lastAffectedVersions: string[] = [];\n\n for (const range of affected.ranges ?? []) {\n if (range.type === 'GIT') {\n continue;\n }\n\n for (const event of range.events) {\n if (\n isNonEmptyString(event.fixed) &&\n versioningApi.isVersion(event.fixed)\n ) {\n fixedVersions.push(event.fixed);\n } else if (\n isNonEmptyString(event.last_affected) &&\n versioningApi.isVersion(event.last_affected)\n ) {\n lastAffectedVersions.push(event.last_affected);\n }\n }\n }\n\n fixedVersions.sort((a, b) => versioningApi.sortVersions(a, b));\n const fixedVersion = fixedVersions.find((version) =>\n this.isVersionGt(version, depVersion, versioningApi),\n );\n if (fixedVersion) {\n return this.getFixedVersionByEcosystem(fixedVersion, ecosystem);\n }\n\n lastAffectedVersions.sort((a, b) => versioningApi.sortVersions(a, b));\n const lastAffected = lastAffectedVersions.find((version) =>\n this.isVersionGtOrEq(version, depVersion, versioningApi),\n );\n if (lastAffected) {\n return this.getLastAffectedByEcosystem(lastAffected, ecosystem);\n }\n\n return null;\n }\n\n private getFixedVersionByEcosystem(\n fixedVersion: string,\n ecosystem: Ecosystem,\n ): string {\n return getFixedVersionConstraint(fixedVersion, ecosystem);\n }\n\n private getLastAffectedByEcosystem(\n lastAffected: string,\n ecosystem: Ecosystem,\n ): string {\n return getLastAffectedVersionConstraint(lastAffected, ecosystem);\n }\n\n private isVersionGt(\n version: string,\n other: string,\n versioningApi: VersioningApi,\n ): boolean {\n return (\n versioningApi.isVersion(version) &&\n versioningApi.isVersion(other) &&\n versioningApi.isGreaterThan(version, other)\n );\n }\n\n private isVersionGtOrEq(\n version: string,\n other: string,\n versioningApi: VersioningApi,\n ): boolean {\n return (\n versioningApi.isVersion(version) &&\n versioningApi.isVersion(other) &&\n (versioningApi.equals(version, other) ||\n versioningApi.isGreaterThan(version, other))\n );\n }\n\n private vulnerabilityToPackageRules(vul: Vulnerability): PackageRule | null {\n const {\n vulnerability,\n affected,\n packageName,\n depVersion,\n fixedVersion,\n datasource,\n packageFileConfig,\n } = vul;\n if (isNullOrUndefined(fixedVersion)) {\n logger.debug(\n `No fixed version available for vulnerability ${vulnerability.id} in ${packageName} ${depVersion}`,\n );\n return null;\n }\n\n logger.debug(\n `Setting allowed version ${fixedVersion} to fix vulnerability ${vulnerability.id} in ${packageName} ${depVersion}`,\n );\n\n const severityDetails = this.extractSeverityDetails(\n vulnerability,\n affected,\n );\n\n return {\n matchDatasources: [datasource],\n matchPackageNames: [packageName],\n matchCurrentVersion: depVersion,\n allowedVersions: fixedVersion,\n isVulnerabilityAlert: true,\n vulnerabilitySeverity: severityDetails.severityLevel,\n prBodyNotes: this.generatePrBodyNotes(vulnerability, affected),\n force: {\n ...packageFileConfig.vulnerabilityAlerts,\n },\n };\n }\n\n static evaluateCvssVector(vector: string): [string, string] {\n const CvssJsonSchema = z.object({\n baseScore: z.number().default(0.0),\n baseSeverity: z.string().toUpperCase().default('UNKNOWN'),\n });\n\n try {\n const parsedCvssScore: CvssVector<any> | null = fromVector(vector);\n const res = CvssJsonSchema.parse(parsedCvssScore?.createJsonSchema());\n\n return [res.baseScore.toFixed(1), res.baseSeverity];\n } catch {\n logger.debug(`Error processing CVSS vector ${vector}`);\n }\n\n return ['', ''];\n }\n\n private generatePrBodyNotes(\n vulnerability: Osv.Vulnerability,\n affected: Osv.Affected,\n ): string[] {\n let aliases = [vulnerability.id].concat(vulnerability.aliases ?? []).sort();\n aliases = aliases.map((id) => {\n if (id.startsWith('CVE-')) {\n return `[${id}](https://nvd.nist.gov/vuln/detail/${id})`;\n } else if (id.startsWith('GHSA-')) {\n return `[${id}](https://github.com/advisories/${id})`;\n } else if (id.startsWith('GO-')) {\n return `[${id}](https://pkg.go.dev/vuln/${id})`;\n } else if (id.startsWith('RUSTSEC-')) {\n return `[${id}](https://rustsec.org/advisories/${id}.html)`;\n }\n\n return id;\n });\n\n let content = '\\n\\n---\\n\\n### ';\n content += vulnerability.summary ? `${vulnerability.summary}\\n` : '';\n content += `${aliases.join(' / ')}\\n`;\n content += `\\n<details>\\n<summary>More information</summary>\\n`;\n\n const details = vulnerability.details?.replace(\n regEx(/^#{1,4} /gm),\n '##### ',\n );\n content += `#### Details\\n${details ?? 'No details.'}\\n`;\n\n content += '#### Severity\\n';\n const severityDetails = this.extractSeverityDetails(\n vulnerability,\n affected,\n );\n\n if (severityDetails.cvssVector) {\n content += `- CVSS Score: ${severityDetails.score}\\n`;\n content += `- Vector String: \\`${severityDetails.cvssVector}\\`\\n`;\n } else {\n content += `${titleCase(severityDetails.severityLevel)}\\n`;\n }\n\n content += `\\n#### References\\n${\n vulnerability.references\n ?.map((ref) => {\n return `- [${ref.url}](${ref.url})`;\n })\n .join('\\n') ?? 'No references.'\n }`;\n\n let attribution = '';\n if (vulnerability.id.startsWith('GHSA-')) {\n attribution = ` and the [GitHub Advisory Database](https://github.com/github/advisory-database) ([CC-BY 4.0](https://github.com/github/advisory-database/blob/main/LICENSE.md))`;\n } else if (vulnerability.id.startsWith('GO-')) {\n attribution = ` and the [Go Vulnerability Database](https://github.com/golang/vulndb) ([CC-BY 4.0](https://github.com/golang/vulndb#license))`;\n } else if (vulnerability.id.startsWith('PYSEC-')) {\n attribution = ` and the [PyPI Advisory Database](https://github.com/pypa/advisory-database) ([CC-BY 4.0](https://github.com/pypa/advisory-database/blob/main/LICENSE))`;\n } else if (vulnerability.id.startsWith('RUSTSEC-')) {\n attribution = ` and the [Rust Advisory Database](https://github.com/RustSec/advisory-db) ([CC0 1.0](https://github.com/rustsec/advisory-db/blob/main/LICENSE.txt))`;\n }\n content += `\\n\\nThis data is provided by [OSV](https://osv.dev/vulnerability/${vulnerability.id})${attribution}.\\n`;\n content += `</details>`;\n\n return [sanitizeMarkdown(content)];\n }\n\n private extractSeverityDetails(\n vulnerability: Osv.Vulnerability,\n affected: Osv.Affected,\n ): SeverityDetails {\n let severityLevel = 'UNKNOWN';\n let score = 'Unknown';\n\n const cvssVector =\n vulnerability.severity?.find((e) => e.type === 'CVSS_V4')?.score ??\n vulnerability.severity?.find((e) => e.type === 'CVSS_V3')?.score ??\n (affected.database_specific?.cvss as string); // RUSTSEC\n\n if (cvssVector) {\n const [baseScore, severity] =\n Vulnerabilities.evaluateCvssVector(cvssVector);\n severityLevel = severity ? severity.toUpperCase() : 'UNKNOWN';\n score = baseScore\n ? `${baseScore} / 10 (${titleCase(severityLevel)})`\n : 'Unknown';\n } else if (\n vulnerability.id.startsWith('GHSA-') &&\n vulnerability.database_specific?.severity\n ) {\n const severity = vulnerability.database_specific.severity as string;\n severityLevel = severity.toUpperCase();\n }\n\n return {\n cvssVector,\n score,\n severityLevel,\n };\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": "43.
|
|
4
|
+
"version": "43.116.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"renovate": "dist/renovate.js",
|
|
@@ -285,7 +285,7 @@
|
|
|
285
285
|
"tmp-promise": "3.0.3",
|
|
286
286
|
"tsdown": "0.21.7",
|
|
287
287
|
"type-fest": "5.5.0",
|
|
288
|
-
"typescript": "
|
|
288
|
+
"typescript": "6.0.2",
|
|
289
289
|
"unified": "11.0.5",
|
|
290
290
|
"vite": "8.0.5",
|
|
291
291
|
"vitest": "4.1.3",
|
package/renovate-schema.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$id": "https://docs.renovatebot.com/renovate-schema.json",
|
|
3
|
-
"title": "JSON schema for Renovate 43.
|
|
3
|
+
"title": "JSON schema for Renovate 43.116.0 config files (https://renovatebot.com/)",
|
|
4
4
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
5
|
-
"x-renovate-version": "43.
|
|
5
|
+
"x-renovate-version": "43.116.0",
|
|
6
6
|
"allowComments": true,
|
|
7
7
|
"type": "object",
|
|
8
8
|
"properties": {
|