renovate 44.94.4 → 44.96.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/dist/config/options/index.js +7 -1
  2. package/dist/config/options/index.js.map +1 -1
  3. package/dist/config/types.d.ts +1 -0
  4. package/dist/config/types.js.map +1 -1
  5. package/dist/global-config-option-defaults.generated.js +1 -1
  6. package/dist/global-config-option-defaults.generated.js.map +1 -1
  7. package/dist/modules/manager/dockerfile/apk.js +176 -0
  8. package/dist/modules/manager/dockerfile/apk.js.map +1 -0
  9. package/dist/modules/manager/dockerfile/dep-types.js +4 -0
  10. package/dist/modules/manager/dockerfile/dep-types.js.map +1 -1
  11. package/dist/modules/manager/dockerfile/extract.js +5 -0
  12. package/dist/modules/manager/dockerfile/extract.js.map +1 -1
  13. package/dist/modules/manager/dockerfile/index.js +2 -1
  14. package/dist/modules/manager/dockerfile/index.js.map +1 -1
  15. package/dist/modules/manager/fingerprint.generated.js +1 -1
  16. package/dist/modules/manager/fingerprint.generated.js.map +1 -1
  17. package/dist/modules/platform/github/index.js +4 -0
  18. package/dist/modules/platform/github/index.js.map +1 -1
  19. package/dist/modules/versioning/conda/index.js +3 -1
  20. package/dist/modules/versioning/conda/index.js.map +1 -1
  21. package/dist/modules/versioning/index.js +2 -1
  22. package/dist/modules/versioning/index.js.map +1 -1
  23. package/dist/modules/versioning/ruby/version.js +1 -0
  24. package/dist/modules/versioning/ruby/version.js.map +1 -1
  25. package/dist/util/minimum-release-age.js +14 -3
  26. package/dist/util/minimum-release-age.js.map +1 -1
  27. package/dist/workers/repository/config-migration/branch/rebase.js +1 -0
  28. package/dist/workers/repository/config-migration/branch/rebase.js.map +1 -1
  29. package/dist/workers/repository/index.js +1 -0
  30. package/dist/workers/repository/index.js.map +1 -1
  31. package/dist/workers/repository/init/merge.js +1 -0
  32. package/dist/workers/repository/init/merge.js.map +1 -1
  33. package/dist/workers/repository/onboarding/pr/pr-list.js +2 -3
  34. package/dist/workers/repository/onboarding/pr/pr-list.js.map +1 -1
  35. package/dist/workers/repository/reconfigure/index.js +1 -3
  36. package/dist/workers/repository/reconfigure/index.js.map +1 -1
  37. package/dist/workers/repository/update/branch/index.js +2 -3
  38. package/dist/workers/repository/update/branch/index.js.map +1 -1
  39. package/dist/workers/repository/update/pr/changelog/release-notes.js +3 -1
  40. package/dist/workers/repository/update/pr/changelog/release-notes.js.map +1 -1
  41. package/dist/workers/repository/update/pr/changelog/source.js +1 -0
  42. package/dist/workers/repository/update/pr/changelog/source.js.map +1 -1
  43. package/dist/workers/repository/updates/flatten.js +1 -1
  44. package/dist/workers/repository/updates/flatten.js.map +1 -1
  45. package/package.json +1 -1
  46. package/renovate-schema.json +11 -2
@@ -1 +1 @@
1
- {"version":3,"file":"pr-list.js","names":[],"sources":["../../../../../lib/workers/repository/onboarding/pr/pr-list.ts"],"sourcesContent":["import { getDefault } from '../../../../config/defaults.ts';\nimport { GlobalConfig } from '../../../../config/global.ts';\nimport { getOptions } from '../../../../config/options/index.ts';\nimport {\n type RenovateConfig,\n type UpdateType,\n UpdateTypesOptions,\n} from '../../../../config/types.ts';\nimport { logger } from '../../../../logger/index.ts';\nimport { emojify } from '../../../../util/emoji.ts';\nimport { coerceNumber } from '../../../../util/number.ts';\nimport { regEx } from '../../../../util/regex.ts';\nimport { calcLimit } from '../../../global/limits.ts';\nimport type { BranchConfig, BranchUpgradeConfig } from '../../../types.ts';\n\n/**\n * The different categories of dependency updates to output, when providing the summary view.\n *\n * - `security`: if the upgrade is driven by a vulnerability alert\n * - `${updateType}`: if it's set. I.e. `major`\n * - `lockfileUpdate` when `isLockfileUpdate` is true, without an `updateType`\n * - `other`: otherwise\n */\ntype SummaryCategory = UpdateType | 'security' | 'other';\n\n/** Priority order when rendering the `SummaryCategory`s in the summary view.\n *\n * NOTE that this is not exhaustive - this is only the priority order for rendering, and other categories, such as `other` are placed after.\n */\nconst SUMMARY_CATEGORY_PRIORITY_ORDER: readonly SummaryCategory[] = [\n 'security',\n ...UpdateTypesOptions,\n // ... anything else\n];\n\ninterface ConcurrentLimit {\n limit: number;\n key: 'prConcurrentLimit' | 'branchConcurrentLimit';\n}\n\n/**\n * Resolves the concurrent limit that governs how many of the expected Pull Requests can be open at once,\n * reusing the same `calcLimit()` used to enforce these limits (see `lib/workers/global/limits.ts`).\n *\n * `branchConcurrentLimit` only takes priority when it's been explicitly configured (it's `null` by default,\n * in which case `calcLimit()` silently inherits the value of `prConcurrentLimit`) and is actually more\n * restrictive - otherwise we'd misattribute the limit to a setting the user never touched.\n */\nfunction resolveConcurrentLimit(config: RenovateConfig): ConcurrentLimit {\n const configAsUpgrade: BranchUpgradeConfig = {\n branchName: '',\n manager: '',\n prConcurrentLimit: config.prConcurrentLimit,\n branchConcurrentLimit: config.branchConcurrentLimit,\n };\n const prConcurrentLimit = calcLimit([configAsUpgrade], 'prConcurrentLimit');\n const branchConcurrentLimit = calcLimit(\n [configAsUpgrade],\n 'branchConcurrentLimit',\n );\n\n if (\n typeof config.branchConcurrentLimit === 'number' &&\n branchConcurrentLimit > 0 &&\n (prConcurrentLimit === 0 || branchConcurrentLimit < prConcurrentLimit)\n ) {\n return {\n limit: branchConcurrentLimit,\n key: 'branchConcurrentLimit',\n };\n }\n\n return { limit: prConcurrentLimit, key: 'prConcurrentLimit' };\n}\n\n/**\n * Vulnerability alert fixes get their own concurrent-limit budget via `vulnerabilityAlerts.prConcurrentLimit`/ `vulnerabilityAlerts.branchConcurrentLimit`, separate from repository-wide/dependency-specific rules.\n * Falls back to the `vulnerabilityAlerts` option's own schema default (currently `0`, i.e. no limit) when\n * unset, via `getDefault()`, rather than duplicating that value here.\n */\nfunction resolveVulnerabilityConcurrentLimit(\n config: RenovateConfig,\n): ConcurrentLimit {\n // `vulnerabilityAlerts` is typed as `RenovateSharedConfig`, which doesn't declare `prConcurrentLimit`/\n // `branchConcurrentLimit`, even though both are valid nested options (see docs for `vulnerabilityAlerts`).\n // oxlint-disable-next-line typescript/no-unnecessary-type-assertion\n const vulnerabilityAlerts = config.vulnerabilityAlerts as\n RenovateConfig | undefined;\n const vulnerabilityAlertsDefault = getDefault(\n getOptions().find((option) => option.name === 'vulnerabilityAlerts')!,\n ) as RenovateConfig;\n const configAsUpgrade: BranchUpgradeConfig = {\n branchName: '',\n manager: '',\n prConcurrentLimit:\n vulnerabilityAlerts?.prConcurrentLimit ??\n vulnerabilityAlertsDefault.prConcurrentLimit,\n // `undefined` and `null` are handled identically by `calcLimit()` (both inherit `prConcurrentLimit`),\n // so there's no default value to duplicate here - unlike `prConcurrentLimit` above.\n branchConcurrentLimit: vulnerabilityAlerts?.branchConcurrentLimit,\n };\n const prConcurrentLimit = calcLimit([configAsUpgrade], 'prConcurrentLimit');\n const branchConcurrentLimit = calcLimit(\n [configAsUpgrade],\n 'branchConcurrentLimit',\n );\n\n if (\n typeof vulnerabilityAlerts?.branchConcurrentLimit === 'number' &&\n branchConcurrentLimit > 0 &&\n (prConcurrentLimit === 0 || branchConcurrentLimit < prConcurrentLimit)\n ) {\n return {\n limit: branchConcurrentLimit,\n key: 'branchConcurrentLimit',\n };\n }\n\n return { limit: prConcurrentLimit, key: 'prConcurrentLimit' };\n}\n\nexport function getExpectedPrList(\n config: RenovateConfig,\n branches: BranchConfig[],\n): string {\n logger.debug('getExpectedPrList()');\n logger.trace({ config });\n let prDesc = `\\n### What to Expect\\n\\n`;\n if (!branches.length) {\n return `${prDesc}It looks like your repository dependencies are already up-to-date and no Pull Requests will be necessary right away.\\n`;\n }\n // Vulnerability alert branches bypass the repository-wide rate/concurrency limits, so they shouldn't\n // count towards them - they get their own budget, see `resolveVulnerabilityConcurrentLimit()`.\n const securityBranchCount = branches.filter(\n (b) => b.isVulnerabilityAlert,\n ).length;\n const throttledBranchCount = branches.length - securityBranchCount;\n\n const { limit: concurrentLimit, key: concurrentLimitKey } =\n resolveConcurrentLimit(config);\n if (concurrentLimit > 0 && concurrentLimit < throttledBranchCount) {\n const securityNote =\n securityBranchCount > 0\n ? `, plus ${securityBranchCount} security update Pull Request${securityBranchCount > 1 ? 's' : ''} which ${securityBranchCount > 1 ? 'are' : 'is'} not subject to this limit`\n : '';\n prDesc += `With your current configuration, Renovate will create ${concurrentLimit} Pull Request${concurrentLimit > 1 ? 's' : ''}, up to a maximum of ${branches.length} over time (see [docs for \\`${concurrentLimitKey}\\`](${GlobalConfig.get('productLinks').documentation}configuration-options/#${concurrentLimitKey.toLowerCase()}))${securityNote}:\\n\\n`;\n } else {\n prDesc += `With your current configuration, Renovate will create ${branches.length} Pull Request`;\n prDesc += branches.length > 1 ? `s:\\n\\n` : `:\\n\\n`;\n }\n prDesc += getSecurityConcurrentLimitNote(\n securityBranchCount,\n concurrentLimit,\n resolveVulnerabilityConcurrentLimit(config),\n );\n\n for (const branch of branches) {\n const prTitleRe = regEx(/@(?<scope>[a-z]+\\/[a-z]+)/);\n // TODO #22198\n prDesc += `<details>\\n<summary>${branch.prTitle!.replace(\n prTitleRe,\n '@&#8203;$<scope>',\n )}</summary>\\n\\n`;\n if (branch.schedule?.length) {\n prDesc += ` - Schedule: ${JSON.stringify(branch.schedule)}\\n`;\n }\n prDesc += ` - Branch name: \\`${branch.branchName}\\`\\n`;\n prDesc += branch.baseBranch\n ? ` - Merge into: \\`${branch.baseBranch}\\`\\n`\n : '';\n const seen: string[] = [];\n for (const upgrade of branch.upgrades) {\n let text = '';\n if (upgrade.updateType === 'lockFileMaintenance') {\n text += ' - Regenerate lock files to use latest dependency versions';\n } else {\n if (upgrade.updateType === 'pin') {\n text += ' - Pin ';\n } else {\n text += ' - Upgrade ';\n }\n if (upgrade.sourceUrl) {\n // TODO: types (#22198)\n text += `[${upgrade.depName!}](${upgrade.sourceUrl})`;\n } else {\n text += upgrade.depName!.replace(prTitleRe, '@&#8203;$1');\n }\n // TODO: types (#22198)\n text += upgrade.isLockfileUpdate\n ? ` to \\`${upgrade.newVersion!}\\``\n : ` to \\`${upgrade.newDigest ?? upgrade.newValue!}\\``;\n text += '\\n';\n }\n if (!seen.includes(text)) {\n prDesc += text;\n seen.push(text);\n }\n }\n prDesc += '\\n\\n';\n prDesc += '</details>\\n\\n';\n }\n const prHourlyLimit = coerceNumber(config.prHourlyLimit);\n const commitHourlyLimit = coerceNumber(config.commitHourlyLimit);\n const securityBypassNote =\n securityBranchCount > 0\n ? ` Security update Pull Request${securityBranchCount > 1 ? 's are' : ' is'} not subject to this limit and will be created straight away.`\n : '';\n if (\n commitHourlyLimit > 0 &&\n commitHourlyLimit < 5 &&\n commitHourlyLimit < throttledBranchCount\n ) {\n prDesc += emojify(\n `\\n\\n:children_crossing: Branch creation and rebasing will be limited to maximum ${commitHourlyLimit} per hour, so it doesn't swamp any CI resources or overwhelm the project. See [docs for \\`commitHourlyLimit\\`](${GlobalConfig.get('productLinks').documentation}configuration-options/#commithourlylimit) for details.${securityBypassNote}\\n\\n`,\n );\n } else if (\n prHourlyLimit > 0 &&\n prHourlyLimit < 5 &&\n prHourlyLimit < throttledBranchCount\n ) {\n prDesc += emojify(\n `\\n\\n:children_crossing: PR creation will be limited to maximum ${prHourlyLimit} per hour, so it doesn't swamp any CI resources or overwhelm the project. See [docs for \\`prHourlyLimit\\`](${GlobalConfig.get('productLinks').documentation}configuration-options/#prhourlylimit) for details.${securityBypassNote}\\n\\n`,\n );\n }\n return prDesc;\n}\n\n/**\n * Security update Pull Requests bypass the repository-wide `prConcurrentLimit`/`branchConcurrentLimit`\n * by default, but they can be rate limited on their own via `vulnerabilityAlerts.prConcurrentLimit`/\n * `branchConcurrentLimit`.\n *\n * - If the user has already opted in to that limit, and it would actually throttle the security updates,\n * say so - the \"not subject to this limit\" wording elsewhere refers only to the repository-wide limit.\n * - Otherwise, once the number of security updates alone would exceed the repository-wide limit, suggest\n * that the user may want to opt in to limiting them too.\n */\nfunction getSecurityConcurrentLimitNote(\n securityCount: number,\n concurrentLimit: number,\n vulnerabilityLimit: ConcurrentLimit,\n): string {\n if (securityCount === 0) {\n return '';\n }\n\n if (vulnerabilityLimit.limit > 0) {\n if (securityCount <= vulnerabilityLimit.limit) {\n return '';\n }\n return emojify(\n `:information_source: Renovate will only create ${vulnerabilityLimit.limit} security update Pull Request${vulnerabilityLimit.limit > 1 ? 's' : ''} at a time, up to a maximum of ${securityCount} over time, due to your [\\`vulnerabilityAlerts.${vulnerabilityLimit.key}\\`](${GlobalConfig.get('productLinks').documentation}configuration-options/#vulnerabilityalerts) setting.\\n\\n`,\n );\n }\n\n if (concurrentLimit <= 0 || securityCount <= concurrentLimit) {\n return '';\n }\n return emojify(\n `:information_source: If you want to rate limit security update Pull Requests too, set [\\`vulnerabilityAlerts.prConcurrentLimit\\`](${GlobalConfig.get('productLinks').documentation}configuration-options/#vulnerabilityalerts).\\n\\n`,\n );\n}\n\nfunction getBranchUpgradeTypes(branch: BranchConfig): Set<SummaryCategory> {\n if (branch.isVulnerabilityAlert) {\n return new Set(['security']);\n }\n const types = new Set<SummaryCategory>();\n for (const upgrade of branch.upgrades) {\n if (upgrade.updateType) {\n types.add(upgrade.updateType);\n } else if (upgrade.isLockfileUpdate) {\n types.add('lockfileUpdate');\n } else {\n types.add('other');\n }\n }\n return types;\n}\n\n// Sort: default branch (empty string) first, then named branches alphabetically.\nfunction sortBaseBranches(bases: Iterable<string>): string[] {\n return [...bases].sort((a, b) => {\n if (a === b) {\n /* v8 ignore next -- base branches are unique Record keys; equal comparison cannot occur */\n return 0;\n }\n if (a === '') {\n return -1;\n }\n if (b === '') {\n return 1;\n }\n return a.localeCompare(b);\n });\n}\n\nfunction describeSecurityGroup(groupBranches: BranchConfig[]): string {\n const firstUpgrade = groupBranches[0].upgrades[0];\n const depName = firstUpgrade?.depName ?? groupBranches[0].prTitle ?? '';\n const updateType = firstUpgrade?.updateType ?? 'unknown';\n const packageFiles = groupBranches\n .map((b) => ({ file: b.packageFile ?? '', manager: b.manager }))\n .filter((f) => f.file);\n const uniqueManagers = new Set(packageFiles.map((f) => f.manager));\n\n // Vulnerability alerts can match on datasource + packageName without a specific file (e.g. GitHub vulnerability alerts),\n // so we need to handle an absent packageFile\n if (packageFiles.length === 0) {\n const branchManagers = new Set(groupBranches.map((b) => b.manager));\n if (branchManagers.size === 1) {\n return `- \\`${depName}\\`, (${[...branchManagers][0]}, ${updateType})\\n`;\n }\n\n return `- \\`${depName}\\`, (${updateType}): ${[...branchManagers].sort().join(', ')}\\n`;\n }\n\n if (packageFiles.length === 1) {\n const file = packageFiles[0].file;\n const [manager] = uniqueManagers;\n return `- \\`${depName}\\`, (${manager}, ${updateType}): \\`${file}\\`\\n`;\n }\n\n if (uniqueManagers.size === 1) {\n const manager = [...uniqueManagers][0];\n const fileLines = packageFiles\n .map(({ file }) => ` - \\`${file}\\`\\n`)\n .join('');\n return `- \\`${depName}\\`, (${manager}, ${updateType}):\\n${fileLines}`;\n }\n\n const fileLines = packageFiles\n .map(({ file, manager }) => ` - \\`${file}\\` (${manager})\\n`)\n .join('');\n return `- \\`${depName}\\`, (${updateType}):\\n${fileLines}`;\n}\n\ninterface BranchStats {\n // PR count per base branch, deduplicated by branchName.\n prCountByBase: Record<string, number>;\n // base -> manager -> type -> count, deduplicated by branchName+manager+type.\n tableStats: Record<\n string,\n Record<string, Partial<Record<SummaryCategory, number>>>\n >;\n // All upgrade types seen anywhere — drives the table columns.\n presentCategories: Set<SummaryCategory>;\n // Security branches grouped by branchName.\n securityGroups: Record<string, BranchConfig[]>;\n prCount: number;\n}\n\nfunction collectBranchStats(branches: BranchConfig[]): BranchStats {\n const prCountByBase: Record<string, number> = {};\n const tableStats: Record<\n string,\n Record<string, Partial<Record<SummaryCategory, number>>>\n > = {};\n const presentTypes = new Set<SummaryCategory>();\n const securityGroups: Record<string, BranchConfig[]> = {};\n const seenPrs = new Set<string>();\n const seenTableKeys = new Set<string>();\n\n for (const branch of branches) {\n const base = branch.baseBranch ?? '';\n const { manager, branchName } = branch;\n const branchTypes = getBranchUpgradeTypes(branch);\n\n for (const type of branchTypes) {\n presentTypes.add(type);\n }\n\n if (!seenPrs.has(branchName)) {\n seenPrs.add(branchName);\n prCountByBase[base] = (prCountByBase[base] ?? 0) + 1;\n }\n\n tableStats[base] ??= {};\n const baseStats = tableStats[base];\n baseStats[manager] ??= {};\n const managerStats = baseStats[manager];\n for (const type of branchTypes) {\n const key = `${branchName}:${manager}:${type}`;\n if (seenTableKeys.has(key)) {\n continue;\n }\n seenTableKeys.add(key);\n managerStats[type] ??= 0;\n managerStats[type]++;\n }\n\n if (branch.isVulnerabilityAlert) {\n securityGroups[branchName] ??= [];\n securityGroups[branchName].push(branch);\n }\n }\n\n return {\n prCountByBase,\n tableStats,\n presentCategories: presentTypes,\n securityGroups,\n prCount: seenPrs.size,\n };\n}\n\nfunction getCategoryColumns(\n presentTypes: Set<SummaryCategory>,\n): SummaryCategory[] {\n const cols: SummaryCategory[] = SUMMARY_CATEGORY_PRIORITY_ORDER.filter((t) =>\n presentTypes.has(t),\n );\n // Append any present types not in the standard display order\n // (e.g. lockfileUpdate, bump).\n for (const t of presentTypes) {\n if (t !== 'other' && !cols.includes(t)) {\n cols.push(t);\n }\n }\n\n if (presentTypes.has('other')) {\n cols.push('other');\n }\n\n return cols;\n}\n\nfunction categoriesToColumnHeaders(cols: readonly string[]): string {\n /* v8 ignore next -- branches always have at least one upgrade, so cols is never empty in practice */\n if (cols.length === 0) {\n return '';\n }\n return ` | ${cols.join(' | ')}`;\n}\n\nfunction renderRowCounts(\n typeColumns: readonly SummaryCategory[],\n typeCounts: Partial<Record<SummaryCategory, number>>,\n): string {\n return categoriesToColumnHeaders(\n typeColumns.map((t) => `${typeCounts[t] ?? 0}`),\n );\n}\n\nfunction sumCategoryCounts(\n rows: Partial<Record<SummaryCategory, number>>[],\n categoryColumns: readonly SummaryCategory[],\n): Partial<Record<SummaryCategory, number>> {\n const sum: Partial<Record<SummaryCategory, number>> = {};\n for (const categoryCounts of rows) {\n for (const category of categoryColumns) {\n sum[category] = (sum[category] ?? 0) + (categoryCounts[category] ?? 0);\n }\n }\n return sum;\n}\n\nexport function getExpectedPrListSummary(\n config: RenovateConfig,\n branches: BranchConfig[],\n): string {\n logger.debug('getExpectedPrListSummary()');\n logger.trace({ config });\n let prDesc = `\\n### What to Expect\\n\\n`;\n if (!branches.length) {\n return `${prDesc}It looks like your repository dependencies are already up-to-date and no Pull Requests will be necessary right away.\\n`;\n }\n\n const stats = collectBranchStats(branches);\n const sortedBases = sortBaseBranches(Object.keys(stats.prCountByBase));\n const hasMultipleBaseBranches = sortedBases.length > 1;\n\n const prHourlyLimit = coerceNumber(config.prHourlyLimit);\n const commitHourlyLimit = coerceNumber(config.commitHourlyLimit);\n const concurrentLimit = resolveConcurrentLimit(config);\n const vulnerabilityLimit = resolveVulnerabilityConcurrentLimit(config);\n // Vulnerability alert branches bypass the repository-wide rate/concurrency limits, so they shouldn't\n // count towards them - they get their own budget, see `resolveVulnerabilityConcurrentLimit()`.\n const securityCount = Object.keys(stats.securityGroups).length;\n\n if (hasMultipleBaseBranches) {\n let total = 0;\n const parts = sortedBases.map((base) => {\n const count = stats.prCountByBase[base];\n total += count;\n const label = base ? `the \\`${base}\\` branch` : 'the default branch';\n return `${count} Pull Request${count > 1 ? 's' : ''} to ${label}`;\n });\n const limitsNotice = determineLimitsNotice(\n concurrentLimit,\n prHourlyLimit,\n commitHourlyLimit,\n total - securityCount,\n securityCount,\n );\n prDesc += `With your current configuration, Renovate will create ${parts.join(' and ')}${limitsNotice}:\\n\\n`;\n } else {\n const limitsNotice = determineLimitsNotice(\n concurrentLimit,\n prHourlyLimit,\n commitHourlyLimit,\n stats.prCount - securityCount,\n securityCount,\n );\n prDesc += `With your current configuration, Renovate will create ${stats.prCount} Pull Request${stats.prCount > 1 ? 's' : ''}${limitsNotice}:\\n\\n`;\n }\n\n const categoryColumns = getCategoryColumns(stats.presentCategories);\n if (hasMultipleBaseBranches) {\n prDesc += `| Branch | Manager${categoriesToColumnHeaders(categoryColumns)} |\\n`;\n prDesc += `| --- | ---${categoryColumns.map(() => ' | ---').join('')} |\\n`;\n for (const base of sortedBases) {\n const label = base || '$default';\n for (const [manager, typeCounts] of Object.entries(\n stats.tableStats[base],\n )) {\n prDesc += `| ${label} | ${manager}${renderRowCounts(categoryColumns, typeCounts)} |\\n`;\n }\n }\n const sumRow = sumCategoryCounts(\n Object.values(stats.tableStats).flatMap((b) => Object.values(b)),\n categoryColumns,\n );\n prDesc += `| **Total** | ${renderRowCounts(categoryColumns, sumRow)} |\\n`;\n } else {\n prDesc += `| Manager${categoriesToColumnHeaders(categoryColumns)} |\\n`;\n prDesc += `| ---${categoryColumns.map(() => ' | ---').join('')} |\\n`;\n for (const [manager, typeCounts] of Object.entries(\n stats.tableStats[sortedBases[0]],\n )) {\n prDesc += `| ${manager}${renderRowCounts(categoryColumns, typeCounts)} |\\n`;\n }\n const sumRow = sumCategoryCounts(\n Object.values(stats.tableStats[sortedBases[0]]),\n categoryColumns,\n );\n prDesc += `| **Total**${renderRowCounts(categoryColumns, sumRow)} |\\n`;\n }\n\n prDesc += `\\n<small>Note that a single PR can update multiple files and/or managers, so the above rows may not align with the number of PRs being listed above.</small>\\n`;\n\n // provide a summary of the given security updates, as they're likely more important to the user\n if (Object.keys(stats.securityGroups).length) {\n prDesc += `\\n**Security updates**:\\n\\n`;\n for (const groupBranches of Object.values(stats.securityGroups)) {\n prDesc += describeSecurityGroup(groupBranches);\n }\n const securityConcurrentLimitNote = getSecurityConcurrentLimitNote(\n securityCount,\n concurrentLimit.limit,\n vulnerabilityLimit,\n );\n if (securityConcurrentLimitNote) {\n prDesc += `\\n${securityConcurrentLimitNote}`;\n }\n }\n\n const throttledPrCount = stats.prCount - securityCount;\n const securityBypassNote =\n securityCount > 0\n ? ` Security update Pull Request${securityCount > 1 ? 's are' : ' is'} not subject to this limit and will be created straight away.`\n : '';\n\n if (concurrentLimit.limit > 0 && concurrentLimit.limit < throttledPrCount) {\n const notice =\n concurrentLimit.key === 'branchConcurrentLimit'\n ? `Renovate will only work on ${concurrentLimit.limit} branch${concurrentLimit.limit > 1 ? 'es' : ''} at a time, so not all Pull Requests will be opened straight away`\n : `Renovate will only keep ${concurrentLimit.limit} Pull Request${concurrentLimit.limit > 1 ? 's' : ''} open at a time, so not all of the above will be opened straight away`;\n prDesc += emojify(\n `\\n\\n:children_crossing: ${notice}. See [docs for \\`${concurrentLimit.key}\\`](${GlobalConfig.get('productLinks').documentation}configuration-options/#${concurrentLimit.key.toLowerCase()}) for details.${securityBypassNote}\\n\\n`,\n );\n }\n\n if (\n commitHourlyLimit > 0 &&\n commitHourlyLimit < 5 &&\n commitHourlyLimit < throttledPrCount\n ) {\n prDesc += emojify(\n `\\n\\n:children_crossing: Branch creation and rebasing will be limited to maximum ${commitHourlyLimit} per hour, so it doesn't swamp any CI resources or overwhelm the project. See [docs for \\`commitHourlyLimit\\`](${GlobalConfig.get('productLinks').documentation}configuration-options/#commithourlylimit) for details.${securityBypassNote}\\n\\n`,\n );\n } else if (\n prHourlyLimit > 0 &&\n prHourlyLimit < 5 &&\n prHourlyLimit < throttledPrCount\n ) {\n prDesc += emojify(\n `\\n\\n:children_crossing: PR creation will be limited to maximum ${prHourlyLimit} per hour, so it doesn't swamp any CI resources or overwhelm the project. See [docs for \\`prHourlyLimit\\`](${GlobalConfig.get('productLinks').documentation}configuration-options/#prhourlylimit) for details.${securityBypassNote}\\n\\n`,\n );\n }\n return prDesc;\n}\n\nfunction determineLimitsNotice(\n concurrentLimit: ConcurrentLimit,\n prHourlyLimit: number,\n commitHourlyLimit: number,\n prCount: number,\n securityCount: number,\n): string {\n const clauses: string[] = [];\n\n if (concurrentLimit.limit > 0 && concurrentLimit.limit < prCount) {\n clauses.push(\n concurrentLimit.key === 'branchConcurrentLimit'\n ? `a maximum of ${concurrentLimit.limit} branch${concurrentLimit.limit > 1 ? 'es' : ''} open at a time`\n : `a maximum of ${concurrentLimit.limit} Pull Request${concurrentLimit.limit > 1 ? 's' : ''} open at a time`,\n );\n }\n\n if (\n commitHourlyLimit > 0 &&\n commitHourlyLimit < 5 &&\n commitHourlyLimit < prCount\n ) {\n clauses.push(\n `a maximum of ${commitHourlyLimit} PR${commitHourlyLimit > 1 ? 's' : ''}/rebase${commitHourlyLimit > 1 ? 's' : ''} per hour`,\n );\n } else if (\n prHourlyLimit > 0 &&\n prHourlyLimit < 5 &&\n prHourlyLimit < prCount\n ) {\n clauses.push(\n `a maximum of ${prHourlyLimit} PR${prHourlyLimit > 1 ? 's' : ''} per hour`,\n );\n }\n\n if (!clauses.length) {\n if (commitHourlyLimit === 0 && prHourlyLimit === 0) {\n return ' (with no configured maximum of PRs per hour)';\n }\n return '';\n }\n\n const securityNote =\n securityCount > 0\n ? `, plus ${securityCount} security update${securityCount > 1 ? 's' : ''} which ${securityCount > 1 ? \"aren't\" : \"isn't\"} subject to these limits`\n : '';\n\n return emojify(` (at ${clauses.join(' and ')}${securityNote})`);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"pr-list.js","names":[],"sources":["../../../../../lib/workers/repository/onboarding/pr/pr-list.ts"],"sourcesContent":["import { getDefault } from '../../../../config/defaults.ts';\nimport { GlobalConfig } from '../../../../config/global.ts';\nimport { getOptions } from '../../../../config/options/index.ts';\nimport {\n type RenovateConfig,\n type UpdateType,\n UpdateTypesOptions,\n} from '../../../../config/types.ts';\nimport { logger } from '../../../../logger/index.ts';\nimport { emojify } from '../../../../util/emoji.ts';\nimport { coerceNumber } from '../../../../util/number.ts';\nimport { regEx } from '../../../../util/regex.ts';\nimport { calcLimit } from '../../../global/limits.ts';\nimport type { BranchConfig, BranchUpgradeConfig } from '../../../types.ts';\n\n/**\n * The different categories of dependency updates to output, when providing the summary view.\n *\n * - `security`: if the upgrade is driven by a vulnerability alert\n * - `${updateType}`: if it's set. I.e. `major`\n * - `lockfileUpdate` when `isLockfileUpdate` is true, without an `updateType`\n * - `other`: otherwise\n */\ntype SummaryCategory = UpdateType | 'security' | 'other';\n\n/** Priority order when rendering the `SummaryCategory`s in the summary view.\n *\n * NOTE that this is not exhaustive - this is only the priority order for rendering, and other categories, such as `other` are placed after.\n */\nconst SUMMARY_CATEGORY_PRIORITY_ORDER: readonly SummaryCategory[] = [\n 'security',\n ...UpdateTypesOptions,\n // ... anything else\n];\n\ninterface ConcurrentLimit {\n limit: number;\n key: 'prConcurrentLimit' | 'branchConcurrentLimit';\n}\n\n/**\n * Resolves the concurrent limit that governs how many of the expected Pull Requests can be open at once,\n * reusing the same `calcLimit()` used to enforce these limits (see `lib/workers/global/limits.ts`).\n *\n * `branchConcurrentLimit` only takes priority when it's been explicitly configured (it's `null` by default,\n * in which case `calcLimit()` silently inherits the value of `prConcurrentLimit`) and is actually more\n * restrictive - otherwise we'd misattribute the limit to a setting the user never touched.\n */\nfunction resolveConcurrentLimit(config: RenovateConfig): ConcurrentLimit {\n const configAsUpgrade: BranchUpgradeConfig = {\n branchName: '',\n manager: '',\n prConcurrentLimit: config.prConcurrentLimit,\n branchConcurrentLimit: config.branchConcurrentLimit,\n };\n const prConcurrentLimit = calcLimit([configAsUpgrade], 'prConcurrentLimit');\n const branchConcurrentLimit = calcLimit(\n [configAsUpgrade],\n 'branchConcurrentLimit',\n );\n\n if (\n typeof config.branchConcurrentLimit === 'number' &&\n branchConcurrentLimit > 0 &&\n (prConcurrentLimit === 0 || branchConcurrentLimit < prConcurrentLimit)\n ) {\n return {\n limit: branchConcurrentLimit,\n key: 'branchConcurrentLimit',\n };\n }\n\n return { limit: prConcurrentLimit, key: 'prConcurrentLimit' };\n}\n\n/**\n * Vulnerability alert fixes get their own concurrent-limit budget via `vulnerabilityAlerts.prConcurrentLimit`/ `vulnerabilityAlerts.branchConcurrentLimit`, separate from repository-wide/dependency-specific rules.\n * Falls back to the `vulnerabilityAlerts` option's own schema default (currently `0`, i.e. no limit) when\n * unset, via `getDefault()`, rather than duplicating that value here.\n */\nfunction resolveVulnerabilityConcurrentLimit(\n config: RenovateConfig,\n): ConcurrentLimit {\n // `vulnerabilityAlerts` is typed as `RenovateSharedConfig`, which doesn't declare `prConcurrentLimit`/\n // `branchConcurrentLimit`, even though both are valid nested options (see docs for `vulnerabilityAlerts`).\n // oxlint-disable-next-line typescript/no-unnecessary-type-assertion\n const vulnerabilityAlerts = config.vulnerabilityAlerts as\n RenovateConfig | undefined;\n const vulnerabilityAlertsDefault = getDefault(\n getOptions().find((option) => option.name === 'vulnerabilityAlerts')!,\n ) as RenovateConfig;\n const configAsUpgrade: BranchUpgradeConfig = {\n branchName: '',\n manager: '',\n prConcurrentLimit:\n vulnerabilityAlerts?.prConcurrentLimit ??\n vulnerabilityAlertsDefault.prConcurrentLimit,\n // `undefined` and `null` are handled identically by `calcLimit()` (both inherit `prConcurrentLimit`),\n // so there's no default value to duplicate here - unlike `prConcurrentLimit` above.\n branchConcurrentLimit: vulnerabilityAlerts?.branchConcurrentLimit,\n };\n const prConcurrentLimit = calcLimit([configAsUpgrade], 'prConcurrentLimit');\n const branchConcurrentLimit = calcLimit(\n [configAsUpgrade],\n 'branchConcurrentLimit',\n );\n\n if (\n typeof vulnerabilityAlerts?.branchConcurrentLimit === 'number' &&\n branchConcurrentLimit > 0 &&\n (prConcurrentLimit === 0 || branchConcurrentLimit < prConcurrentLimit)\n ) {\n return {\n limit: branchConcurrentLimit,\n key: 'branchConcurrentLimit',\n };\n }\n\n return { limit: prConcurrentLimit, key: 'prConcurrentLimit' };\n}\n\nexport function getExpectedPrList(\n config: RenovateConfig,\n branches: BranchConfig[],\n): string {\n logger.debug('getExpectedPrList()');\n logger.trace({ config });\n let prDesc = `\\n### What to Expect\\n\\n`;\n if (!branches.length) {\n return `${prDesc}It looks like your repository dependencies are already up-to-date and no Pull Requests will be necessary right away.\\n`;\n }\n // Vulnerability alert branches bypass the repository-wide rate/concurrency limits, so they shouldn't\n // count towards them - they get their own budget, see `resolveVulnerabilityConcurrentLimit()`.\n const securityBranchCount = branches.filter(\n (b) => b.isVulnerabilityAlert,\n ).length;\n const throttledBranchCount = branches.length - securityBranchCount;\n\n const { limit: concurrentLimit, key: concurrentLimitKey } =\n resolveConcurrentLimit(config);\n if (concurrentLimit > 0 && concurrentLimit < throttledBranchCount) {\n const securityNote =\n securityBranchCount > 0\n ? `, plus ${securityBranchCount} security update Pull Request${securityBranchCount > 1 ? 's' : ''} which ${securityBranchCount > 1 ? 'are' : 'is'} not subject to this limit`\n : '';\n prDesc += `With your current configuration, Renovate will create ${concurrentLimit} Pull Request${concurrentLimit > 1 ? 's' : ''}, up to a maximum of ${branches.length} over time (see [docs for \\`${concurrentLimitKey}\\`](${GlobalConfig.get('productLinks').documentation}configuration-options/#${concurrentLimitKey.toLowerCase()}))${securityNote}:\\n\\n`;\n } else {\n prDesc += `With your current configuration, Renovate will create ${branches.length} Pull Request`;\n prDesc += branches.length > 1 ? `s:\\n\\n` : `:\\n\\n`;\n }\n prDesc += getSecurityConcurrentLimitNote(\n securityBranchCount,\n concurrentLimit,\n resolveVulnerabilityConcurrentLimit(config),\n );\n\n for (const branch of branches) {\n const prTitleRe = regEx(/@(?<scope>[a-z]+\\/[a-z]+)/);\n // TODO #22198\n prDesc += `<details>\\n<summary>${branch.prTitle!.replace(\n prTitleRe,\n '@&#8203;$<scope>',\n )}</summary>\\n\\n`;\n if (branch.schedule?.length) {\n prDesc += ` - Schedule: ${JSON.stringify(branch.schedule)}\\n`;\n }\n prDesc += ` - Branch name: \\`${branch.branchName}\\`\\n`;\n prDesc += branch.baseBranch\n ? ` - Merge into: \\`${branch.baseBranch}\\`\\n`\n : '';\n const seen: string[] = [];\n for (const upgrade of branch.upgrades) {\n let text = '';\n if (upgrade.updateType === 'lockFileMaintenance') {\n text += ' - Regenerate lock files to use latest dependency versions';\n } else {\n if (upgrade.updateType === 'pin') {\n text += ' - Pin ';\n } else {\n text += ' - Upgrade ';\n }\n if (upgrade.sourceUrl) {\n // TODO: types (#22198)\n text += `[${upgrade.depName!}](${upgrade.sourceUrl})`;\n } else {\n text += upgrade.depName!.replace(prTitleRe, '@&#8203;$1');\n }\n // TODO: types (#22198)\n text += upgrade.isLockfileUpdate\n ? ` to \\`${upgrade.newVersion!}\\``\n : ` to \\`${upgrade.newDigest ?? upgrade.newValue!}\\``;\n text += '\\n';\n }\n if (!seen.includes(text)) {\n prDesc += text;\n seen.push(text);\n }\n }\n prDesc += '\\n\\n';\n prDesc += '</details>\\n\\n';\n }\n const prHourlyLimit = coerceNumber(config.prHourlyLimit);\n const commitHourlyLimit = coerceNumber(config.commitHourlyLimit);\n const securityBypassNote =\n securityBranchCount > 0\n ? ` Security update Pull Request${securityBranchCount > 1 ? 's are' : ' is'} not subject to this limit and will be created straight away.`\n : '';\n if (\n commitHourlyLimit > 0 &&\n commitHourlyLimit < 5 &&\n commitHourlyLimit < throttledBranchCount\n ) {\n prDesc += emojify(\n `\\n\\n:children_crossing: Branch creation and rebasing will be limited to maximum ${commitHourlyLimit} per hour, so it doesn't swamp any CI resources or overwhelm the project. See [docs for \\`commitHourlyLimit\\`](${GlobalConfig.get('productLinks').documentation}configuration-options/#commithourlylimit) for details.${securityBypassNote}\\n\\n`,\n );\n } else if (\n prHourlyLimit > 0 &&\n prHourlyLimit < 5 &&\n prHourlyLimit < throttledBranchCount\n ) {\n prDesc += emojify(\n `\\n\\n:children_crossing: PR creation will be limited to maximum ${prHourlyLimit} per hour, so it doesn't swamp any CI resources or overwhelm the project. See [docs for \\`prHourlyLimit\\`](${GlobalConfig.get('productLinks').documentation}configuration-options/#prhourlylimit) for details.${securityBypassNote}\\n\\n`,\n );\n }\n return prDesc;\n}\n\n/**\n * Security update Pull Requests bypass the repository-wide `prConcurrentLimit`/`branchConcurrentLimit`\n * by default, but they can be rate limited on their own via `vulnerabilityAlerts.prConcurrentLimit`/\n * `branchConcurrentLimit`.\n *\n * - If the user has already opted in to that limit, and it would actually throttle the security updates,\n * say so - the \"not subject to this limit\" wording elsewhere refers only to the repository-wide limit.\n * - Otherwise, once the number of security updates alone would exceed the repository-wide limit, suggest\n * that the user may want to opt in to limiting them too.\n */\nfunction getSecurityConcurrentLimitNote(\n securityCount: number,\n concurrentLimit: number,\n vulnerabilityLimit: ConcurrentLimit,\n): string {\n if (securityCount === 0) {\n return '';\n }\n\n if (vulnerabilityLimit.limit > 0) {\n if (securityCount <= vulnerabilityLimit.limit) {\n return '';\n }\n return emojify(\n `:information_source: Renovate will only create ${vulnerabilityLimit.limit} security update Pull Request${vulnerabilityLimit.limit > 1 ? 's' : ''} at a time, up to a maximum of ${securityCount} over time, due to your [\\`vulnerabilityAlerts.${vulnerabilityLimit.key}\\`](${GlobalConfig.get('productLinks').documentation}configuration-options/#vulnerabilityalerts) setting.\\n\\n`,\n );\n }\n\n if (concurrentLimit <= 0 || securityCount <= concurrentLimit) {\n return '';\n }\n return emojify(\n `:information_source: If you want to rate limit security update Pull Requests too, set [\\`vulnerabilityAlerts.prConcurrentLimit\\`](${GlobalConfig.get('productLinks').documentation}configuration-options/#vulnerabilityalerts).\\n\\n`,\n );\n}\n\nfunction getBranchUpgradeTypes(branch: BranchConfig): Set<SummaryCategory> {\n if (branch.isVulnerabilityAlert) {\n return new Set(['security']);\n }\n const types = new Set<SummaryCategory>();\n for (const upgrade of branch.upgrades) {\n if (upgrade.updateType) {\n types.add(upgrade.updateType);\n } else if (upgrade.isLockfileUpdate) {\n types.add('lockfileUpdate');\n } else {\n types.add('other');\n }\n }\n return types;\n}\n\n// Sort: default branch (empty string) first, then named branches alphabetically.\nfunction sortBaseBranches(bases: Iterable<string>): string[] {\n return [...bases].sort((a, b) => {\n // v8 ignore if -- base branches are unique Record keys, so never equal\n if (a === b) {\n return 0;\n }\n if (a === '') {\n return -1;\n }\n if (b === '') {\n return 1;\n }\n return a.localeCompare(b);\n });\n}\n\nfunction describeSecurityGroup(groupBranches: BranchConfig[]): string {\n const firstUpgrade = groupBranches[0].upgrades[0];\n const depName = firstUpgrade?.depName ?? groupBranches[0].prTitle ?? '';\n const updateType = firstUpgrade?.updateType ?? 'unknown';\n const packageFiles = groupBranches\n .map((b) => ({ file: b.packageFile ?? '', manager: b.manager }))\n .filter((f) => f.file);\n const uniqueManagers = new Set(packageFiles.map((f) => f.manager));\n\n // Vulnerability alerts can match on datasource + packageName without a specific file (e.g. GitHub vulnerability alerts),\n // so we need to handle an absent packageFile\n if (packageFiles.length === 0) {\n const branchManagers = new Set(groupBranches.map((b) => b.manager));\n if (branchManagers.size === 1) {\n return `- \\`${depName}\\`, (${[...branchManagers][0]}, ${updateType})\\n`;\n }\n\n return `- \\`${depName}\\`, (${updateType}): ${[...branchManagers].sort().join(', ')}\\n`;\n }\n\n if (packageFiles.length === 1) {\n const file = packageFiles[0].file;\n const [manager] = uniqueManagers;\n return `- \\`${depName}\\`, (${manager}, ${updateType}): \\`${file}\\`\\n`;\n }\n\n if (uniqueManagers.size === 1) {\n const manager = [...uniqueManagers][0];\n const fileLines = packageFiles\n .map(({ file }) => ` - \\`${file}\\`\\n`)\n .join('');\n return `- \\`${depName}\\`, (${manager}, ${updateType}):\\n${fileLines}`;\n }\n\n const fileLines = packageFiles\n .map(({ file, manager }) => ` - \\`${file}\\` (${manager})\\n`)\n .join('');\n return `- \\`${depName}\\`, (${updateType}):\\n${fileLines}`;\n}\n\ninterface BranchStats {\n // PR count per base branch, deduplicated by branchName.\n prCountByBase: Record<string, number>;\n // base -> manager -> type -> count, deduplicated by branchName+manager+type.\n tableStats: Record<\n string,\n Record<string, Partial<Record<SummaryCategory, number>>>\n >;\n // All upgrade types seen anywhere — drives the table columns.\n presentCategories: Set<SummaryCategory>;\n // Security branches grouped by branchName.\n securityGroups: Record<string, BranchConfig[]>;\n prCount: number;\n}\n\nfunction collectBranchStats(branches: BranchConfig[]): BranchStats {\n const prCountByBase: Record<string, number> = {};\n const tableStats: Record<\n string,\n Record<string, Partial<Record<SummaryCategory, number>>>\n > = {};\n const presentTypes = new Set<SummaryCategory>();\n const securityGroups: Record<string, BranchConfig[]> = {};\n const seenPrs = new Set<string>();\n const seenTableKeys = new Set<string>();\n\n for (const branch of branches) {\n const base = branch.baseBranch ?? '';\n const { manager, branchName } = branch;\n const branchTypes = getBranchUpgradeTypes(branch);\n\n for (const type of branchTypes) {\n presentTypes.add(type);\n }\n\n if (!seenPrs.has(branchName)) {\n seenPrs.add(branchName);\n prCountByBase[base] = (prCountByBase[base] ?? 0) + 1;\n }\n\n tableStats[base] ??= {};\n const baseStats = tableStats[base];\n baseStats[manager] ??= {};\n const managerStats = baseStats[manager];\n for (const type of branchTypes) {\n const key = `${branchName}:${manager}:${type}`;\n if (seenTableKeys.has(key)) {\n continue;\n }\n seenTableKeys.add(key);\n managerStats[type] ??= 0;\n managerStats[type]++;\n }\n\n if (branch.isVulnerabilityAlert) {\n securityGroups[branchName] ??= [];\n securityGroups[branchName].push(branch);\n }\n }\n\n return {\n prCountByBase,\n tableStats,\n presentCategories: presentTypes,\n securityGroups,\n prCount: seenPrs.size,\n };\n}\n\nfunction getCategoryColumns(\n presentTypes: Set<SummaryCategory>,\n): SummaryCategory[] {\n const cols: SummaryCategory[] = SUMMARY_CATEGORY_PRIORITY_ORDER.filter((t) =>\n presentTypes.has(t),\n );\n // Append any present types not in the standard display order\n // (e.g. lockfileUpdate, bump).\n for (const t of presentTypes) {\n if (t !== 'other' && !cols.includes(t)) {\n cols.push(t);\n }\n }\n\n if (presentTypes.has('other')) {\n cols.push('other');\n }\n\n return cols;\n}\n\nfunction categoriesToColumnHeaders(cols: readonly string[]): string {\n /* v8 ignore next -- branches always have at least one upgrade, so cols is never empty in practice */\n if (cols.length === 0) {\n return '';\n }\n return ` | ${cols.join(' | ')}`;\n}\n\nfunction renderRowCounts(\n typeColumns: readonly SummaryCategory[],\n typeCounts: Partial<Record<SummaryCategory, number>>,\n): string {\n return categoriesToColumnHeaders(\n typeColumns.map((t) => `${typeCounts[t] ?? 0}`),\n );\n}\n\nfunction sumCategoryCounts(\n rows: Partial<Record<SummaryCategory, number>>[],\n categoryColumns: readonly SummaryCategory[],\n): Partial<Record<SummaryCategory, number>> {\n const sum: Partial<Record<SummaryCategory, number>> = {};\n for (const categoryCounts of rows) {\n for (const category of categoryColumns) {\n sum[category] = (sum[category] ?? 0) + (categoryCounts[category] ?? 0);\n }\n }\n return sum;\n}\n\nexport function getExpectedPrListSummary(\n config: RenovateConfig,\n branches: BranchConfig[],\n): string {\n logger.debug('getExpectedPrListSummary()');\n logger.trace({ config });\n let prDesc = `\\n### What to Expect\\n\\n`;\n if (!branches.length) {\n return `${prDesc}It looks like your repository dependencies are already up-to-date and no Pull Requests will be necessary right away.\\n`;\n }\n\n const stats = collectBranchStats(branches);\n const sortedBases = sortBaseBranches(Object.keys(stats.prCountByBase));\n const hasMultipleBaseBranches = sortedBases.length > 1;\n\n const prHourlyLimit = coerceNumber(config.prHourlyLimit);\n const commitHourlyLimit = coerceNumber(config.commitHourlyLimit);\n const concurrentLimit = resolveConcurrentLimit(config);\n const vulnerabilityLimit = resolveVulnerabilityConcurrentLimit(config);\n // Vulnerability alert branches bypass the repository-wide rate/concurrency limits, so they shouldn't\n // count towards them - they get their own budget, see `resolveVulnerabilityConcurrentLimit()`.\n const securityCount = Object.keys(stats.securityGroups).length;\n\n if (hasMultipleBaseBranches) {\n let total = 0;\n const parts = sortedBases.map((base) => {\n const count = stats.prCountByBase[base];\n total += count;\n const label = base ? `the \\`${base}\\` branch` : 'the default branch';\n return `${count} Pull Request${count > 1 ? 's' : ''} to ${label}`;\n });\n const limitsNotice = determineLimitsNotice(\n concurrentLimit,\n prHourlyLimit,\n commitHourlyLimit,\n total - securityCount,\n securityCount,\n );\n prDesc += `With your current configuration, Renovate will create ${parts.join(' and ')}${limitsNotice}:\\n\\n`;\n } else {\n const limitsNotice = determineLimitsNotice(\n concurrentLimit,\n prHourlyLimit,\n commitHourlyLimit,\n stats.prCount - securityCount,\n securityCount,\n );\n prDesc += `With your current configuration, Renovate will create ${stats.prCount} Pull Request${stats.prCount > 1 ? 's' : ''}${limitsNotice}:\\n\\n`;\n }\n\n const categoryColumns = getCategoryColumns(stats.presentCategories);\n if (hasMultipleBaseBranches) {\n prDesc += `| Branch | Manager${categoriesToColumnHeaders(categoryColumns)} |\\n`;\n prDesc += `| --- | ---${categoryColumns.map(() => ' | ---').join('')} |\\n`;\n for (const base of sortedBases) {\n const label = base || '$default';\n for (const [manager, typeCounts] of Object.entries(\n stats.tableStats[base],\n )) {\n prDesc += `| ${label} | ${manager}${renderRowCounts(categoryColumns, typeCounts)} |\\n`;\n }\n }\n const sumRow = sumCategoryCounts(\n Object.values(stats.tableStats).flatMap((b) => Object.values(b)),\n categoryColumns,\n );\n prDesc += `| **Total** | ${renderRowCounts(categoryColumns, sumRow)} |\\n`;\n } else {\n prDesc += `| Manager${categoriesToColumnHeaders(categoryColumns)} |\\n`;\n prDesc += `| ---${categoryColumns.map(() => ' | ---').join('')} |\\n`;\n for (const [manager, typeCounts] of Object.entries(\n stats.tableStats[sortedBases[0]],\n )) {\n prDesc += `| ${manager}${renderRowCounts(categoryColumns, typeCounts)} |\\n`;\n }\n const sumRow = sumCategoryCounts(\n Object.values(stats.tableStats[sortedBases[0]]),\n categoryColumns,\n );\n prDesc += `| **Total**${renderRowCounts(categoryColumns, sumRow)} |\\n`;\n }\n\n prDesc += `\\n<small>Note that a single PR can update multiple files and/or managers, so the above rows may not align with the number of PRs being listed above.</small>\\n`;\n\n // provide a summary of the given security updates, as they're likely more important to the user\n if (Object.keys(stats.securityGroups).length) {\n prDesc += `\\n**Security updates**:\\n\\n`;\n for (const groupBranches of Object.values(stats.securityGroups)) {\n prDesc += describeSecurityGroup(groupBranches);\n }\n const securityConcurrentLimitNote = getSecurityConcurrentLimitNote(\n securityCount,\n concurrentLimit.limit,\n vulnerabilityLimit,\n );\n if (securityConcurrentLimitNote) {\n prDesc += `\\n${securityConcurrentLimitNote}`;\n }\n }\n\n const throttledPrCount = stats.prCount - securityCount;\n const securityBypassNote =\n securityCount > 0\n ? ` Security update Pull Request${securityCount > 1 ? 's are' : ' is'} not subject to this limit and will be created straight away.`\n : '';\n\n if (concurrentLimit.limit > 0 && concurrentLimit.limit < throttledPrCount) {\n const notice =\n concurrentLimit.key === 'branchConcurrentLimit'\n ? `Renovate will only work on ${concurrentLimit.limit} branch${concurrentLimit.limit > 1 ? 'es' : ''} at a time, so not all Pull Requests will be opened straight away`\n : `Renovate will only keep ${concurrentLimit.limit} Pull Request${concurrentLimit.limit > 1 ? 's' : ''} open at a time, so not all of the above will be opened straight away`;\n prDesc += emojify(\n `\\n\\n:children_crossing: ${notice}. See [docs for \\`${concurrentLimit.key}\\`](${GlobalConfig.get('productLinks').documentation}configuration-options/#${concurrentLimit.key.toLowerCase()}) for details.${securityBypassNote}\\n\\n`,\n );\n }\n\n if (\n commitHourlyLimit > 0 &&\n commitHourlyLimit < 5 &&\n commitHourlyLimit < throttledPrCount\n ) {\n prDesc += emojify(\n `\\n\\n:children_crossing: Branch creation and rebasing will be limited to maximum ${commitHourlyLimit} per hour, so it doesn't swamp any CI resources or overwhelm the project. See [docs for \\`commitHourlyLimit\\`](${GlobalConfig.get('productLinks').documentation}configuration-options/#commithourlylimit) for details.${securityBypassNote}\\n\\n`,\n );\n } else if (\n prHourlyLimit > 0 &&\n prHourlyLimit < 5 &&\n prHourlyLimit < throttledPrCount\n ) {\n prDesc += emojify(\n `\\n\\n:children_crossing: PR creation will be limited to maximum ${prHourlyLimit} per hour, so it doesn't swamp any CI resources or overwhelm the project. See [docs for \\`prHourlyLimit\\`](${GlobalConfig.get('productLinks').documentation}configuration-options/#prhourlylimit) for details.${securityBypassNote}\\n\\n`,\n );\n }\n return prDesc;\n}\n\nfunction determineLimitsNotice(\n concurrentLimit: ConcurrentLimit,\n prHourlyLimit: number,\n commitHourlyLimit: number,\n prCount: number,\n securityCount: number,\n): string {\n const clauses: string[] = [];\n\n if (concurrentLimit.limit > 0 && concurrentLimit.limit < prCount) {\n clauses.push(\n concurrentLimit.key === 'branchConcurrentLimit'\n ? `a maximum of ${concurrentLimit.limit} branch${concurrentLimit.limit > 1 ? 'es' : ''} open at a time`\n : `a maximum of ${concurrentLimit.limit} Pull Request${concurrentLimit.limit > 1 ? 's' : ''} open at a time`,\n );\n }\n\n if (\n commitHourlyLimit > 0 &&\n commitHourlyLimit < 5 &&\n commitHourlyLimit < prCount\n ) {\n clauses.push(\n `a maximum of ${commitHourlyLimit} PR${commitHourlyLimit > 1 ? 's' : ''}/rebase${commitHourlyLimit > 1 ? 's' : ''} per hour`,\n );\n } else if (\n prHourlyLimit > 0 &&\n prHourlyLimit < 5 &&\n prHourlyLimit < prCount\n ) {\n clauses.push(\n `a maximum of ${prHourlyLimit} PR${prHourlyLimit > 1 ? 's' : ''} per hour`,\n );\n }\n\n if (!clauses.length) {\n if (commitHourlyLimit === 0 && prHourlyLimit === 0) {\n return ' (with no configured maximum of PRs per hour)';\n }\n return '';\n }\n\n const securityNote =\n securityCount > 0\n ? `, plus ${securityCount} security update${securityCount > 1 ? 's' : ''} which ${securityCount > 1 ? \"aren't\" : \"isn't\"} subject to these limits`\n : '';\n\n return emojify(` (at ${clauses.join(' and ')}${securityNote})`);\n}\n"],"mappings":"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"}
@@ -72,10 +72,8 @@ async function checkReconfigureBranch(config, repoConfig) {
72
72
  await scm.checkoutBranch(config.defaultBranch);
73
73
  return;
74
74
  }
75
- let commentEnsured = false;
76
- if (extractResult) commentEnsured = await ensureReconfigurePrComment(newConfig, extractResult.packageFiles, extractResult.branches, reconfigureBranch, existingPr);
77
75
  // istanbul ignore if: should rarely happen
78
- if (!commentEnsured) extractResult = void 0;
76
+ if (!await ensureReconfigurePrComment(newConfig, extractResult.packageFiles, extractResult.branches, reconfigureBranch, existingPr)) extractResult = void 0;
79
77
  await setBranchStatus(reconfigureBranch, "Validation Successful", "green", context);
80
78
  setReconfigureBranchCache(branchSha, true, extractResult);
81
79
  await scm.checkoutBranch(config.defaultBranch);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../../lib/workers/repository/reconfigure/index.ts"],"sourcesContent":["import { GlobalConfig } from '../../../config/global.ts';\nimport { applySecretsAndVariablesToConfig } from '../../../config/secrets.ts';\nimport type { AllConfig, RenovateConfig } from '../../../config/types.ts';\nimport { logger } from '../../../logger/index.ts';\nimport { platform } from '../../../modules/platform/index.ts';\nimport { scm } from '../../../modules/platform/scm.ts';\nimport { getCache } from '../../../util/cache/repository/index.ts';\nimport { getBranchCommit } from '../../../util/git/index.ts';\nimport { mergeInheritedConfig } from '../init/inherited.ts';\nimport { mergeRenovateConfig } from '../init/merge.ts';\nimport type { ExtractResult } from '../process/extract-update.ts';\nimport { extractDependencies } from '../process/index.ts';\nimport { ensureReconfigurePrComment } from './comment.ts';\nimport {\n deleteReconfigureBranchCache,\n setReconfigureBranchCache,\n} from './reconfigure-cache.ts';\nimport {\n getReconfigureBranchName,\n getReconfigureConfig,\n setBranchStatus,\n} from './utils.ts';\nimport { validateReconfigureBranch } from './validate.ts';\n\nexport async function checkReconfigureBranch(\n config: RenovateConfig,\n repoConfig: AllConfig,\n): Promise<void> {\n logger.debug('checkReconfigureBranch()');\n if (GlobalConfig.get('platform') === 'local') {\n logger.debug(\n 'Not attempting to reconfigure when running with local platform',\n );\n return;\n }\n\n const context = config.statusCheckNames?.configValidation;\n const reconfigureBranch = getReconfigureBranchName(config.branchPrefix!);\n const branchExists = await scm.branchExists(reconfigureBranch);\n\n // this is something the user initiates, skip if no branch exists\n if (!branchExists) {\n logger.debug({ reconfigureBranch }, 'No reconfigure branch found');\n deleteReconfigureBranchCache(); // in order to remove cache when the branch has been deleted\n return;\n }\n\n const existingPr = await platform.findPr({\n branchName: reconfigureBranch,\n state: 'open',\n includeOtherAuthors: true,\n targetBranch: config.defaultBranch,\n });\n const branchSha = getBranchCommit(reconfigureBranch)!;\n const cache = getCache();\n const reconfigureCache = cache.reconfigureBranchCache;\n\n // only use valid cached information\n if (\n reconfigureCache?.reconfigureBranchSha === branchSha &&\n (!existingPr || reconfigureCache.extractResult)\n ) {\n logger.debug('Skipping validation check as branch sha is unchanged');\n return;\n }\n\n const result = await getReconfigureConfig(reconfigureBranch);\n\n if (!result.ok) {\n await setBranchStatus(reconfigureBranch, result.errMessage, 'red', context);\n setReconfigureBranchCache(branchSha, false);\n await scm.checkoutBranch(config.defaultBranch!);\n return;\n }\n\n const isValidConfig = await validateReconfigureBranch(\n config,\n result.config,\n result.configFileName,\n existingPr,\n );\n\n if (!isValidConfig) {\n logger.debug(\n 'Found errors in reconfigure config. Skipping dependencies extraction',\n );\n await scm.checkoutBranch(config.defaultBranch!);\n return;\n }\n\n if (!existingPr) {\n logger.debug('No reconfigure pr found. Skipping dependencies extraction');\n await scm.checkoutBranch(config.defaultBranch!);\n return;\n }\n\n let extractResult: ExtractResult | undefined;\n // Recompute config similar to repo config processing\n // Get non-global config from file config\n // Merge it with inherited and static repo config\n // Finally, merge the reconfigure config\n let newConfig = GlobalConfig.set(\n applySecretsAndVariablesToConfig({\n config: repoConfig,\n }),\n );\n newConfig.baseBranch = config.defaultBranch;\n newConfig.repoIsOnboarded = true;\n newConfig.errors = [];\n newConfig.warnings = [];\n\n try {\n newConfig = await mergeInheritedConfig(newConfig);\n newConfig = await mergeRenovateConfig(newConfig, reconfigureBranch);\n await scm.checkoutBranch(config.defaultBranch!);\n extractResult = await extractDependencies(newConfig, false);\n } catch (err) {\n logger.debug(\n { err },\n 'Error while extracting dependencies using the reconfigure config',\n );\n setReconfigureBranchCache(branchSha, true);\n await scm.checkoutBranch(config.defaultBranch!); // being cautious\n return;\n }\n\n let commentEnsured = false;\n if (extractResult) {\n commentEnsured = await ensureReconfigurePrComment(\n newConfig,\n extractResult.packageFiles,\n extractResult.branches,\n reconfigureBranch,\n existingPr,\n );\n }\n\n // if comment is not added or updated\n // do not store extractResult in cache so that we re-process the reconfigure branch on next run and do not skip\n // istanbul ignore if: should rarely happen\n if (!commentEnsured) {\n extractResult = undefined;\n }\n await setBranchStatus(\n reconfigureBranch,\n 'Validation Successful',\n 'green',\n context,\n );\n setReconfigureBranchCache(branchSha, true, extractResult);\n await scm.checkoutBranch(config.defaultBranch!); //being cautious\n}\n"],"mappings":";;;;;;;;;;;;;;;AAwBA,eAAsB,uBACpB,QACA,YACe;CACf,OAAO,MAAM,0BAA0B;CACvC,IAAI,aAAa,IAAI,UAAU,MAAM,SAAS;EAC5C,OAAO,MACL,gEACF;EACA;CACF;CAEA,MAAM,UAAU,OAAO,kBAAkB;CACzC,MAAM,oBAAoB,yBAAyB,OAAO,YAAa;CAIvE,IAAI,CAAC,MAHsB,IAAI,aAAa,iBAAiB,GAG1C;EACjB,OAAO,MAAM,EAAE,kBAAkB,GAAG,6BAA6B;EACjE,6BAA6B;EAC7B;CACF;CAEA,MAAM,aAAa,MAAM,SAAS,OAAO;EACvC,YAAY;EACZ,OAAO;EACP,qBAAqB;EACrB,cAAc,OAAO;CACvB,CAAC;CACD,MAAM,YAAY,gBAAgB,iBAAiB;CAEnD,MAAM,mBADQ,SACe,CAAC,CAAC;CAG/B,IACE,kBAAkB,yBAAyB,cAC1C,CAAC,cAAc,iBAAiB,gBACjC;EACA,OAAO,MAAM,sDAAsD;EACnE;CACF;CAEA,MAAM,SAAS,MAAM,qBAAqB,iBAAiB;CAE3D,IAAI,CAAC,OAAO,IAAI;EACd,MAAM,gBAAgB,mBAAmB,OAAO,YAAY,OAAO,OAAO;EAC1E,0BAA0B,WAAW,KAAK;EAC1C,MAAM,IAAI,eAAe,OAAO,aAAc;EAC9C;CACF;CASA,IAAI,CAAC,MAPuB,0BAC1B,QACA,OAAO,QACP,OAAO,gBACP,UACF,GAEoB;EAClB,OAAO,MACL,sEACF;EACA,MAAM,IAAI,eAAe,OAAO,aAAc;EAC9C;CACF;CAEA,IAAI,CAAC,YAAY;EACf,OAAO,MAAM,2DAA2D;EACxE,MAAM,IAAI,eAAe,OAAO,aAAc;EAC9C;CACF;CAEA,IAAI;CAKJ,IAAI,YAAY,aAAa,IAC3B,iCAAiC,EAC/B,QAAQ,WACV,CAAC,CACH;CACA,UAAU,aAAa,OAAO;CAC9B,UAAU,kBAAkB;CAC5B,UAAU,SAAS,CAAC;CACpB,UAAU,WAAW,CAAC;CAEtB,IAAI;EACF,YAAY,MAAM,qBAAqB,SAAS;EAChD,YAAY,MAAM,oBAAoB,WAAW,iBAAiB;EAClE,MAAM,IAAI,eAAe,OAAO,aAAc;EAC9C,gBAAgB,MAAM,oBAAoB,WAAW,KAAK;CAC5D,SAAS,KAAK;EACZ,OAAO,MACL,EAAE,IAAI,GACN,kEACF;EACA,0BAA0B,WAAW,IAAI;EACzC,MAAM,IAAI,eAAe,OAAO,aAAc;EAC9C;CACF;CAEA,IAAI,iBAAiB;CACrB,IAAI,eACF,iBAAiB,MAAM,2BACrB,WACA,cAAc,cACd,cAAc,UACd,mBACA,UACF;;CAMF,IAAI,CAAC,gBACH,gBAAgB,KAAA;CAElB,MAAM,gBACJ,mBACA,yBACA,SACA,OACF;CACA,0BAA0B,WAAW,MAAM,aAAa;CACxD,MAAM,IAAI,eAAe,OAAO,aAAc;AAChD"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../../lib/workers/repository/reconfigure/index.ts"],"sourcesContent":["import { GlobalConfig } from '../../../config/global.ts';\nimport { applySecretsAndVariablesToConfig } from '../../../config/secrets.ts';\nimport type { AllConfig, RenovateConfig } from '../../../config/types.ts';\nimport { logger } from '../../../logger/index.ts';\nimport { platform } from '../../../modules/platform/index.ts';\nimport { scm } from '../../../modules/platform/scm.ts';\nimport { getCache } from '../../../util/cache/repository/index.ts';\nimport { getBranchCommit } from '../../../util/git/index.ts';\nimport { mergeInheritedConfig } from '../init/inherited.ts';\nimport { mergeRenovateConfig } from '../init/merge.ts';\nimport type { ExtractResult } from '../process/extract-update.ts';\nimport { extractDependencies } from '../process/index.ts';\nimport { ensureReconfigurePrComment } from './comment.ts';\nimport {\n deleteReconfigureBranchCache,\n setReconfigureBranchCache,\n} from './reconfigure-cache.ts';\nimport {\n getReconfigureBranchName,\n getReconfigureConfig,\n setBranchStatus,\n} from './utils.ts';\nimport { validateReconfigureBranch } from './validate.ts';\n\nexport async function checkReconfigureBranch(\n config: RenovateConfig,\n repoConfig: AllConfig,\n): Promise<void> {\n logger.debug('checkReconfigureBranch()');\n if (GlobalConfig.get('platform') === 'local') {\n logger.debug(\n 'Not attempting to reconfigure when running with local platform',\n );\n return;\n }\n\n const context = config.statusCheckNames?.configValidation;\n const reconfigureBranch = getReconfigureBranchName(config.branchPrefix!);\n const branchExists = await scm.branchExists(reconfigureBranch);\n\n // this is something the user initiates, skip if no branch exists\n if (!branchExists) {\n logger.debug({ reconfigureBranch }, 'No reconfigure branch found');\n deleteReconfigureBranchCache(); // in order to remove cache when the branch has been deleted\n return;\n }\n\n const existingPr = await platform.findPr({\n branchName: reconfigureBranch,\n state: 'open',\n includeOtherAuthors: true,\n targetBranch: config.defaultBranch,\n });\n const branchSha = getBranchCommit(reconfigureBranch)!;\n const cache = getCache();\n const reconfigureCache = cache.reconfigureBranchCache;\n\n // only use valid cached information\n if (\n reconfigureCache?.reconfigureBranchSha === branchSha &&\n (!existingPr || reconfigureCache.extractResult)\n ) {\n logger.debug('Skipping validation check as branch sha is unchanged');\n return;\n }\n\n const result = await getReconfigureConfig(reconfigureBranch);\n\n if (!result.ok) {\n await setBranchStatus(reconfigureBranch, result.errMessage, 'red', context);\n setReconfigureBranchCache(branchSha, false);\n await scm.checkoutBranch(config.defaultBranch!);\n return;\n }\n\n const isValidConfig = await validateReconfigureBranch(\n config,\n result.config,\n result.configFileName,\n existingPr,\n );\n\n if (!isValidConfig) {\n logger.debug(\n 'Found errors in reconfigure config. Skipping dependencies extraction',\n );\n await scm.checkoutBranch(config.defaultBranch!);\n return;\n }\n\n if (!existingPr) {\n logger.debug('No reconfigure pr found. Skipping dependencies extraction');\n await scm.checkoutBranch(config.defaultBranch!);\n return;\n }\n\n let extractResult: ExtractResult | undefined;\n // Recompute config similar to repo config processing\n // Get non-global config from file config\n // Merge it with inherited and static repo config\n // Finally, merge the reconfigure config\n let newConfig = GlobalConfig.set(\n applySecretsAndVariablesToConfig({\n config: repoConfig,\n }),\n );\n newConfig.baseBranch = config.defaultBranch;\n newConfig.repoIsOnboarded = true;\n newConfig.errors = [];\n newConfig.warnings = [];\n\n try {\n newConfig = await mergeInheritedConfig(newConfig);\n newConfig = await mergeRenovateConfig(newConfig, reconfigureBranch);\n await scm.checkoutBranch(config.defaultBranch!);\n extractResult = await extractDependencies(newConfig, false);\n } catch (err) {\n logger.debug(\n { err },\n 'Error while extracting dependencies using the reconfigure config',\n );\n setReconfigureBranchCache(branchSha, true);\n await scm.checkoutBranch(config.defaultBranch!); // being cautious\n return;\n }\n\n const commentEnsured = await ensureReconfigurePrComment(\n newConfig,\n extractResult.packageFiles,\n extractResult.branches,\n reconfigureBranch,\n existingPr,\n );\n\n // if comment is not added or updated\n // do not store extractResult in cache so that we re-process the reconfigure branch on next run and do not skip\n // istanbul ignore if: should rarely happen\n if (!commentEnsured) {\n extractResult = undefined;\n }\n await setBranchStatus(\n reconfigureBranch,\n 'Validation Successful',\n 'green',\n context,\n );\n setReconfigureBranchCache(branchSha, true, extractResult);\n await scm.checkoutBranch(config.defaultBranch!); //being cautious\n}\n"],"mappings":";;;;;;;;;;;;;;;AAwBA,eAAsB,uBACpB,QACA,YACe;CACf,OAAO,MAAM,0BAA0B;CACvC,IAAI,aAAa,IAAI,UAAU,MAAM,SAAS;EAC5C,OAAO,MACL,gEACF;EACA;CACF;CAEA,MAAM,UAAU,OAAO,kBAAkB;CACzC,MAAM,oBAAoB,yBAAyB,OAAO,YAAa;CAIvE,IAAI,CAAC,MAHsB,IAAI,aAAa,iBAAiB,GAG1C;EACjB,OAAO,MAAM,EAAE,kBAAkB,GAAG,6BAA6B;EACjE,6BAA6B;EAC7B;CACF;CAEA,MAAM,aAAa,MAAM,SAAS,OAAO;EACvC,YAAY;EACZ,OAAO;EACP,qBAAqB;EACrB,cAAc,OAAO;CACvB,CAAC;CACD,MAAM,YAAY,gBAAgB,iBAAiB;CAEnD,MAAM,mBADQ,SACe,CAAC,CAAC;CAG/B,IACE,kBAAkB,yBAAyB,cAC1C,CAAC,cAAc,iBAAiB,gBACjC;EACA,OAAO,MAAM,sDAAsD;EACnE;CACF;CAEA,MAAM,SAAS,MAAM,qBAAqB,iBAAiB;CAE3D,IAAI,CAAC,OAAO,IAAI;EACd,MAAM,gBAAgB,mBAAmB,OAAO,YAAY,OAAO,OAAO;EAC1E,0BAA0B,WAAW,KAAK;EAC1C,MAAM,IAAI,eAAe,OAAO,aAAc;EAC9C;CACF;CASA,IAAI,CAAC,MAPuB,0BAC1B,QACA,OAAO,QACP,OAAO,gBACP,UACF,GAEoB;EAClB,OAAO,MACL,sEACF;EACA,MAAM,IAAI,eAAe,OAAO,aAAc;EAC9C;CACF;CAEA,IAAI,CAAC,YAAY;EACf,OAAO,MAAM,2DAA2D;EACxE,MAAM,IAAI,eAAe,OAAO,aAAc;EAC9C;CACF;CAEA,IAAI;CAKJ,IAAI,YAAY,aAAa,IAC3B,iCAAiC,EAC/B,QAAQ,WACV,CAAC,CACH;CACA,UAAU,aAAa,OAAO;CAC9B,UAAU,kBAAkB;CAC5B,UAAU,SAAS,CAAC;CACpB,UAAU,WAAW,CAAC;CAEtB,IAAI;EACF,YAAY,MAAM,qBAAqB,SAAS;EAChD,YAAY,MAAM,oBAAoB,WAAW,iBAAiB;EAClE,MAAM,IAAI,eAAe,OAAO,aAAc;EAC9C,gBAAgB,MAAM,oBAAoB,WAAW,KAAK;CAC5D,SAAS,KAAK;EACZ,OAAO,MACL,EAAE,IAAI,GACN,kEACF;EACA,0BAA0B,WAAW,IAAI;EACzC,MAAM,IAAI,eAAe,OAAO,aAAc;EAC9C;CACF;;CAaA,IAAI,CAAC,MAXwB,2BAC3B,WACA,cAAc,cACd,cAAc,UACd,mBACA,UACF,GAME,gBAAgB,KAAA;CAElB,MAAM,gBACJ,mBACA,yBACA,SACA,OACF;CACA,0BAA0B,WAAW,MAAM,aAAa;CACxD,MAAM,IAAI,eAAe,OAAO,aAAc;AAChD"}
@@ -2,12 +2,10 @@ import { MANAGER_LOCKFILE_ERROR, PLATFORM_AUTHENTICATION_ERROR, PLATFORM_BAD_CRE
2
2
  import { GlobalConfig } from "../../../../config/global.js";
3
3
  import { coerceArray } from "../../../../util/array.js";
4
4
  import { logger, removeMeta } from "../../../../logger/index.js";
5
- import { toMs } from "../../../../util/pretty-time.js";
6
5
  import { compile } from "../../../../util/template/index.js";
7
6
  import { filterValidCommitTrailers } from "../../../../util/git/commit-trailers.js";
8
7
  import { isScheduledNow } from "./schedule.js";
9
8
  import { ExternalHostError } from "../../../../types/errors/external-host-error.js";
10
- import { coerceNumber } from "../../../../util/number.js";
11
9
  import { getCount, isLimitReached } from "../../../global/limits.js";
12
10
  import { getElapsedMs } from "../../../../util/date.js";
13
11
  import { emojify } from "../../../../util/emoji.js";
@@ -18,6 +16,7 @@ import { embedChangelogs } from "../../changelog/index.js";
18
16
  import { getMergeConfidenceLevel, isActiveConfidenceLevel, satisfiesConfidenceLevel } from "../../../../util/merge-confidence/index.js";
19
17
  import { setConfidence, setStability } from "./status-checks.js";
20
18
  import { ensurePr, getPlatformPrOptions } from "../pr/index.js";
19
+ import { calculateMinimumReleaseAgeMs } from "../../../../util/minimum-release-age.js";
21
20
  import { updateActionsLockfile } from "../../../../modules/manager/github-actions/artifacts.js";
22
21
  import { getAdditionalFiles } from "../../../../modules/manager/npm/post-update/index.js";
23
22
  import { checkAutoMerge } from "../pr/automerge.js";
@@ -284,7 +283,7 @@ async function processBranch(branchConfig, forceRebase = false) {
284
283
  };
285
284
  config.stabilityStatus = "green";
286
285
  for (const upgrade of config.upgrades) {
287
- const minimumReleaseAgeMs = isNonEmptyString(upgrade.minimumReleaseAge) ? coerceNumber(toMs(upgrade.minimumReleaseAge), 0) : 0;
286
+ const minimumReleaseAgeMs = calculateMinimumReleaseAgeMs(upgrade);
288
287
  if (minimumReleaseAgeMs) {
289
288
  const minimumReleaseAgeBehaviour = upgrade.minimumReleaseAgeBehaviour ?? "timestamp-required";
290
289
  if (upgrade.releaseTimestamp) {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["template.compile"],"sources":["../../../../../lib/workers/repository/update/branch/index.ts"],"sourcesContent":["import { isNonEmptyString } from '@sindresorhus/is';\nimport { DateTime } from 'luxon';\nimport { GlobalConfig } from '../../../../config/global.ts';\nimport {\n type MinimumReleaseAgeBehaviour,\n type RenovateConfig,\n type UpdateType,\n} from '../../../../config/types.ts';\nimport {\n CONFIG_VALIDATION,\n MANAGER_LOCKFILE_ERROR,\n PLATFORM_AUTHENTICATION_ERROR,\n PLATFORM_BAD_CREDENTIALS,\n PLATFORM_INTEGRATION_UNAUTHORIZED,\n PLATFORM_RATE_LIMIT_EXCEEDED,\n PR_ALREADY_IN_MERGE_QUEUE,\n REPOSITORY_CHANGED,\n SYSTEM_INSUFFICIENT_DISK_SPACE,\n TEMPORARY_ERROR,\n WORKER_FILE_UPDATE_FAILED,\n} from '../../../../constants/error-messages.ts';\nimport { logger, removeMeta } from '../../../../logger/index.ts';\nimport { updateActionsLockfile } from '../../../../modules/manager/github-actions/artifacts.ts';\nimport { getAdditionalFiles } from '../../../../modules/manager/npm/post-update/index.ts';\nimport {\n ensureComment,\n ensureCommentRemoval,\n} from '../../../../modules/platform/comment.ts';\nimport type { Pr } from '../../../../modules/platform/index.ts';\nimport { platform } from '../../../../modules/platform/index.ts';\nimport { scm } from '../../../../modules/platform/scm.ts';\nimport { ExternalHostError } from '../../../../types/errors/external-host-error.ts';\nimport { coerceArray } from '../../../../util/array.ts';\nimport { getElapsedMs } from '../../../../util/date.ts';\nimport { emojify } from '../../../../util/emoji.ts';\nimport { filterValidCommitTrailers } from '../../../../util/git/commit-trailers.ts';\nimport {\n getMergeConfidenceLevel,\n isActiveConfidenceLevel,\n satisfiesConfidenceLevel,\n} from '../../../../util/merge-confidence/index.ts';\nimport { coerceNumber } from '../../../../util/number.ts';\nimport { toMs } from '../../../../util/pretty-time.ts';\nimport * as template from '../../../../util/template/index.ts';\nimport { getCount, isLimitReached } from '../../../global/limits.ts';\nimport type {\n BranchConfig,\n BranchResult,\n PrBlockedBy,\n} from '../../../types.ts';\nimport { embedChangelogs } from '../../changelog/index.ts';\nimport { checkAutoMerge } from '../pr/automerge.ts';\nimport { ensurePr, getPlatformPrOptions } from '../pr/index.ts';\nimport { setArtifactErrorStatus } from './artifacts.ts';\nimport { tryBranchAutomerge } from './automerge.ts';\nimport { bumpVersions } from './bump-versions.ts';\nimport { prAlreadyExisted } from './check-existing.ts';\nimport { commitFilesToBranch } from './commit.ts';\nimport executePostUpgradeCommands from './execute-post-upgrade-commands.ts';\nimport { getUpdatedPackageFiles } from './get-updated.ts';\nimport { handleClosedPr, handleModifiedPr } from './handle-existing.ts';\nimport { shouldReuseExistingBranch } from './reuse.ts';\nimport { isScheduledNow } from './schedule.ts';\nimport { setConfidence, setStability } from './status-checks.ts';\n\nasync function setBranchStatusChecks(config: BranchConfig): Promise<void> {\n await setStability(config);\n await setConfidence(config);\n}\n\nasync function rebaseCheck(\n config: RenovateConfig,\n branchPr: Pr,\n): Promise<boolean> {\n const titleRebase = branchPr.title?.startsWith('rebase!');\n if (titleRebase) {\n logger.debug(\n `Manual rebase requested via PR title for #${branchPr.number}`,\n );\n return true;\n }\n const labelRebase = !!branchPr.labels?.includes(config.rebaseLabel!);\n if (labelRebase) {\n logger.debug(\n `Manual rebase requested via PR labels for #${branchPr.number}`,\n );\n /* v8 ignore next -- needs test */\n if (GlobalConfig.get('dryRun')) {\n logger.info(\n `DRY-RUN: Would delete label ${config.rebaseLabel!} from #${\n branchPr.number\n }`,\n );\n } else {\n await platform.deleteLabel(branchPr.number, config.rebaseLabel!);\n }\n return true;\n }\n const prRebaseChecked = !!branchPr.bodyStruct?.rebaseRequested;\n if (prRebaseChecked) {\n logger.debug(\n `Manual rebase requested via PR checkbox for #${branchPr.number}`,\n );\n return true;\n }\n\n return false;\n}\n\nasync function deleteBranchSilently(branchName: string): Promise<void> {\n try {\n await scm.deleteBranch(branchName);\n } catch (err) {\n /* v8 ignore next -- needs test */\n logger.debug({ branchName, err }, 'Branch auto-remove failed');\n }\n}\n\nfunction userChangedTargetBranch(pr: Pr): boolean {\n const oldTargetBranch = pr.bodyStruct?.debugData?.targetBranch;\n if (oldTargetBranch && pr.targetBranch) {\n return pr.targetBranch !== oldTargetBranch;\n }\n return false;\n}\n\nexport interface ProcessBranchResult {\n branchExists: boolean;\n updatesVerified?: boolean;\n prBlockedBy?: PrBlockedBy;\n prNo?: number;\n result: BranchResult;\n commitSha?: string | null;\n}\n\nexport async function processBranch(\n branchConfig: BranchConfig,\n forceRebase = false,\n): Promise<ProcessBranchResult> {\n let commitSha: string | null = null;\n let config: BranchConfig = { ...branchConfig };\n logger.trace({ config }, 'processBranch()');\n let branchExists = await scm.branchExists(config.branchName);\n const dependencyDashboardCheck =\n config.dependencyDashboardChecks?.[config.branchName];\n // Only allow a branch to be recreated with updates that are `pending` if we've explicitly constented with an `unpend` on the Dependency Dashboard, or when using `checkedBranches`\n const unpendRequested =\n dependencyDashboardCheck === 'unpend' ||\n dependencyDashboardCheck === 'global-config';\n let updatesVerified = false;\n if (!branchExists && config.branchPrefix !== config.branchPrefixOld) {\n const branchName = config.branchName.replace(\n config.branchPrefix!,\n config.branchPrefixOld!,\n );\n branchExists = await scm.branchExists(branchName);\n // v8 ignore else -- TODO: add test #40625\n if (branchExists) {\n config.branchName = branchName;\n logger.debug('Found existing branch with branchPrefixOld');\n }\n }\n\n if (\n !branchExists &&\n branchConfig.minimumGroupSize &&\n branchConfig.minimumGroupSize > branchConfig.upgrades.length &&\n !dependencyDashboardCheck\n ) {\n logger.debug(\n `Skipping branch creation as minimumGroupSize: ${branchConfig.minimumGroupSize} is not met`,\n );\n return {\n branchExists: false,\n result: 'minimum-group-size-not-met',\n };\n }\n\n let branchPr = await platform.getBranchPr(\n config.branchName,\n config.baseBranch,\n );\n logger.debug(`branchExists=${branchExists}`);\n logger.debug(`dependencyDashboardCheck=${dependencyDashboardCheck!}`);\n if (branchPr) {\n config.rebaseRequested = await rebaseCheck(config, branchPr);\n logger.debug(`PR rebase requested=${config.rebaseRequested}`);\n }\n const keepUpdatedLabel = config.keepUpdatedLabel;\n const pendingRebaseTopic = emojify(':warning: Rebase not applied');\n const artifactErrorTopic = emojify(':warning: Artifact update problem');\n const artifactNoticeTopic = emojify(\n ':information_source: Artifact update notice',\n );\n try {\n // Check if branch already existed\n const existingPr =\n !branchPr || config.automerge\n ? await prAlreadyExisted(config)\n : undefined;\n if (existingPr?.state === 'merged') {\n logger.debug(`Matching PR #${existingPr.number} was merged previously`);\n if (config.automerge) {\n logger.debug('Disabling automerge because PR was merged previously');\n config.automerge = false;\n config.automergedPreviously = true;\n }\n } else if (!branchPr && existingPr && !dependencyDashboardCheck) {\n logger.debug(\n { prTitle: config.prTitle },\n `Closed PR #${existingPr.number} already exists. Skipping branch.`,\n );\n await handleClosedPr(config, existingPr);\n return {\n branchExists: false,\n prNo: existingPr.number,\n result: 'already-existed',\n };\n }\n if (!branchExists && branchConfig.pendingChecks && !unpendRequested) {\n logger.debug(\n `Branch ${config.branchName} creation is disabled because internalChecksFilter was not met`,\n );\n return {\n branchExists: false,\n result: 'pending',\n };\n }\n if (!branchExists) {\n if (config.mode === 'silent' && !dependencyDashboardCheck) {\n logger.debug(\n `Branch ${config.branchName} creation is disabled because mode=silent`,\n );\n return {\n branchExists,\n result: 'needs-approval',\n };\n }\n if (config.dependencyDashboardApproval && !dependencyDashboardCheck) {\n logger.debug(\n `Branch ${config.branchName} creation is disabled because dependencyDashboardApproval=true`,\n );\n return {\n branchExists,\n result: 'needs-approval',\n };\n }\n }\n\n logger.debug(\n `Open PR Count: ${getCount('ConcurrentPRs')}, Existing Branch Count: ${getCount('Branches')}, Hourly PR Count: ${getCount('HourlyPRs')}, Hourly Commit Count: ${getCount('HourlyCommits')}`,\n );\n\n // for a vulnerability alert this checks the VulnerabilityBranches count\n if (\n !branchExists &&\n isLimitReached('Branches', branchConfig) &&\n !dependencyDashboardCheck\n ) {\n logger.debug('Reached branch limit - skipping branch creation');\n return {\n branchExists,\n result: 'branch-limit-reached',\n };\n }\n if (\n !config.rebaseRequested &&\n isLimitReached('Commits') &&\n !dependencyDashboardCheck &&\n !config.isVulnerabilityAlert\n ) {\n logger.debug('Reached commits per run limit - skipping branch');\n return {\n branchExists,\n prNo: branchPr?.number,\n result: 'commit-per-run-limit-reached',\n };\n }\n if (\n !config.rebaseRequested &&\n isLimitReached('HourlyCommits', branchConfig) &&\n !dependencyDashboardCheck &&\n !config.isVulnerabilityAlert\n ) {\n logger.debug('Reached hourly commits limit - skipping branch');\n return {\n branchExists,\n prNo: branchPr?.number,\n result: 'commit-hourly-limit-reached',\n };\n }\n if (branchExists) {\n // check if branch is labelled to stop\n config.stopUpdating = branchPr?.labels?.includes(\n config.stopUpdatingLabel!,\n );\n\n const prRebaseChecked = !!branchPr?.bodyStruct?.rebaseRequested;\n\n if (\n !dependencyDashboardCheck &&\n !prRebaseChecked &&\n config.stopUpdating\n ) {\n logger.info(\n 'Branch updating is skipped because stopUpdatingLabel is present in config',\n );\n return {\n branchExists: true,\n prNo: branchPr?.number,\n result: 'no-work',\n };\n }\n\n // A rebase or retry request is not consent to add an upgrade which has not met its internal checks, so only an unpend of this branch may override this\n if (!unpendRequested && config.pendingChecks) {\n if (config.rebaseRequested) {\n logger.info(\n 'Branch updating is skipped because internalChecksFilter was not met, despite the requested rebase',\n );\n if (branchPr) {\n const content =\n 'This branch has not been rebased, as its update has not yet met the internal checks configured for it, such as `minimumReleaseAge`. Rebasing it now would add a dependency version which is still within its configured observation period.\\n\\nRenovate will rebase this branch once its update has met those checks.';\n if (GlobalConfig.get('dryRun')) {\n logger.info(\n `DRY-RUN: Would ensure pending rebase comment in PR #${branchPr.number}`,\n );\n } else {\n await ensureComment({\n number: branchPr.number,\n topic: pendingRebaseTopic,\n content,\n });\n }\n }\n } else {\n logger.info(\n 'Branch updating is skipped because internalChecksFilter was not met',\n );\n }\n return {\n branchExists: true,\n prNo: branchPr?.number,\n result: 'pending',\n };\n }\n\n logger.debug('Checking if PR has been edited');\n const branchIsModified = await scm.isBranchModified(\n config.branchName,\n config.baseBranch,\n );\n if (branchPr) {\n logger.debug(`Found existing branch PR #${branchPr.number}`);\n if (branchPr.state !== 'open') {\n logger.debug(\n 'PR has been closed or merged since this run started - aborting',\n );\n throw new Error(REPOSITORY_CHANGED);\n }\n if (branchIsModified || userChangedTargetBranch(branchPr)) {\n logger.debug(`PR has been edited, PrNo:${branchPr.number}`);\n await handleModifiedPr(config, branchPr);\n if (!(!!dependencyDashboardCheck || config.rebaseRequested)) {\n return {\n branchExists,\n prNo: branchPr.number,\n result: 'pr-edited',\n };\n }\n }\n } else if (branchIsModified && !dependencyDashboardCheck) {\n const oldPr = await platform.findPr({\n branchName: config.branchName,\n state: '!open',\n targetBranch: config.baseBranch,\n });\n if (!oldPr) {\n logger.debug('Branch has been edited but found no PR - skipping');\n return {\n branchExists,\n result: 'pr-edited',\n };\n }\n const branchSha = await scm.getBranchCommit(config.branchName);\n const oldPrSha = oldPr?.sha;\n if (!oldPrSha || oldPrSha === branchSha) {\n logger.debug(\n { oldPrNumber: oldPr.number, oldPrSha, branchSha },\n 'Found old PR matching this branch - will override it',\n );\n } else {\n logger.debug(\n { oldPrNumber: oldPr.number, oldPrSha, branchSha },\n 'Found old PR but the SHA is different',\n );\n return {\n branchExists,\n result: 'pr-edited',\n };\n }\n }\n }\n\n // Check schedule\n config.isScheduledNow = isScheduledNow(config, 'schedule');\n if (!config.isScheduledNow && !dependencyDashboardCheck) {\n if (!branchExists) {\n logger.debug('Skipping branch creation as not within schedule');\n return {\n branchExists,\n result: 'not-scheduled',\n };\n }\n if (config.updateNotScheduled === false && !config.rebaseRequested) {\n logger.debug('Skipping branch update as not within schedule');\n return {\n branchExists,\n prNo: branchPr?.number,\n result: 'update-not-scheduled',\n };\n }\n if (\n !branchPr &&\n !(config.automerge && config.automergeType === 'branch') // if branch is configured for automerge there's no need for a PR\n ) {\n logger.debug('Skipping PR creation out of schedule');\n return {\n branchExists,\n result: 'not-scheduled',\n };\n }\n logger.debug(\n 'Branch + PR exists but is not scheduled -- will update if necessary',\n );\n }\n //stability checks\n if (\n config.upgrades.some(\n (upgrade) =>\n isNonEmptyString(upgrade.minimumReleaseAge) ||\n isActiveConfidenceLevel(upgrade.minimumConfidence!),\n )\n ) {\n const depNamesWithoutReleaseTimestamp: Record<\n MinimumReleaseAgeBehaviour,\n {\n depName: string;\n updateType: UpdateType;\n }[]\n > = {\n 'timestamp-required': [],\n 'timestamp-optional': [],\n };\n\n // Only set a stability status check if one or more of the updates contain\n // both a minimumReleaseAge setting and a releaseTimestamp\n config.stabilityStatus = 'green';\n // Default to 'success' but set 'pending' if any update is pending\n for (const upgrade of config.upgrades) {\n const minimumReleaseAgeMs = isNonEmptyString(upgrade.minimumReleaseAge)\n ? coerceNumber(toMs(upgrade.minimumReleaseAge), 0)\n : 0;\n\n if (minimumReleaseAgeMs) {\n const minimumReleaseAgeBehaviour: MinimumReleaseAgeBehaviour =\n upgrade.minimumReleaseAgeBehaviour ?? 'timestamp-required';\n\n // regardless of the value of `minimumReleaseAgeBehaviour`, if there is a timestamp, we will process it according to `minimumReleaseAge`\n if (upgrade.releaseTimestamp) {\n const timeElapsed = getElapsedMs(upgrade.releaseTimestamp);\n if (timeElapsed < minimumReleaseAgeMs) {\n logger.debug(\n {\n depName: upgrade.depName,\n timeElapsed,\n minimumReleaseAge: upgrade.minimumReleaseAge,\n },\n 'Update has not passed minimum release age',\n );\n config.stabilityStatus = 'yellow';\n continue;\n }\n } else {\n // if we're set to `minimumReleaseAgeBehaviour=timestamp-required`, and there isn't a timestamp, always mark the update as pending\n if (minimumReleaseAgeBehaviour === 'timestamp-required') {\n depNamesWithoutReleaseTimestamp['timestamp-required'].push({\n depName: upgrade.depName!,\n updateType: upgrade.updateType!,\n });\n config.stabilityStatus = 'yellow';\n continue;\n } else {\n // if there is no timestamp, and we're running in `optional` mode, we can allow it, but make sure to warn the user\n depNamesWithoutReleaseTimestamp['timestamp-optional'].push({\n depName: upgrade.depName!,\n updateType: upgrade.updateType!,\n });\n }\n }\n }\n const datasource = upgrade.datasource!;\n const depName = upgrade.depName!;\n const packageName = upgrade.packageName!;\n const minimumConfidence = upgrade.minimumConfidence!;\n const updateType = upgrade.updateType!;\n const currentVersion = upgrade.currentVersion!;\n const newVersion = upgrade.newVersion!;\n if (isActiveConfidenceLevel(minimumConfidence)) {\n const confidence =\n (await getMergeConfidenceLevel(\n datasource,\n packageName,\n currentVersion,\n newVersion,\n updateType,\n )) ?? 'neutral';\n if (satisfiesConfidenceLevel(confidence, minimumConfidence)) {\n config.confidenceStatus = 'green';\n } else {\n logger.debug(\n { depName, confidence, minimumConfidence },\n 'Update does not meet minimum confidence scores',\n );\n config.confidenceStatus = 'yellow';\n continue;\n }\n }\n }\n\n if (depNamesWithoutReleaseTimestamp['timestamp-required'].length) {\n logger.once.debug(\n { updates: depNamesWithoutReleaseTimestamp['timestamp-required'] },\n `Marking ${depNamesWithoutReleaseTimestamp['timestamp-required'].length} release(s) as pending, as they do not have a releaseTimestamp and we're running with minimumReleaseAgeBehaviour=timestamp-required`,\n );\n }\n if (depNamesWithoutReleaseTimestamp['timestamp-optional'].length) {\n logger.once.warn(\n \"Some upgrade(s) did not have a releaseTimestamp, but as we're running with minimumReleaseAgeBehaviour=timestamp-optional, proceeding. See debug logs for more information\",\n );\n logger.once.debug(\n { updates: depNamesWithoutReleaseTimestamp['timestamp-optional'] },\n `${depNamesWithoutReleaseTimestamp['timestamp-optional'].length} upgrade(s) did not have a releaseTimestamp, but as we're running with minimumReleaseAgeBehaviour=timestamp-optional, proceeding`,\n );\n }\n\n // Don't create a branch if we know it will be status 'pending'\n if (\n !dependencyDashboardCheck &&\n !branchExists &&\n config.stabilityStatus === 'yellow' &&\n ['not-pending', 'status-success'].includes(config.prCreation!)\n ) {\n logger.debug(\n 'Skipping branch creation due to internal status checks not met',\n );\n return {\n branchExists,\n result: 'pending',\n };\n }\n }\n\n let userRebaseRequested =\n dependencyDashboardCheck === 'rebase' ||\n !!config.dependencyDashboardRebaseAllOpen ||\n !!config.rebaseRequested;\n const userApproveAllPendingPR = !!config.dependencyDashboardAllPending;\n const userOpenAllRateLimtedPR = !!config.dependencyDashboardAllRateLimited;\n const userOpenAllSchedulePendingPR =\n !!config.dependencyDashboardAllAwaitingSchedule;\n\n if (forceRebase) {\n logger.debug('Force rebase because branch needs updating');\n config.reuseExistingBranch = false;\n } else if (userRebaseRequested) {\n logger.debug('User has requested rebase');\n config.reuseExistingBranch = false;\n } else if (dependencyDashboardCheck === 'global-config') {\n logger.debug(`Manual create/rebase requested via checkedBranches`);\n config.reuseExistingBranch = false;\n userRebaseRequested = true;\n } else if (userApproveAllPendingPR) {\n logger.debug(\n 'A user manually approved all pending PRs via the Dependency Dashboard.',\n );\n } else if (userOpenAllRateLimtedPR) {\n logger.debug(\n 'A user manually approved all rate-limited PRs via the Dependency Dashboard.',\n );\n } else if (userOpenAllSchedulePendingPR) {\n logger.debug(\n 'A user manually requested all awaiting schedule PRs via the Dependency Dashboard.',\n );\n } else if (\n branchExists &&\n config.rebaseWhen === 'never' &&\n !(keepUpdatedLabel && branchPr?.labels?.includes(keepUpdatedLabel)) &&\n !dependencyDashboardCheck\n ) {\n logger.debug('rebaseWhen=never so skipping branch update check');\n return {\n branchExists,\n prNo: branchPr?.number,\n result: 'no-work',\n };\n }\n // if the base branch has been changed by user in renovate config, rebase onto the new baseBranch\n // we have already confirmed earlier that branch isn't modified, so its safe to use targetBranch here\n else if (\n branchPr?.targetBranch &&\n branchPr.targetBranch !== config.baseBranch\n ) {\n logger.debug(\n 'Base branch changed by user, rebasing the branch onto new base',\n );\n config.reuseExistingBranch = false;\n } else if (config.cacheFingerprintMatch === 'no-match') {\n logger.debug(\n 'Cache fingerprint does not match, cannot reuse existing branch',\n );\n config.reuseExistingBranch = false;\n } else {\n config = await shouldReuseExistingBranch(config);\n }\n // TODO: types (#22198)\n logger.debug(`Using reuseExistingBranch: ${config.reuseExistingBranch!}`);\n if (!(\n config.reuseExistingBranch && config.cacheFingerprintMatch === 'matched'\n )) {\n await scm.checkoutBranch(config.baseBranch);\n const res = await getUpdatedPackageFiles(config);\n if (res.artifactErrors && config.artifactErrors) {\n res.artifactErrors = config.artifactErrors.concat(res.artifactErrors);\n }\n config = { ...config, ...res };\n if (config.updatedPackageFiles?.length) {\n logger.debug(\n `Updated ${config.updatedPackageFiles.length} package files`,\n );\n if (config.reuseExistingBranch && !forceRebase) {\n logger.debug(\n 'Existing branch needs updating. Restarting processBranch() with a clean branch',\n );\n return processBranch(branchConfig, true);\n }\n } else {\n logger.debug('No package files need updating');\n }\n const additionalFiles = await getAdditionalFiles(\n config,\n branchConfig.packageFiles!,\n );\n config.artifactErrors = coerceArray(config.artifactErrors).concat(\n additionalFiles.artifactErrors,\n );\n config.artifactNotices = coerceArray(config.artifactNotices).concat(\n coerceArray(additionalFiles.artifactNotices),\n );\n config.updatedArtifacts = coerceArray(config.updatedArtifacts).concat(\n additionalFiles.updatedArtifacts,\n );\n // `gh actions-lock` rewrites the whole lockfile from the workflows on disk, so like the lock files above it runs once here, after every updated package file has been written, rather than per package file.\n const actionsLockfile = await updateActionsLockfile(\n config,\n branchConfig.packageFiles,\n );\n config.artifactErrors = config.artifactErrors.concat(\n actionsLockfile.artifactErrors,\n );\n config.updatedArtifacts = config.updatedArtifacts.concat(\n actionsLockfile.updatedArtifacts,\n );\n if (config.updatedArtifacts?.length) {\n logger.debug(\n {\n updatedArtifacts: config.updatedArtifacts.map((f) =>\n f.type === 'deletion' ? `${f.path} (delete)` : f.path,\n ),\n },\n `Updated ${config.updatedArtifacts.length} lock files`,\n );\n if (config.reuseExistingBranch && !forceRebase) {\n logger.debug(\n 'Existing branch needs updating. Restarting processBranch() with a clean branch',\n );\n return processBranch(branchConfig, true);\n }\n } else {\n logger.debug('No updated lock files in branch');\n }\n\n await embedChangelogs({\n upgrades: config.upgrades,\n stage: 'branch',\n });\n\n const postUpgradeCommandResults =\n await executePostUpgradeCommands(config);\n\n if (postUpgradeCommandResults !== null) {\n const { updatedArtifacts, artifactErrors } = postUpgradeCommandResults;\n config.updatedArtifacts = updatedArtifacts;\n config.artifactErrors = artifactErrors;\n }\n\n // modifies the file changes in place to allow having a version bump in a packageFile or artifact\n await bumpVersions(config);\n\n removeMeta(['dep']);\n\n if (config.artifactErrors?.length) {\n if (config.releaseTimestamp) {\n logger.debug(`Branch timestamp: ${config.releaseTimestamp}`);\n const releaseTimestamp = DateTime.fromISO(config.releaseTimestamp);\n if (releaseTimestamp.plus({ hours: 2 }) < DateTime.local()) {\n logger.debug(\n 'PR is older than 2 hours, raise PR with lock file errors',\n );\n } else if (branchExists) {\n logger.debug(\n 'PR is less than 2 hours old but branchExists so updating anyway',\n );\n } else {\n logger.debug(\n 'PR is less than 2 hours old - raise error instead of PR',\n );\n throw new Error(MANAGER_LOCKFILE_ERROR);\n }\n } else {\n logger.debug('PR has no releaseTimestamp');\n }\n } else if (config.updatedArtifacts?.length && branchPr) {\n // If there are artifacts, no errors, and an existing PR then ensure any artifacts error comment is removed\n if (GlobalConfig.get('dryRun')) {\n logger.info(\n `DRY-RUN: Would ensure comment removal in PR #${branchPr.number}`,\n );\n } else {\n // Remove artifacts error comment only if this run has successfully updated artifacts\n await ensureCommentRemoval({\n type: 'by-topic',\n number: branchPr.number,\n topic: artifactErrorTopic,\n });\n\n // v8 ignore else -- TODO: add test #40625\n if (!config.artifactNotices?.length) {\n await ensureCommentRemoval({\n type: 'by-topic',\n number: branchPr.number,\n topic: artifactNoticeTopic,\n });\n }\n }\n }\n const forcedManually = userRebaseRequested || !branchExists;\n\n config.isConflicted ??=\n branchExists &&\n (await scm.isBranchConflicted(config.baseBranch, config.branchName));\n config.forceCommit = forcedManually || config.isConflicted;\n\n // compile commit message with body, which maybe needs changelogs\n if (config.commitBody) {\n // changelog is on first upgrade\n config.commitMessage = `${config.commitMessage!}\\n\\n${template.compile(\n config.commitBody,\n {\n ...config,\n logJSON: config.upgrades[0].logJSON,\n releases: config.upgrades[0].releases,\n },\n )}`;\n\n logger.trace(`commitMessage: ${JSON.stringify(config.commitMessage)}`);\n }\n\n if (config.commitTrailers) {\n // Template expansions can produce broken trailers\n config.commitTrailers = filterValidCommitTrailers(\n config.commitTrailers.map((trailer) =>\n template.compile(trailer, config),\n ),\n );\n logger.trace(\n `commitTrailers: ${JSON.stringify(config.commitTrailers)}`,\n );\n }\n\n commitSha = await commitFilesToBranch(config);\n // Checkout to base branch to ensure that the next branch processing always starts with git being on the baseBranch\n // baseBranch is not checked out at the start of processBranch() due to pull/16246\n await scm.checkoutBranch(config.baseBranch);\n updatesVerified = true;\n\n // only update artifact status if branch was updated\n // also do before platform automerge reattempt\n if (commitSha) {\n await setArtifactErrorStatus(config);\n }\n\n // a requested rebase has now been applied, so any comment explaining why we'd skipped it no longer applies\n if (commitSha && branchPr && config.rebaseRequested) {\n if (GlobalConfig.get('dryRun')) {\n logger.info(\n `DRY-RUN: Would ensure pending rebase comment removal in PR #${branchPr.number}`,\n );\n } else {\n await ensureCommentRemoval({\n type: 'by-topic',\n number: branchPr.number,\n topic: pendingRebaseTopic,\n });\n }\n }\n }\n\n if (branchPr) {\n const platformPrOptions = getPlatformPrOptions(config);\n if (\n commitSha &&\n platformPrOptions.usePlatformAutomerge &&\n platform.reattemptPlatformAutomerge\n ) {\n if (GlobalConfig.get('dryRun')) {\n logger.info(\n `DRY-RUN: Would reattempt platform automerge for PR #${branchPr.number}`,\n );\n } else {\n await platform.reattemptPlatformAutomerge({\n number: branchPr.number,\n platformPrOptions,\n });\n }\n }\n // v8 ignore else -- TODO: add test #40625\n if (platform.refreshPr) {\n await platform.refreshPr(branchPr.number);\n }\n }\n if (!commitSha && !branchExists) {\n return {\n branchExists,\n result: 'no-work',\n };\n }\n if (commitSha) {\n const action = branchExists ? 'updated' : 'created';\n logger.info({ commitSha }, `Branch ${action}`);\n }\n await setBranchStatusChecks(config);\n // new commit means status check are pretty sure pending but maybe not reported yet\n // if PR has not been created + new commit + prCreation !== immediate skip\n // but do not break when there are artifact errors\n if (\n !branchPr &&\n !config.artifactErrors?.length &&\n !userRebaseRequested &&\n commitSha &&\n config.prCreation !== 'immediate'\n ) {\n logger.debug(`Branch status pending, current sha: ${commitSha}`);\n return {\n branchExists: true,\n updatesVerified,\n result: 'pending',\n commitSha,\n };\n }\n\n // Try to automerge branch and finish if successful, but only if branch already existed before this run\n // skip if we have a non-immediate pr and there is an existing PR,\n // we want to update the PR and skip the Auto merge since status checks aren't done yet\n if (!config.artifactErrors?.length && (!commitSha || config.ignoreTests)) {\n const mergeStatus = await tryBranchAutomerge(config);\n logger.debug(`mergeStatus=${mergeStatus}`);\n if (mergeStatus === 'automerged') {\n if (GlobalConfig.get('dryRun')) {\n logger.info(`DRY-RUN: Would delete branch${config.branchName}`);\n } else {\n await deleteBranchSilently(config.branchName);\n }\n logger.debug('Branch is automerged - returning');\n return { branchExists: false, result: 'automerged' };\n }\n if (mergeStatus === 'off schedule') {\n if (userRebaseRequested) {\n config.forcePr = true;\n } else {\n logger.debug(\n 'Branch cannot automerge now because automergeSchedule is off schedule - skipping',\n );\n return {\n branchExists,\n result: 'not-scheduled',\n commitSha,\n };\n }\n }\n if (\n mergeStatus === 'stale' &&\n ['conflicted', 'never'].includes(config.rebaseWhen!) &&\n /* v8 ignore next -- needs test */\n !(keepUpdatedLabel && branchPr?.labels?.includes(keepUpdatedLabel))\n ) {\n logger.warn(\n 'Branch cannot automerge because it is behind base branch and rebaseWhen setting disallows rebasing - raising a PR instead',\n );\n config.forcePr = true;\n config.branchAutomergeFailureMessage = mergeStatus;\n }\n if (\n mergeStatus === 'automerge aborted - merge queue' ||\n mergeStatus === 'automerge aborted - PR exists' ||\n mergeStatus === 'branch status error' ||\n mergeStatus === 'failed'\n ) {\n logger.debug(\n `Branch automerge not possible, mergeStatus:${mergeStatus}`,\n );\n config.forcePr = true;\n config.branchAutomergeFailureMessage = mergeStatus;\n }\n }\n } catch (err) {\n /* v8 ignore if -- needs test */\n if (err.statusCode === 404) {\n logger.debug({ err }, 'Received a 404 error - aborting run');\n throw new Error(REPOSITORY_CHANGED);\n }\n /* v8 ignore if -- needs test */\n if (err.message === PLATFORM_RATE_LIMIT_EXCEEDED) {\n logger.debug('Passing rate-limit-exceeded error up');\n throw err;\n }\n if (err.message === REPOSITORY_CHANGED) {\n logger.debug('Passing repository-changed error up');\n throw err;\n }\n /* v8 ignore if -- needs test */\n if (err.message?.startsWith('remote: Invalid username or password')) {\n logger.debug('Throwing bad credentials');\n throw new Error(PLATFORM_BAD_CREDENTIALS);\n }\n /* v8 ignore if -- needs test */\n if (\n err.message?.startsWith(\n 'ssh_exchange_identification: Connection closed by remote host',\n )\n ) {\n logger.debug('Throwing bad credentials');\n throw new Error(PLATFORM_BAD_CREDENTIALS);\n }\n /* v8 ignore if -- needs test */\n if (err.message === PLATFORM_BAD_CREDENTIALS) {\n logger.debug('Passing bad-credentials error up');\n throw err;\n }\n /* v8 ignore if -- needs test */\n if (err.message === PLATFORM_INTEGRATION_UNAUTHORIZED) {\n logger.debug('Passing integration-unauthorized error up');\n throw err;\n }\n if (err.message === MANAGER_LOCKFILE_ERROR) {\n logger.debug('Passing lockfile-error up');\n throw err;\n }\n if (err.message === PR_ALREADY_IN_MERGE_QUEUE) {\n logger.debug('Branch PR is in the merge queue - skipping branch update');\n return {\n branchExists,\n prNo: branchPr?.number,\n result: 'done',\n commitSha,\n };\n }\n /* v8 ignore if -- needs test */\n if (err.message?.includes('space left on device')) {\n throw new Error(SYSTEM_INSUFFICIENT_DISK_SPACE);\n }\n /* v8 ignore if -- needs test */\n if (err.message === SYSTEM_INSUFFICIENT_DISK_SPACE) {\n logger.debug('Passing disk-space error up');\n throw err;\n }\n /* v8 ignore if -- needs test */\n if (err.message.startsWith('Resource not accessible by integration')) {\n logger.debug('Passing 403 error up');\n throw err;\n }\n /* v8 ignore next -- needs test */\n if (err.message === WORKER_FILE_UPDATE_FAILED) {\n logger.warn('Error updating branch: update failure');\n } else if (err.message.startsWith('bundler-')) {\n // we have already warned inside the bundler artifacts error handling, so just return\n return {\n branchExists: true,\n updatesVerified,\n prNo: branchPr?.number,\n result: 'error',\n commitSha,\n };\n } else if (err.message?.includes('fatal: Authentication failed')) {\n throw new Error(PLATFORM_AUTHENTICATION_ERROR);\n } else if (err.message?.includes('fatal: bad revision')) {\n logger.debug({ err }, 'Aborting job due to bad revision error');\n throw new Error(REPOSITORY_CHANGED);\n } else if (err.message === CONFIG_VALIDATION) {\n logger.debug('Passing config validation error up');\n throw err;\n } else if (err.message === TEMPORARY_ERROR) {\n logger.debug('Passing TEMPORARY_ERROR error up');\n throw err;\n } else if (!(err instanceof ExternalHostError)) {\n logger.warn({ err }, `Error updating branch`);\n }\n // Don't throw here - we don't want to stop the other renovations\n return {\n branchExists,\n prNo: branchPr?.number,\n result: 'error',\n commitSha,\n };\n }\n try {\n logger.debug('Ensuring PR');\n logger.debug(\n `There are ${config.errors!.length} errors and ${\n config.warnings!.length\n } warnings`,\n );\n const ensurePrResult = await ensurePr(config);\n if (ensurePrResult.type === 'without-pr') {\n const { prBlockedBy } = ensurePrResult;\n branchPr = null;\n if (prBlockedBy === 'RateLimited' && !config.isVulnerabilityAlert) {\n logger.debug('Reached PR limit - skipping PR creation');\n return {\n branchExists,\n prBlockedBy,\n result: 'pr-limit-reached',\n commitSha,\n };\n }\n // TODO: ensurePr should check for automerge itself (#9719)\n if (prBlockedBy === 'NeedsApproval') {\n return {\n branchExists,\n prBlockedBy,\n result: 'needs-pr-approval',\n commitSha,\n };\n }\n if (prBlockedBy === 'AwaitingTests') {\n return {\n branchExists,\n prBlockedBy,\n result: 'pending',\n commitSha,\n };\n }\n if (prBlockedBy === 'BranchAutomerge') {\n return {\n branchExists,\n prBlockedBy,\n result: 'done',\n commitSha,\n };\n }\n if (prBlockedBy === 'Error') {\n return {\n branchExists,\n prBlockedBy,\n result: 'error',\n commitSha,\n };\n }\n logger.warn({ prBlockedBy }, 'Unknown PrBlockedBy result');\n return {\n branchExists,\n prBlockedBy,\n result: 'error',\n commitSha,\n };\n }\n // v8 ignore else -- TODO: add test #40625\n if (ensurePrResult.type === 'with-pr') {\n const { pr } = ensurePrResult;\n branchPr = pr;\n // Retry setting branch statuses after PR/MR creation so that\n // platforms using MR pipelines (e.g. GitLab) have a pipeline to\n // associate the status with. The earlier call may have been\n // skipped if no pipeline existed yet.\n await setBranchStatusChecks(config);\n\n // only update artifact status if branch was updated\n if (commitSha) {\n await setArtifactErrorStatus(config);\n }\n if (config.artifactErrors?.length) {\n logger.warn(\n { artifactErrors: config.artifactErrors },\n 'artifactErrors',\n );\n let content = `Renovate failed to update `;\n content +=\n config.artifactErrors.length > 1 ? 'artifacts' : 'an artifact';\n content += ' related to this branch. ';\n content += template.compile(\n config.userStrings!.artifactErrorWarning,\n config,\n );\n content += emojify(\n `\\n\\n:recycle: Renovate will retry this branch, including artifacts, only when one of the following happens:\\n\\n`,\n );\n content +=\n ' - any of the package files in this branch needs updating, or \\n';\n content += ' - the branch becomes conflicted, or\\n';\n content +=\n ' - you click the rebase/retry checkbox if found above, or\\n';\n content +=\n ' - you rename this PR\\'s title to start with \"rebase!\" to trigger it manually';\n content += '\\n\\nThe artifact failure details are included below:\\n\\n';\n // TODO: types (#22198)\n config.artifactErrors.forEach((error) => {\n content += `##### File name: ${error.fileName!}\\n\\n`;\n content += `\\`\\`\\`\\n${error.stderr!}\\n\\`\\`\\`\\n\\n`;\n });\n content = platform.massageMarkdown(content, config.rebaseLabel);\n // v8 ignore else -- TODO: add test #40625\n if (!(\n config.suppressNotifications!.includes('artifactErrors') ||\n config.suppressNotifications!.includes('lockFileErrors')\n )) {\n if (GlobalConfig.get('dryRun')) {\n logger.info(\n `DRY-RUN: Would ensure lock file error comment in PR #${pr.number}`,\n );\n } else {\n await ensureComment({\n number: pr.number,\n topic: artifactErrorTopic,\n content,\n });\n }\n }\n } else {\n if (config.artifactNotices?.length) {\n const contentLines: string[] = [];\n for (const notice of config.artifactNotices) {\n contentLines.push(`##### File name: ${notice.file}`);\n contentLines.push(notice.message);\n }\n const content = contentLines.join('\\n\\n');\n await ensureComment({\n number: pr.number,\n topic: artifactNoticeTopic,\n content,\n });\n }\n\n if (config.automerge) {\n logger.debug('PR is configured for automerge');\n // skip automerge if there is a new commit since status checks aren't done yet\n // v8 ignore else -- TODO: add test #40625\n if (config.ignoreTests === true || !commitSha) {\n logger.debug('checking auto-merge');\n const prAutomergeResult = await checkAutoMerge(pr, config);\n if (prAutomergeResult?.automerged) {\n return {\n branchExists,\n result: 'automerged',\n commitSha,\n };\n }\n }\n } else {\n logger.debug('PR is not configured for automerge');\n }\n }\n }\n } catch (err) {\n /* v8 ignore if -- needs test */\n if (\n err instanceof ExternalHostError ||\n [PLATFORM_RATE_LIMIT_EXCEEDED, REPOSITORY_CHANGED].includes(err.message)\n ) {\n logger.debug('Passing PR error up');\n throw err;\n }\n // Otherwise don't throw here - we don't want to stop the other renovations\n logger.error({ err }, `Error ensuring PR`);\n }\n if (!branchExists) {\n return {\n branchExists: true,\n updatesVerified,\n prNo: branchPr?.number,\n result: 'pr-created',\n commitSha,\n };\n }\n return {\n branchExists,\n updatesVerified,\n prNo: branchPr?.number,\n result: 'done',\n commitSha,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["template.compile"],"sources":["../../../../../lib/workers/repository/update/branch/index.ts"],"sourcesContent":["import { isNonEmptyString } from '@sindresorhus/is';\nimport { DateTime } from 'luxon';\nimport { GlobalConfig } from '../../../../config/global.ts';\nimport {\n type MinimumReleaseAgeBehaviour,\n type RenovateConfig,\n type UpdateType,\n} from '../../../../config/types.ts';\nimport {\n CONFIG_VALIDATION,\n MANAGER_LOCKFILE_ERROR,\n PLATFORM_AUTHENTICATION_ERROR,\n PLATFORM_BAD_CREDENTIALS,\n PLATFORM_INTEGRATION_UNAUTHORIZED,\n PLATFORM_RATE_LIMIT_EXCEEDED,\n PR_ALREADY_IN_MERGE_QUEUE,\n REPOSITORY_CHANGED,\n SYSTEM_INSUFFICIENT_DISK_SPACE,\n TEMPORARY_ERROR,\n WORKER_FILE_UPDATE_FAILED,\n} from '../../../../constants/error-messages.ts';\nimport { logger, removeMeta } from '../../../../logger/index.ts';\nimport { updateActionsLockfile } from '../../../../modules/manager/github-actions/artifacts.ts';\nimport { getAdditionalFiles } from '../../../../modules/manager/npm/post-update/index.ts';\nimport {\n ensureComment,\n ensureCommentRemoval,\n} from '../../../../modules/platform/comment.ts';\nimport type { Pr } from '../../../../modules/platform/index.ts';\nimport { platform } from '../../../../modules/platform/index.ts';\nimport { scm } from '../../../../modules/platform/scm.ts';\nimport { ExternalHostError } from '../../../../types/errors/external-host-error.ts';\nimport { coerceArray } from '../../../../util/array.ts';\nimport { getElapsedMs } from '../../../../util/date.ts';\nimport { emojify } from '../../../../util/emoji.ts';\nimport { filterValidCommitTrailers } from '../../../../util/git/commit-trailers.ts';\nimport {\n getMergeConfidenceLevel,\n isActiveConfidenceLevel,\n satisfiesConfidenceLevel,\n} from '../../../../util/merge-confidence/index.ts';\nimport { calculateMinimumReleaseAgeMs } from '../../../../util/minimum-release-age.ts';\nimport * as template from '../../../../util/template/index.ts';\nimport { getCount, isLimitReached } from '../../../global/limits.ts';\nimport type {\n BranchConfig,\n BranchResult,\n PrBlockedBy,\n} from '../../../types.ts';\nimport { embedChangelogs } from '../../changelog/index.ts';\nimport { checkAutoMerge } from '../pr/automerge.ts';\nimport { ensurePr, getPlatformPrOptions } from '../pr/index.ts';\nimport { setArtifactErrorStatus } from './artifacts.ts';\nimport { tryBranchAutomerge } from './automerge.ts';\nimport { bumpVersions } from './bump-versions.ts';\nimport { prAlreadyExisted } from './check-existing.ts';\nimport { commitFilesToBranch } from './commit.ts';\nimport executePostUpgradeCommands from './execute-post-upgrade-commands.ts';\nimport { getUpdatedPackageFiles } from './get-updated.ts';\nimport { handleClosedPr, handleModifiedPr } from './handle-existing.ts';\nimport { shouldReuseExistingBranch } from './reuse.ts';\nimport { isScheduledNow } from './schedule.ts';\nimport { setConfidence, setStability } from './status-checks.ts';\n\nasync function setBranchStatusChecks(config: BranchConfig): Promise<void> {\n await setStability(config);\n await setConfidence(config);\n}\n\nasync function rebaseCheck(\n config: RenovateConfig,\n branchPr: Pr,\n): Promise<boolean> {\n const titleRebase = branchPr.title?.startsWith('rebase!');\n if (titleRebase) {\n logger.debug(\n `Manual rebase requested via PR title for #${branchPr.number}`,\n );\n return true;\n }\n const labelRebase = !!branchPr.labels?.includes(config.rebaseLabel!);\n if (labelRebase) {\n logger.debug(\n `Manual rebase requested via PR labels for #${branchPr.number}`,\n );\n /* v8 ignore next -- needs test */\n if (GlobalConfig.get('dryRun')) {\n logger.info(\n `DRY-RUN: Would delete label ${config.rebaseLabel!} from #${\n branchPr.number\n }`,\n );\n } else {\n await platform.deleteLabel(branchPr.number, config.rebaseLabel!);\n }\n return true;\n }\n const prRebaseChecked = !!branchPr.bodyStruct?.rebaseRequested;\n if (prRebaseChecked) {\n logger.debug(\n `Manual rebase requested via PR checkbox for #${branchPr.number}`,\n );\n return true;\n }\n\n return false;\n}\n\nasync function deleteBranchSilently(branchName: string): Promise<void> {\n try {\n await scm.deleteBranch(branchName);\n } catch (err) {\n /* v8 ignore next -- needs test */\n logger.debug({ branchName, err }, 'Branch auto-remove failed');\n }\n}\n\nfunction userChangedTargetBranch(pr: Pr): boolean {\n const oldTargetBranch = pr.bodyStruct?.debugData?.targetBranch;\n if (oldTargetBranch && pr.targetBranch) {\n return pr.targetBranch !== oldTargetBranch;\n }\n return false;\n}\n\nexport interface ProcessBranchResult {\n branchExists: boolean;\n updatesVerified?: boolean;\n prBlockedBy?: PrBlockedBy;\n prNo?: number;\n result: BranchResult;\n commitSha?: string | null;\n}\n\nexport async function processBranch(\n branchConfig: BranchConfig,\n forceRebase = false,\n): Promise<ProcessBranchResult> {\n let commitSha: string | null = null;\n let config: BranchConfig = { ...branchConfig };\n logger.trace({ config }, 'processBranch()');\n let branchExists = await scm.branchExists(config.branchName);\n const dependencyDashboardCheck =\n config.dependencyDashboardChecks?.[config.branchName];\n // Only allow a branch to be recreated with updates that are `pending` if we've explicitly constented with an `unpend` on the Dependency Dashboard, or when using `checkedBranches`\n const unpendRequested =\n dependencyDashboardCheck === 'unpend' ||\n dependencyDashboardCheck === 'global-config';\n let updatesVerified = false;\n if (!branchExists && config.branchPrefix !== config.branchPrefixOld) {\n const branchName = config.branchName.replace(\n config.branchPrefix!,\n config.branchPrefixOld!,\n );\n branchExists = await scm.branchExists(branchName);\n // v8 ignore else -- TODO: add test #40625\n if (branchExists) {\n config.branchName = branchName;\n logger.debug('Found existing branch with branchPrefixOld');\n }\n }\n\n if (\n !branchExists &&\n branchConfig.minimumGroupSize &&\n branchConfig.minimumGroupSize > branchConfig.upgrades.length &&\n !dependencyDashboardCheck\n ) {\n logger.debug(\n `Skipping branch creation as minimumGroupSize: ${branchConfig.minimumGroupSize} is not met`,\n );\n return {\n branchExists: false,\n result: 'minimum-group-size-not-met',\n };\n }\n\n let branchPr = await platform.getBranchPr(\n config.branchName,\n config.baseBranch,\n );\n logger.debug(`branchExists=${branchExists}`);\n logger.debug(`dependencyDashboardCheck=${dependencyDashboardCheck!}`);\n if (branchPr) {\n config.rebaseRequested = await rebaseCheck(config, branchPr);\n logger.debug(`PR rebase requested=${config.rebaseRequested}`);\n }\n const keepUpdatedLabel = config.keepUpdatedLabel;\n const pendingRebaseTopic = emojify(':warning: Rebase not applied');\n const artifactErrorTopic = emojify(':warning: Artifact update problem');\n const artifactNoticeTopic = emojify(\n ':information_source: Artifact update notice',\n );\n try {\n // Check if branch already existed\n const existingPr =\n !branchPr || config.automerge\n ? await prAlreadyExisted(config)\n : undefined;\n if (existingPr?.state === 'merged') {\n logger.debug(`Matching PR #${existingPr.number} was merged previously`);\n if (config.automerge) {\n logger.debug('Disabling automerge because PR was merged previously');\n config.automerge = false;\n config.automergedPreviously = true;\n }\n } else if (!branchPr && existingPr && !dependencyDashboardCheck) {\n logger.debug(\n { prTitle: config.prTitle },\n `Closed PR #${existingPr.number} already exists. Skipping branch.`,\n );\n await handleClosedPr(config, existingPr);\n return {\n branchExists: false,\n prNo: existingPr.number,\n result: 'already-existed',\n };\n }\n if (!branchExists && branchConfig.pendingChecks && !unpendRequested) {\n logger.debug(\n `Branch ${config.branchName} creation is disabled because internalChecksFilter was not met`,\n );\n return {\n branchExists: false,\n result: 'pending',\n };\n }\n if (!branchExists) {\n if (config.mode === 'silent' && !dependencyDashboardCheck) {\n logger.debug(\n `Branch ${config.branchName} creation is disabled because mode=silent`,\n );\n return {\n branchExists,\n result: 'needs-approval',\n };\n }\n if (config.dependencyDashboardApproval && !dependencyDashboardCheck) {\n logger.debug(\n `Branch ${config.branchName} creation is disabled because dependencyDashboardApproval=true`,\n );\n return {\n branchExists,\n result: 'needs-approval',\n };\n }\n }\n\n logger.debug(\n `Open PR Count: ${getCount('ConcurrentPRs')}, Existing Branch Count: ${getCount('Branches')}, Hourly PR Count: ${getCount('HourlyPRs')}, Hourly Commit Count: ${getCount('HourlyCommits')}`,\n );\n\n // for a vulnerability alert this checks the VulnerabilityBranches count\n if (\n !branchExists &&\n isLimitReached('Branches', branchConfig) &&\n !dependencyDashboardCheck\n ) {\n logger.debug('Reached branch limit - skipping branch creation');\n return {\n branchExists,\n result: 'branch-limit-reached',\n };\n }\n if (\n !config.rebaseRequested &&\n isLimitReached('Commits') &&\n !dependencyDashboardCheck &&\n !config.isVulnerabilityAlert\n ) {\n logger.debug('Reached commits per run limit - skipping branch');\n return {\n branchExists,\n prNo: branchPr?.number,\n result: 'commit-per-run-limit-reached',\n };\n }\n if (\n !config.rebaseRequested &&\n isLimitReached('HourlyCommits', branchConfig) &&\n !dependencyDashboardCheck &&\n !config.isVulnerabilityAlert\n ) {\n logger.debug('Reached hourly commits limit - skipping branch');\n return {\n branchExists,\n prNo: branchPr?.number,\n result: 'commit-hourly-limit-reached',\n };\n }\n if (branchExists) {\n // check if branch is labelled to stop\n config.stopUpdating = branchPr?.labels?.includes(\n config.stopUpdatingLabel!,\n );\n\n const prRebaseChecked = !!branchPr?.bodyStruct?.rebaseRequested;\n\n if (\n !dependencyDashboardCheck &&\n !prRebaseChecked &&\n config.stopUpdating\n ) {\n logger.info(\n 'Branch updating is skipped because stopUpdatingLabel is present in config',\n );\n return {\n branchExists: true,\n prNo: branchPr?.number,\n result: 'no-work',\n };\n }\n\n // A rebase or retry request is not consent to add an upgrade which has not met its internal checks, so only an unpend of this branch may override this\n if (!unpendRequested && config.pendingChecks) {\n if (config.rebaseRequested) {\n logger.info(\n 'Branch updating is skipped because internalChecksFilter was not met, despite the requested rebase',\n );\n if (branchPr) {\n const content =\n 'This branch has not been rebased, as its update has not yet met the internal checks configured for it, such as `minimumReleaseAge`. Rebasing it now would add a dependency version which is still within its configured observation period.\\n\\nRenovate will rebase this branch once its update has met those checks.';\n if (GlobalConfig.get('dryRun')) {\n logger.info(\n `DRY-RUN: Would ensure pending rebase comment in PR #${branchPr.number}`,\n );\n } else {\n await ensureComment({\n number: branchPr.number,\n topic: pendingRebaseTopic,\n content,\n });\n }\n }\n } else {\n logger.info(\n 'Branch updating is skipped because internalChecksFilter was not met',\n );\n }\n return {\n branchExists: true,\n prNo: branchPr?.number,\n result: 'pending',\n };\n }\n\n logger.debug('Checking if PR has been edited');\n const branchIsModified = await scm.isBranchModified(\n config.branchName,\n config.baseBranch,\n );\n if (branchPr) {\n logger.debug(`Found existing branch PR #${branchPr.number}`);\n if (branchPr.state !== 'open') {\n logger.debug(\n 'PR has been closed or merged since this run started - aborting',\n );\n throw new Error(REPOSITORY_CHANGED);\n }\n if (branchIsModified || userChangedTargetBranch(branchPr)) {\n logger.debug(`PR has been edited, PrNo:${branchPr.number}`);\n await handleModifiedPr(config, branchPr);\n if (!(!!dependencyDashboardCheck || config.rebaseRequested)) {\n return {\n branchExists,\n prNo: branchPr.number,\n result: 'pr-edited',\n };\n }\n }\n } else if (branchIsModified && !dependencyDashboardCheck) {\n const oldPr = await platform.findPr({\n branchName: config.branchName,\n state: '!open',\n targetBranch: config.baseBranch,\n });\n if (!oldPr) {\n logger.debug('Branch has been edited but found no PR - skipping');\n return {\n branchExists,\n result: 'pr-edited',\n };\n }\n const branchSha = await scm.getBranchCommit(config.branchName);\n const oldPrSha = oldPr?.sha;\n if (!oldPrSha || oldPrSha === branchSha) {\n logger.debug(\n { oldPrNumber: oldPr.number, oldPrSha, branchSha },\n 'Found old PR matching this branch - will override it',\n );\n } else {\n logger.debug(\n { oldPrNumber: oldPr.number, oldPrSha, branchSha },\n 'Found old PR but the SHA is different',\n );\n return {\n branchExists,\n result: 'pr-edited',\n };\n }\n }\n }\n\n // Check schedule\n config.isScheduledNow = isScheduledNow(config, 'schedule');\n if (!config.isScheduledNow && !dependencyDashboardCheck) {\n if (!branchExists) {\n logger.debug('Skipping branch creation as not within schedule');\n return {\n branchExists,\n result: 'not-scheduled',\n };\n }\n if (config.updateNotScheduled === false && !config.rebaseRequested) {\n logger.debug('Skipping branch update as not within schedule');\n return {\n branchExists,\n prNo: branchPr?.number,\n result: 'update-not-scheduled',\n };\n }\n if (\n !branchPr &&\n !(config.automerge && config.automergeType === 'branch') // if branch is configured for automerge there's no need for a PR\n ) {\n logger.debug('Skipping PR creation out of schedule');\n return {\n branchExists,\n result: 'not-scheduled',\n };\n }\n logger.debug(\n 'Branch + PR exists but is not scheduled -- will update if necessary',\n );\n }\n //stability checks\n if (\n config.upgrades.some(\n (upgrade) =>\n isNonEmptyString(upgrade.minimumReleaseAge) ||\n isActiveConfidenceLevel(upgrade.minimumConfidence!),\n )\n ) {\n const depNamesWithoutReleaseTimestamp: Record<\n MinimumReleaseAgeBehaviour,\n {\n depName: string;\n updateType: UpdateType;\n }[]\n > = {\n 'timestamp-required': [],\n 'timestamp-optional': [],\n };\n\n // Only set a stability status check if one or more of the updates contain\n // both a minimumReleaseAge setting and a releaseTimestamp\n config.stabilityStatus = 'green';\n // Default to 'success' but set 'pending' if any update is pending\n for (const upgrade of config.upgrades) {\n const minimumReleaseAgeMs = calculateMinimumReleaseAgeMs(upgrade);\n\n if (minimumReleaseAgeMs) {\n const minimumReleaseAgeBehaviour: MinimumReleaseAgeBehaviour =\n upgrade.minimumReleaseAgeBehaviour ?? 'timestamp-required';\n\n // regardless of the value of `minimumReleaseAgeBehaviour`, if there is a timestamp, we will process it according to `minimumReleaseAge`\n if (upgrade.releaseTimestamp) {\n const timeElapsed = getElapsedMs(upgrade.releaseTimestamp);\n if (timeElapsed < minimumReleaseAgeMs) {\n logger.debug(\n {\n depName: upgrade.depName,\n timeElapsed,\n minimumReleaseAge: upgrade.minimumReleaseAge,\n },\n 'Update has not passed minimum release age',\n );\n config.stabilityStatus = 'yellow';\n continue;\n }\n } else {\n // if we're set to `minimumReleaseAgeBehaviour=timestamp-required`, and there isn't a timestamp, always mark the update as pending\n if (minimumReleaseAgeBehaviour === 'timestamp-required') {\n depNamesWithoutReleaseTimestamp['timestamp-required'].push({\n depName: upgrade.depName!,\n updateType: upgrade.updateType!,\n });\n config.stabilityStatus = 'yellow';\n continue;\n } else {\n // if there is no timestamp, and we're running in `optional` mode, we can allow it, but make sure to warn the user\n depNamesWithoutReleaseTimestamp['timestamp-optional'].push({\n depName: upgrade.depName!,\n updateType: upgrade.updateType!,\n });\n }\n }\n }\n const datasource = upgrade.datasource!;\n const depName = upgrade.depName!;\n const packageName = upgrade.packageName!;\n const minimumConfidence = upgrade.minimumConfidence!;\n const updateType = upgrade.updateType!;\n const currentVersion = upgrade.currentVersion!;\n const newVersion = upgrade.newVersion!;\n if (isActiveConfidenceLevel(minimumConfidence)) {\n const confidence =\n (await getMergeConfidenceLevel(\n datasource,\n packageName,\n currentVersion,\n newVersion,\n updateType,\n )) ?? 'neutral';\n if (satisfiesConfidenceLevel(confidence, minimumConfidence)) {\n config.confidenceStatus = 'green';\n } else {\n logger.debug(\n { depName, confidence, minimumConfidence },\n 'Update does not meet minimum confidence scores',\n );\n config.confidenceStatus = 'yellow';\n continue;\n }\n }\n }\n\n if (depNamesWithoutReleaseTimestamp['timestamp-required'].length) {\n logger.once.debug(\n { updates: depNamesWithoutReleaseTimestamp['timestamp-required'] },\n `Marking ${depNamesWithoutReleaseTimestamp['timestamp-required'].length} release(s) as pending, as they do not have a releaseTimestamp and we're running with minimumReleaseAgeBehaviour=timestamp-required`,\n );\n }\n if (depNamesWithoutReleaseTimestamp['timestamp-optional'].length) {\n logger.once.warn(\n \"Some upgrade(s) did not have a releaseTimestamp, but as we're running with minimumReleaseAgeBehaviour=timestamp-optional, proceeding. See debug logs for more information\",\n );\n logger.once.debug(\n { updates: depNamesWithoutReleaseTimestamp['timestamp-optional'] },\n `${depNamesWithoutReleaseTimestamp['timestamp-optional'].length} upgrade(s) did not have a releaseTimestamp, but as we're running with minimumReleaseAgeBehaviour=timestamp-optional, proceeding`,\n );\n }\n\n // Don't create a branch if we know it will be status 'pending'\n if (\n !dependencyDashboardCheck &&\n !branchExists &&\n config.stabilityStatus === 'yellow' &&\n ['not-pending', 'status-success'].includes(config.prCreation!)\n ) {\n logger.debug(\n 'Skipping branch creation due to internal status checks not met',\n );\n return {\n branchExists,\n result: 'pending',\n };\n }\n }\n\n let userRebaseRequested =\n dependencyDashboardCheck === 'rebase' ||\n !!config.dependencyDashboardRebaseAllOpen ||\n !!config.rebaseRequested;\n const userApproveAllPendingPR = !!config.dependencyDashboardAllPending;\n const userOpenAllRateLimtedPR = !!config.dependencyDashboardAllRateLimited;\n const userOpenAllSchedulePendingPR =\n !!config.dependencyDashboardAllAwaitingSchedule;\n\n if (forceRebase) {\n logger.debug('Force rebase because branch needs updating');\n config.reuseExistingBranch = false;\n } else if (userRebaseRequested) {\n logger.debug('User has requested rebase');\n config.reuseExistingBranch = false;\n } else if (dependencyDashboardCheck === 'global-config') {\n logger.debug(`Manual create/rebase requested via checkedBranches`);\n config.reuseExistingBranch = false;\n userRebaseRequested = true;\n } else if (userApproveAllPendingPR) {\n logger.debug(\n 'A user manually approved all pending PRs via the Dependency Dashboard.',\n );\n } else if (userOpenAllRateLimtedPR) {\n logger.debug(\n 'A user manually approved all rate-limited PRs via the Dependency Dashboard.',\n );\n } else if (userOpenAllSchedulePendingPR) {\n logger.debug(\n 'A user manually requested all awaiting schedule PRs via the Dependency Dashboard.',\n );\n } else if (\n branchExists &&\n config.rebaseWhen === 'never' &&\n !(keepUpdatedLabel && branchPr?.labels?.includes(keepUpdatedLabel)) &&\n !dependencyDashboardCheck\n ) {\n logger.debug('rebaseWhen=never so skipping branch update check');\n return {\n branchExists,\n prNo: branchPr?.number,\n result: 'no-work',\n };\n }\n // if the base branch has been changed by user in renovate config, rebase onto the new baseBranch\n // we have already confirmed earlier that branch isn't modified, so its safe to use targetBranch here\n else if (\n branchPr?.targetBranch &&\n branchPr.targetBranch !== config.baseBranch\n ) {\n logger.debug(\n 'Base branch changed by user, rebasing the branch onto new base',\n );\n config.reuseExistingBranch = false;\n } else if (config.cacheFingerprintMatch === 'no-match') {\n logger.debug(\n 'Cache fingerprint does not match, cannot reuse existing branch',\n );\n config.reuseExistingBranch = false;\n } else {\n config = await shouldReuseExistingBranch(config);\n }\n // TODO: types (#22198)\n logger.debug(`Using reuseExistingBranch: ${config.reuseExistingBranch!}`);\n if (!(\n config.reuseExistingBranch && config.cacheFingerprintMatch === 'matched'\n )) {\n await scm.checkoutBranch(config.baseBranch);\n const res = await getUpdatedPackageFiles(config);\n if (res.artifactErrors && config.artifactErrors) {\n res.artifactErrors = config.artifactErrors.concat(res.artifactErrors);\n }\n config = { ...config, ...res };\n if (config.updatedPackageFiles?.length) {\n logger.debug(\n `Updated ${config.updatedPackageFiles.length} package files`,\n );\n if (config.reuseExistingBranch && !forceRebase) {\n logger.debug(\n 'Existing branch needs updating. Restarting processBranch() with a clean branch',\n );\n return processBranch(branchConfig, true);\n }\n } else {\n logger.debug('No package files need updating');\n }\n const additionalFiles = await getAdditionalFiles(\n config,\n branchConfig.packageFiles!,\n );\n config.artifactErrors = coerceArray(config.artifactErrors).concat(\n additionalFiles.artifactErrors,\n );\n config.artifactNotices = coerceArray(config.artifactNotices).concat(\n coerceArray(additionalFiles.artifactNotices),\n );\n config.updatedArtifacts = coerceArray(config.updatedArtifacts).concat(\n additionalFiles.updatedArtifacts,\n );\n // `gh actions-lock` rewrites the whole lockfile from the workflows on disk, so like the lock files above it runs once here, after every updated package file has been written, rather than per package file.\n const actionsLockfile = await updateActionsLockfile(\n config,\n branchConfig.packageFiles,\n );\n config.artifactErrors = config.artifactErrors.concat(\n actionsLockfile.artifactErrors,\n );\n config.updatedArtifacts = config.updatedArtifacts.concat(\n actionsLockfile.updatedArtifacts,\n );\n if (config.updatedArtifacts?.length) {\n logger.debug(\n {\n updatedArtifacts: config.updatedArtifacts.map((f) =>\n f.type === 'deletion' ? `${f.path} (delete)` : f.path,\n ),\n },\n `Updated ${config.updatedArtifacts.length} lock files`,\n );\n if (config.reuseExistingBranch && !forceRebase) {\n logger.debug(\n 'Existing branch needs updating. Restarting processBranch() with a clean branch',\n );\n return processBranch(branchConfig, true);\n }\n } else {\n logger.debug('No updated lock files in branch');\n }\n\n await embedChangelogs({\n upgrades: config.upgrades,\n stage: 'branch',\n });\n\n const postUpgradeCommandResults =\n await executePostUpgradeCommands(config);\n\n if (postUpgradeCommandResults !== null) {\n const { updatedArtifacts, artifactErrors } = postUpgradeCommandResults;\n config.updatedArtifacts = updatedArtifacts;\n config.artifactErrors = artifactErrors;\n }\n\n // modifies the file changes in place to allow having a version bump in a packageFile or artifact\n await bumpVersions(config);\n\n removeMeta(['dep']);\n\n if (config.artifactErrors?.length) {\n if (config.releaseTimestamp) {\n logger.debug(`Branch timestamp: ${config.releaseTimestamp}`);\n const releaseTimestamp = DateTime.fromISO(config.releaseTimestamp);\n if (releaseTimestamp.plus({ hours: 2 }) < DateTime.local()) {\n logger.debug(\n 'PR is older than 2 hours, raise PR with lock file errors',\n );\n } else if (branchExists) {\n logger.debug(\n 'PR is less than 2 hours old but branchExists so updating anyway',\n );\n } else {\n logger.debug(\n 'PR is less than 2 hours old - raise error instead of PR',\n );\n throw new Error(MANAGER_LOCKFILE_ERROR);\n }\n } else {\n logger.debug('PR has no releaseTimestamp');\n }\n } else if (config.updatedArtifacts?.length && branchPr) {\n // If there are artifacts, no errors, and an existing PR then ensure any artifacts error comment is removed\n if (GlobalConfig.get('dryRun')) {\n logger.info(\n `DRY-RUN: Would ensure comment removal in PR #${branchPr.number}`,\n );\n } else {\n // Remove artifacts error comment only if this run has successfully updated artifacts\n await ensureCommentRemoval({\n type: 'by-topic',\n number: branchPr.number,\n topic: artifactErrorTopic,\n });\n\n // v8 ignore else -- TODO: add test #40625\n if (!config.artifactNotices?.length) {\n await ensureCommentRemoval({\n type: 'by-topic',\n number: branchPr.number,\n topic: artifactNoticeTopic,\n });\n }\n }\n }\n const forcedManually = userRebaseRequested || !branchExists;\n\n config.isConflicted ??=\n branchExists &&\n (await scm.isBranchConflicted(config.baseBranch, config.branchName));\n config.forceCommit = forcedManually || config.isConflicted;\n\n // compile commit message with body, which maybe needs changelogs\n if (config.commitBody) {\n // changelog is on first upgrade\n config.commitMessage = `${config.commitMessage!}\\n\\n${template.compile(\n config.commitBody,\n {\n ...config,\n logJSON: config.upgrades[0].logJSON,\n releases: config.upgrades[0].releases,\n },\n )}`;\n\n logger.trace(`commitMessage: ${JSON.stringify(config.commitMessage)}`);\n }\n\n if (config.commitTrailers) {\n // Template expansions can produce broken trailers\n config.commitTrailers = filterValidCommitTrailers(\n config.commitTrailers.map((trailer) =>\n template.compile(trailer, config),\n ),\n );\n logger.trace(\n `commitTrailers: ${JSON.stringify(config.commitTrailers)}`,\n );\n }\n\n commitSha = await commitFilesToBranch(config);\n // Checkout to base branch to ensure that the next branch processing always starts with git being on the baseBranch\n // baseBranch is not checked out at the start of processBranch() due to pull/16246\n await scm.checkoutBranch(config.baseBranch);\n updatesVerified = true;\n\n // only update artifact status if branch was updated\n // also do before platform automerge reattempt\n if (commitSha) {\n await setArtifactErrorStatus(config);\n }\n\n // a requested rebase has now been applied, so any comment explaining why we'd skipped it no longer applies\n if (commitSha && branchPr && config.rebaseRequested) {\n if (GlobalConfig.get('dryRun')) {\n logger.info(\n `DRY-RUN: Would ensure pending rebase comment removal in PR #${branchPr.number}`,\n );\n } else {\n await ensureCommentRemoval({\n type: 'by-topic',\n number: branchPr.number,\n topic: pendingRebaseTopic,\n });\n }\n }\n }\n\n if (branchPr) {\n const platformPrOptions = getPlatformPrOptions(config);\n if (\n commitSha &&\n platformPrOptions.usePlatformAutomerge &&\n platform.reattemptPlatformAutomerge\n ) {\n if (GlobalConfig.get('dryRun')) {\n logger.info(\n `DRY-RUN: Would reattempt platform automerge for PR #${branchPr.number}`,\n );\n } else {\n await platform.reattemptPlatformAutomerge({\n number: branchPr.number,\n platformPrOptions,\n });\n }\n }\n // v8 ignore else -- TODO: add test #40625\n if (platform.refreshPr) {\n await platform.refreshPr(branchPr.number);\n }\n }\n if (!commitSha && !branchExists) {\n return {\n branchExists,\n result: 'no-work',\n };\n }\n if (commitSha) {\n const action = branchExists ? 'updated' : 'created';\n logger.info({ commitSha }, `Branch ${action}`);\n }\n await setBranchStatusChecks(config);\n // new commit means status check are pretty sure pending but maybe not reported yet\n // if PR has not been created + new commit + prCreation !== immediate skip\n // but do not break when there are artifact errors\n if (\n !branchPr &&\n !config.artifactErrors?.length &&\n !userRebaseRequested &&\n commitSha &&\n config.prCreation !== 'immediate'\n ) {\n logger.debug(`Branch status pending, current sha: ${commitSha}`);\n return {\n branchExists: true,\n updatesVerified,\n result: 'pending',\n commitSha,\n };\n }\n\n // Try to automerge branch and finish if successful, but only if branch already existed before this run\n // skip if we have a non-immediate pr and there is an existing PR,\n // we want to update the PR and skip the Auto merge since status checks aren't done yet\n if (!config.artifactErrors?.length && (!commitSha || config.ignoreTests)) {\n const mergeStatus = await tryBranchAutomerge(config);\n logger.debug(`mergeStatus=${mergeStatus}`);\n if (mergeStatus === 'automerged') {\n if (GlobalConfig.get('dryRun')) {\n logger.info(`DRY-RUN: Would delete branch${config.branchName}`);\n } else {\n await deleteBranchSilently(config.branchName);\n }\n logger.debug('Branch is automerged - returning');\n return { branchExists: false, result: 'automerged' };\n }\n if (mergeStatus === 'off schedule') {\n if (userRebaseRequested) {\n config.forcePr = true;\n } else {\n logger.debug(\n 'Branch cannot automerge now because automergeSchedule is off schedule - skipping',\n );\n return {\n branchExists,\n result: 'not-scheduled',\n commitSha,\n };\n }\n }\n if (\n mergeStatus === 'stale' &&\n ['conflicted', 'never'].includes(config.rebaseWhen!) &&\n /* v8 ignore next -- needs test */\n !(keepUpdatedLabel && branchPr?.labels?.includes(keepUpdatedLabel))\n ) {\n logger.warn(\n 'Branch cannot automerge because it is behind base branch and rebaseWhen setting disallows rebasing - raising a PR instead',\n );\n config.forcePr = true;\n config.branchAutomergeFailureMessage = mergeStatus;\n }\n if (\n mergeStatus === 'automerge aborted - merge queue' ||\n mergeStatus === 'automerge aborted - PR exists' ||\n mergeStatus === 'branch status error' ||\n mergeStatus === 'failed'\n ) {\n logger.debug(\n `Branch automerge not possible, mergeStatus:${mergeStatus}`,\n );\n config.forcePr = true;\n config.branchAutomergeFailureMessage = mergeStatus;\n }\n }\n } catch (err) {\n /* v8 ignore if -- needs test */\n if (err.statusCode === 404) {\n logger.debug({ err }, 'Received a 404 error - aborting run');\n throw new Error(REPOSITORY_CHANGED);\n }\n /* v8 ignore if -- needs test */\n if (err.message === PLATFORM_RATE_LIMIT_EXCEEDED) {\n logger.debug('Passing rate-limit-exceeded error up');\n throw err;\n }\n if (err.message === REPOSITORY_CHANGED) {\n logger.debug('Passing repository-changed error up');\n throw err;\n }\n /* v8 ignore if -- needs test */\n if (err.message?.startsWith('remote: Invalid username or password')) {\n logger.debug('Throwing bad credentials');\n throw new Error(PLATFORM_BAD_CREDENTIALS);\n }\n /* v8 ignore if -- needs test */\n if (\n err.message?.startsWith(\n 'ssh_exchange_identification: Connection closed by remote host',\n )\n ) {\n logger.debug('Throwing bad credentials');\n throw new Error(PLATFORM_BAD_CREDENTIALS);\n }\n /* v8 ignore if -- needs test */\n if (err.message === PLATFORM_BAD_CREDENTIALS) {\n logger.debug('Passing bad-credentials error up');\n throw err;\n }\n /* v8 ignore if -- needs test */\n if (err.message === PLATFORM_INTEGRATION_UNAUTHORIZED) {\n logger.debug('Passing integration-unauthorized error up');\n throw err;\n }\n if (err.message === MANAGER_LOCKFILE_ERROR) {\n logger.debug('Passing lockfile-error up');\n throw err;\n }\n if (err.message === PR_ALREADY_IN_MERGE_QUEUE) {\n logger.debug('Branch PR is in the merge queue - skipping branch update');\n return {\n branchExists,\n prNo: branchPr?.number,\n result: 'done',\n commitSha,\n };\n }\n /* v8 ignore if -- needs test */\n if (err.message?.includes('space left on device')) {\n throw new Error(SYSTEM_INSUFFICIENT_DISK_SPACE);\n }\n /* v8 ignore if -- needs test */\n if (err.message === SYSTEM_INSUFFICIENT_DISK_SPACE) {\n logger.debug('Passing disk-space error up');\n throw err;\n }\n /* v8 ignore if -- needs test */\n if (err.message.startsWith('Resource not accessible by integration')) {\n logger.debug('Passing 403 error up');\n throw err;\n }\n /* v8 ignore next -- needs test */\n if (err.message === WORKER_FILE_UPDATE_FAILED) {\n logger.warn('Error updating branch: update failure');\n } else if (err.message.startsWith('bundler-')) {\n // we have already warned inside the bundler artifacts error handling, so just return\n return {\n branchExists: true,\n updatesVerified,\n prNo: branchPr?.number,\n result: 'error',\n commitSha,\n };\n } else if (err.message?.includes('fatal: Authentication failed')) {\n throw new Error(PLATFORM_AUTHENTICATION_ERROR);\n } else if (err.message?.includes('fatal: bad revision')) {\n logger.debug({ err }, 'Aborting job due to bad revision error');\n throw new Error(REPOSITORY_CHANGED);\n } else if (err.message === CONFIG_VALIDATION) {\n logger.debug('Passing config validation error up');\n throw err;\n } else if (err.message === TEMPORARY_ERROR) {\n logger.debug('Passing TEMPORARY_ERROR error up');\n throw err;\n } else if (!(err instanceof ExternalHostError)) {\n logger.warn({ err }, `Error updating branch`);\n }\n // Don't throw here - we don't want to stop the other renovations\n return {\n branchExists,\n prNo: branchPr?.number,\n result: 'error',\n commitSha,\n };\n }\n try {\n logger.debug('Ensuring PR');\n logger.debug(\n `There are ${config.errors!.length} errors and ${\n config.warnings!.length\n } warnings`,\n );\n const ensurePrResult = await ensurePr(config);\n if (ensurePrResult.type === 'without-pr') {\n const { prBlockedBy } = ensurePrResult;\n branchPr = null;\n if (prBlockedBy === 'RateLimited' && !config.isVulnerabilityAlert) {\n logger.debug('Reached PR limit - skipping PR creation');\n return {\n branchExists,\n prBlockedBy,\n result: 'pr-limit-reached',\n commitSha,\n };\n }\n // TODO: ensurePr should check for automerge itself (#9719)\n if (prBlockedBy === 'NeedsApproval') {\n return {\n branchExists,\n prBlockedBy,\n result: 'needs-pr-approval',\n commitSha,\n };\n }\n if (prBlockedBy === 'AwaitingTests') {\n return {\n branchExists,\n prBlockedBy,\n result: 'pending',\n commitSha,\n };\n }\n if (prBlockedBy === 'BranchAutomerge') {\n return {\n branchExists,\n prBlockedBy,\n result: 'done',\n commitSha,\n };\n }\n if (prBlockedBy === 'Error') {\n return {\n branchExists,\n prBlockedBy,\n result: 'error',\n commitSha,\n };\n }\n logger.warn({ prBlockedBy }, 'Unknown PrBlockedBy result');\n return {\n branchExists,\n prBlockedBy,\n result: 'error',\n commitSha,\n };\n }\n // v8 ignore else -- TODO: add test #40625\n if (ensurePrResult.type === 'with-pr') {\n const { pr } = ensurePrResult;\n branchPr = pr;\n // Retry setting branch statuses after PR/MR creation so that\n // platforms using MR pipelines (e.g. GitLab) have a pipeline to\n // associate the status with. The earlier call may have been\n // skipped if no pipeline existed yet.\n await setBranchStatusChecks(config);\n\n // only update artifact status if branch was updated\n if (commitSha) {\n await setArtifactErrorStatus(config);\n }\n if (config.artifactErrors?.length) {\n logger.warn(\n { artifactErrors: config.artifactErrors },\n 'artifactErrors',\n );\n let content = `Renovate failed to update `;\n content +=\n config.artifactErrors.length > 1 ? 'artifacts' : 'an artifact';\n content += ' related to this branch. ';\n content += template.compile(\n config.userStrings!.artifactErrorWarning,\n config,\n );\n content += emojify(\n `\\n\\n:recycle: Renovate will retry this branch, including artifacts, only when one of the following happens:\\n\\n`,\n );\n content +=\n ' - any of the package files in this branch needs updating, or \\n';\n content += ' - the branch becomes conflicted, or\\n';\n content +=\n ' - you click the rebase/retry checkbox if found above, or\\n';\n content +=\n ' - you rename this PR\\'s title to start with \"rebase!\" to trigger it manually';\n content += '\\n\\nThe artifact failure details are included below:\\n\\n';\n // TODO: types (#22198)\n config.artifactErrors.forEach((error) => {\n content += `##### File name: ${error.fileName!}\\n\\n`;\n content += `\\`\\`\\`\\n${error.stderr!}\\n\\`\\`\\`\\n\\n`;\n });\n content = platform.massageMarkdown(content, config.rebaseLabel);\n // v8 ignore else -- TODO: add test #40625\n if (!(\n config.suppressNotifications!.includes('artifactErrors') ||\n config.suppressNotifications!.includes('lockFileErrors')\n )) {\n if (GlobalConfig.get('dryRun')) {\n logger.info(\n `DRY-RUN: Would ensure lock file error comment in PR #${pr.number}`,\n );\n } else {\n await ensureComment({\n number: pr.number,\n topic: artifactErrorTopic,\n content,\n });\n }\n }\n } else {\n if (config.artifactNotices?.length) {\n const contentLines: string[] = [];\n for (const notice of config.artifactNotices) {\n contentLines.push(`##### File name: ${notice.file}`);\n contentLines.push(notice.message);\n }\n const content = contentLines.join('\\n\\n');\n await ensureComment({\n number: pr.number,\n topic: artifactNoticeTopic,\n content,\n });\n }\n\n if (config.automerge) {\n logger.debug('PR is configured for automerge');\n // skip automerge if there is a new commit since status checks aren't done yet\n // v8 ignore else -- TODO: add test #40625\n if (config.ignoreTests === true || !commitSha) {\n logger.debug('checking auto-merge');\n const prAutomergeResult = await checkAutoMerge(pr, config);\n if (prAutomergeResult?.automerged) {\n return {\n branchExists,\n result: 'automerged',\n commitSha,\n };\n }\n }\n } else {\n logger.debug('PR is not configured for automerge');\n }\n }\n }\n } catch (err) {\n /* v8 ignore if -- needs test */\n if (\n err instanceof ExternalHostError ||\n [PLATFORM_RATE_LIMIT_EXCEEDED, REPOSITORY_CHANGED].includes(err.message)\n ) {\n logger.debug('Passing PR error up');\n throw err;\n }\n // Otherwise don't throw here - we don't want to stop the other renovations\n logger.error({ err }, `Error ensuring PR`);\n }\n if (!branchExists) {\n return {\n branchExists: true,\n updatesVerified,\n prNo: branchPr?.number,\n result: 'pr-created',\n commitSha,\n };\n }\n return {\n branchExists,\n updatesVerified,\n prNo: branchPr?.number,\n result: 'done',\n commitSha,\n };\n}\n"],"mappings":"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"}
@@ -144,7 +144,9 @@ async function releaseNotesResult(releaseMatch, project) {
144
144
  const { baseUrl, repository } = project;
145
145
  const releaseNotes = releaseMatch;
146
146
  if (detectPlatform(baseUrl) === "gitlab") releaseNotes.url = `${baseUrl}${repository}/tags/${releaseMatch.tag}`;
147
- else releaseNotes.url = releaseMatch.url ? releaseMatch.url : `${baseUrl}${repository}/releases/${releaseMatch.tag}`;
147
+ else
148
+ // v8 ignore next -- a matched release always carries its own url
149
+ releaseNotes.url = releaseMatch.url ? releaseMatch.url : `${baseUrl}${repository}/releases/${releaseMatch.tag}`;
148
150
  releaseNotes.body = massageBody(releaseNotes.body, baseUrl);
149
151
  releaseNotes.name = massageName(releaseNotes.name, releaseNotes.tag);
150
152
  if (releaseNotes.body.length || releaseNotes.name?.length) try {