renovate 44.76.0 → 44.78.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.
@@ -91,6 +91,7 @@ async function start() {
91
91
  else if (regexEngineStatus.type === "unavailable") logger.warn({ err: regexEngineStatus.err }, "RE2 not usable, falling back to RegExp");
92
92
  else if (regexEngineStatus.type === "ignored") logger.debug("RE2 regex engine is ignored via RENOVATE_X_IGNORE_RE2");
93
93
  let config;
94
+ let repoExitCode = 0;
94
95
  const env = getEnv();
95
96
  try {
96
97
  if (isNonEmptyStringAndNotWhitespace(env.AWS_SECRET_ACCESS_KEY)) addSecretForSanitizing(env.AWS_SECRET_ACCESS_KEY, "global");
@@ -140,7 +141,8 @@ async function start() {
140
141
  }
141
142
  clear$1();
142
143
  clear$2();
143
- await renovateRepository(repoConfig);
144
+ const repoResult = await renovateRepository(repoConfig);
145
+ if (config.exitCodeForErrors && !repoExitCode) repoExitCode = repoResult?.exitCode ?? 0;
144
146
  setMeta({});
145
147
  }, { attributes: {
146
148
  [ATTR_VCS_PROVIDER_NAME]: config.platform,
@@ -163,6 +165,10 @@ async function start() {
163
165
  await globalFinalize(config);
164
166
  if (logLevel() === "info") logger.info(`Renovate was run at log level "${logLevel()}". Set LOG_LEVEL=debug in environment variables to see extended debug logs.`);
165
167
  }
168
+ if (repoExitCode) {
169
+ logger.info({ exitCode: repoExitCode }, "Renovate is exiting with an error-specific code due to a repository error");
170
+ return repoExitCode;
171
+ }
166
172
  const loggerErrors = getProblems().filter((p) => p.level >= ERROR);
167
173
  if (loggerErrors.length) {
168
174
  logger.info({ loggerErrors }, "Renovate is exiting with a non-zero code due to the following logged errors");
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["configParser.filterConfig","hostRules.filterAllowedHeaders","repositoryWorker.renovateRepository"],"sources":["../../../lib/workers/global/index.ts"],"sourcesContent":["import {\n ATTR_VCS_OWNER_NAME,\n ATTR_VCS_PROVIDER_NAME,\n ATTR_VCS_REPOSITORY_NAME,\n} from '@opentelemetry/semantic-conventions/incubating';\nimport {\n isNonEmptyObject,\n isNonEmptyString,\n isNonEmptyStringAndNotWhitespace,\n isString,\n} from '@sindresorhus/is';\nimport { ERROR } from 'bunyan';\nimport fs from 'fs-extra';\nimport semver from 'semver';\nimport upath from 'upath';\nimport { GlobalConfig } from '../../config/global.ts';\nimport * as configParser from '../../config/index.ts';\nimport { resolveConfigPresets } from '../../config/presets/index.ts';\nimport { validateConfigSecretsAndVariables } from '../../config/secrets.ts';\nimport type {\n AllConfig,\n InternalGlobalConfigOptions,\n RenovateConfig,\n RenovateRepository,\n RepoGlobalConfig,\n} from '../../config/types.ts';\nimport { CONFIG_PRESETS_INVALID } from '../../constants/error-messages.ts';\nimport { pkg } from '../../expose.ts';\nimport { instrument } from '../../instrumentation/index.ts';\nimport {\n exportStats,\n finalizeReport,\n} from '../../instrumentation/reporting.ts';\nimport { getProblems, logLevel, logger, setMeta } from '../../logger/index.ts';\nimport { setGlobalLogLevelRemaps } from '../../logger/remap.ts';\nimport type { HostRule } from '../../types/index.ts';\nimport { getEnv } from '../../util/env.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 { regexEngineStatus } from '../../util/regex.ts';\nimport { addSecretForSanitizing } from '../../util/sanitize.ts';\nimport { coerceString } from '../../util/string.ts';\nimport * as repositoryWorker from '../repository/index.ts';\nimport type { RepositoryWorkerConfig } from '../repository/init/types.ts';\nimport { autodiscoverRepositories } from './autodiscover.ts';\nimport { parseConfigs } from './config/parse/index.ts';\nimport { globalFinalize, globalInitialize } from './initialize.ts';\nimport { isLimitReached } from './limits.ts';\n\nfunction applyGlobalOption<\n K extends keyof RepoGlobalConfig | keyof InternalGlobalConfigOptions,\n>(\n target: RepoGlobalConfig & InternalGlobalConfigOptions,\n source: RepoGlobalConfig & InternalGlobalConfigOptions,\n key: K,\n): void {\n target[key] = source[key];\n delete source[key];\n}\n\nexport async function getRepositoryConfig(\n globalConfig: RenovateConfig,\n repository: RenovateRepository,\n): Promise<RepositoryWorkerConfig> {\n const repoIsString = isString(repository);\n const repoName = repoIsString ? repository : repository.repository;\n\n const repoConfig: RepositoryWorkerConfig = {\n ...globalConfig,\n repository: repoName,\n };\n\n if (!repoIsString) {\n const { repository: _repository, ...repositoryEntryConfig } = repository;\n\n // Promote GlobalConfig.OPTIONS keys into repoConfig directly so that\n // GlobalConfig.set(repoConfig) in the repository worker picks them up\n // with per-repo overrides before onboarding checks run.\n for (const option of GlobalConfig.OPTIONS) {\n if (option in repositoryEntryConfig) {\n applyGlobalOption(repoConfig, repositoryEntryConfig, option);\n }\n }\n\n if (isNonEmptyObject(repositoryEntryConfig)) {\n // mergeRenovateConfig later resolves this repositories[] object-entry\n // config in the correct order\n repoConfig.repositoryEntryConfig = repositoryEntryConfig;\n }\n }\n\n const repoParts = repoName.split('/');\n repoParts.pop();\n repoConfig.parentOrg = repoParts.join('/');\n repoConfig.topLevelOrg = repoParts.shift();\n const platform = GlobalConfig.get('platform');\n repoConfig.localDir =\n platform === 'local'\n ? process.cwd()\n : // TODO: types (#22198)\n upath.join(repoConfig.baseDir!, `./repos/${platform}/${repoName}`);\n await fs.ensureDir(repoConfig.localDir);\n delete repoConfig.baseDir;\n return configParser.filterConfig(repoConfig, 'repository');\n}\n\nfunction getGlobalConfig(): Promise<RenovateConfig> {\n return parseConfigs(getEnv(), process.argv);\n}\n\nfunction haveReachedLimits(): boolean {\n if (isLimitReached('Commits')) {\n logger.info('Max commits created for this run.');\n return true;\n }\n return false;\n}\n\n/* istanbul ignore next */\nfunction checkEnv(): void {\n const range = pkg.engines.node;\n if (process.release?.name !== 'node' || !process.versions?.node) {\n logger.warn(\n { release: process.release, versions: process.versions },\n 'Unknown node environment detected.',\n );\n } else if (!semver.satisfies(process.versions?.node, range)) {\n logger.error(\n { versions: process.versions, range },\n 'Unsupported node environment detected. Please update your node version.',\n );\n }\n}\n\nexport async function validatePresets(config: AllConfig): Promise<void> {\n logger.debug('validatePresets()');\n try {\n await resolveConfigPresets(config);\n } catch (err) /* istanbul ignore next */ {\n logger.error({ err }, CONFIG_PRESETS_INVALID);\n throw new Error(CONFIG_PRESETS_INVALID);\n }\n}\n\nexport async function start(): Promise<number> {\n logger.info({ renovateVersion: pkg.version }, 'Renovate started');\n // istanbul ignore next\n if (regexEngineStatus.type === 'available') {\n logger.debug('Using RE2 regex engine');\n } else if (regexEngineStatus.type === 'unavailable') {\n logger.warn(\n { err: regexEngineStatus.err },\n 'RE2 not usable, falling back to RegExp',\n );\n } else if (regexEngineStatus.type === 'ignored') {\n logger.debug('RE2 regex engine is ignored via RENOVATE_X_IGNORE_RE2');\n }\n\n let config: AllConfig;\n const env = getEnv();\n try {\n if (isNonEmptyStringAndNotWhitespace(env.AWS_SECRET_ACCESS_KEY)) {\n addSecretForSanitizing(env.AWS_SECRET_ACCESS_KEY, 'global');\n }\n if (isNonEmptyStringAndNotWhitespace(env.AWS_SESSION_TOKEN)) {\n addSecretForSanitizing(env.AWS_SESSION_TOKEN, 'global');\n }\n if (isNonEmptyStringAndNotWhitespace(env.COREPACK_NPM_TOKEN)) {\n addSecretForSanitizing(env.COREPACK_NPM_TOKEN, 'global');\n }\n if (isNonEmptyStringAndNotWhitespace(env.COREPACK_NPM_PASSWORD)) {\n addSecretForSanitizing(env.COREPACK_NPM_PASSWORD, 'global');\n }\n\n await instrument('config', async () => {\n // read global config from file, env and cli args\n config = await getGlobalConfig();\n\n // Set allowedHeaders and userAgent in case hostRules headers are configured in file config\n GlobalConfig.set({\n allowedHeaders: config.allowedHeaders,\n userAgent: config.userAgent,\n });\n // initialize all submodules\n config = await globalInitialize(config);\n\n // Set platform, endpoint, allowedHeaders and userAgent in case local presets are used\n GlobalConfig.set({\n allowedHeaders: config.allowedHeaders,\n platform: config.platform,\n endpoint: config.endpoint,\n userAgent: config.userAgent,\n });\n\n await validatePresets(config);\n\n setGlobalLogLevelRemaps(config.logLevelRemap);\n\n checkEnv();\n\n // validate secrets and variables. Will throw and abort if invalid\n validateConfigSecretsAndVariables(config);\n });\n\n // autodiscover repositories (needs to come after platform initialization)\n config = await instrument('discover', () =>\n autodiscoverRepositories(config),\n );\n\n if (isNonEmptyString(config.writeDiscoveredRepos)) {\n const content = JSON.stringify(config.repositories);\n await fs.writeFile(config.writeDiscoveredRepos, content);\n logger.info(\n `Written discovered repositories to ${config.writeDiscoveredRepos}`,\n );\n return 0;\n }\n\n // the self-hosted admin's own headers get no exemption from `allowedHeaders` either, as `applyHostRule` filters the rule it matches by header name alone whoever set it - so we drop them here too, with a WARN, rather than leave them to be silently discarded at request time\n // filtered once, outside the loop, rather than for every repository it processes\n let filteredGlobalHostRules: HostRule[] | undefined;\n\n // Iterate through repositories sequentially\n for (const repository of config.repositories!) {\n if (haveReachedLimits()) {\n break;\n }\n\n const { owner, repo } = repositoryToOwnerAndRepo(\n isString(repository) ? repository : repository.repository,\n );\n\n await instrument(\n 'repository',\n async () => {\n const repoConfig = await getRepositoryConfig(config, repository);\n if (repoConfig.hostRules) {\n logger.debug('Reinitializing hostRules for repo');\n hostRules.clear();\n // `GlobalConfig` still reflects the previous repository at this point, so filter with this repository's own `allowedHeaders`: usually the global allowlist (filtered once, above), re-filtered only for a `repositories[]` entry carrying an override of its own\n const rules =\n // reuse the memo only for the exact global inputs it was computed from - today `repoConfig.hostRules` is always the global array, but nothing should break if that ever changes\n repoConfig.hostRules === config.hostRules &&\n repoConfig.allowedHeaders === config.allowedHeaders\n ? (filteredGlobalHostRules ??= hostRules.filterAllowedHeaders(\n repoConfig.hostRules,\n config.allowedHeaders,\n // `globalInitialize` already registered these very rules against this very allowlist, and warned about whatever it dropped\n false,\n ))\n : hostRules.filterAllowedHeaders(\n repoConfig.hostRules,\n repoConfig.allowedHeaders,\n );\n for (const rule of rules) {\n // already filtered: pass the same allowlist through so `add()` does not re-filter against a stale `GlobalConfig`\n // the self-hosted admin's own rules: `trusted`, so that their `headers` are applied over any a repository or preset sets for the same host\n hostRules.add(rule, {\n // we haven't yet set `GlobalConfig`, so we need to explicitly pass these in\n allowedHeaders: repoConfig.allowedHeaders,\n trusted: true,\n });\n }\n repoConfig.hostRules = [];\n }\n\n // host rules can change concurrency\n queue.clear();\n throttle.clear();\n\n await repositoryWorker.renovateRepository(repoConfig);\n setMeta({});\n },\n {\n attributes: {\n [ATTR_VCS_PROVIDER_NAME]: config.platform,\n [ATTR_VCS_OWNER_NAME]: owner,\n [ATTR_VCS_REPOSITORY_NAME]: repo,\n /** @deprecated TODO remove */\n repository: isString(repository)\n ? repository\n : repository.repository,\n },\n },\n );\n }\n\n finalizeReport();\n await exportStats(config);\n } catch (err) /* istanbul ignore next */ {\n if (err.message.startsWith('Init: ')) {\n logger.fatal(\n { errorMessage: err.message.substring(6) },\n 'Initialization error',\n );\n } else {\n logger.fatal({ err }, 'Unknown error');\n }\n if (!config!) {\n // return early if we can't parse config options\n logger.debug(`Missing config`);\n return 2;\n }\n } finally {\n await globalFinalize(config!);\n if (logLevel() === 'info') {\n logger.info(\n `Renovate was run at log level \"${logLevel()}\". Set LOG_LEVEL=debug in environment variables to see extended debug logs.`,\n );\n }\n }\n const loggerErrors = getProblems().filter((p) => p.level >= ERROR);\n if (loggerErrors.length) {\n logger.info(\n { loggerErrors },\n 'Renovate is exiting with a non-zero code due to the following logged errors',\n );\n return 1;\n }\n return 0;\n}\n\nfunction repositoryToOwnerAndRepo(fullName: string): {\n owner: string;\n repo: string;\n} {\n const parts = fullName.split('/');\n const repo = coerceString(parts.pop());\n const owner = parts.join('/');\n return { owner, repo };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["configParser.filterConfig","hostRules.filterAllowedHeaders","repositoryWorker.renovateRepository"],"sources":["../../../lib/workers/global/index.ts"],"sourcesContent":["import {\n ATTR_VCS_OWNER_NAME,\n ATTR_VCS_PROVIDER_NAME,\n ATTR_VCS_REPOSITORY_NAME,\n} from '@opentelemetry/semantic-conventions/incubating';\nimport {\n isNonEmptyObject,\n isNonEmptyString,\n isNonEmptyStringAndNotWhitespace,\n isString,\n} from '@sindresorhus/is';\nimport { ERROR } from 'bunyan';\nimport fs from 'fs-extra';\nimport semver from 'semver';\nimport upath from 'upath';\nimport { GlobalConfig } from '../../config/global.ts';\nimport * as configParser from '../../config/index.ts';\nimport { resolveConfigPresets } from '../../config/presets/index.ts';\nimport { validateConfigSecretsAndVariables } from '../../config/secrets.ts';\nimport type {\n AllConfig,\n InternalGlobalConfigOptions,\n RenovateConfig,\n RenovateRepository,\n RepoGlobalConfig,\n} from '../../config/types.ts';\nimport { CONFIG_PRESETS_INVALID } from '../../constants/error-messages.ts';\nimport { pkg } from '../../expose.ts';\nimport { instrument } from '../../instrumentation/index.ts';\nimport {\n exportStats,\n finalizeReport,\n} from '../../instrumentation/reporting.ts';\nimport { getProblems, logLevel, logger, setMeta } from '../../logger/index.ts';\nimport { setGlobalLogLevelRemaps } from '../../logger/remap.ts';\nimport type { HostRule } from '../../types/index.ts';\nimport { getEnv } from '../../util/env.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 { regexEngineStatus } from '../../util/regex.ts';\nimport { addSecretForSanitizing } from '../../util/sanitize.ts';\nimport { coerceString } from '../../util/string.ts';\nimport * as repositoryWorker from '../repository/index.ts';\nimport type { RepositoryWorkerConfig } from '../repository/init/types.ts';\nimport { autodiscoverRepositories } from './autodiscover.ts';\nimport { parseConfigs } from './config/parse/index.ts';\nimport { globalFinalize, globalInitialize } from './initialize.ts';\nimport { isLimitReached } from './limits.ts';\n\nfunction applyGlobalOption<\n K extends keyof RepoGlobalConfig | keyof InternalGlobalConfigOptions,\n>(\n target: RepoGlobalConfig & InternalGlobalConfigOptions,\n source: RepoGlobalConfig & InternalGlobalConfigOptions,\n key: K,\n): void {\n target[key] = source[key];\n delete source[key];\n}\n\nexport async function getRepositoryConfig(\n globalConfig: RenovateConfig,\n repository: RenovateRepository,\n): Promise<RepositoryWorkerConfig> {\n const repoIsString = isString(repository);\n const repoName = repoIsString ? repository : repository.repository;\n\n const repoConfig: RepositoryWorkerConfig = {\n ...globalConfig,\n repository: repoName,\n };\n\n if (!repoIsString) {\n const { repository: _repository, ...repositoryEntryConfig } = repository;\n\n // Promote GlobalConfig.OPTIONS keys into repoConfig directly so that\n // GlobalConfig.set(repoConfig) in the repository worker picks them up\n // with per-repo overrides before onboarding checks run.\n for (const option of GlobalConfig.OPTIONS) {\n if (option in repositoryEntryConfig) {\n applyGlobalOption(repoConfig, repositoryEntryConfig, option);\n }\n }\n\n if (isNonEmptyObject(repositoryEntryConfig)) {\n // mergeRenovateConfig later resolves this repositories[] object-entry\n // config in the correct order\n repoConfig.repositoryEntryConfig = repositoryEntryConfig;\n }\n }\n\n const repoParts = repoName.split('/');\n repoParts.pop();\n repoConfig.parentOrg = repoParts.join('/');\n repoConfig.topLevelOrg = repoParts.shift();\n const platform = GlobalConfig.get('platform');\n repoConfig.localDir =\n platform === 'local'\n ? process.cwd()\n : // TODO: types (#22198)\n upath.join(repoConfig.baseDir!, `./repos/${platform}/${repoName}`);\n await fs.ensureDir(repoConfig.localDir);\n delete repoConfig.baseDir;\n return configParser.filterConfig(repoConfig, 'repository');\n}\n\nfunction getGlobalConfig(): Promise<RenovateConfig> {\n return parseConfigs(getEnv(), process.argv);\n}\n\nfunction haveReachedLimits(): boolean {\n if (isLimitReached('Commits')) {\n logger.info('Max commits created for this run.');\n return true;\n }\n return false;\n}\n\n/* istanbul ignore next */\nfunction checkEnv(): void {\n const range = pkg.engines.node;\n if (process.release?.name !== 'node' || !process.versions?.node) {\n logger.warn(\n { release: process.release, versions: process.versions },\n 'Unknown node environment detected.',\n );\n } else if (!semver.satisfies(process.versions?.node, range)) {\n logger.error(\n { versions: process.versions, range },\n 'Unsupported node environment detected. Please update your node version.',\n );\n }\n}\n\nexport async function validatePresets(config: AllConfig): Promise<void> {\n logger.debug('validatePresets()');\n try {\n await resolveConfigPresets(config);\n } catch (err) /* istanbul ignore next */ {\n logger.error({ err }, CONFIG_PRESETS_INVALID);\n throw new Error(CONFIG_PRESETS_INVALID);\n }\n}\n\nexport async function start(): Promise<number> {\n logger.info({ renovateVersion: pkg.version }, 'Renovate started');\n // istanbul ignore next\n if (regexEngineStatus.type === 'available') {\n logger.debug('Using RE2 regex engine');\n } else if (regexEngineStatus.type === 'unavailable') {\n logger.warn(\n { err: regexEngineStatus.err },\n 'RE2 not usable, falling back to RegExp',\n );\n } else if (regexEngineStatus.type === 'ignored') {\n logger.debug('RE2 regex engine is ignored via RENOVATE_X_IGNORE_RE2');\n }\n\n let config: AllConfig;\n let repoExitCode = 0;\n const env = getEnv();\n try {\n if (isNonEmptyStringAndNotWhitespace(env.AWS_SECRET_ACCESS_KEY)) {\n addSecretForSanitizing(env.AWS_SECRET_ACCESS_KEY, 'global');\n }\n if (isNonEmptyStringAndNotWhitespace(env.AWS_SESSION_TOKEN)) {\n addSecretForSanitizing(env.AWS_SESSION_TOKEN, 'global');\n }\n if (isNonEmptyStringAndNotWhitespace(env.COREPACK_NPM_TOKEN)) {\n addSecretForSanitizing(env.COREPACK_NPM_TOKEN, 'global');\n }\n if (isNonEmptyStringAndNotWhitespace(env.COREPACK_NPM_PASSWORD)) {\n addSecretForSanitizing(env.COREPACK_NPM_PASSWORD, 'global');\n }\n\n await instrument('config', async () => {\n // read global config from file, env and cli args\n config = await getGlobalConfig();\n\n // Set allowedHeaders and userAgent in case hostRules headers are configured in file config\n GlobalConfig.set({\n allowedHeaders: config.allowedHeaders,\n userAgent: config.userAgent,\n });\n // initialize all submodules\n config = await globalInitialize(config);\n\n // Set platform, endpoint, allowedHeaders and userAgent in case local presets are used\n GlobalConfig.set({\n allowedHeaders: config.allowedHeaders,\n platform: config.platform,\n endpoint: config.endpoint,\n userAgent: config.userAgent,\n });\n\n await validatePresets(config);\n\n setGlobalLogLevelRemaps(config.logLevelRemap);\n\n checkEnv();\n\n // validate secrets and variables. Will throw and abort if invalid\n validateConfigSecretsAndVariables(config);\n });\n\n // autodiscover repositories (needs to come after platform initialization)\n config = await instrument('discover', () =>\n autodiscoverRepositories(config),\n );\n\n if (isNonEmptyString(config.writeDiscoveredRepos)) {\n const content = JSON.stringify(config.repositories);\n await fs.writeFile(config.writeDiscoveredRepos, content);\n logger.info(\n `Written discovered repositories to ${config.writeDiscoveredRepos}`,\n );\n return 0;\n }\n\n // the self-hosted admin's own headers get no exemption from `allowedHeaders` either, as `applyHostRule` filters the rule it matches by header name alone whoever set it - so we drop them here too, with a WARN, rather than leave them to be silently discarded at request time\n // filtered once, outside the loop, rather than for every repository it processes\n let filteredGlobalHostRules: HostRule[] | undefined;\n\n // Iterate through repositories sequentially\n for (const repository of config.repositories!) {\n if (haveReachedLimits()) {\n break;\n }\n\n const { owner, repo } = repositoryToOwnerAndRepo(\n isString(repository) ? repository : repository.repository,\n );\n\n await instrument(\n 'repository',\n async () => {\n const repoConfig = await getRepositoryConfig(config, repository);\n if (repoConfig.hostRules) {\n logger.debug('Reinitializing hostRules for repo');\n hostRules.clear();\n // `GlobalConfig` still reflects the previous repository at this point, so filter with this repository's own `allowedHeaders`: usually the global allowlist (filtered once, above), re-filtered only for a `repositories[]` entry carrying an override of its own\n const rules =\n // reuse the memo only for the exact global inputs it was computed from - today `repoConfig.hostRules` is always the global array, but nothing should break if that ever changes\n repoConfig.hostRules === config.hostRules &&\n repoConfig.allowedHeaders === config.allowedHeaders\n ? (filteredGlobalHostRules ??= hostRules.filterAllowedHeaders(\n repoConfig.hostRules,\n config.allowedHeaders,\n // `globalInitialize` already registered these very rules against this very allowlist, and warned about whatever it dropped\n false,\n ))\n : hostRules.filterAllowedHeaders(\n repoConfig.hostRules,\n repoConfig.allowedHeaders,\n );\n for (const rule of rules) {\n // already filtered: pass the same allowlist through so `add()` does not re-filter against a stale `GlobalConfig`\n // the self-hosted admin's own rules: `trusted`, so that their `headers` are applied over any a repository or preset sets for the same host\n hostRules.add(rule, {\n // we haven't yet set `GlobalConfig`, so we need to explicitly pass these in\n allowedHeaders: repoConfig.allowedHeaders,\n trusted: true,\n });\n }\n repoConfig.hostRules = [];\n }\n\n // host rules can change concurrency\n queue.clear();\n throttle.clear();\n\n const repoResult =\n await repositoryWorker.renovateRepository(repoConfig);\n if (config.exitCodeForErrors && !repoExitCode) {\n repoExitCode = repoResult?.exitCode ?? 0;\n }\n setMeta({});\n },\n {\n attributes: {\n [ATTR_VCS_PROVIDER_NAME]: config.platform,\n [ATTR_VCS_OWNER_NAME]: owner,\n [ATTR_VCS_REPOSITORY_NAME]: repo,\n /** @deprecated TODO remove */\n repository: isString(repository)\n ? repository\n : repository.repository,\n },\n },\n );\n }\n\n finalizeReport();\n await exportStats(config);\n } catch (err) /* istanbul ignore next */ {\n if (err.message.startsWith('Init: ')) {\n logger.fatal(\n { errorMessage: err.message.substring(6) },\n 'Initialization error',\n );\n } else {\n logger.fatal({ err }, 'Unknown error');\n }\n if (!config!) {\n // return early if we can't parse config options\n logger.debug(`Missing config`);\n return 2;\n }\n } finally {\n await globalFinalize(config!);\n if (logLevel() === 'info') {\n logger.info(\n `Renovate was run at log level \"${logLevel()}\". Set LOG_LEVEL=debug in environment variables to see extended debug logs.`,\n );\n }\n }\n if (repoExitCode) {\n logger.info(\n { exitCode: repoExitCode },\n 'Renovate is exiting with an error-specific code due to a repository error',\n );\n return repoExitCode;\n }\n const loggerErrors = getProblems().filter((p) => p.level >= ERROR);\n if (loggerErrors.length) {\n logger.info(\n { loggerErrors },\n 'Renovate is exiting with a non-zero code due to the following logged errors',\n );\n return 1;\n }\n return 0;\n}\n\nfunction repositoryToOwnerAndRepo(fullName: string): {\n owner: string;\n repo: string;\n} {\n const parts = fullName.split('/');\n const repo = coerceString(parts.pop());\n const owner = parts.join('/');\n return { owner, repo };\n}\n"],"mappings":"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"}
@@ -143,7 +143,8 @@ async function renovateRepository(repoConfig, canRetry = true) {
143
143
  result: repoResult?.res,
144
144
  status: repoResult?.status,
145
145
  enabled: repoResult?.enabled,
146
- onboarded: repoResult?.onboarded
146
+ onboarded: repoResult?.onboarded,
147
+ exitCode: repoResult?.exitCode
147
148
  }, "Repository finished");
148
149
  resetRepositoryLogLevelRemaps();
149
150
  return repoResult;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../lib/workers/repository/index.ts"],"sourcesContent":["import { GlobalConfig } from '../../config/global.ts';\nimport { applySecretsAndVariablesToConfig } from '../../config/secrets.ts';\nimport type { RenovateConfig } from '../../config/types.ts';\nimport {\n REPOSITORY_DISABLED_BY_CONFIG,\n REPOSITORY_FORKED,\n REPOSITORY_NO_CONFIG,\n} from '../../constants/error-messages.ts';\nimport { pkg } from '../../expose.ts';\nimport { instrument } from '../../instrumentation/index.ts';\nimport { addExtractionStats } from '../../instrumentation/reporting.ts';\nimport { ATTR_RENOVATE_SPLIT } from '../../instrumentation/types.ts';\nimport { logger, setMeta } from '../../logger/index.ts';\nimport { resetRepositoryLogLevelRemaps } from '../../logger/remap.ts';\nimport { getInheritedOrGlobal } from '../../util/common.ts';\nimport { removeDanglingContainers } from '../../util/exec/docker/index.ts';\nimport {\n deleteLocalFile,\n ensureDir,\n privateCacheDir,\n rmCache,\n} from '../../util/fs/index.ts';\nimport { isCloned } from '../../util/git/index.ts';\nimport { detectSemanticCommits } from '../../util/git/semantic.ts';\nimport * as queue from '../../util/http/queue.ts';\nimport * as throttle from '../../util/http/throttle.ts';\nimport { addSplit, getSplits, splitInit } from '../../util/split.ts';\nimport {\n AbandonedPackageStats,\n DatasourceCacheStats,\n GetDatasourceReleasesStats,\n GitOperationStats,\n HttpCacheStats,\n HttpStats,\n LookupStats,\n ObsoleteCacheHitLogger,\n PackageCacheStats,\n} from '../../util/stats.ts';\nimport { setBranchCache } from './cache.ts';\nimport { extractRepoProblems } from './common.ts';\nimport { configMigration } from './config-migration/index.ts';\nimport { ensureDependencyDashboard } from './dependency-dashboard.ts';\nimport handleError from './error.ts';\nimport { finalizeRepo } from './finalize/index.ts';\nimport { pruneStaleBranches } from './finalize/prune.ts';\nimport { initRepo } from './init/index.ts';\nimport { OnboardingState } from './onboarding/common.ts';\nimport { ensureOnboardingPr } from './onboarding/pr/index.ts';\nimport type { ExtractResult } from './process/extract-update.ts';\nimport { extractDependencies, updateRepo } from './process/index.ts';\nimport type { ProcessResult, RepositoryResult } from './result.ts';\nimport { processResult } from './result.ts';\n\n// istanbul ignore next\nexport async function renovateRepository(\n repoConfig: RenovateConfig,\n canRetry = true,\n): Promise<ProcessResult | undefined> {\n splitInit();\n\n let repoResult: ProcessResult | undefined;\n const { config, localDir, error } = await instrument(\n 'init',\n async (): Promise<{\n config: RenovateConfig;\n localDir: string;\n error?: Error;\n }> => {\n let config = GlobalConfig.set(\n applySecretsAndVariablesToConfig({\n config: repoConfig,\n deleteVariables: false,\n deleteSecrets: false,\n }),\n );\n await removeDanglingContainers();\n setMeta({ repository: config.repository });\n logger.info({ renovateVersion: pkg.version }, 'Repository started');\n logger.trace({ config });\n queue.clear();\n throttle.clear();\n const localDir = GlobalConfig.get('localDir');\n\n try {\n await ensureDir(localDir);\n logger.debug(`Using localDir: ${localDir}`);\n config = await initRepo(config);\n addSplit('init');\n } catch (err) /* istanbul ignore next */ {\n setMeta({ repository: config.repository });\n const errorRes = await handleError(config, err);\n const pruneWhenErrors = [\n REPOSITORY_DISABLED_BY_CONFIG,\n REPOSITORY_FORKED,\n REPOSITORY_NO_CONFIG,\n ];\n if (pruneWhenErrors.includes(errorRes)) {\n await pruneStaleBranches(config, []);\n }\n repoResult = processResult(config, errorRes);\n\n return { config, localDir, error: err };\n }\n\n return { config, localDir };\n },\n {\n attributes: {\n [ATTR_RENOVATE_SPLIT]: 'init',\n },\n },\n );\n\n // only continue if init stage was successful\n if (error === undefined) {\n try {\n const performExtract =\n config.repoIsOnboarded! ||\n !OnboardingState.onboardingCacheValid ||\n OnboardingState.prUpdateRequested;\n const extractResult = performExtract\n ? await extractDependencies(config)\n : emptyExtract();\n addExtractionStats(config, extractResult);\n\n const { branches, branchList, packageFiles } = extractResult;\n\n if (config.semanticCommits === 'auto') {\n config.semanticCommits = await detectSemanticCommits();\n }\n\n if (\n GlobalConfig.get('dryRun') !== 'lookup' &&\n GlobalConfig.get('dryRun') !== 'extract'\n ) {\n let res: RepositoryResult;\n if (config.repoIsOnboarded) {\n addSplit('onboarding'); // no onboarding work was needed\n res = await instrument('update', () => updateRepo(config, branches), {\n attributes: {\n [ATTR_RENOVATE_SPLIT]: 'update',\n },\n });\n setMeta({ repository: config.repository });\n } else {\n res = await instrument(\n 'onboarding',\n () => ensureOnboardingPr(config, packageFiles, branches),\n {\n attributes: {\n [ATTR_RENOVATE_SPLIT]: 'onboarding',\n },\n },\n );\n addSplit('onboarding');\n }\n addSplit('update');\n if (performExtract) {\n await setBranchCache(branches); // update branch cache if performed extraction\n }\n if (res === 'automerged') {\n if (canRetry) {\n logger.info('Restarting repository job after automerge result');\n const recursiveRes = await renovateRepository(repoConfig, false);\n return recursiveRes;\n }\n logger.debug(`Automerged but already retried once`);\n } else {\n const configMigrationRes = await configMigration(config, branchList);\n await ensureDependencyDashboard(\n config,\n branches,\n packageFiles,\n configMigrationRes,\n );\n }\n await finalizeRepo(config, branchList, repoConfig);\n repoResult = processResult(config, res);\n }\n printRepositoryProblems(config.repository);\n } catch (err) /* istanbul ignore next */ {\n setMeta({ repository: config.repository });\n const errorRes = await handleError(config, err);\n const pruneWhenErrors = [\n REPOSITORY_DISABLED_BY_CONFIG,\n REPOSITORY_FORKED,\n REPOSITORY_NO_CONFIG,\n ];\n if (pruneWhenErrors.includes(errorRes)) {\n await pruneStaleBranches(config, []);\n }\n repoResult = processResult(config, errorRes);\n }\n } else {\n logger.debug(\n { err: error },\n 'Skipping the rest to the Renovate run due to error in `init` phase',\n );\n }\n\n if (localDir && !repoConfig.persistRepoData) {\n try {\n await deleteLocalFile('.');\n } catch (err) /* istanbul ignore if */ {\n logger.warn({ err }, 'localDir deletion error');\n }\n }\n try {\n await rmCache(privateCacheDir());\n } catch (err) /* istanbul ignore if */ {\n logger.warn({ err }, 'privateCacheDir deletion error');\n }\n const splits = getSplits();\n logger.debug(splits, 'Repository timing splits (milliseconds)');\n PackageCacheStats.report();\n DatasourceCacheStats.report();\n HttpStats.report();\n HttpCacheStats.report();\n LookupStats.report();\n GetDatasourceReleasesStats.report();\n ObsoleteCacheHitLogger.report();\n AbandonedPackageStats.report();\n GitOperationStats.report();\n const cloned = isCloned();\n /* v8 ignore next -- coverage not required of these `undefined` checks, as we're happy receiving an `undefined` in the logs */\n logger.info(\n {\n cloned,\n durationMs: splits.total,\n result: repoResult?.res,\n status: repoResult?.status,\n enabled: repoResult?.enabled,\n onboarded: repoResult?.onboarded,\n },\n 'Repository finished',\n );\n resetRepositoryLogLevelRemaps();\n return repoResult;\n}\n\n// istanbul ignore next: renovateRepository is ignored\nfunction emptyExtract(): ExtractResult {\n return instrument(\n 'extract',\n () => {\n addSplit('extract');\n addSplit('lookup');\n return {\n branches: [],\n branchList: [getInheritedOrGlobal('onboardingBranch')!], // to prevent auto closing\n packageFiles: {},\n };\n },\n {\n attributes: {\n [ATTR_RENOVATE_SPLIT]: 'extract',\n },\n },\n );\n}\n\nexport function printRepositoryProblems(repository: string | undefined): void {\n const repoProblems = extractRepoProblems(repository);\n if (repoProblems.size) {\n logger.debug(\n { repoProblems: Array.from(repoProblems) },\n 'repository problems',\n );\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsDA,eAAsB,mBACpB,YACA,WAAW,MACyB;CACpC,UAAU;CAEV,IAAI;CACJ,MAAM,EAAE,QAAQ,UAAU,UAAU,MAAM,WACxC,QACA,YAIM;EACJ,IAAI,SAAS,aAAa,IACxB,iCAAiC;GAC/B,QAAQ;GACR,iBAAiB;GACjB,eAAe;EACjB,CAAC,CACH;EACA,MAAM,yBAAyB;EAC/B,QAAQ,EAAE,YAAY,OAAO,WAAW,CAAC;EACzC,OAAO,KAAK,EAAE,iBAAiB,IAAI,QAAQ,GAAG,oBAAoB;EAClE,OAAO,MAAM,EAAE,OAAO,CAAC;EACvB,MAAY;EACZ,QAAe;EACf,MAAM,WAAW,aAAa,IAAI,UAAU;EAE5C,IAAI;GACF,MAAM,UAAU,QAAQ;GACxB,OAAO,MAAM,mBAAmB,UAAU;GAC1C,SAAS,MAAM,SAAS,MAAM;GAC9B,SAAS,MAAM;EACjB,SAAS,gCAAgC;GACvC,QAAQ,EAAE,YAAY,OAAO,WAAW,CAAC;GACzC,MAAM,WAAW,MAAM,YAAY,QAAQ,GAAG;GAM9C,IAAI;;;;GAAc,CAAC,CAAC,SAAS,QAAQ,GACnC,MAAM,mBAAmB,QAAQ,CAAC,CAAC;GAErC,aAAa,cAAc,QAAQ,QAAQ;GAE3C,OAAO;IAAE;IAAQ;IAAU,OAAO;GAAI;EACxC;EAEA,OAAO;GAAE;GAAQ;EAAS;CAC5B,GACA,EACE,YAAY,GACT,sBAAsB,OACzB,EACF,CACF;CAGA,IAAI,UAAU,KAAA,GACZ,IAAI;EACF,MAAM,iBACJ,OAAO,mBACP,CAAC,gBAAgB,wBACjB,gBAAgB;EAClB,MAAM,gBAAgB,iBAClB,MAAM,oBAAoB,MAAM,IAChC,aAAa;EACjB,mBAAmB,QAAQ,aAAa;EAExC,MAAM,EAAE,UAAU,YAAY,iBAAiB;EAE/C,IAAI,OAAO,oBAAoB,QAC7B,OAAO,kBAAkB,MAAM,sBAAsB;EAGvD,IACE,aAAa,IAAI,QAAQ,MAAM,YAC/B,aAAa,IAAI,QAAQ,MAAM,WAC/B;GACA,IAAI;GACJ,IAAI,OAAO,iBAAiB;IAC1B,SAAS,YAAY;IACrB,MAAM,MAAM,WAAW,gBAAgB,WAAW,QAAQ,QAAQ,GAAG,EACnE,YAAY,GACT,sBAAsB,SACzB,EACF,CAAC;IACD,QAAQ,EAAE,YAAY,OAAO,WAAW,CAAC;GAC3C,OAAO;IACL,MAAM,MAAM,WACV,oBACM,mBAAmB,QAAQ,cAAc,QAAQ,GACvD,EACE,YAAY,GACT,sBAAsB,aACzB,EACF,CACF;IACA,SAAS,YAAY;GACvB;GACA,SAAS,QAAQ;GACjB,IAAI,gBACF,MAAM,eAAe,QAAQ;GAE/B,IAAI,QAAQ,cAAc;IACxB,IAAI,UAAU;KACZ,OAAO,KAAK,kDAAkD;KAE9D,OAAO,MADoB,mBAAmB,YAAY,KAAK;IAEjE;IACA,OAAO,MAAM,qCAAqC;GACpD,OAAO;IACL,MAAM,qBAAqB,MAAM,gBAAgB,QAAQ,UAAU;IACnE,MAAM,0BACJ,QACA,UACA,cACA,kBACF;GACF;GACA,MAAM,aAAa,QAAQ,YAAY,UAAU;GACjD,aAAa,cAAc,QAAQ,GAAG;EACxC;EACA,wBAAwB,OAAO,UAAU;CAC3C,SAAS,gCAAgC;EACvC,QAAQ,EAAE,YAAY,OAAO,WAAW,CAAC;EACzC,MAAM,WAAW,MAAM,YAAY,QAAQ,GAAG;EAM9C,IAAI;;;;EAAc,CAAC,CAAC,SAAS,QAAQ,GACnC,MAAM,mBAAmB,QAAQ,CAAC,CAAC;EAErC,aAAa,cAAc,QAAQ,QAAQ;CAC7C;MAEA,OAAO,MACL,EAAE,KAAK,MAAM,GACb,oEACF;CAGF,IAAI,YAAY,CAAC,WAAW,iBAC1B,IAAI;EACF,MAAM,gBAAgB,GAAG;CAC3B,SAAS,8BAA8B;EACrC,OAAO,KAAK,EAAE,IAAI,GAAG,yBAAyB;CAChD;CAEF,IAAI;EACF,MAAM,QAAQ,gBAAgB,CAAC;CACjC,SAAS,8BAA8B;EACrC,OAAO,KAAK,EAAE,IAAI,GAAG,gCAAgC;CACvD;CACA,MAAM,SAAS,UAAU;CACzB,OAAO,MAAM,QAAQ,yCAAyC;CAC9D,kBAAkB,OAAO;CACzB,qBAAqB,OAAO;CAC5B,UAAU,OAAO;CACjB,eAAe,OAAO;CACtB,YAAY,OAAO;CACnB,2BAA2B,OAAO;CAClC,uBAAuB,OAAO;CAC9B,sBAAsB,OAAO;CAC7B,kBAAkB,OAAO;CACzB,MAAM,SAAS,SAAS;;CAExB,OAAO,KACL;EACE;EACA,YAAY,OAAO;EACnB,QAAQ,YAAY;EACpB,QAAQ,YAAY;EACpB,SAAS,YAAY;EACrB,WAAW,YAAY;CACzB,GACA,qBACF;CACA,8BAA8B;CAC9B,OAAO;AACT;;AAGA,SAAS,eAA8B;CACrC,OAAO,WACL,iBACM;EACJ,SAAS,SAAS;EAClB,SAAS,QAAQ;EACjB,OAAO;GACL,UAAU,CAAC;GACX,YAAY,CAAC,qBAAqB,kBAAkB,CAAE;GACtD,cAAc,CAAC;EACjB;CACF,GACA,EACE,YAAY,GACT,sBAAsB,UACzB,EACF,CACF;AACF;AAEA,SAAgB,wBAAwB,YAAsC;CAC5E,MAAM,eAAe,oBAAoB,UAAU;CACnD,IAAI,aAAa,MACf,OAAO,MACL,EAAE,cAAc,MAAM,KAAK,YAAY,EAAE,GACzC,qBACF;AAEJ"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../lib/workers/repository/index.ts"],"sourcesContent":["import { GlobalConfig } from '../../config/global.ts';\nimport { applySecretsAndVariablesToConfig } from '../../config/secrets.ts';\nimport type { RenovateConfig } from '../../config/types.ts';\nimport {\n REPOSITORY_DISABLED_BY_CONFIG,\n REPOSITORY_FORKED,\n REPOSITORY_NO_CONFIG,\n} from '../../constants/error-messages.ts';\nimport { pkg } from '../../expose.ts';\nimport { instrument } from '../../instrumentation/index.ts';\nimport { addExtractionStats } from '../../instrumentation/reporting.ts';\nimport { ATTR_RENOVATE_SPLIT } from '../../instrumentation/types.ts';\nimport { logger, setMeta } from '../../logger/index.ts';\nimport { resetRepositoryLogLevelRemaps } from '../../logger/remap.ts';\nimport { getInheritedOrGlobal } from '../../util/common.ts';\nimport { removeDanglingContainers } from '../../util/exec/docker/index.ts';\nimport {\n deleteLocalFile,\n ensureDir,\n privateCacheDir,\n rmCache,\n} from '../../util/fs/index.ts';\nimport { isCloned } from '../../util/git/index.ts';\nimport { detectSemanticCommits } from '../../util/git/semantic.ts';\nimport * as queue from '../../util/http/queue.ts';\nimport * as throttle from '../../util/http/throttle.ts';\nimport { addSplit, getSplits, splitInit } from '../../util/split.ts';\nimport {\n AbandonedPackageStats,\n DatasourceCacheStats,\n GetDatasourceReleasesStats,\n GitOperationStats,\n HttpCacheStats,\n HttpStats,\n LookupStats,\n ObsoleteCacheHitLogger,\n PackageCacheStats,\n} from '../../util/stats.ts';\nimport { setBranchCache } from './cache.ts';\nimport { extractRepoProblems } from './common.ts';\nimport { configMigration } from './config-migration/index.ts';\nimport { ensureDependencyDashboard } from './dependency-dashboard.ts';\nimport handleError from './error.ts';\nimport { finalizeRepo } from './finalize/index.ts';\nimport { pruneStaleBranches } from './finalize/prune.ts';\nimport { initRepo } from './init/index.ts';\nimport { OnboardingState } from './onboarding/common.ts';\nimport { ensureOnboardingPr } from './onboarding/pr/index.ts';\nimport type { ExtractResult } from './process/extract-update.ts';\nimport { extractDependencies, updateRepo } from './process/index.ts';\nimport type { ProcessResult, RepositoryResult } from './result.ts';\nimport { processResult } from './result.ts';\n\n// istanbul ignore next\nexport async function renovateRepository(\n repoConfig: RenovateConfig,\n canRetry = true,\n): Promise<ProcessResult | undefined> {\n splitInit();\n\n let repoResult: ProcessResult | undefined;\n const { config, localDir, error } = await instrument(\n 'init',\n async (): Promise<{\n config: RenovateConfig;\n localDir: string;\n error?: Error;\n }> => {\n let config = GlobalConfig.set(\n applySecretsAndVariablesToConfig({\n config: repoConfig,\n deleteVariables: false,\n deleteSecrets: false,\n }),\n );\n await removeDanglingContainers();\n setMeta({ repository: config.repository });\n logger.info({ renovateVersion: pkg.version }, 'Repository started');\n logger.trace({ config });\n queue.clear();\n throttle.clear();\n const localDir = GlobalConfig.get('localDir');\n\n try {\n await ensureDir(localDir);\n logger.debug(`Using localDir: ${localDir}`);\n config = await initRepo(config);\n addSplit('init');\n } catch (err) /* istanbul ignore next */ {\n setMeta({ repository: config.repository });\n const errorRes = await handleError(config, err);\n const pruneWhenErrors = [\n REPOSITORY_DISABLED_BY_CONFIG,\n REPOSITORY_FORKED,\n REPOSITORY_NO_CONFIG,\n ];\n if (pruneWhenErrors.includes(errorRes)) {\n await pruneStaleBranches(config, []);\n }\n repoResult = processResult(config, errorRes);\n\n return { config, localDir, error: err };\n }\n\n return { config, localDir };\n },\n {\n attributes: {\n [ATTR_RENOVATE_SPLIT]: 'init',\n },\n },\n );\n\n // only continue if init stage was successful\n if (error === undefined) {\n try {\n const performExtract =\n config.repoIsOnboarded! ||\n !OnboardingState.onboardingCacheValid ||\n OnboardingState.prUpdateRequested;\n const extractResult = performExtract\n ? await extractDependencies(config)\n : emptyExtract();\n addExtractionStats(config, extractResult);\n\n const { branches, branchList, packageFiles } = extractResult;\n\n if (config.semanticCommits === 'auto') {\n config.semanticCommits = await detectSemanticCommits();\n }\n\n if (\n GlobalConfig.get('dryRun') !== 'lookup' &&\n GlobalConfig.get('dryRun') !== 'extract'\n ) {\n let res: RepositoryResult;\n if (config.repoIsOnboarded) {\n addSplit('onboarding'); // no onboarding work was needed\n res = await instrument('update', () => updateRepo(config, branches), {\n attributes: {\n [ATTR_RENOVATE_SPLIT]: 'update',\n },\n });\n setMeta({ repository: config.repository });\n } else {\n res = await instrument(\n 'onboarding',\n () => ensureOnboardingPr(config, packageFiles, branches),\n {\n attributes: {\n [ATTR_RENOVATE_SPLIT]: 'onboarding',\n },\n },\n );\n addSplit('onboarding');\n }\n addSplit('update');\n if (performExtract) {\n await setBranchCache(branches); // update branch cache if performed extraction\n }\n if (res === 'automerged') {\n if (canRetry) {\n logger.info('Restarting repository job after automerge result');\n const recursiveRes = await renovateRepository(repoConfig, false);\n return recursiveRes;\n }\n logger.debug(`Automerged but already retried once`);\n } else {\n const configMigrationRes = await configMigration(config, branchList);\n await ensureDependencyDashboard(\n config,\n branches,\n packageFiles,\n configMigrationRes,\n );\n }\n await finalizeRepo(config, branchList, repoConfig);\n repoResult = processResult(config, res);\n }\n printRepositoryProblems(config.repository);\n } catch (err) /* istanbul ignore next */ {\n setMeta({ repository: config.repository });\n const errorRes = await handleError(config, err);\n const pruneWhenErrors = [\n REPOSITORY_DISABLED_BY_CONFIG,\n REPOSITORY_FORKED,\n REPOSITORY_NO_CONFIG,\n ];\n if (pruneWhenErrors.includes(errorRes)) {\n await pruneStaleBranches(config, []);\n }\n repoResult = processResult(config, errorRes);\n }\n } else {\n logger.debug(\n { err: error },\n 'Skipping the rest to the Renovate run due to error in `init` phase',\n );\n }\n\n if (localDir && !repoConfig.persistRepoData) {\n try {\n await deleteLocalFile('.');\n } catch (err) /* istanbul ignore if */ {\n logger.warn({ err }, 'localDir deletion error');\n }\n }\n try {\n await rmCache(privateCacheDir());\n } catch (err) /* istanbul ignore if */ {\n logger.warn({ err }, 'privateCacheDir deletion error');\n }\n const splits = getSplits();\n logger.debug(splits, 'Repository timing splits (milliseconds)');\n PackageCacheStats.report();\n DatasourceCacheStats.report();\n HttpStats.report();\n HttpCacheStats.report();\n LookupStats.report();\n GetDatasourceReleasesStats.report();\n ObsoleteCacheHitLogger.report();\n AbandonedPackageStats.report();\n GitOperationStats.report();\n const cloned = isCloned();\n /* v8 ignore next -- coverage not required of these `undefined` checks, as we're happy receiving an `undefined` in the logs */\n logger.info(\n {\n cloned,\n durationMs: splits.total,\n result: repoResult?.res,\n status: repoResult?.status,\n enabled: repoResult?.enabled,\n onboarded: repoResult?.onboarded,\n exitCode: repoResult?.exitCode,\n },\n 'Repository finished',\n );\n resetRepositoryLogLevelRemaps();\n return repoResult;\n}\n\n// istanbul ignore next: renovateRepository is ignored\nfunction emptyExtract(): ExtractResult {\n return instrument(\n 'extract',\n () => {\n addSplit('extract');\n addSplit('lookup');\n return {\n branches: [],\n branchList: [getInheritedOrGlobal('onboardingBranch')!], // to prevent auto closing\n packageFiles: {},\n };\n },\n {\n attributes: {\n [ATTR_RENOVATE_SPLIT]: 'extract',\n },\n },\n );\n}\n\nexport function printRepositoryProblems(repository: string | undefined): void {\n const repoProblems = extractRepoProblems(repository);\n if (repoProblems.size) {\n logger.debug(\n { repoProblems: Array.from(repoProblems) },\n 'repository problems',\n );\n }\n}\n"],"mappings":"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"}
@@ -29,6 +29,8 @@ interface ProcessResult {
29
29
  status: ProcessStatus;
30
30
  enabled: boolean | undefined;
31
31
  onboarded: boolean | undefined;
32
+ /** the process exit code this result maps to, used when `exitCodeForErrors` is enabled */
33
+ exitCode: number;
32
34
  }
33
35
  /** a strong type for any repository result status that Renovate may report */
34
36
  type RepositoryResult =
@@ -1,6 +1,26 @@
1
- import { CONFIG_SECRETS_EXPOSED, CONFIG_VALIDATION, MISSING_API_CREDENTIALS, RepositoryErrors } from "../../constants/error-messages.js";
1
+ import { CONFIG_SECRETS_EXPOSED, CONFIG_VALIDATION, ConfigErrors, EXTERNAL_HOST_ERROR, MANAGER_LOCKFILE_ERROR, MISSING_API_CREDENTIALS, PlatformErrors, RepositoryErrors, SystemErrors, TemporaryErrors, UNKNOWN_ERROR } from "../../constants/error-messages.js";
2
2
  import { logger } from "../../logger/index.js";
3
3
  //#region lib/workers/repository/result.ts
4
+ /**
5
+ * Exit code per known error group, used when `exitCodeForErrors` is enabled.
6
+ *
7
+ * `RepositoryErrors` are deliberately absent: they mean the repository is disabled, not that the run failed.
8
+ */
9
+ const exitCodes = [
10
+ [SystemErrors, 3],
11
+ [PlatformErrors, 4],
12
+ [ConfigErrors, 5],
13
+ [TemporaryErrors, 6],
14
+ [[
15
+ EXTERNAL_HOST_ERROR,
16
+ MANAGER_LOCKFILE_ERROR,
17
+ MISSING_API_CREDENTIALS
18
+ ], 7],
19
+ [[UNKNOWN_ERROR], 8]
20
+ ];
21
+ function getExitCode(res) {
22
+ return exitCodes.find(([errors]) => errors.includes(res))?.[1] ?? 0;
23
+ }
4
24
  function processResult(config, res) {
5
25
  const enabledStatuses = [
6
26
  CONFIG_SECRETS_EXPOSED,
@@ -35,7 +55,8 @@ function processResult(config, res) {
35
55
  res,
36
56
  status,
37
57
  enabled,
38
- onboarded
58
+ onboarded,
59
+ exitCode: getExitCode(res)
39
60
  };
40
61
  }
41
62
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"result.js","names":[],"sources":["../../../lib/workers/repository/result.ts"],"sourcesContent":["import type { RenovateConfig } from '../../config/types.ts';\n\nimport type {\n ConfigErrors,\n EXTERNAL_HOST_ERROR,\n MANAGER_LOCKFILE_ERROR,\n PlatformErrors,\n SystemErrors,\n TemporaryErrors,\n UNKNOWN_ERROR,\n} from '../../constants/error-messages.ts';\nimport {\n CONFIG_SECRETS_EXPOSED,\n CONFIG_VALIDATION,\n MISSING_API_CREDENTIALS,\n RepositoryErrors,\n} from '../../constants/error-messages.ts';\n\nimport { logger } from '../../logger/index.ts';\n\nexport type ProcessStatus =\n /**\n * The repository has been disabled, and will not be processed.\n *\n * See {@link RepositoryErrors} for information on which statuses lead to this.\n */\n | 'disabled'\n /**\n * The repository has onboarded to Renovate, so will see PRs and/or branches raised by Renovate.\n *\n * The repository has not yet merged any PRs, or the repository performs branch-based automerge and those have not been detected (TODO #40635).\n */\n | 'onboarded'\n /**\n * The repository has onboarded to Renovate, and has merged at least 1 Renovate PR.\n *\n * The repository may also perform branch-based automerge which has not been detected (TODO #40635).\n */\n | 'activated'\n /**\n * The repository has an onboarding PR from Renovate that has not yet been reviewed and merged.\n */\n | 'onboarding'\n | 'unknown';\n\nexport interface ProcessResult {\n res: RepositoryResult;\n status: ProcessStatus;\n enabled: boolean | undefined;\n onboarded: boolean | undefined;\n}\n\n/** a strong type for any repository result status that Renovate may report */\nexport type RepositoryResult =\n /** repository was processed successfully */\n | 'done'\n /** Renovate performed branch-based automerge on one branch during its run */\n | 'automerged'\n /** the repository is not yet onboarded, and its onboarding PR was processed during this run */\n | 'onboarding'\n // common set of errors\n | (typeof SystemErrors)[number]\n | (typeof RepositoryErrors)[number]\n | (typeof TemporaryErrors)[number]\n | (typeof ConfigErrors)[number]\n | (typeof PlatformErrors)[number]\n // other errors\n | typeof EXTERNAL_HOST_ERROR\n | typeof MISSING_API_CREDENTIALS\n | typeof MANAGER_LOCKFILE_ERROR\n | typeof UNKNOWN_ERROR;\n\nexport function processResult(\n config: RenovateConfig,\n res: RepositoryResult,\n): ProcessResult {\n const enabledStatuses = [\n CONFIG_SECRETS_EXPOSED,\n CONFIG_VALIDATION,\n MISSING_API_CREDENTIALS,\n ];\n let status: ProcessStatus;\n let enabled: boolean | undefined;\n let onboarded: boolean | undefined;\n // istanbul ignore next\n if (RepositoryErrors.includes(res as (typeof RepositoryErrors)[number])) {\n status = 'disabled';\n enabled = false;\n } else if (config.repoIsActivated) {\n status = 'activated';\n enabled = true;\n onboarded = true;\n } else if (enabledStatuses.includes(res) || config.repoIsOnboarded) {\n status = 'onboarded';\n enabled = true;\n onboarded = true;\n } else if (config.repoIsOnboarded === false) {\n status = 'onboarding';\n enabled = true;\n onboarded = false;\n } else {\n logger.debug(`Unknown res: ${res}`);\n status = 'unknown';\n }\n logger.debug(\n // TODO: types (#22198)\n `Repository result: ${res}, status: ${status}, enabled: ${enabled!}, onboarded: ${onboarded!}`,\n );\n return { res, status, enabled, onboarded };\n}\n"],"mappings":";;;AAwEA,SAAgB,cACd,QACA,KACe;CACf,MAAM,kBAAkB;EACtB;EACA;EACA;CACF;CACA,IAAI;CACJ,IAAI;CACJ,IAAI;;CAEJ,IAAI,iBAAiB,SAAS,GAAwC,GAAG;EACvE,SAAS;EACT,UAAU;CACZ,OAAO,IAAI,OAAO,iBAAiB;EACjC,SAAS;EACT,UAAU;EACV,YAAY;CACd,OAAO,IAAI,gBAAgB,SAAS,GAAG,KAAK,OAAO,iBAAiB;EAClE,SAAS;EACT,UAAU;EACV,YAAY;CACd,OAAO,IAAI,OAAO,oBAAoB,OAAO;EAC3C,SAAS;EACT,UAAU;EACV,YAAY;CACd,OAAO;EACL,OAAO,MAAM,gBAAgB,KAAK;EAClC,SAAS;CACX;CACA,OAAO,MAEL,sBAAsB,IAAI,YAAY,OAAO,aAAa,QAAS,eAAe,WACpF;CACA,OAAO;EAAE;EAAK;EAAQ;EAAS;CAAU;AAC3C"}
1
+ {"version":3,"file":"result.js","names":[],"sources":["../../../lib/workers/repository/result.ts"],"sourcesContent":["import type { RenovateConfig } from '../../config/types.ts';\n\nimport {\n CONFIG_SECRETS_EXPOSED,\n CONFIG_VALIDATION,\n ConfigErrors,\n EXTERNAL_HOST_ERROR,\n MANAGER_LOCKFILE_ERROR,\n MISSING_API_CREDENTIALS,\n PlatformErrors,\n RepositoryErrors,\n SystemErrors,\n TemporaryErrors,\n UNKNOWN_ERROR,\n} from '../../constants/error-messages.ts';\n\nimport { logger } from '../../logger/index.ts';\n\nexport type ProcessStatus =\n /**\n * The repository has been disabled, and will not be processed.\n *\n * See {@link RepositoryErrors} for information on which statuses lead to this.\n */\n | 'disabled'\n /**\n * The repository has onboarded to Renovate, so will see PRs and/or branches raised by Renovate.\n *\n * The repository has not yet merged any PRs, or the repository performs branch-based automerge and those have not been detected (TODO #40635).\n */\n | 'onboarded'\n /**\n * The repository has onboarded to Renovate, and has merged at least 1 Renovate PR.\n *\n * The repository may also perform branch-based automerge which has not been detected (TODO #40635).\n */\n | 'activated'\n /**\n * The repository has an onboarding PR from Renovate that has not yet been reviewed and merged.\n */\n | 'onboarding'\n | 'unknown';\n\nexport interface ProcessResult {\n res: RepositoryResult;\n status: ProcessStatus;\n enabled: boolean | undefined;\n onboarded: boolean | undefined;\n /** the process exit code this result maps to, used when `exitCodeForErrors` is enabled */\n exitCode: number;\n}\n\n/** a strong type for any repository result status that Renovate may report */\nexport type RepositoryResult =\n /** repository was processed successfully */\n | 'done'\n /** Renovate performed branch-based automerge on one branch during its run */\n | 'automerged'\n /** the repository is not yet onboarded, and its onboarding PR was processed during this run */\n | 'onboarding'\n // common set of errors\n | (typeof SystemErrors)[number]\n | (typeof RepositoryErrors)[number]\n | (typeof TemporaryErrors)[number]\n | (typeof ConfigErrors)[number]\n | (typeof PlatformErrors)[number]\n // other errors\n | typeof EXTERNAL_HOST_ERROR\n | typeof MISSING_API_CREDENTIALS\n | typeof MANAGER_LOCKFILE_ERROR\n | typeof UNKNOWN_ERROR;\n\n/**\n * Exit code per known error group, used when `exitCodeForErrors` is enabled.\n *\n * `RepositoryErrors` are deliberately absent: they mean the repository is disabled, not that the run failed.\n */\nconst exitCodes: [readonly string[], number][] = [\n [SystemErrors, 3],\n [PlatformErrors, 4],\n [ConfigErrors, 5],\n [TemporaryErrors, 6],\n [[EXTERNAL_HOST_ERROR, MANAGER_LOCKFILE_ERROR, MISSING_API_CREDENTIALS], 7],\n [[UNKNOWN_ERROR], 8],\n];\n\nfunction getExitCode(res: RepositoryResult): number {\n return exitCodes.find(([errors]) => errors.includes(res))?.[1] ?? 0;\n}\n\nexport function processResult(\n config: RenovateConfig,\n res: RepositoryResult,\n): ProcessResult {\n const enabledStatuses = [\n CONFIG_SECRETS_EXPOSED,\n CONFIG_VALIDATION,\n MISSING_API_CREDENTIALS,\n ];\n let status: ProcessStatus;\n let enabled: boolean | undefined;\n let onboarded: boolean | undefined;\n // istanbul ignore next\n if (RepositoryErrors.includes(res as (typeof RepositoryErrors)[number])) {\n status = 'disabled';\n enabled = false;\n } else if (config.repoIsActivated) {\n status = 'activated';\n enabled = true;\n onboarded = true;\n } else if (enabledStatuses.includes(res) || config.repoIsOnboarded) {\n status = 'onboarded';\n enabled = true;\n onboarded = true;\n } else if (config.repoIsOnboarded === false) {\n status = 'onboarding';\n enabled = true;\n onboarded = false;\n } else {\n logger.debug(`Unknown res: ${res}`);\n status = 'unknown';\n }\n logger.debug(\n // TODO: types (#22198)\n `Repository result: ${res}, status: ${status}, enabled: ${enabled!}, onboarded: ${onboarded!}`,\n );\n return { res, status, enabled, onboarded, exitCode: getExitCode(res) };\n}\n"],"mappings":";;;;;;;;AA6EA,MAAM,YAA2C;CAC/C,CAAC,cAAc,CAAC;CAChB,CAAC,gBAAgB,CAAC;CAClB,CAAC,cAAc,CAAC;CAChB,CAAC,iBAAiB,CAAC;CACnB,CAAC;EAAC;EAAqB;EAAwB;CAAuB,GAAG,CAAC;CAC1E,CAAC,CAAC,aAAa,GAAG,CAAC;AACrB;AAEA,SAAS,YAAY,KAA+B;CAClD,OAAO,UAAU,MAAM,CAAC,YAAY,OAAO,SAAS,GAAG,CAAC,CAAC,GAAG,MAAM;AACpE;AAEA,SAAgB,cACd,QACA,KACe;CACf,MAAM,kBAAkB;EACtB;EACA;EACA;CACF;CACA,IAAI;CACJ,IAAI;CACJ,IAAI;;CAEJ,IAAI,iBAAiB,SAAS,GAAwC,GAAG;EACvE,SAAS;EACT,UAAU;CACZ,OAAO,IAAI,OAAO,iBAAiB;EACjC,SAAS;EACT,UAAU;EACV,YAAY;CACd,OAAO,IAAI,gBAAgB,SAAS,GAAG,KAAK,OAAO,iBAAiB;EAClE,SAAS;EACT,UAAU;EACV,YAAY;CACd,OAAO,IAAI,OAAO,oBAAoB,OAAO;EAC3C,SAAS;EACT,UAAU;EACV,YAAY;CACd,OAAO;EACL,OAAO,MAAM,gBAAgB,KAAK;EAClC,SAAS;CACX;CACA,OAAO,MAEL,sBAAsB,IAAI,YAAY,OAAO,aAAa,QAAS,eAAe,WACpF;CACA,OAAO;EAAE;EAAK;EAAQ;EAAS;EAAW,UAAU,YAAY,GAAG;CAAE;AACvE"}
@@ -1,6 +1,7 @@
1
1
  import { logger } from "../../../../../logger/index.js";
2
2
  import { instrument } from "../../../../../instrumentation/index.js";
3
3
  import { detectPlatform } from "../../../../../util/common.js";
4
+ import { ExternalHostError } from "../../../../../types/errors/external-host-error.js";
4
5
  import { get } from "../../../../../modules/versioning/index.js";
5
6
  import api from "./api.js";
6
7
  import { isNullOrUndefined } from "@sindresorhus/is";
@@ -29,8 +30,12 @@ async function getChangeLogJSON(config) {
29
30
  return null;
30
31
  }
31
32
  return await changeLogSource.getChangeLogJSON(config);
32
- } catch (err) /* istanbul ignore next */ {
33
- logger.error({
33
+ } catch (err) {
34
+ if (err instanceof ExternalHostError) logger.warn({
35
+ config,
36
+ err
37
+ }, "getChangeLogJSON error");
38
+ else logger.error({
34
39
  config,
35
40
  err
36
41
  }, "getChangeLogJSON error");
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["allVersioning.get"],"sources":["../../../../../../lib/workers/repository/update/pr/changelog/index.ts"],"sourcesContent":["import { isNullOrUndefined } from '@sindresorhus/is';\nimport { instrument } from '../../../../../instrumentation/index.ts';\nimport { logger } from '../../../../../logger/index.ts';\nimport * as allVersioning from '../../../../../modules/versioning/index.ts';\nimport { detectPlatform } from '../../../../../util/common.ts';\nimport type { BranchUpgradeConfig } from '../../../../types.ts';\nimport api from './api.ts';\nimport type { ChangeLogSource } from './source.ts';\nimport type { ChangeLogResult } from './types.ts';\n\nexport * from './types.ts';\n\nexport async function getChangeLogJSON(\n config: BranchUpgradeConfig,\n): Promise<ChangeLogResult | null> {\n return await instrument('getChangeLogJSON()', async () => {\n const { sourceUrl, versioning, currentVersion, newVersion } = config;\n try {\n if (!(sourceUrl && currentVersion && newVersion)) {\n return null;\n }\n const versioningApi = allVersioning.get(versioning);\n if (versioningApi.equals(currentVersion, newVersion)) {\n return null;\n }\n logger.debug(\n `Fetching changelog: ${sourceUrl} (${currentVersion} -> ${newVersion})`,\n );\n\n const platform = detectPlatform(sourceUrl);\n\n if (isNullOrUndefined(platform)) {\n logger.info(\n { sourceUrl, hostType: platform },\n 'Unknown platform, skipping changelog fetching.',\n );\n return null;\n }\n\n const changeLogSource = getChangeLogSourceFor(platform);\n\n if (isNullOrUndefined(changeLogSource)) {\n logger.info(\n { sourceUrl, hostType: platform },\n 'Unknown changelog source, skipping changelog fetching.',\n );\n return null;\n }\n\n return await changeLogSource.getChangeLogJSON(config);\n } catch (err) /* istanbul ignore next */ {\n logger.error({ config, err }, 'getChangeLogJSON error');\n return null;\n }\n });\n}\n\nexport function getChangeLogSourceFor(\n platform: string,\n): ChangeLogSource | null {\n return api.get(platform) ?? null;\n}\n"],"mappings":";;;;;;;AAYA,eAAsB,iBACpB,QACiC;CACjC,OAAO,MAAM,WAAW,sBAAsB,YAAY;EACxD,MAAM,EAAE,WAAW,YAAY,gBAAgB,eAAe;EAC9D,IAAI;GACF,IAAI,EAAE,aAAa,kBAAkB,aACnC,OAAO;GAGT,IADsBA,IAAkB,UACxB,CAAC,CAAC,OAAO,gBAAgB,UAAU,GACjD,OAAO;GAET,OAAO,MACL,uBAAuB,UAAU,IAAI,eAAe,MAAM,WAAW,EACvE;GAEA,MAAM,WAAW,eAAe,SAAS;GAEzC,IAAI,kBAAkB,QAAQ,GAAG;IAC/B,OAAO,KACL;KAAE;KAAW,UAAU;IAAS,GAChC,gDACF;IACA,OAAO;GACT;GAEA,MAAM,kBAAkB,sBAAsB,QAAQ;GAEtD,IAAI,kBAAkB,eAAe,GAAG;IACtC,OAAO,KACL;KAAE;KAAW,UAAU;IAAS,GAChC,wDACF;IACA,OAAO;GACT;GAEA,OAAO,MAAM,gBAAgB,iBAAiB,MAAM;EACtD,SAAS,gCAAgC;GACvC,OAAO,MAAM;IAAE;IAAQ;GAAI,GAAG,wBAAwB;GACtD,OAAO;EACT;CACF,CAAC;AACH;AAEA,SAAgB,sBACd,UACwB;CACxB,OAAO,IAAI,IAAI,QAAQ,KAAK;AAC9B"}
1
+ {"version":3,"file":"index.js","names":["allVersioning.get"],"sources":["../../../../../../lib/workers/repository/update/pr/changelog/index.ts"],"sourcesContent":["import { isNullOrUndefined } from '@sindresorhus/is';\nimport { instrument } from '../../../../../instrumentation/index.ts';\nimport { logger } from '../../../../../logger/index.ts';\nimport * as allVersioning from '../../../../../modules/versioning/index.ts';\nimport { ExternalHostError } from '../../../../../types/errors/external-host-error.ts';\nimport { detectPlatform } from '../../../../../util/common.ts';\nimport type { BranchUpgradeConfig } from '../../../../types.ts';\nimport api from './api.ts';\nimport type { ChangeLogSource } from './source.ts';\nimport type { ChangeLogResult } from './types.ts';\n\nexport * from './types.ts';\n\nexport async function getChangeLogJSON(\n config: BranchUpgradeConfig,\n): Promise<ChangeLogResult | null> {\n return await instrument('getChangeLogJSON()', async () => {\n const { sourceUrl, versioning, currentVersion, newVersion } = config;\n try {\n if (!(sourceUrl && currentVersion && newVersion)) {\n return null;\n }\n const versioningApi = allVersioning.get(versioning);\n if (versioningApi.equals(currentVersion, newVersion)) {\n return null;\n }\n logger.debug(\n `Fetching changelog: ${sourceUrl} (${currentVersion} -> ${newVersion})`,\n );\n\n const platform = detectPlatform(sourceUrl);\n\n if (isNullOrUndefined(platform)) {\n logger.info(\n { sourceUrl, hostType: platform },\n 'Unknown platform, skipping changelog fetching.',\n );\n return null;\n }\n\n const changeLogSource = getChangeLogSourceFor(platform);\n\n if (isNullOrUndefined(changeLogSource)) {\n logger.info(\n { sourceUrl, hostType: platform },\n 'Unknown changelog source, skipping changelog fetching.',\n );\n return null;\n }\n\n return await changeLogSource.getChangeLogJSON(config);\n } catch (err) {\n // A changelog fetch is best-effort: on failure we return null and the\n // update proceeds. A transient external host error must not be logged at\n // error level, because logged errors alone cause a non-zero run exit.\n if (err instanceof ExternalHostError) {\n logger.warn({ config, err }, 'getChangeLogJSON error');\n } else {\n logger.error({ config, err }, 'getChangeLogJSON error');\n }\n return null;\n }\n });\n}\n\nexport function getChangeLogSourceFor(\n platform: string,\n): ChangeLogSource | null {\n return api.get(platform) ?? null;\n}\n"],"mappings":";;;;;;;;AAaA,eAAsB,iBACpB,QACiC;CACjC,OAAO,MAAM,WAAW,sBAAsB,YAAY;EACxD,MAAM,EAAE,WAAW,YAAY,gBAAgB,eAAe;EAC9D,IAAI;GACF,IAAI,EAAE,aAAa,kBAAkB,aACnC,OAAO;GAGT,IADsBA,IAAkB,UACxB,CAAC,CAAC,OAAO,gBAAgB,UAAU,GACjD,OAAO;GAET,OAAO,MACL,uBAAuB,UAAU,IAAI,eAAe,MAAM,WAAW,EACvE;GAEA,MAAM,WAAW,eAAe,SAAS;GAEzC,IAAI,kBAAkB,QAAQ,GAAG;IAC/B,OAAO,KACL;KAAE;KAAW,UAAU;IAAS,GAChC,gDACF;IACA,OAAO;GACT;GAEA,MAAM,kBAAkB,sBAAsB,QAAQ;GAEtD,IAAI,kBAAkB,eAAe,GAAG;IACtC,OAAO,KACL;KAAE;KAAW,UAAU;IAAS,GAChC,wDACF;IACA,OAAO;GACT;GAEA,OAAO,MAAM,gBAAgB,iBAAiB,MAAM;EACtD,SAAS,KAAK;GAIZ,IAAI,eAAe,mBACjB,OAAO,KAAK;IAAE;IAAQ;GAAI,GAAG,wBAAwB;QAErD,OAAO,MAAM;IAAE;IAAQ;GAAI,GAAG,wBAAwB;GAExD,OAAO;EACT;CACF,CAAC;AACH;AAEA,SAAgB,sBACd,UACwB;CACxB,OAAO,IAAI,IAAI,QAAQ,KAAK;AAC9B"}
@@ -6,7 +6,7 @@ import { ExternalHostError } from "../../../../types/errors/external-host-error.
6
6
  import { incCountValue, isLimitReached } from "../../../global/limits.js";
7
7
  import { getBranchLastCommitTime } from "../../../../util/git/index.js";
8
8
  import { getElapsedHours } from "../../../../util/date.js";
9
- import { stripEmojis } from "../../../../util/emoji.js";
9
+ import { emojify, stripEmojis } from "../../../../util/emoji.js";
10
10
  import { getPrBodyStruct, hashBody } from "../../../../modules/platform/pr-body.js";
11
11
  import { scm } from "../../../../modules/platform/scm.js";
12
12
  import { platform } from "../../../../modules/platform/index.js";
@@ -22,6 +22,7 @@ import { addParticipants } from "./participants.js";
22
22
  import { generatePrBodyFingerprintConfig, validatePrCache } from "./pr-fingerprint.js";
23
23
  import { tryReuseAutoclosedPr } from "./pr-reuse.js";
24
24
  import { isArray, isNonEmptyArray, isNumber, isUndefined } from "@sindresorhus/is";
25
+ import { codeBlock } from "common-tags";
25
26
  //#region lib/workers/repository/update/pr/index.ts
26
27
  function getPlatformPrOptions(config) {
27
28
  const usePlatformAutomerge = Boolean(config.automerge && (config.automergeType === "pr" || config.automergeType === "branch") && config.platformAutomerge);
@@ -59,13 +60,12 @@ function addPullRequestNoteIfAttestationHasBeenLost(upgrade, currentReleaseHasAt
59
60
  const newRelease = upgrade.releases?.find((release) => release.version === newVersion);
60
61
  if (newRelease && currentReleaseHasAttestation === true && newRelease.attestation !== true) {
61
62
  upgrade.prBodyNotes ??= [];
62
- upgrade.prBodyNotes.push([
63
- "> :stop_sign: **Caution**",
64
- ">",
65
- `> ${name} ${currentVersion} was released with an attestation, but ${newVersion} has no attestation.`,
66
- `> Verify that release ${newVersion} was published by the expected author.`,
67
- "\n"
68
- ].join("\n"));
63
+ upgrade.prBodyNotes.push(emojify(codeBlock`
64
+ > :stop_sign: **Caution**
65
+ >
66
+ > ${name} ${currentVersion} was released with an attestation, but ${newVersion} has no attestation.
67
+ > Verify that release ${newVersion} was published by the expected author.
68
+ `));
69
69
  }
70
70
  }
71
71
  async function ensurePr(prConfig) {
@@ -178,13 +178,12 @@ async function ensurePr(prConfig) {
178
178
  }
179
179
  } else if (logJSON.error === "MissingGithubToken") {
180
180
  upgrade.prBodyNotes ??= [];
181
- upgrade.prBodyNotes.push([
182
- "> :exclamation: **Important**",
183
- "> ",
184
- "> Release Notes retrieval for this PR were skipped because no github.com credentials were available. ",
185
- "> If you are self-hosted, please see [this instruction](https://github.com/renovatebot/renovate/blob/master/docs/usage/examples/self-hosting.md#githubcom-token-for-release-notes).",
186
- "\n"
187
- ].join("\n"));
181
+ upgrade.prBodyNotes.push(emojify(codeBlock`
182
+ > :exclamation: **Important**
183
+ >
184
+ > Release Notes retrieval for this PR were skipped because no github.com credentials were available.
185
+ > If you are self-hosted, please see [this instruction](https://github.com/renovatebot/renovate/blob/master/docs/usage/examples/self-hosting.md#githubcom-token-for-release-notes).
186
+ `));
188
187
  }
189
188
  }
190
189
  addPullRequestNoteIfAttestationHasBeenLost(upgrade, currentReleaseHasAttestation);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../../../lib/workers/repository/update/pr/index.ts"],"sourcesContent":["import {\n isArray,\n isNonEmptyArray,\n isNumber,\n isUndefined,\n} from '@sindresorhus/is';\nimport { GlobalConfig } from '../../../../config/global.ts';\nimport type { RenovateConfig } from '../../../../config/types.ts';\nimport {\n PLATFORM_INTEGRATION_UNAUTHORIZED,\n PLATFORM_RATE_LIMIT_EXCEEDED,\n REPOSITORY_CHANGED,\n} from '../../../../constants/error-messages.ts';\nimport { pkg } from '../../../../expose.ts';\nimport { logger } from '../../../../logger/index.ts';\nimport { ensureComment } from '../../../../modules/platform/comment.ts';\nimport type {\n PlatformPrOptions,\n Pr,\n PrDebugData,\n UpdatePrConfig,\n} from '../../../../modules/platform/index.ts';\nimport { platform } from '../../../../modules/platform/index.ts';\nimport {\n getPrBodyStruct,\n hashBody,\n} from '../../../../modules/platform/pr-body.ts';\nimport { scm } from '../../../../modules/platform/scm.ts';\nimport { ExternalHostError } from '../../../../types/errors/external-host-error.ts';\nimport { getElapsedHours } from '../../../../util/date.ts';\nimport { stripEmojis } from '../../../../util/emoji.ts';\nimport { fingerprint } from '../../../../util/fingerprint.ts';\nimport { getBranchLastCommitTime } from '../../../../util/git/index.ts';\nimport { memoize } from '../../../../util/memoize.ts';\nimport { incCountValue, isLimitReached } from '../../../global/limits.ts';\nimport type {\n BranchConfig,\n BranchUpgradeConfig,\n PrBlockedBy,\n} from '../../../types.ts';\nimport { embedChangelogs } from '../../changelog/index.ts';\nimport { resolveBranchStatus } from '../branch/status-checks.ts';\nimport { getPrBody } from './body/index.ts';\nimport {\n getChangedLabels,\n prepareLabels,\n shouldUpdateLabels,\n} from './labels.ts';\nimport { addParticipants } from './participants.ts';\nimport { getPrCache, setPrCache } from './pr-cache.ts';\nimport {\n generatePrBodyFingerprintConfig,\n validatePrCache,\n} from './pr-fingerprint.ts';\nimport { tryReuseAutoclosedPr } from './pr-reuse.ts';\n\nexport function getPlatformPrOptions(\n config: RenovateConfig & PlatformPrOptions,\n): PlatformPrOptions {\n const usePlatformAutomerge = Boolean(\n config.automerge &&\n (config.automergeType === 'pr' || config.automergeType === 'branch') &&\n config.platformAutomerge,\n );\n\n return {\n autoApprove: !!config.autoApprove,\n automergeCommitMessage: config.commitMessage,\n automergeStrategy: config.automergeStrategy,\n azureWorkItemId: config.azureWorkItemId ?? 0,\n bbAutoResolvePrTasks: !!config.bbAutoResolvePrTasks,\n bbUseDefaultReviewers: !!config.bbUseDefaultReviewers,\n gitLabIgnoreApprovals: !!config.gitLabIgnoreApprovals,\n forkModeDisallowMaintainerEdits: !!config.forkModeDisallowMaintainerEdits,\n usePlatformAutomerge,\n };\n}\n\nexport interface ResultWithPr {\n type: 'with-pr';\n pr: Pr;\n}\n\nexport interface ResultWithoutPr {\n type: 'without-pr';\n prBlockedBy: PrBlockedBy;\n}\n\nexport type EnsurePrResult = ResultWithPr | ResultWithoutPr;\n\nexport function updatePrDebugData(\n targetBranch: string,\n labels: string[],\n debugData: PrDebugData | undefined,\n): PrDebugData {\n const createdByRenovateVersion = debugData?.createdInVer ?? pkg.version;\n const updatedByRenovateVersion = pkg.version;\n\n const updatedPrDebugData: PrDebugData = {\n createdInVer: createdByRenovateVersion,\n updatedInVer: updatedByRenovateVersion,\n targetBranch,\n };\n\n // Add labels to the debug data object.\n // When to add:\n // 1. Add it when a new PR is created, i.e., when debugData is undefined.\n // 2. Add it if an existing PR already has labels in the debug data, confirming that we can update its labels.\n if (!debugData || isArray(debugData.labels)) {\n updatedPrDebugData.labels = labels;\n }\n\n return updatedPrDebugData;\n}\n\nfunction hasNotIgnoredReviewers(pr: Pr, config: BranchConfig): boolean {\n if (\n isNonEmptyArray(config.ignoreReviewers) &&\n isNonEmptyArray(pr.reviewers)\n ) {\n const ignoreReviewers = new Set(config.ignoreReviewers);\n return (\n pr.reviewers.filter((reviewer) => !ignoreReviewers.has(reviewer)).length >\n 0\n );\n }\n return isNonEmptyArray(pr.reviewers);\n}\n\nfunction addPullRequestNoteIfAttestationHasBeenLost(\n upgrade: BranchUpgradeConfig,\n currentReleaseHasAttestation: boolean | undefined,\n): void {\n const { packageName, depName, currentVersion, newVersion } = upgrade;\n const name = packageName ?? depName;\n\n const newRelease = upgrade.releases?.find(\n (release) => release.version === newVersion,\n );\n\n if (\n newRelease &&\n currentReleaseHasAttestation === true &&\n newRelease.attestation !== true\n ) {\n upgrade.prBodyNotes ??= [];\n upgrade.prBodyNotes.push(\n [\n '> :stop_sign: **Caution**',\n '>',\n `> ${name} ${currentVersion} was released with an attestation, but ${newVersion} has no attestation.`,\n `> Verify that release ${newVersion} was published by the expected author.`,\n '\\n',\n ].join('\\n'),\n );\n }\n}\n\n// Ensures that PR exists with matching title/body\nexport async function ensurePr(\n prConfig: BranchConfig,\n): Promise<EnsurePrResult> {\n const config: BranchConfig = { ...prConfig };\n const filteredPrConfig = generatePrBodyFingerprintConfig(config);\n const prBodyFingerprint = fingerprint(filteredPrConfig);\n logger.trace({ config }, 'ensurePr');\n // If there is a group, it will use the config of the first upgrade in the array\n const {\n branchName,\n ignoreTests,\n internalChecksAsSuccess,\n prTitle = '',\n upgrades,\n hasAttestation: currentReleaseHasAttestation,\n } = config;\n const getBranchStatus = memoize(() =>\n resolveBranchStatus(branchName, !!internalChecksAsSuccess, ignoreTests),\n );\n const dependencyDashboardCheck =\n config.dependencyDashboardChecks?.[config.branchName];\n const dependencyDashboardApproved =\n dependencyDashboardCheck === 'approvePr' ||\n dependencyDashboardCheck === 'unpend';\n // Check if PR already exists\n const existingPr =\n (await platform.getBranchPr(branchName, config.baseBranch)) ??\n (await tryReuseAutoclosedPr(branchName, prTitle));\n const prCache = getPrCache(branchName);\n if (existingPr) {\n logger.debug('Found existing PR');\n if (existingPr.bodyStruct?.rebaseRequested) {\n logger.debug('PR rebase requested, so skipping cache check');\n } else if (prCache) {\n logger.trace({ prCache }, 'Found existing PR cache');\n // return if pr cache is valid and pr was not changed in the past 24hrs\n // skip cache when autoApprove is set, since new commits may have\n // reset platform approvals (e.g. GitLab's \"Remove all approvals\" setting)\n if (validatePrCache(prCache, prBodyFingerprint) && !config.autoApprove) {\n return { type: 'with-pr', pr: existingPr };\n }\n } else if (config.repositoryCache === 'enabled') {\n logger.debug('PR cache not found');\n }\n }\n config.upgrades = [];\n\n if (config.artifactErrors?.length) {\n logger.debug('Forcing PR because of artifact errors');\n config.forcePr = true;\n }\n\n if (dependencyDashboardApproved) {\n logger.debug('Forcing PR because of dependency dashboard approval');\n config.forcePr = true;\n }\n\n if (!existingPr) {\n // Only create a PR if a branch automerge has failed\n if (\n config.automerge === true &&\n config.automergeType?.startsWith('branch') &&\n !config.forcePr\n ) {\n logger.debug(`Branch automerge is enabled`);\n if (\n config.stabilityStatus !== 'yellow' &&\n (await getBranchStatus()) === 'yellow' &&\n isNumber(config.prNotPendingHours)\n ) {\n logger.debug('Checking how long this branch has been pending');\n const lastCommitTime = await getBranchLastCommitTime(branchName);\n if (getElapsedHours(lastCommitTime) >= config.prNotPendingHours) {\n logger.debug(\n `Branch exceeds prNotPending=${config.prNotPendingHours}, hours - forcing PR creation`,\n );\n config.forcePr = true;\n }\n }\n if (config.forcePr || (await getBranchStatus()) === 'red') {\n logger.debug(`Branch tests failed, so will create PR`);\n } else {\n // Branch should be automerged, so we don't want to create a PR\n return { type: 'without-pr', prBlockedBy: 'BranchAutomerge' };\n }\n }\n if (config.prCreation === 'status-success') {\n logger.debug('Checking branch combined status');\n if ((await getBranchStatus()) !== 'green') {\n logger.debug(`Branch status isn't green - not creating PR`);\n return { type: 'without-pr', prBlockedBy: 'AwaitingTests' };\n }\n logger.debug('Branch status success');\n } else if (\n config.prCreation === 'approval' &&\n !dependencyDashboardApproved\n ) {\n return { type: 'without-pr', prBlockedBy: 'NeedsApproval' };\n } else if (config.prCreation === 'not-pending' && !config.forcePr) {\n logger.debug('Checking branch combined status');\n if ((await getBranchStatus()) === 'yellow') {\n logger.debug(`Branch status is yellow - checking timeout`);\n const lastCommitTime = await getBranchLastCommitTime(branchName);\n const elapsedHours = getElapsedHours(lastCommitTime);\n if (\n !dependencyDashboardCheck &&\n ((config.stabilityStatus && config.stabilityStatus !== 'yellow') ||\n (isNumber(config.prNotPendingHours) &&\n elapsedHours < config.prNotPendingHours))\n ) {\n logger.debug(\n `Branch is ${elapsedHours} hours old - skipping PR creation as prNotPendingHours is set to ${config.prNotPendingHours}`,\n );\n return {\n type: 'without-pr',\n prBlockedBy: 'AwaitingTests',\n };\n }\n const prNotPendingHours = String(config.prNotPendingHours);\n logger.debug(\n `prNotPendingHours=${prNotPendingHours} threshold hit - creating PR`,\n );\n }\n logger.debug('Branch status success');\n }\n }\n\n const processedUpgrades: string[] = [];\n const commitRepos: string[] = [];\n\n function getRepoNameWithSourceDirectory(\n upgrade: BranchUpgradeConfig,\n ): string {\n // TODO: types (#22198)\n return `${upgrade.repoName!}${\n upgrade.sourceDirectory ? `:${upgrade.sourceDirectory}` : ''\n }`;\n }\n\n // fetch changelogs for matching upgrades.\n await embedChangelogs({\n upgrades: upgrades,\n stage: 'pr',\n });\n\n // Get changelog and then generate template strings\n for (const upgrade of upgrades) {\n // TODO: types (#22198)\n const upgradeKey = `${upgrade.depType!}-${upgrade.depName!}-${upgrade.manager}-${upgrade.currentVersion ?? ''}-${upgrade.currentValue ?? ''}-${upgrade.newVersion ?? ''}-${upgrade.newValue ?? ''}`;\n if (processedUpgrades.includes(upgradeKey)) {\n continue;\n }\n processedUpgrades.push(upgradeKey);\n\n const logJSON = upgrade.logJSON;\n\n if (logJSON) {\n if (isUndefined(logJSON.error)) {\n if (logJSON.project) {\n upgrade.repoName = logJSON.project.repository;\n }\n upgrade.hasReleaseNotes = false;\n upgrade.releases = [];\n if (\n logJSON.hasReleaseNotes &&\n upgrade.repoName &&\n !commitRepos.includes(getRepoNameWithSourceDirectory(upgrade))\n ) {\n commitRepos.push(getRepoNameWithSourceDirectory(upgrade));\n upgrade.hasReleaseNotes = logJSON.hasReleaseNotes;\n if (logJSON.versions) {\n for (const version of logJSON.versions) {\n const release = { ...version };\n upgrade.releases.push(release);\n }\n }\n }\n } else if (logJSON.error === 'MissingGithubToken') {\n upgrade.prBodyNotes ??= [];\n upgrade.prBodyNotes.push(\n [\n '> :exclamation: **Important**',\n '> ',\n '> Release Notes retrieval for this PR were skipped because no github.com credentials were available. ',\n '> If you are self-hosted, please see [this instruction](https://github.com/renovatebot/renovate/blob/master/docs/usage/examples/self-hosting.md#githubcom-token-for-release-notes).',\n '\\n',\n ].join('\\n'),\n );\n }\n }\n\n addPullRequestNoteIfAttestationHasBeenLost(\n upgrade,\n currentReleaseHasAttestation,\n );\n\n config.upgrades.push(upgrade);\n }\n\n config.hasReleaseNotes = config.upgrades.some((upg) => upg.hasReleaseNotes);\n\n const releaseNotesSources: string[] = [];\n for (const upgrade of config.upgrades) {\n let notesSourceUrl = upgrade.releases?.[0]?.releaseNotes?.notesSourceUrl;\n // TODO: types (#22198)\n notesSourceUrl ??= `${upgrade.sourceUrl!}${\n upgrade.sourceDirectory ? `:${upgrade.sourceDirectory}` : ''\n }`;\n\n if (upgrade.hasReleaseNotes && notesSourceUrl) {\n if (releaseNotesSources.includes(notesSourceUrl)) {\n logger.debug(\n { depName: upgrade.depName },\n 'Removing duplicate release notes',\n );\n upgrade.hasReleaseNotes = false;\n } else {\n releaseNotesSources.push(notesSourceUrl);\n }\n }\n }\n\n const prBody = getPrBody(\n config,\n {\n debugData: updatePrDebugData(\n config.baseBranch,\n prepareLabels(config), // include labels in debug data\n existingPr?.bodyStruct?.debugData,\n ),\n },\n config,\n );\n\n try {\n if (existingPr) {\n logger.debug('Processing existing PR');\n\n if (\n !existingPr.hasAssignees &&\n !hasNotIgnoredReviewers(existingPr, config) &&\n config.automerge &&\n !config.assignAutomerge &&\n (await getBranchStatus()) === 'red'\n ) {\n logger.debug(`Setting assignees and reviewers as status checks failed`);\n await addParticipants(config, existingPr);\n }\n // Check if existing PR needs updating\n const existingPrTitle = stripEmojis(existingPr.title);\n const existingPrBodyHash = existingPr.bodyStruct?.hash;\n const newPrTitle = stripEmojis(prTitle);\n const newPrBodyHash = hashBody(prBody);\n\n const prInitialLabels = existingPr.bodyStruct?.debugData?.labels;\n const prCurrentLabels = existingPr.labels;\n const configuredLabels = prepareLabels(config);\n\n const labelsNeedUpdate = shouldUpdateLabels(\n prInitialLabels,\n prCurrentLabels,\n configuredLabels,\n );\n\n if (\n existingPr?.targetBranch === config.baseBranch &&\n existingPrTitle === newPrTitle &&\n existingPrBodyHash === newPrBodyHash &&\n !labelsNeedUpdate &&\n !config.autoApprove\n ) {\n // adds or-cache for existing PRs\n setPrCache(branchName, prBodyFingerprint, false);\n logger.debug(\n `Pull Request #${existingPr.number} does not need updating`,\n );\n return { type: 'with-pr', pr: existingPr };\n }\n\n const updatePrConfig: UpdatePrConfig = {\n number: existingPr.number,\n prTitle,\n prBody,\n platformPrOptions: getPlatformPrOptions(config),\n };\n // PR must need updating\n if (existingPr?.targetBranch !== config.baseBranch) {\n logger.debug(\n {\n branchName,\n oldBaseBranch: existingPr?.targetBranch,\n newBaseBranch: config.baseBranch,\n },\n 'PR base branch has changed',\n );\n updatePrConfig.targetBranch = config.baseBranch;\n }\n\n if (labelsNeedUpdate) {\n logger.debug(\n {\n branchName,\n prCurrentLabels,\n configuredLabels,\n },\n 'PR labels have changed',\n );\n\n // Divide labels into three categories:\n // i) addLabels: Labels that need to be added\n // ii) removeLabels: Labels that need to be removed\n // iii) labels: New labels for the PR, replacing the old labels array entirely.\n // This distinction is necessary because different platforms update labels differently\n // For more details, refer to the updatePr function of each platform.\n\n const [addLabels, removeLabels] = getChangedLabels(\n prCurrentLabels,\n configuredLabels,\n );\n\n // for Gitea\n updatePrConfig.labels = configuredLabels;\n\n // for GitHub, GitLab\n updatePrConfig.addLabels = addLabels;\n updatePrConfig.removeLabels = removeLabels;\n }\n if (existingPrTitle !== newPrTitle) {\n logger.debug(\n {\n branchName,\n oldPrTitle: existingPr.title,\n newPrTitle: prTitle,\n },\n 'PR title changed',\n );\n } else if (config.autoApprove) {\n logger.debug({ prTitle }, 'PR approval required');\n } else if (!config.committedFiles && !config.rebaseRequested) {\n logger.debug(\n {\n prTitle,\n },\n 'PR body changed',\n );\n }\n\n if (GlobalConfig.get('dryRun')) {\n logger.info(`DRY-RUN: Would update PR #${existingPr.number}`);\n return { type: 'with-pr', pr: existingPr };\n }\n await platform.updatePr(updatePrConfig);\n logger.info({ pr: existingPr.number, prTitle }, `PR updated`);\n setPrCache(branchName, prBodyFingerprint, true);\n\n return {\n type: 'with-pr',\n pr: {\n ...existingPr,\n bodyStruct: getPrBodyStruct(prBody),\n title: prTitle,\n targetBranch: config.baseBranch,\n },\n };\n }\n logger.debug({ branch: branchName, prTitle }, `Creating PR`);\n if (config.updateType === 'rollback') {\n logger.info('Creating Rollback PR');\n }\n let pr: Pr | null;\n if (GlobalConfig.get('dryRun')) {\n logger.info(\n { labels: prepareLabels(config) },\n `DRY-RUN: Would create PR: ${prTitle}`,\n );\n pr = { number: 0 } as never;\n } else {\n try {\n // for a vulnerability alert this checks the VulnerabilityConcurrentPRs count\n if (\n !dependencyDashboardCheck &&\n isLimitReached('ConcurrentPRs', prConfig)\n ) {\n logger.debug('Skipping PR - limit reached');\n return { type: 'without-pr', prBlockedBy: 'RateLimited' };\n }\n pr = await platform.createPr({\n sourceBranch: branchName,\n targetBranch: config.baseBranch,\n prTitle,\n prBody,\n labels: prepareLabels(config),\n platformPrOptions: getPlatformPrOptions(config),\n draftPR: !!config.draftPR,\n milestone: config.milestone,\n });\n\n incCountValue(\n config.isVulnerabilityAlert\n ? 'VulnerabilityConcurrentPRs'\n : 'ConcurrentPRs',\n );\n incCountValue('HourlyPRs');\n logger.info(\n { pr: pr?.number, prTitle, labels: pr?.labels },\n 'PR created',\n );\n } catch (err) {\n logger.debug({ err }, 'Pull request creation error');\n if (\n err.body?.message === 'Validation failed' &&\n err.body.errors?.length &&\n err.body.errors.some((error: { message?: string }) =>\n error.message?.startsWith('A pull request already exists'),\n )\n ) {\n logger.warn('A pull requests already exists');\n return { type: 'without-pr', prBlockedBy: 'Error' };\n }\n if (err.statusCode === 502) {\n logger.warn(\n { branch: branchName },\n 'Deleting branch due to server error',\n );\n await scm.deleteBranch(branchName);\n }\n return { type: 'without-pr', prBlockedBy: 'Error' };\n }\n }\n if (\n pr &&\n config.branchAutomergeFailureMessage &&\n !config.suppressNotifications?.includes('branchAutomergeFailure')\n ) {\n const topic = 'Branch automerge failure';\n let content =\n 'This PR was configured for branch automerge. However, this is not possible, so it has been raised as a PR instead.';\n if (config.branchAutomergeFailureMessage === 'branch status error') {\n content += '\\n___\\n * Branch has one or more failed status checks';\n }\n if (\n config.branchAutomergeFailureMessage ===\n 'automerge aborted - merge queue'\n ) {\n content +=\n '\\n___\\n * The base branch only accepts changes through its merge queue and rejected the direct push, so branch automerge is not possible. Please set `automergeType=pr` instead, or allow Renovate to bypass the merge queue.';\n }\n content = platform.massageMarkdown(content, config.rebaseLabel);\n logger.debug('Adding branch automerge failure message to PR');\n if (GlobalConfig.get('dryRun')) {\n logger.info(`DRY-RUN: Would add comment to PR #${pr.number}`);\n } else {\n await ensureComment({\n number: pr.number,\n topic,\n content,\n });\n }\n }\n // Skip assign and review if automerging PR\n if (pr) {\n if (\n config.automerge &&\n !config.assignAutomerge &&\n (await getBranchStatus()) !== 'red'\n ) {\n logger.debug(\n `Skipping assignees and reviewers as automerge=${config.automerge}`,\n );\n } else {\n await addParticipants(config, pr);\n }\n setPrCache(branchName, prBodyFingerprint, true);\n logger.debug(`Created Pull Request #${pr.number}`);\n return { type: 'with-pr', pr };\n }\n } catch (err) {\n if (\n // oxlint-disable-next-line typescript/prefer-optional-chain -- instanceof is not a null guard\n err instanceof ExternalHostError ||\n err.message === REPOSITORY_CHANGED ||\n err.message === PLATFORM_RATE_LIMIT_EXCEEDED ||\n err.message === PLATFORM_INTEGRATION_UNAUTHORIZED\n ) {\n logger.debug('Passing error up');\n throw err;\n }\n logger.warn({ err, prTitle }, 'Failed to ensure PR');\n }\n if (existingPr) {\n return { type: 'with-pr', pr: existingPr };\n }\n return { type: 'without-pr', prBlockedBy: 'Error' };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../../../lib/workers/repository/update/pr/index.ts"],"sourcesContent":["import {\n isArray,\n isNonEmptyArray,\n isNumber,\n isUndefined,\n} from '@sindresorhus/is';\nimport { codeBlock } from 'common-tags';\nimport { GlobalConfig } from '../../../../config/global.ts';\nimport type { RenovateConfig } from '../../../../config/types.ts';\nimport {\n PLATFORM_INTEGRATION_UNAUTHORIZED,\n PLATFORM_RATE_LIMIT_EXCEEDED,\n REPOSITORY_CHANGED,\n} from '../../../../constants/error-messages.ts';\nimport { pkg } from '../../../../expose.ts';\nimport { logger } from '../../../../logger/index.ts';\nimport { ensureComment } from '../../../../modules/platform/comment.ts';\nimport type {\n PlatformPrOptions,\n Pr,\n PrDebugData,\n UpdatePrConfig,\n} from '../../../../modules/platform/index.ts';\nimport { platform } from '../../../../modules/platform/index.ts';\nimport {\n getPrBodyStruct,\n hashBody,\n} from '../../../../modules/platform/pr-body.ts';\nimport { scm } from '../../../../modules/platform/scm.ts';\nimport { ExternalHostError } from '../../../../types/errors/external-host-error.ts';\nimport { getElapsedHours } from '../../../../util/date.ts';\nimport { emojify, stripEmojis } from '../../../../util/emoji.ts';\nimport { fingerprint } from '../../../../util/fingerprint.ts';\nimport { getBranchLastCommitTime } from '../../../../util/git/index.ts';\nimport { memoize } from '../../../../util/memoize.ts';\nimport { incCountValue, isLimitReached } from '../../../global/limits.ts';\nimport type {\n BranchConfig,\n BranchUpgradeConfig,\n PrBlockedBy,\n} from '../../../types.ts';\nimport { embedChangelogs } from '../../changelog/index.ts';\nimport { resolveBranchStatus } from '../branch/status-checks.ts';\nimport { getPrBody } from './body/index.ts';\nimport {\n getChangedLabels,\n prepareLabels,\n shouldUpdateLabels,\n} from './labels.ts';\nimport { addParticipants } from './participants.ts';\nimport { getPrCache, setPrCache } from './pr-cache.ts';\nimport {\n generatePrBodyFingerprintConfig,\n validatePrCache,\n} from './pr-fingerprint.ts';\nimport { tryReuseAutoclosedPr } from './pr-reuse.ts';\n\nexport function getPlatformPrOptions(\n config: RenovateConfig & PlatformPrOptions,\n): PlatformPrOptions {\n const usePlatformAutomerge = Boolean(\n config.automerge &&\n (config.automergeType === 'pr' || config.automergeType === 'branch') &&\n config.platformAutomerge,\n );\n\n return {\n autoApprove: !!config.autoApprove,\n automergeCommitMessage: config.commitMessage,\n automergeStrategy: config.automergeStrategy,\n azureWorkItemId: config.azureWorkItemId ?? 0,\n bbAutoResolvePrTasks: !!config.bbAutoResolvePrTasks,\n bbUseDefaultReviewers: !!config.bbUseDefaultReviewers,\n gitLabIgnoreApprovals: !!config.gitLabIgnoreApprovals,\n forkModeDisallowMaintainerEdits: !!config.forkModeDisallowMaintainerEdits,\n usePlatformAutomerge,\n };\n}\n\nexport interface ResultWithPr {\n type: 'with-pr';\n pr: Pr;\n}\n\nexport interface ResultWithoutPr {\n type: 'without-pr';\n prBlockedBy: PrBlockedBy;\n}\n\nexport type EnsurePrResult = ResultWithPr | ResultWithoutPr;\n\nexport function updatePrDebugData(\n targetBranch: string,\n labels: string[],\n debugData: PrDebugData | undefined,\n): PrDebugData {\n const createdByRenovateVersion = debugData?.createdInVer ?? pkg.version;\n const updatedByRenovateVersion = pkg.version;\n\n const updatedPrDebugData: PrDebugData = {\n createdInVer: createdByRenovateVersion,\n updatedInVer: updatedByRenovateVersion,\n targetBranch,\n };\n\n // Add labels to the debug data object.\n // When to add:\n // 1. Add it when a new PR is created, i.e., when debugData is undefined.\n // 2. Add it if an existing PR already has labels in the debug data, confirming that we can update its labels.\n if (!debugData || isArray(debugData.labels)) {\n updatedPrDebugData.labels = labels;\n }\n\n return updatedPrDebugData;\n}\n\nfunction hasNotIgnoredReviewers(pr: Pr, config: BranchConfig): boolean {\n if (\n isNonEmptyArray(config.ignoreReviewers) &&\n isNonEmptyArray(pr.reviewers)\n ) {\n const ignoreReviewers = new Set(config.ignoreReviewers);\n return (\n pr.reviewers.filter((reviewer) => !ignoreReviewers.has(reviewer)).length >\n 0\n );\n }\n return isNonEmptyArray(pr.reviewers);\n}\n\nfunction addPullRequestNoteIfAttestationHasBeenLost(\n upgrade: BranchUpgradeConfig,\n currentReleaseHasAttestation: boolean | undefined,\n): void {\n const { packageName, depName, currentVersion, newVersion } = upgrade;\n const name = packageName ?? depName;\n\n const newRelease = upgrade.releases?.find(\n (release) => release.version === newVersion,\n );\n\n if (\n newRelease &&\n currentReleaseHasAttestation === true &&\n newRelease.attestation !== true\n ) {\n upgrade.prBodyNotes ??= [];\n upgrade.prBodyNotes.push(\n emojify(\n codeBlock`\n > :stop_sign: **Caution**\n >\n > ${name} ${currentVersion} was released with an attestation, but ${newVersion} has no attestation.\n > Verify that release ${newVersion} was published by the expected author.\n `,\n ),\n );\n }\n}\n\n// Ensures that PR exists with matching title/body\nexport async function ensurePr(\n prConfig: BranchConfig,\n): Promise<EnsurePrResult> {\n const config: BranchConfig = { ...prConfig };\n const filteredPrConfig = generatePrBodyFingerprintConfig(config);\n const prBodyFingerprint = fingerprint(filteredPrConfig);\n logger.trace({ config }, 'ensurePr');\n // If there is a group, it will use the config of the first upgrade in the array\n const {\n branchName,\n ignoreTests,\n internalChecksAsSuccess,\n prTitle = '',\n upgrades,\n hasAttestation: currentReleaseHasAttestation,\n } = config;\n const getBranchStatus = memoize(() =>\n resolveBranchStatus(branchName, !!internalChecksAsSuccess, ignoreTests),\n );\n const dependencyDashboardCheck =\n config.dependencyDashboardChecks?.[config.branchName];\n const dependencyDashboardApproved =\n dependencyDashboardCheck === 'approvePr' ||\n dependencyDashboardCheck === 'unpend';\n // Check if PR already exists\n const existingPr =\n (await platform.getBranchPr(branchName, config.baseBranch)) ??\n (await tryReuseAutoclosedPr(branchName, prTitle));\n const prCache = getPrCache(branchName);\n if (existingPr) {\n logger.debug('Found existing PR');\n if (existingPr.bodyStruct?.rebaseRequested) {\n logger.debug('PR rebase requested, so skipping cache check');\n } else if (prCache) {\n logger.trace({ prCache }, 'Found existing PR cache');\n // return if pr cache is valid and pr was not changed in the past 24hrs\n // skip cache when autoApprove is set, since new commits may have\n // reset platform approvals (e.g. GitLab's \"Remove all approvals\" setting)\n if (validatePrCache(prCache, prBodyFingerprint) && !config.autoApprove) {\n return { type: 'with-pr', pr: existingPr };\n }\n } else if (config.repositoryCache === 'enabled') {\n logger.debug('PR cache not found');\n }\n }\n config.upgrades = [];\n\n if (config.artifactErrors?.length) {\n logger.debug('Forcing PR because of artifact errors');\n config.forcePr = true;\n }\n\n if (dependencyDashboardApproved) {\n logger.debug('Forcing PR because of dependency dashboard approval');\n config.forcePr = true;\n }\n\n if (!existingPr) {\n // Only create a PR if a branch automerge has failed\n if (\n config.automerge === true &&\n config.automergeType?.startsWith('branch') &&\n !config.forcePr\n ) {\n logger.debug(`Branch automerge is enabled`);\n if (\n config.stabilityStatus !== 'yellow' &&\n (await getBranchStatus()) === 'yellow' &&\n isNumber(config.prNotPendingHours)\n ) {\n logger.debug('Checking how long this branch has been pending');\n const lastCommitTime = await getBranchLastCommitTime(branchName);\n if (getElapsedHours(lastCommitTime) >= config.prNotPendingHours) {\n logger.debug(\n `Branch exceeds prNotPending=${config.prNotPendingHours}, hours - forcing PR creation`,\n );\n config.forcePr = true;\n }\n }\n if (config.forcePr || (await getBranchStatus()) === 'red') {\n logger.debug(`Branch tests failed, so will create PR`);\n } else {\n // Branch should be automerged, so we don't want to create a PR\n return { type: 'without-pr', prBlockedBy: 'BranchAutomerge' };\n }\n }\n if (config.prCreation === 'status-success') {\n logger.debug('Checking branch combined status');\n if ((await getBranchStatus()) !== 'green') {\n logger.debug(`Branch status isn't green - not creating PR`);\n return { type: 'without-pr', prBlockedBy: 'AwaitingTests' };\n }\n logger.debug('Branch status success');\n } else if (\n config.prCreation === 'approval' &&\n !dependencyDashboardApproved\n ) {\n return { type: 'without-pr', prBlockedBy: 'NeedsApproval' };\n } else if (config.prCreation === 'not-pending' && !config.forcePr) {\n logger.debug('Checking branch combined status');\n if ((await getBranchStatus()) === 'yellow') {\n logger.debug(`Branch status is yellow - checking timeout`);\n const lastCommitTime = await getBranchLastCommitTime(branchName);\n const elapsedHours = getElapsedHours(lastCommitTime);\n if (\n !dependencyDashboardCheck &&\n ((config.stabilityStatus && config.stabilityStatus !== 'yellow') ||\n (isNumber(config.prNotPendingHours) &&\n elapsedHours < config.prNotPendingHours))\n ) {\n logger.debug(\n `Branch is ${elapsedHours} hours old - skipping PR creation as prNotPendingHours is set to ${config.prNotPendingHours}`,\n );\n return {\n type: 'without-pr',\n prBlockedBy: 'AwaitingTests',\n };\n }\n const prNotPendingHours = String(config.prNotPendingHours);\n logger.debug(\n `prNotPendingHours=${prNotPendingHours} threshold hit - creating PR`,\n );\n }\n logger.debug('Branch status success');\n }\n }\n\n const processedUpgrades: string[] = [];\n const commitRepos: string[] = [];\n\n function getRepoNameWithSourceDirectory(\n upgrade: BranchUpgradeConfig,\n ): string {\n // TODO: types (#22198)\n return `${upgrade.repoName!}${\n upgrade.sourceDirectory ? `:${upgrade.sourceDirectory}` : ''\n }`;\n }\n\n // fetch changelogs for matching upgrades.\n await embedChangelogs({\n upgrades: upgrades,\n stage: 'pr',\n });\n\n // Get changelog and then generate template strings\n for (const upgrade of upgrades) {\n // TODO: types (#22198)\n const upgradeKey = `${upgrade.depType!}-${upgrade.depName!}-${upgrade.manager}-${upgrade.currentVersion ?? ''}-${upgrade.currentValue ?? ''}-${upgrade.newVersion ?? ''}-${upgrade.newValue ?? ''}`;\n if (processedUpgrades.includes(upgradeKey)) {\n continue;\n }\n processedUpgrades.push(upgradeKey);\n\n const logJSON = upgrade.logJSON;\n\n if (logJSON) {\n if (isUndefined(logJSON.error)) {\n if (logJSON.project) {\n upgrade.repoName = logJSON.project.repository;\n }\n upgrade.hasReleaseNotes = false;\n upgrade.releases = [];\n if (\n logJSON.hasReleaseNotes &&\n upgrade.repoName &&\n !commitRepos.includes(getRepoNameWithSourceDirectory(upgrade))\n ) {\n commitRepos.push(getRepoNameWithSourceDirectory(upgrade));\n upgrade.hasReleaseNotes = logJSON.hasReleaseNotes;\n if (logJSON.versions) {\n for (const version of logJSON.versions) {\n const release = { ...version };\n upgrade.releases.push(release);\n }\n }\n }\n } else if (logJSON.error === 'MissingGithubToken') {\n upgrade.prBodyNotes ??= [];\n upgrade.prBodyNotes.push(\n emojify(\n codeBlock`\n > :exclamation: **Important**\n >\n > Release Notes retrieval for this PR were skipped because no github.com credentials were available.\n > If you are self-hosted, please see [this instruction](https://github.com/renovatebot/renovate/blob/master/docs/usage/examples/self-hosting.md#githubcom-token-for-release-notes).\n `,\n ),\n );\n }\n }\n\n addPullRequestNoteIfAttestationHasBeenLost(\n upgrade,\n currentReleaseHasAttestation,\n );\n\n config.upgrades.push(upgrade);\n }\n\n config.hasReleaseNotes = config.upgrades.some((upg) => upg.hasReleaseNotes);\n\n const releaseNotesSources: string[] = [];\n for (const upgrade of config.upgrades) {\n let notesSourceUrl = upgrade.releases?.[0]?.releaseNotes?.notesSourceUrl;\n // TODO: types (#22198)\n notesSourceUrl ??= `${upgrade.sourceUrl!}${\n upgrade.sourceDirectory ? `:${upgrade.sourceDirectory}` : ''\n }`;\n\n if (upgrade.hasReleaseNotes && notesSourceUrl) {\n if (releaseNotesSources.includes(notesSourceUrl)) {\n logger.debug(\n { depName: upgrade.depName },\n 'Removing duplicate release notes',\n );\n upgrade.hasReleaseNotes = false;\n } else {\n releaseNotesSources.push(notesSourceUrl);\n }\n }\n }\n\n const prBody = getPrBody(\n config,\n {\n debugData: updatePrDebugData(\n config.baseBranch,\n prepareLabels(config), // include labels in debug data\n existingPr?.bodyStruct?.debugData,\n ),\n },\n config,\n );\n\n try {\n if (existingPr) {\n logger.debug('Processing existing PR');\n\n if (\n !existingPr.hasAssignees &&\n !hasNotIgnoredReviewers(existingPr, config) &&\n config.automerge &&\n !config.assignAutomerge &&\n (await getBranchStatus()) === 'red'\n ) {\n logger.debug(`Setting assignees and reviewers as status checks failed`);\n await addParticipants(config, existingPr);\n }\n // Check if existing PR needs updating\n const existingPrTitle = stripEmojis(existingPr.title);\n const existingPrBodyHash = existingPr.bodyStruct?.hash;\n const newPrTitle = stripEmojis(prTitle);\n const newPrBodyHash = hashBody(prBody);\n\n const prInitialLabels = existingPr.bodyStruct?.debugData?.labels;\n const prCurrentLabels = existingPr.labels;\n const configuredLabels = prepareLabels(config);\n\n const labelsNeedUpdate = shouldUpdateLabels(\n prInitialLabels,\n prCurrentLabels,\n configuredLabels,\n );\n\n if (\n existingPr?.targetBranch === config.baseBranch &&\n existingPrTitle === newPrTitle &&\n existingPrBodyHash === newPrBodyHash &&\n !labelsNeedUpdate &&\n !config.autoApprove\n ) {\n // adds or-cache for existing PRs\n setPrCache(branchName, prBodyFingerprint, false);\n logger.debug(\n `Pull Request #${existingPr.number} does not need updating`,\n );\n return { type: 'with-pr', pr: existingPr };\n }\n\n const updatePrConfig: UpdatePrConfig = {\n number: existingPr.number,\n prTitle,\n prBody,\n platformPrOptions: getPlatformPrOptions(config),\n };\n // PR must need updating\n if (existingPr?.targetBranch !== config.baseBranch) {\n logger.debug(\n {\n branchName,\n oldBaseBranch: existingPr?.targetBranch,\n newBaseBranch: config.baseBranch,\n },\n 'PR base branch has changed',\n );\n updatePrConfig.targetBranch = config.baseBranch;\n }\n\n if (labelsNeedUpdate) {\n logger.debug(\n {\n branchName,\n prCurrentLabels,\n configuredLabels,\n },\n 'PR labels have changed',\n );\n\n // Divide labels into three categories:\n // i) addLabels: Labels that need to be added\n // ii) removeLabels: Labels that need to be removed\n // iii) labels: New labels for the PR, replacing the old labels array entirely.\n // This distinction is necessary because different platforms update labels differently\n // For more details, refer to the updatePr function of each platform.\n\n const [addLabels, removeLabels] = getChangedLabels(\n prCurrentLabels,\n configuredLabels,\n );\n\n // for Gitea\n updatePrConfig.labels = configuredLabels;\n\n // for GitHub, GitLab\n updatePrConfig.addLabels = addLabels;\n updatePrConfig.removeLabels = removeLabels;\n }\n if (existingPrTitle !== newPrTitle) {\n logger.debug(\n {\n branchName,\n oldPrTitle: existingPr.title,\n newPrTitle: prTitle,\n },\n 'PR title changed',\n );\n } else if (config.autoApprove) {\n logger.debug({ prTitle }, 'PR approval required');\n } else if (!config.committedFiles && !config.rebaseRequested) {\n logger.debug(\n {\n prTitle,\n },\n 'PR body changed',\n );\n }\n\n if (GlobalConfig.get('dryRun')) {\n logger.info(`DRY-RUN: Would update PR #${existingPr.number}`);\n return { type: 'with-pr', pr: existingPr };\n }\n await platform.updatePr(updatePrConfig);\n logger.info({ pr: existingPr.number, prTitle }, `PR updated`);\n setPrCache(branchName, prBodyFingerprint, true);\n\n return {\n type: 'with-pr',\n pr: {\n ...existingPr,\n bodyStruct: getPrBodyStruct(prBody),\n title: prTitle,\n targetBranch: config.baseBranch,\n },\n };\n }\n logger.debug({ branch: branchName, prTitle }, `Creating PR`);\n if (config.updateType === 'rollback') {\n logger.info('Creating Rollback PR');\n }\n let pr: Pr | null;\n if (GlobalConfig.get('dryRun')) {\n logger.info(\n { labels: prepareLabels(config) },\n `DRY-RUN: Would create PR: ${prTitle}`,\n );\n pr = { number: 0 } as never;\n } else {\n try {\n // for a vulnerability alert this checks the VulnerabilityConcurrentPRs count\n if (\n !dependencyDashboardCheck &&\n isLimitReached('ConcurrentPRs', prConfig)\n ) {\n logger.debug('Skipping PR - limit reached');\n return { type: 'without-pr', prBlockedBy: 'RateLimited' };\n }\n pr = await platform.createPr({\n sourceBranch: branchName,\n targetBranch: config.baseBranch,\n prTitle,\n prBody,\n labels: prepareLabels(config),\n platformPrOptions: getPlatformPrOptions(config),\n draftPR: !!config.draftPR,\n milestone: config.milestone,\n });\n\n incCountValue(\n config.isVulnerabilityAlert\n ? 'VulnerabilityConcurrentPRs'\n : 'ConcurrentPRs',\n );\n incCountValue('HourlyPRs');\n logger.info(\n { pr: pr?.number, prTitle, labels: pr?.labels },\n 'PR created',\n );\n } catch (err) {\n logger.debug({ err }, 'Pull request creation error');\n if (\n err.body?.message === 'Validation failed' &&\n err.body.errors?.length &&\n err.body.errors.some((error: { message?: string }) =>\n error.message?.startsWith('A pull request already exists'),\n )\n ) {\n logger.warn('A pull requests already exists');\n return { type: 'without-pr', prBlockedBy: 'Error' };\n }\n if (err.statusCode === 502) {\n logger.warn(\n { branch: branchName },\n 'Deleting branch due to server error',\n );\n await scm.deleteBranch(branchName);\n }\n return { type: 'without-pr', prBlockedBy: 'Error' };\n }\n }\n if (\n pr &&\n config.branchAutomergeFailureMessage &&\n !config.suppressNotifications?.includes('branchAutomergeFailure')\n ) {\n const topic = 'Branch automerge failure';\n let content =\n 'This PR was configured for branch automerge. However, this is not possible, so it has been raised as a PR instead.';\n if (config.branchAutomergeFailureMessage === 'branch status error') {\n content += '\\n___\\n * Branch has one or more failed status checks';\n }\n if (\n config.branchAutomergeFailureMessage ===\n 'automerge aborted - merge queue'\n ) {\n content +=\n '\\n___\\n * The base branch only accepts changes through its merge queue and rejected the direct push, so branch automerge is not possible. Please set `automergeType=pr` instead, or allow Renovate to bypass the merge queue.';\n }\n content = platform.massageMarkdown(content, config.rebaseLabel);\n logger.debug('Adding branch automerge failure message to PR');\n if (GlobalConfig.get('dryRun')) {\n logger.info(`DRY-RUN: Would add comment to PR #${pr.number}`);\n } else {\n await ensureComment({\n number: pr.number,\n topic,\n content,\n });\n }\n }\n // Skip assign and review if automerging PR\n if (pr) {\n if (\n config.automerge &&\n !config.assignAutomerge &&\n (await getBranchStatus()) !== 'red'\n ) {\n logger.debug(\n `Skipping assignees and reviewers as automerge=${config.automerge}`,\n );\n } else {\n await addParticipants(config, pr);\n }\n setPrCache(branchName, prBodyFingerprint, true);\n logger.debug(`Created Pull Request #${pr.number}`);\n return { type: 'with-pr', pr };\n }\n } catch (err) {\n if (\n // oxlint-disable-next-line typescript/prefer-optional-chain -- instanceof is not a null guard\n err instanceof ExternalHostError ||\n err.message === REPOSITORY_CHANGED ||\n err.message === PLATFORM_RATE_LIMIT_EXCEEDED ||\n err.message === PLATFORM_INTEGRATION_UNAUTHORIZED\n ) {\n logger.debug('Passing error up');\n throw err;\n }\n logger.warn({ err, prTitle }, 'Failed to ensure PR');\n }\n if (existingPr) {\n return { type: 'with-pr', pr: existingPr };\n }\n return { type: 'without-pr', prBlockedBy: 'Error' };\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "renovate",
3
3
  "description": "Automated dependency updates. Flexible so you don't need to be.",
4
- "version": "44.76.0",
4
+ "version": "44.78.0",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "renovate": "dist/renovate.js",
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "$id": "https://docs.renovatebot.com/renovate-schema.json",
3
- "title": "JSON schema for Renovate 44.76.0 config files (https://renovatebot.com/)",
3
+ "title": "JSON schema for Renovate 44.78.0 config files (https://renovatebot.com/)",
4
4
  "$schema": "http://json-schema.org/draft-07/schema#",
5
- "x-renovate-version": "44.76.0",
5
+ "x-renovate-version": "44.78.0",
6
6
  "allowComments": true,
7
7
  "type": "object",
8
8
  "definitions": {
@@ -11907,6 +11907,11 @@
11907
11907
  "executionTimeout"
11908
11908
  ]
11909
11909
  },
11910
+ {
11911
+ "required": [
11912
+ "exitCodeForErrors"
11913
+ ]
11914
+ },
11910
11915
  {
11911
11916
  "required": [
11912
11917
  "processEnv"