renovate 44.198.2 → 44.199.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 (60) hide show
  1. package/dist/data/replacements.js +11 -0
  2. package/dist/modules/manager/fingerprint.generated.js +1 -1
  3. package/dist/modules/manager/fingerprint.generated.js.map +1 -1
  4. package/dist/modules/manager/git-submodules/update.js +8 -2
  5. package/dist/modules/manager/git-submodules/update.js.map +1 -1
  6. package/dist/modules/manager/types.d.ts +8 -1
  7. package/dist/util/http/github.d.ts +4 -0
  8. package/dist/util/http/github.js +8 -2
  9. package/dist/util/http/github.js.map +1 -1
  10. package/dist/workers/repository/config-migration/branch/commit-message.js +9 -9
  11. package/dist/workers/repository/config-migration/branch/commit-message.js.map +1 -1
  12. package/dist/workers/repository/config-migration/branch/create.js +13 -16
  13. package/dist/workers/repository/config-migration/branch/create.js.map +1 -1
  14. package/dist/workers/repository/config-migration/branch/rebase.js +15 -20
  15. package/dist/workers/repository/config-migration/branch/rebase.js.map +1 -1
  16. package/dist/workers/repository/config-migration/pr/index.js +13 -58
  17. package/dist/workers/repository/config-migration/pr/index.js.map +1 -1
  18. package/dist/workers/repository/model/commit-body.js +27 -0
  19. package/dist/workers/repository/model/commit-body.js.map +1 -0
  20. package/dist/workers/repository/model/commit-config-file.js +40 -0
  21. package/dist/workers/repository/model/commit-config-file.js.map +1 -0
  22. package/dist/workers/repository/model/commit-message-factory.js.map +1 -1
  23. package/dist/workers/repository/onboarding/branch/commit-message.js +8 -17
  24. package/dist/workers/repository/onboarding/branch/commit-message.js.map +1 -1
  25. package/dist/workers/repository/onboarding/branch/create.js +9 -27
  26. package/dist/workers/repository/onboarding/branch/create.js.map +1 -1
  27. package/dist/workers/repository/onboarding/branch/rebase.js +9 -15
  28. package/dist/workers/repository/onboarding/branch/rebase.js.map +1 -1
  29. package/dist/workers/repository/onboarding/common.js +5 -1
  30. package/dist/workers/repository/onboarding/common.js.map +1 -1
  31. package/dist/workers/repository/onboarding/pr/index.js +16 -65
  32. package/dist/workers/repository/onboarding/pr/index.js.map +1 -1
  33. package/dist/workers/repository/process/lookup/filter-checks.js +1 -1
  34. package/dist/workers/repository/update/branch/automerge.js +2 -2
  35. package/dist/workers/repository/update/branch/automerge.js.map +1 -1
  36. package/dist/workers/repository/update/branch/check-existing.js +61 -1
  37. package/dist/workers/repository/update/branch/check-existing.js.map +1 -1
  38. package/dist/workers/repository/update/branch/errors.js +90 -0
  39. package/dist/workers/repository/update/branch/errors.js.map +1 -0
  40. package/dist/workers/repository/update/branch/get-updated.js +8 -5
  41. package/dist/workers/repository/update/branch/get-updated.js.map +1 -1
  42. package/dist/workers/repository/update/branch/index.js +43 -302
  43. package/dist/workers/repository/update/branch/index.js.map +1 -1
  44. package/dist/workers/repository/update/branch/pr-blocked-by.js +25 -0
  45. package/dist/workers/repository/update/branch/pr-blocked-by.js.map +1 -0
  46. package/dist/workers/repository/update/branch/reuse.js +84 -7
  47. package/dist/workers/repository/update/branch/reuse.js.map +1 -1
  48. package/dist/workers/repository/update/branch/status-checks.js +84 -2
  49. package/dist/workers/repository/update/branch/status-checks.js.map +1 -1
  50. package/dist/workers/repository/update/pr/body/controls.js +6 -2
  51. package/dist/workers/repository/update/pr/body/controls.js.map +1 -1
  52. package/dist/workers/repository/update/pr/body/footer.js.map +1 -1
  53. package/dist/workers/repository/update/pr/body/header.js.map +1 -1
  54. package/dist/workers/repository/update/pr/body/index.js +2 -2
  55. package/dist/workers/repository/update/pr/ensure-config-pr.js +75 -0
  56. package/dist/workers/repository/update/pr/ensure-config-pr.js.map +1 -0
  57. package/dist/workers/repository/update/pr/index.js +6 -5
  58. package/dist/workers/repository/update/pr/index.js.map +1 -1
  59. package/package.json +1 -1
  60. package/renovate-schema.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["template.compile"],"sources":["../../../../../lib/workers/repository/onboarding/pr/index.ts"],"sourcesContent":["import { isNumber, isString } from '@sindresorhus/is';\nimport { GlobalConfig } from '../../../../config/global.ts';\nimport type { RenovateConfig } from '../../../../config/types.ts';\nimport { REPOSITORY_CLOSED_ONBOARDING } from '../../../../constants/error-messages.ts';\nimport { logger } from '../../../../logger/index.ts';\nimport type { PackageFile } from '../../../../modules/manager/types.ts';\nimport { ensureComment } from '../../../../modules/platform/comment.ts';\nimport type { Pr } from '../../../../modules/platform/index.ts';\nimport { platform } from '../../../../modules/platform/index.ts';\nimport { hashBody } from '../../../../modules/platform/pr-body.ts';\nimport { scm } from '../../../../modules/platform/scm.ts';\nimport { getInheritedOrGlobal } from '../../../../util/common.ts';\nimport { getElapsedDays } from '../../../../util/date.ts';\nimport { emojify } from '../../../../util/emoji.ts';\nimport { getFile } from '../../../../util/git/index.ts';\nimport { toSha256 } from '../../../../util/hash.ts';\nimport * as template from '../../../../util/template/index.ts';\nimport type { BranchConfig } from '../../../types.ts';\nimport {\n getDepWarningsOnboardingPR,\n getErrors,\n getWarnings,\n} from '../../errors-warnings.ts';\nimport type { RepositoryResult } from '../../result.ts';\nimport { getPlatformPrOptions } from '../../update/pr/index.ts';\nimport { prepareLabels } from '../../update/pr/labels.ts';\nimport { addParticipants } from '../../update/pr/participants.ts';\nimport { isOnboardingBranchConflicted } from '../branch/onboarding-branch-cache.ts';\nimport {\n OnboardingState,\n getDefaultConfigFileName,\n getSemanticCommitPrTitle,\n} from '../common.ts';\nimport { getBaseBranchDesc } from './base-branch.ts';\nimport { getConfigDesc } from './config-description.ts';\nimport {\n getPackageFilesDesc,\n getPackageFilesSummary,\n} from './package-files.ts';\nimport { getExpectedPrList, getExpectedPrListSummary } from './pr-list.ts';\nimport type { OnboardingPrSections } from './types.ts';\n\n/**\n * Given an existing PR, if onboardingAutoCloseAge has passed, close the PR.\n *\n * Returns true if the PR was closed.\n */\nasync function ensureOnboardingAutoCloseAge(existingPr: Pr): Promise<boolean> {\n // check if the existing pr crosses the onboarding autoclose age\n const ageOfOnboardingPr = getElapsedDays(existingPr.createdAt!, false);\n const onboardingAutoCloseAge = getInheritedOrGlobal('onboardingAutoCloseAge');\n if (onboardingAutoCloseAge) {\n logger.debug(\n {\n onboardingAutoCloseAge,\n createdAt: existingPr.createdAt!,\n ageOfOnboardingPr,\n },\n `Determining that the onboarding PR created at \\`${existingPr.createdAt!}\\` was created ${ageOfOnboardingPr.toFixed(2)} days ago`,\n );\n }\n if (\n isNumber(onboardingAutoCloseAge) &&\n ageOfOnboardingPr > onboardingAutoCloseAge\n ) {\n // close the pr\n await platform.updatePr({\n number: existingPr.number,\n state: 'closed',\n prTitle: existingPr.title,\n });\n // ensure comment\n await ensureComment({\n number: existingPr.number,\n topic: `Renovate is disabled`,\n content: `Renovate is disabled because the onboarding PR has been unmerged for more than ${onboardingAutoCloseAge} days. To enable Renovate, you can either (a) change this PR's title to get a new onboarding PR, and merge the new onboarding PR, or (b) create a Renovate config file, and commit that file to your base branch.`,\n });\n logger.debug(\n {\n ageOfOnboardingPr,\n onboardingAutoCloseAge,\n },\n `Renovate is being disabled for this repository as the onboarding PR has been unmerged for more than ${onboardingAutoCloseAge} days`,\n );\n return true;\n }\n return false;\n}\n\n/**\n * Full onboarding PRs list package files before the PR list.\n */\nconst FULL_SECTION_ORDER = [\n 'PACKAGE FILES',\n 'CONFIG',\n 'BASEBRANCH',\n 'PRLIST',\n 'WARNINGS',\n 'ERRORS',\n] as const;\n\n/**\n * \"Summarised\" onboarding PRs list PRs before other sections.\n */\nconst SUMMARY_SECTION_ORDER = [\n 'PRLIST',\n 'CONFIG',\n 'BASEBRANCH',\n 'PACKAGE FILES',\n 'WARNINGS',\n 'ERRORS',\n] as const;\n\nfunction buildOnboardingPrTemplate(\n config: RenovateConfig,\n configFile: string,\n rebaseCheckBox: string,\n sectionOrder: readonly string[],\n): string {\n let prTemplate = `Welcome to [Renovate](${\n GlobalConfig.get('productLinks').homepage\n })! This is an onboarding PR to help you understand and configure settings before regular Pull Requests begin.\\n\\n`;\n prTemplate +=\n getInheritedOrGlobal('requireConfig') === 'required'\n ? emojify(\n `:vertical_traffic_light: To activate Renovate, merge this Pull Request. To disable Renovate, simply close this Pull Request unmerged.\\n\\n`,\n )\n : emojify(\n `:vertical_traffic_light: Renovate will begin keeping your dependencies up-to-date only once you merge or close this Pull Request.\\n\\n`,\n );\n\n prTemplate += emojify(\n `:books: See our [Reading List](${GlobalConfig.get('productLinks').documentation}reading-list/) for relevant documentation you may be interested in reading.\\n\\n`,\n );\n\n prTemplate += emojify(\n `:abcd: Do you want to change how Renovate upgrades your dependencies?`,\n );\n prTemplate += ` Add your custom config to \\`${configFile}\\` in this branch${\n config.onboardingRebaseCheckbox\n ? ' and select the Retry/Rebase checkbox below'\n : ''\n }. Renovate will update the Pull Request description the next time it runs.`;\n prTemplate += '\\n\\n';\n // TODO #22198\n prTemplate += emojify(\n `\n\n---\n${sectionOrder.map((section) => `{{${section}}}`).join('\\n')}\n\n---\n\n:question: Got questions? Check out Renovate's [Docs](${\n GlobalConfig.get('productLinks').documentation\n }), particularly the Getting Started section.\nIf you need any further assistance then you can also [request help here](${\n GlobalConfig.get('productLinks').help\n }).\n`,\n );\n prTemplate += rebaseCheckBox;\n return prTemplate;\n}\n\nfunction fillOnboardingPrBody(\n prTemplate: string,\n sections: OnboardingPrSections,\n): string {\n let prBody = prTemplate;\n if (sections.packageFiles) {\n prBody = `${prBody.replace('{{PACKAGE FILES}}', sections.packageFiles)}\\n`;\n } else {\n prBody = prBody.replace('{{PACKAGE FILES}}\\n', '');\n }\n prBody = prBody.replace('{{CONFIG}}\\n', sections.config);\n prBody = prBody.replace('{{WARNINGS}}\\n', sections.warnings);\n prBody = prBody.replace('{{ERRORS}}\\n', sections.errors);\n prBody = prBody.replace('{{BASEBRANCH}}\\n', sections.baseBranch);\n prBody = prBody.replace('{{PRLIST}}\\n', sections.prList);\n return prBody;\n}\n\nfunction finalizeOnboardingPrBody(\n prBody: string,\n config: RenovateConfig,\n onboardingConfigHashComment: string,\n): string {\n let finalPrBody = prBody;\n if (isString(config.prHeader)) {\n finalPrBody = `${template.compile(config.prHeader, config)}\\n\\n${finalPrBody}`;\n }\n if (isString(config.prFooter)) {\n finalPrBody = `${finalPrBody}\\n---\\n\\n${template.compile(config.prFooter, config)}\\n`;\n }\n return finalPrBody + onboardingConfigHashComment;\n}\n\nexport async function ensureOnboardingPr(\n config: RenovateConfig,\n packageFiles: Record<string, PackageFile[]> | null,\n branches: BranchConfig[],\n): Promise<RepositoryResult> {\n if (config.onboardingRebaseCheckbox && !OnboardingState.prUpdateRequested) {\n return 'onboarding';\n }\n logger.debug('ensureOnboardingPr()');\n logger.trace({ config });\n // TODO #22198\n const onboardingBranch = getInheritedOrGlobal('onboardingBranch')!;\n const existingPr = await platform.getBranchPr(\n onboardingBranch,\n config.defaultBranch,\n );\n if (existingPr) {\n const wasClosed = await ensureOnboardingAutoCloseAge(existingPr);\n if (wasClosed) {\n throw new Error(REPOSITORY_CLOSED_ONBOARDING);\n }\n\n // skip pr-update if branch is conflicted\n if (\n await isOnboardingBranchConflicted(\n config.defaultBranch!,\n onboardingBranch,\n )\n ) {\n if (GlobalConfig.get('dryRun')) {\n logger.info(\n 'DRY-RUN: Would comment that Onboarding PR is conflicted and needs manual resolving',\n );\n return 'onboarding';\n }\n await ensureComment({\n number: existingPr.number,\n topic: 'Branch Conflicted',\n content: emojify(\n `:warning: This PR has a merge conflict which Renovate is unable to automatically resolve, so updates to this PR description are now paused. Please resolve the merge conflict manually.\\n\\n`,\n ),\n });\n return 'onboarding';\n }\n }\n\n if (OnboardingState.onboardingCacheValid) {\n return 'onboarding';\n }\n\n const onboardingConfigHashComment = await getOnboardingConfigHashComment();\n const rebaseCheckBox = getRebaseCheckbox(config.onboardingRebaseCheckbox);\n const configFile = getDefaultConfigFileName();\n logger.debug('Filling in onboarding PR template');\n\n const packageFilesDesc = getPackageFilesDesc(packageFiles);\n let configDesc = '';\n if (GlobalConfig.get('dryRun')) {\n // TODO: types (#22198)\n logger.info(`DRY-RUN: Would check branch ${onboardingBranch}`);\n } else {\n configDesc = getConfigDesc(config, packageFiles!);\n }\n const warnings =\n getWarnings(config) + getDepWarningsOnboardingPR(packageFiles!, config);\n const errors = getErrors(config);\n const baseBranchDesc = getBaseBranchDesc(config);\n const prList = getExpectedPrList(config, branches);\n\n let prBody = finalizeOnboardingPrBody(\n fillOnboardingPrBody(\n buildOnboardingPrTemplate(\n config,\n configFile,\n rebaseCheckBox,\n FULL_SECTION_ORDER,\n ),\n {\n packageFiles: packageFilesDesc,\n config: configDesc,\n baseBranch: baseBranchDesc,\n prList,\n warnings,\n errors,\n },\n ),\n config,\n onboardingConfigHashComment,\n );\n\n if (prBody.length > platform.maxBodyLength()) {\n logger.debug(\n 'Onboarding PR body exceeds platform limit, switching to summary PR list and package files',\n );\n const prListSummary = getExpectedPrListSummary(config, branches);\n if (packageFilesDesc) {\n const packageFilesSummary = `### Detected Package Files\\n\\n${getPackageFilesSummary(packageFiles)}`;\n // \"What to Expect\" should render before \"Detected Package Files\" in the summary view,\n // so rebuild from a template with that section order rather than reordering the rendered body.\n prBody = finalizeOnboardingPrBody(\n fillOnboardingPrBody(\n buildOnboardingPrTemplate(\n config,\n configFile,\n rebaseCheckBox,\n SUMMARY_SECTION_ORDER,\n ),\n {\n packageFiles: packageFilesSummary,\n config: configDesc,\n baseBranch: baseBranchDesc,\n prList: prListSummary,\n warnings,\n errors,\n },\n ),\n config,\n onboardingConfigHashComment,\n );\n } else {\n prBody = prBody.replace(prList, prListSummary);\n }\n }\n\n logger.trace(`prBody:\\n${prBody}`);\n\n prBody = platform.massageMarkdown(prBody, config.rebaseLabel);\n\n if (existingPr) {\n logger.debug('Found open onboarding PR');\n // Check if existing PR needs updating\n const prBodyHash = hashBody(prBody);\n if (existingPr.bodyStruct?.hash === prBodyHash) {\n logger.debug(`Pull Request #${existingPr.number} does not need updating`);\n return 'onboarding';\n }\n // PR must need updating\n if (GlobalConfig.get('dryRun')) {\n logger.info('DRY-RUN: Would update onboarding PR');\n } else {\n await platform.updatePr({\n number: existingPr.number,\n prTitle: existingPr.title,\n prBody,\n });\n logger.info({ pr: existingPr.number }, 'Onboarding PR updated');\n }\n return 'onboarding';\n }\n logger.debug('Creating onboarding PR');\n const labels: string[] = prepareLabels(config);\n try {\n if (GlobalConfig.get('dryRun')) {\n logger.info('DRY-RUN: Would create onboarding PR');\n } else {\n // TODO #22198\n const prTitle =\n config.semanticCommits === 'enabled'\n ? getSemanticCommitPrTitle(config)\n : getInheritedOrGlobal('onboardingPrTitle')!;\n const pr = await platform.createPr({\n sourceBranch: onboardingBranch,\n targetBranch: config.defaultBranch!,\n prTitle,\n prBody,\n labels,\n platformPrOptions: getPlatformPrOptions({\n ...config,\n automerge: false,\n }),\n });\n logger.info(\n { pr: `Pull Request #${pr!.number}` },\n 'Onboarding PR created',\n );\n await addParticipants(config, pr!);\n }\n } catch (err) {\n if (\n err.response?.statusCode === 422 &&\n err.response?.body?.errors?.[0]?.message?.startsWith(\n 'A pull request already exists',\n )\n ) {\n logger.warn(\n 'Onboarding PR already exists but cannot find it. It was probably created by a different user.',\n );\n await scm.deleteBranch(onboardingBranch);\n return 'onboarding';\n }\n throw err;\n }\n\n return 'onboarding';\n}\n\nfunction getRebaseCheckbox(onboardingRebaseCheckbox?: boolean): string {\n let rebaseCheckBox = '';\n if (onboardingRebaseCheckbox) {\n // Create markdown checkbox\n rebaseCheckBox = `\\n\\n---\\n\\n - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, click this checkbox.\\n`;\n }\n\n return rebaseCheckBox;\n}\n\nasync function getOnboardingConfigHashComment(): Promise<string> {\n const configFile = getDefaultConfigFileName();\n const existingContents =\n (await getFile(configFile, getInheritedOrGlobal('onboardingBranch'))) ?? '';\n const hash = toSha256(existingContents);\n\n return `\\n<!--renovate-config-hash:${hash}-->\\n`;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../../../lib/workers/repository/onboarding/pr/index.ts"],"sourcesContent":["import { isNumber } from '@sindresorhus/is';\nimport { GlobalConfig } from '../../../../config/global.ts';\nimport type { RenovateConfig } from '../../../../config/types.ts';\nimport { REPOSITORY_CLOSED_ONBOARDING } from '../../../../constants/error-messages.ts';\nimport { logger } from '../../../../logger/index.ts';\nimport type { PackageFile } from '../../../../modules/manager/types.ts';\nimport { ensureComment } from '../../../../modules/platform/comment.ts';\nimport type { Pr } from '../../../../modules/platform/index.ts';\nimport { platform } from '../../../../modules/platform/index.ts';\nimport { getInheritedOrGlobal } from '../../../../util/common.ts';\nimport { getElapsedDays } from '../../../../util/date.ts';\nimport { emojify } from '../../../../util/emoji.ts';\nimport { getFile } from '../../../../util/git/index.ts';\nimport { toSha256 } from '../../../../util/hash.ts';\nimport type { BranchConfig } from '../../../types.ts';\nimport {\n getDepWarningsOnboardingPR,\n getErrors,\n getWarnings,\n} from '../../errors-warnings.ts';\nimport type { RepositoryResult } from '../../result.ts';\nimport { getRebaseCheckbox } from '../../update/pr/body/controls.ts';\nimport { getPrFooter } from '../../update/pr/body/footer.ts';\nimport { getPrHeader } from '../../update/pr/body/header.ts';\nimport { ensureConfigPr } from '../../update/pr/ensure-config-pr.ts';\nimport { isOnboardingBranchConflicted } from '../branch/onboarding-branch-cache.ts';\nimport {\n OnboardingState,\n getDefaultConfigFileName,\n getOnboardingPrTitle,\n} from '../common.ts';\nimport { getBaseBranchDesc } from './base-branch.ts';\nimport { getConfigDesc } from './config-description.ts';\nimport {\n getPackageFilesDesc,\n getPackageFilesSummary,\n} from './package-files.ts';\nimport { getExpectedPrList, getExpectedPrListSummary } from './pr-list.ts';\nimport type { OnboardingPrSections } from './types.ts';\n\n/**\n * Given an existing PR, if onboardingAutoCloseAge has passed, close the PR.\n *\n * Returns true if the PR was closed.\n */\nasync function ensureOnboardingAutoCloseAge(existingPr: Pr): Promise<boolean> {\n // check if the existing pr crosses the onboarding autoclose age\n const ageOfOnboardingPr = getElapsedDays(existingPr.createdAt!, false);\n const onboardingAutoCloseAge = getInheritedOrGlobal('onboardingAutoCloseAge');\n if (onboardingAutoCloseAge) {\n logger.debug(\n {\n onboardingAutoCloseAge,\n createdAt: existingPr.createdAt!,\n ageOfOnboardingPr,\n },\n `Determining that the onboarding PR created at \\`${existingPr.createdAt!}\\` was created ${ageOfOnboardingPr.toFixed(2)} days ago`,\n );\n }\n if (\n isNumber(onboardingAutoCloseAge) &&\n ageOfOnboardingPr > onboardingAutoCloseAge\n ) {\n // close the pr\n await platform.updatePr({\n number: existingPr.number,\n state: 'closed',\n prTitle: existingPr.title,\n });\n // ensure comment\n await ensureComment({\n number: existingPr.number,\n topic: `Renovate is disabled`,\n content: `Renovate is disabled because the onboarding PR has been unmerged for more than ${onboardingAutoCloseAge} days. To enable Renovate, you can either (a) change this PR's title to get a new onboarding PR, and merge the new onboarding PR, or (b) create a Renovate config file, and commit that file to your base branch.`,\n });\n logger.debug(\n {\n ageOfOnboardingPr,\n onboardingAutoCloseAge,\n },\n `Renovate is being disabled for this repository as the onboarding PR has been unmerged for more than ${onboardingAutoCloseAge} days`,\n );\n return true;\n }\n return false;\n}\n\n/**\n * Full onboarding PRs list package files before the PR list.\n */\nconst FULL_SECTION_ORDER = [\n 'PACKAGE FILES',\n 'CONFIG',\n 'BASEBRANCH',\n 'PRLIST',\n 'WARNINGS',\n 'ERRORS',\n] as const;\n\n/**\n * \"Summarised\" onboarding PRs list PRs before other sections.\n */\nconst SUMMARY_SECTION_ORDER = [\n 'PRLIST',\n 'CONFIG',\n 'BASEBRANCH',\n 'PACKAGE FILES',\n 'WARNINGS',\n 'ERRORS',\n] as const;\n\nfunction buildOnboardingPrTemplate(\n config: RenovateConfig,\n configFile: string,\n rebaseCheckBox: string,\n sectionOrder: readonly string[],\n): string {\n let prTemplate = `Welcome to [Renovate](${\n GlobalConfig.get('productLinks').homepage\n })! This is an onboarding PR to help you understand and configure settings before regular Pull Requests begin.\\n\\n`;\n prTemplate +=\n getInheritedOrGlobal('requireConfig') === 'required'\n ? emojify(\n `:vertical_traffic_light: To activate Renovate, merge this Pull Request. To disable Renovate, simply close this Pull Request unmerged.\\n\\n`,\n )\n : emojify(\n `:vertical_traffic_light: Renovate will begin keeping your dependencies up-to-date only once you merge or close this Pull Request.\\n\\n`,\n );\n\n prTemplate += emojify(\n `:books: See our [Reading List](${GlobalConfig.get('productLinks').documentation}reading-list/) for relevant documentation you may be interested in reading.\\n\\n`,\n );\n\n prTemplate += emojify(\n `:abcd: Do you want to change how Renovate upgrades your dependencies?`,\n );\n prTemplate += ` Add your custom config to \\`${configFile}\\` in this branch${\n config.onboardingRebaseCheckbox\n ? ' and select the Retry/Rebase checkbox below'\n : ''\n }. Renovate will update the Pull Request description the next time it runs.`;\n prTemplate += '\\n\\n';\n // TODO #22198\n prTemplate += emojify(\n `\n\n---\n${sectionOrder.map((section) => `{{${section}}}`).join('\\n')}\n\n---\n\n:question: Got questions? Check out Renovate's [Docs](${\n GlobalConfig.get('productLinks').documentation\n }), particularly the Getting Started section.\nIf you need any further assistance then you can also [request help here](${\n GlobalConfig.get('productLinks').help\n }).\n`,\n );\n prTemplate += rebaseCheckBox;\n return prTemplate;\n}\n\nfunction fillOnboardingPrBody(\n prTemplate: string,\n sections: OnboardingPrSections,\n): string {\n let prBody = prTemplate;\n if (sections.packageFiles) {\n prBody = `${prBody.replace('{{PACKAGE FILES}}', sections.packageFiles)}\\n`;\n } else {\n prBody = prBody.replace('{{PACKAGE FILES}}\\n', '');\n }\n prBody = prBody.replace('{{CONFIG}}\\n', sections.config);\n prBody = prBody.replace('{{WARNINGS}}\\n', sections.warnings);\n prBody = prBody.replace('{{ERRORS}}\\n', sections.errors);\n prBody = prBody.replace('{{BASEBRANCH}}\\n', sections.baseBranch);\n prBody = prBody.replace('{{PRLIST}}\\n', sections.prList);\n return prBody;\n}\n\nfunction finalizeOnboardingPrBody(\n prBody: string,\n config: RenovateConfig,\n onboardingConfigHashComment: string,\n): string {\n return `${getPrHeader(config)}${prBody}${getPrFooter(config)}${onboardingConfigHashComment}`;\n}\n\nexport async function ensureOnboardingPr(\n config: RenovateConfig,\n packageFiles: Record<string, PackageFile[]> | null,\n branches: BranchConfig[],\n): Promise<RepositoryResult> {\n if (config.onboardingRebaseCheckbox && !OnboardingState.prUpdateRequested) {\n return 'onboarding';\n }\n logger.debug('ensureOnboardingPr()');\n logger.trace({ config });\n // TODO #22198\n const onboardingBranch = getInheritedOrGlobal('onboardingBranch')!;\n const existingPr = await platform.getBranchPr(\n onboardingBranch,\n config.defaultBranch,\n );\n if (existingPr) {\n const wasClosed = await ensureOnboardingAutoCloseAge(existingPr);\n if (wasClosed) {\n throw new Error(REPOSITORY_CLOSED_ONBOARDING);\n }\n\n // skip pr-update if branch is conflicted\n if (\n await isOnboardingBranchConflicted(\n config.defaultBranch!,\n onboardingBranch,\n )\n ) {\n if (GlobalConfig.get('dryRun')) {\n logger.info(\n 'DRY-RUN: Would comment that Onboarding PR is conflicted and needs manual resolving',\n );\n return 'onboarding';\n }\n await ensureComment({\n number: existingPr.number,\n topic: 'Branch Conflicted',\n content: emojify(\n `:warning: This PR has a merge conflict which Renovate is unable to automatically resolve, so updates to this PR description are now paused. Please resolve the merge conflict manually.\\n\\n`,\n ),\n });\n return 'onboarding';\n }\n }\n\n if (OnboardingState.onboardingCacheValid) {\n return 'onboarding';\n }\n\n const onboardingConfigHashComment = await getOnboardingConfigHashComment();\n const rebaseCheckBox = getRebaseCheckbox(config.onboardingRebaseCheckbox);\n const configFile = getDefaultConfigFileName();\n logger.debug('Filling in onboarding PR template');\n\n const packageFilesDesc = getPackageFilesDesc(packageFiles);\n let configDesc = '';\n if (GlobalConfig.get('dryRun')) {\n // TODO: types (#22198)\n logger.info(`DRY-RUN: Would check branch ${onboardingBranch}`);\n } else {\n configDesc = getConfigDesc(config, packageFiles!);\n }\n const warnings =\n getWarnings(config) + getDepWarningsOnboardingPR(packageFiles!, config);\n const errors = getErrors(config);\n const baseBranchDesc = getBaseBranchDesc(config);\n const prList = getExpectedPrList(config, branches);\n\n let prBody = finalizeOnboardingPrBody(\n fillOnboardingPrBody(\n buildOnboardingPrTemplate(\n config,\n configFile,\n rebaseCheckBox,\n FULL_SECTION_ORDER,\n ),\n {\n packageFiles: packageFilesDesc,\n config: configDesc,\n baseBranch: baseBranchDesc,\n prList,\n warnings,\n errors,\n },\n ),\n config,\n onboardingConfigHashComment,\n );\n\n if (prBody.length > platform.maxBodyLength()) {\n logger.debug(\n 'Onboarding PR body exceeds platform limit, switching to summary PR list and package files',\n );\n const prListSummary = getExpectedPrListSummary(config, branches);\n if (packageFilesDesc) {\n const packageFilesSummary = `### Detected Package Files\\n\\n${getPackageFilesSummary(packageFiles)}`;\n // \"What to Expect\" should render before \"Detected Package Files\" in the summary view,\n // so rebuild from a template with that section order rather than reordering the rendered body.\n prBody = finalizeOnboardingPrBody(\n fillOnboardingPrBody(\n buildOnboardingPrTemplate(\n config,\n configFile,\n rebaseCheckBox,\n SUMMARY_SECTION_ORDER,\n ),\n {\n packageFiles: packageFilesSummary,\n config: configDesc,\n baseBranch: baseBranchDesc,\n prList: prListSummary,\n warnings,\n errors,\n },\n ),\n config,\n onboardingConfigHashComment,\n );\n } else {\n prBody = prBody.replace(prList, prListSummary);\n }\n }\n\n await ensureConfigPr({\n branchName: onboardingBranch,\n // TODO #22198\n targetBranch: config.defaultBranch!,\n // Keep the title of an existing onboarding PR, because renaming it is the\n // documented way to request a fresh onboarding PR.\n prTitle: existingPr?.title ?? getOnboardingPrTitle(config),\n prBody,\n config,\n existingPr,\n type: 'onboarding',\n });\n\n return 'onboarding';\n}\n\nasync function getOnboardingConfigHashComment(): Promise<string> {\n const configFile = getDefaultConfigFileName();\n const existingContents =\n (await getFile(configFile, getInheritedOrGlobal('onboardingBranch'))) ?? '';\n const hash = toSha256(existingContents);\n\n return `\\n<!--renovate-config-hash:${hash}-->\\n`;\n}\n"],"mappings":"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"}
@@ -2,10 +2,10 @@ import { logger } from "../../../../logger/index.js";
2
2
  import { mergeChildConfig } from "../../../../config/utils.js";
3
3
  import "../../../../config/index.js";
4
4
  import { getMergeConfidenceLevel, isActiveConfidenceLevel, satisfiesConfidenceLevel } from "../../../../util/merge-confidence/index.js";
5
+ import { checkMinimumReleaseAge } from "../../../../util/minimum-release-age.js";
5
6
  import { applyPackageRules } from "../../../../util/package-rules/index.js";
6
7
  import { postprocessRelease } from "../../../../modules/datasource/postprocess-release.js";
7
8
  import { classifyRelease } from "./update-type.js";
8
- import { checkMinimumReleaseAge } from "../../../../util/minimum-release-age.js";
9
9
  //#region lib/workers/repository/process/lookup/filter-checks.ts
10
10
  /**
11
11
  * Emitted by every `minimumReleaseAge` check which had no `releaseTimestamp` to
@@ -5,11 +5,11 @@ import { scm } from "../../../../modules/platform/scm.js";
5
5
  import { platform } from "../../../../modules/platform/index.js";
6
6
  import { resolveBranchStatus } from "./status-checks.js";
7
7
  //#region lib/workers/repository/update/branch/automerge.ts
8
- async function tryBranchAutomerge(config) {
8
+ async function tryBranchAutomerge(config, branchPr) {
9
9
  logger.debug("Checking if we can automerge branch");
10
10
  if (!(config.automerge && config.automergeType === "branch")) return "no automerge";
11
11
  if (!isScheduledNow(config, "automergeSchedule")) return "off schedule";
12
- if (await platform.getBranchPr(config.branchName, config.baseBranch)) return "automerge aborted - PR exists";
12
+ if (branchPr) return "automerge aborted - PR exists";
13
13
  const branchStatus = await resolveBranchStatus(config.branchName, !!config.internalChecksAsSuccess, config.ignoreTests);
14
14
  if (branchStatus === "green") {
15
15
  logger.debug(`Automerging branch`);
@@ -1 +1 @@
1
- {"version":3,"file":"automerge.js","names":[],"sources":["../../../../../lib/workers/repository/update/branch/automerge.ts"],"sourcesContent":["import { GlobalConfig } from '../../../../config/global.ts';\nimport type { 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 { isScheduledNow } from './schedule.ts';\nimport { resolveBranchStatus } from './status-checks.ts';\n\nexport type AutomergeResult =\n | 'automerged'\n | 'automerge aborted - merge queue'\n | 'automerge aborted - PR exists'\n | 'branch status error'\n | 'failed'\n | 'no automerge'\n | 'stale'\n | 'off schedule'\n | 'not ready';\n\nexport async function tryBranchAutomerge(\n config: RenovateConfig,\n): Promise<AutomergeResult> {\n logger.debug('Checking if we can automerge branch');\n if (!(config.automerge && config.automergeType === 'branch')) {\n return 'no automerge';\n }\n if (!isScheduledNow(config, 'automergeSchedule')) {\n return 'off schedule';\n }\n const existingPr = await platform.getBranchPr(\n config.branchName!,\n config.baseBranch,\n );\n if (existingPr) {\n return 'automerge aborted - PR exists';\n }\n const branchStatus = await resolveBranchStatus(\n config.branchName!,\n !!config.internalChecksAsSuccess,\n config.ignoreTests,\n );\n if (branchStatus === 'green') {\n logger.debug(`Automerging branch`);\n try {\n if (GlobalConfig.get('dryRun')) {\n // TODO: types (#22198)\n logger.info(`DRY-RUN: Would automerge branch ${config.branchName!}`);\n } else {\n await scm.checkoutBranch(config.baseBranch!);\n await scm.mergeAndPush(config.branchName!);\n }\n logger.info({ branch: config.branchName }, 'Branch automerged');\n return 'automerged'; // Branch no longer exists\n } catch (err) {\n /* v8 ignore if -- TODO: needs test */\n if (err.message === 'not ready') {\n logger.debug('Branch is not ready for automerge');\n return 'not ready';\n }\n /* v8 ignore if -- TODO: needs test */\n if (\n err.message.includes('refusing to merge unrelated histories') ||\n err.message.includes('Not possible to fast-forward') ||\n err.message.includes(\n 'Updates were rejected because the tip of your current branch is behind',\n )\n ) {\n logger.debug({ err }, 'Branch automerge error');\n logger.info('Branch is not up to date - cannot automerge');\n return 'stale';\n }\n // A merge queue (or merge train) rejects direct pushes unless Renovate\n // is allowed to bypass it, so the push is attempted first and a PR is\n // created only if it was refused. The rejection message is platform\n // specific, so the platform is asked instead of parsing it.\n if (await platform.isBranchMergeQueueEnabled?.(config.baseBranch!)) {\n logger.warn(\n { baseBranch: config.baseBranch, err },\n 'automergeType=branch is not possible because the base branch only accepts changes through its merge queue - falling back to creating a PR. Set automergeType=pr instead, or allow Renovate to bypass the merge queue.',\n );\n return 'automerge aborted - merge queue';\n }\n /* v8 ignore if -- TODO: needs test */\n if (err.message.includes('Protected branch')) {\n if (err.message.includes('status check')) {\n logger.debug(\n { err },\n 'Branch is not ready for automerge: required status checks are remaining',\n );\n return 'not ready';\n }\n if (err.stack?.includes('reviewers')) {\n logger.info(\n { err },\n 'Branch automerge is not possible due to branch protection (required reviewers)',\n );\n return 'failed';\n }\n logger.info(\n { err },\n 'Branch automerge is not possible due to branch protection',\n );\n return 'failed';\n }\n logger.warn({ err }, 'Unknown error when attempting branch automerge');\n return 'failed';\n }\n } else if (branchStatus === 'red') {\n return 'branch status error';\n } else {\n logger.debug(`Branch status is \"${branchStatus}\" - skipping automerge`);\n }\n return 'no automerge';\n}\n"],"mappings":";;;;;;;AAmBA,eAAsB,mBACpB,QAC0B;CAC1B,OAAO,MAAM,qCAAqC;CAClD,IAAI,EAAE,OAAO,aAAa,OAAO,kBAAkB,WACjD,OAAO;CAET,IAAI,CAAC,eAAe,QAAQ,mBAAmB,GAC7C,OAAO;CAMT,IAAI,MAJqB,SAAS,YAChC,OAAO,YACP,OAAO,UACT,GAEE,OAAO;CAET,MAAM,eAAe,MAAM,oBACzB,OAAO,YACP,CAAC,CAAC,OAAO,yBACT,OAAO,WACT;CACA,IAAI,iBAAiB,SAAS;EAC5B,OAAO,MAAM,oBAAoB;EACjC,IAAI;GACF,IAAI,aAAa,IAAI,QAAQ,GAE3B,OAAO,KAAK,mCAAmC,OAAO,YAAa;QAC9D;IACL,MAAM,IAAI,eAAe,OAAO,UAAW;IAC3C,MAAM,IAAI,aAAa,OAAO,UAAW;GAC3C;GACA,OAAO,KAAK,EAAE,QAAQ,OAAO,WAAW,GAAG,mBAAmB;GAC9D,OAAO;EACT,SAAS,KAAK;;GAEZ,IAAI,IAAI,YAAY,aAAa;IAC/B,OAAO,MAAM,mCAAmC;IAChD,OAAO;GACT;;GAEA,IACE,IAAI,QAAQ,SAAS,uCAAuC,KAC5D,IAAI,QAAQ,SAAS,8BAA8B,KACnD,IAAI,QAAQ,SACV,wEACF,GACA;IACA,OAAO,MAAM,EAAE,IAAI,GAAG,wBAAwB;IAC9C,OAAO,KAAK,6CAA6C;IACzD,OAAO;GACT;GAKA,IAAI,MAAM,SAAS,4BAA4B,OAAO,UAAW,GAAG;IAClE,OAAO,KACL;KAAE,YAAY,OAAO;KAAY;IAAI,GACrC,uNACF;IACA,OAAO;GACT;;GAEA,IAAI,IAAI,QAAQ,SAAS,kBAAkB,GAAG;IAC5C,IAAI,IAAI,QAAQ,SAAS,cAAc,GAAG;KACxC,OAAO,MACL,EAAE,IAAI,GACN,yEACF;KACA,OAAO;IACT;IACA,IAAI,IAAI,OAAO,SAAS,WAAW,GAAG;KACpC,OAAO,KACL,EAAE,IAAI,GACN,gFACF;KACA,OAAO;IACT;IACA,OAAO,KACL,EAAE,IAAI,GACN,2DACF;IACA,OAAO;GACT;GACA,OAAO,KAAK,EAAE,IAAI,GAAG,gDAAgD;GACrE,OAAO;EACT;CACF,OAAO,IAAI,iBAAiB,OAC1B,OAAO;MAEP,OAAO,MAAM,qBAAqB,aAAa,uBAAuB;CAExE,OAAO;AACT"}
1
+ {"version":3,"file":"automerge.js","names":[],"sources":["../../../../../lib/workers/repository/update/branch/automerge.ts"],"sourcesContent":["import { GlobalConfig } from '../../../../config/global.ts';\nimport type { RenovateConfig } from '../../../../config/types.ts';\nimport { logger } from '../../../../logger/index.ts';\nimport type { Pr } from '../../../../modules/platform/index.ts';\nimport { platform } from '../../../../modules/platform/index.ts';\nimport { scm } from '../../../../modules/platform/scm.ts';\nimport { isScheduledNow } from './schedule.ts';\nimport { resolveBranchStatus } from './status-checks.ts';\n\nexport type AutomergeResult =\n | 'automerged'\n | 'automerge aborted - merge queue'\n | 'automerge aborted - PR exists'\n | 'branch status error'\n | 'failed'\n | 'no automerge'\n | 'stale'\n | 'off schedule'\n | 'not ready';\n\nexport async function tryBranchAutomerge(\n config: RenovateConfig,\n branchPr: Pr | null,\n): Promise<AutomergeResult> {\n logger.debug('Checking if we can automerge branch');\n if (!(config.automerge && config.automergeType === 'branch')) {\n return 'no automerge';\n }\n if (!isScheduledNow(config, 'automergeSchedule')) {\n return 'off schedule';\n }\n if (branchPr) {\n return 'automerge aborted - PR exists';\n }\n const branchStatus = await resolveBranchStatus(\n config.branchName!,\n !!config.internalChecksAsSuccess,\n config.ignoreTests,\n );\n if (branchStatus === 'green') {\n logger.debug(`Automerging branch`);\n try {\n if (GlobalConfig.get('dryRun')) {\n // TODO: types (#22198)\n logger.info(`DRY-RUN: Would automerge branch ${config.branchName!}`);\n } else {\n await scm.checkoutBranch(config.baseBranch!);\n await scm.mergeAndPush(config.branchName!);\n }\n logger.info({ branch: config.branchName }, 'Branch automerged');\n return 'automerged'; // Branch no longer exists\n } catch (err) {\n /* v8 ignore if -- TODO: needs test */\n if (err.message === 'not ready') {\n logger.debug('Branch is not ready for automerge');\n return 'not ready';\n }\n /* v8 ignore if -- TODO: needs test */\n if (\n err.message.includes('refusing to merge unrelated histories') ||\n err.message.includes('Not possible to fast-forward') ||\n err.message.includes(\n 'Updates were rejected because the tip of your current branch is behind',\n )\n ) {\n logger.debug({ err }, 'Branch automerge error');\n logger.info('Branch is not up to date - cannot automerge');\n return 'stale';\n }\n // A merge queue (or merge train) rejects direct pushes unless Renovate\n // is allowed to bypass it, so the push is attempted first and a PR is\n // created only if it was refused. The rejection message is platform\n // specific, so the platform is asked instead of parsing it.\n if (await platform.isBranchMergeQueueEnabled?.(config.baseBranch!)) {\n logger.warn(\n { baseBranch: config.baseBranch, err },\n 'automergeType=branch is not possible because the base branch only accepts changes through its merge queue - falling back to creating a PR. Set automergeType=pr instead, or allow Renovate to bypass the merge queue.',\n );\n return 'automerge aborted - merge queue';\n }\n /* v8 ignore if -- TODO: needs test */\n if (err.message.includes('Protected branch')) {\n if (err.message.includes('status check')) {\n logger.debug(\n { err },\n 'Branch is not ready for automerge: required status checks are remaining',\n );\n return 'not ready';\n }\n if (err.stack?.includes('reviewers')) {\n logger.info(\n { err },\n 'Branch automerge is not possible due to branch protection (required reviewers)',\n );\n return 'failed';\n }\n logger.info(\n { err },\n 'Branch automerge is not possible due to branch protection',\n );\n return 'failed';\n }\n logger.warn({ err }, 'Unknown error when attempting branch automerge');\n return 'failed';\n }\n } else if (branchStatus === 'red') {\n return 'branch status error';\n } else {\n logger.debug(`Branch status is \"${branchStatus}\" - skipping automerge`);\n }\n return 'no automerge';\n}\n"],"mappings":";;;;;;;AAoBA,eAAsB,mBACpB,QACA,UAC0B;CAC1B,OAAO,MAAM,qCAAqC;CAClD,IAAI,EAAE,OAAO,aAAa,OAAO,kBAAkB,WACjD,OAAO;CAET,IAAI,CAAC,eAAe,QAAQ,mBAAmB,GAC7C,OAAO;CAET,IAAI,UACF,OAAO;CAET,MAAM,eAAe,MAAM,oBACzB,OAAO,YACP,CAAC,CAAC,OAAO,yBACT,OAAO,WACT;CACA,IAAI,iBAAiB,SAAS;EAC5B,OAAO,MAAM,oBAAoB;EACjC,IAAI;GACF,IAAI,aAAa,IAAI,QAAQ,GAE3B,OAAO,KAAK,mCAAmC,OAAO,YAAa;QAC9D;IACL,MAAM,IAAI,eAAe,OAAO,UAAW;IAC3C,MAAM,IAAI,aAAa,OAAO,UAAW;GAC3C;GACA,OAAO,KAAK,EAAE,QAAQ,OAAO,WAAW,GAAG,mBAAmB;GAC9D,OAAO;EACT,SAAS,KAAK;;GAEZ,IAAI,IAAI,YAAY,aAAa;IAC/B,OAAO,MAAM,mCAAmC;IAChD,OAAO;GACT;;GAEA,IACE,IAAI,QAAQ,SAAS,uCAAuC,KAC5D,IAAI,QAAQ,SAAS,8BAA8B,KACnD,IAAI,QAAQ,SACV,wEACF,GACA;IACA,OAAO,MAAM,EAAE,IAAI,GAAG,wBAAwB;IAC9C,OAAO,KAAK,6CAA6C;IACzD,OAAO;GACT;GAKA,IAAI,MAAM,SAAS,4BAA4B,OAAO,UAAW,GAAG;IAClE,OAAO,KACL;KAAE,YAAY,OAAO;KAAY;IAAI,GACrC,uNACF;IACA,OAAO;GACT;;GAEA,IAAI,IAAI,QAAQ,SAAS,kBAAkB,GAAG;IAC5C,IAAI,IAAI,QAAQ,SAAS,cAAc,GAAG;KACxC,OAAO,MACL,EAAE,IAAI,GACN,yEACF;KACA,OAAO;IACT;IACA,IAAI,IAAI,OAAO,SAAS,WAAW,GAAG;KACpC,OAAO,KACL,EAAE,IAAI,GACN,gFACF;KACA,OAAO;IACT;IACA,OAAO,KACL,EAAE,IAAI,GACN,2DACF;IACA,OAAO;GACT;GACA,OAAO,KAAK,EAAE,IAAI,GAAG,gDAAgD;GACrE,OAAO;EACT;CACF,OAAO,IAAI,iBAAiB,OAC1B,OAAO;MAEP,OAAO,MAAM,qBAAqB,aAAa,uBAAuB;CAExE,OAAO;AACT"}
@@ -1,5 +1,7 @@
1
1
  import { REPOSITORY_CHANGED } from "../../../../constants/error-messages.js";
2
+ import { GlobalConfig } from "../../../../config/global.js";
2
3
  import { logger } from "../../../../logger/index.js";
4
+ import { scm } from "../../../../modules/platform/scm.js";
3
5
  import { platform } from "../../../../modules/platform/index.js";
4
6
  //#region lib/workers/repository/update/branch/check-existing.ts
5
7
  async function prAlreadyExisted(config) {
@@ -36,7 +38,65 @@ async function prAlreadyExisted(config) {
36
38
  logger.debug("prAlreadyExisted=false");
37
39
  return null;
38
40
  }
41
+ /**
42
+ * Finds the closed PR which a modified branch without an open PR may still be
43
+ * overridden from. Returns `null` if the branch must be left alone, either
44
+ * because no closed PR matches it or because that PR points at another commit.
45
+ */
46
+ async function findClosedPrForModifiedBranch(config) {
47
+ const oldPr = await platform.findPr({
48
+ branchName: config.branchName,
49
+ state: "!open",
50
+ targetBranch: config.baseBranch
51
+ });
52
+ if (!oldPr) {
53
+ logger.debug("Branch has been edited but found no PR - skipping");
54
+ return null;
55
+ }
56
+ const branchSha = await scm.getBranchCommit(config.branchName);
57
+ const oldPrSha = oldPr.sha;
58
+ if (!oldPrSha || oldPrSha === branchSha) {
59
+ logger.debug({
60
+ oldPrNumber: oldPr.number,
61
+ oldPrSha,
62
+ branchSha
63
+ }, "Found old PR matching this branch - will override it");
64
+ return oldPr;
65
+ }
66
+ logger.debug({
67
+ oldPrNumber: oldPr.number,
68
+ oldPrSha,
69
+ branchSha
70
+ }, "Found old PR but the SHA is different");
71
+ return null;
72
+ }
73
+ /**
74
+ * Checks whether the user requested a rebase of the branch, either via the PR
75
+ * title, a PR label or the rebase checkbox in the PR body.
76
+ */
77
+ async function rebaseCheck(config, branchPr) {
78
+ if (branchPr.title?.startsWith("rebase!")) {
79
+ logger.debug(`Manual rebase requested via PR title for #${branchPr.number}`);
80
+ return true;
81
+ }
82
+ if (!!branchPr.labels?.includes(config.rebaseLabel)) {
83
+ logger.debug(`Manual rebase requested via PR labels for #${branchPr.number}`);
84
+ if (GlobalConfig.get("dryRun")) logger.info(`DRY-RUN: Would delete label ${config.rebaseLabel} from #${branchPr.number}`);
85
+ else await platform.deleteLabel(branchPr.number, config.rebaseLabel);
86
+ return true;
87
+ }
88
+ if (!!branchPr.bodyStruct?.rebaseRequested) {
89
+ logger.debug(`Manual rebase requested via PR checkbox for #${branchPr.number}`);
90
+ return true;
91
+ }
92
+ return false;
93
+ }
94
+ function userChangedTargetBranch(pr) {
95
+ const oldTargetBranch = pr.bodyStruct?.debugData?.targetBranch;
96
+ if (oldTargetBranch && pr.targetBranch) return pr.targetBranch !== oldTargetBranch;
97
+ return false;
98
+ }
39
99
  //#endregion
40
- export { prAlreadyExisted };
100
+ export { findClosedPrForModifiedBranch, prAlreadyExisted, rebaseCheck, userChangedTargetBranch };
41
101
 
42
102
  //# sourceMappingURL=check-existing.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"check-existing.js","names":[],"sources":["../../../../../lib/workers/repository/update/branch/check-existing.ts"],"sourcesContent":["// TODO #22198\nimport { REPOSITORY_CHANGED } from '../../../../constants/error-messages.ts';\nimport { logger } from '../../../../logger/index.ts';\nimport type { Pr } from '../../../../modules/platform/index.ts';\nimport { platform } from '../../../../modules/platform/index.ts';\nimport type { BranchConfig } from '../../../types.ts';\n\nexport async function prAlreadyExisted(\n config: BranchConfig,\n): Promise<Pr | null> {\n logger.trace({ config }, 'prAlreadyExisted');\n if (config.recreateClosed) {\n logger.debug('recreateClosed is true. No need to check for closed PR.');\n return null;\n }\n logger.debug(\n 'Check for closed PR because recreating closed PRs is disabled.',\n );\n // Return if same PR already existed\n let pr = await platform.findPr({\n branchName: config.branchName,\n prTitle: config.prTitle,\n state: '!open',\n targetBranch: config.baseBranch,\n });\n\n if (!pr && config.branchPrefix !== config.branchPrefixOld) {\n pr = await platform.findPr({\n branchName: config.branchName.replace(\n config.branchPrefix!,\n config.branchPrefixOld!,\n ),\n prTitle: config.prTitle,\n state: '!open',\n targetBranch: config.baseBranch,\n });\n if (pr) {\n logger.debug('Found closed PR with branchPrefixOld');\n }\n }\n\n if (pr) {\n logger.debug('Found closed PR with current title');\n const prDetails = await platform.getPr(pr.number);\n // istanbul ignore if\n if (prDetails!.state === 'open') {\n logger.debug('PR reopened - aborting run');\n throw new Error(REPOSITORY_CHANGED);\n }\n return pr;\n }\n logger.debug('prAlreadyExisted=false');\n return null;\n}\n"],"mappings":";;;;AAOA,eAAsB,iBACpB,QACoB;CACpB,OAAO,MAAM,EAAE,OAAO,GAAG,kBAAkB;CAC3C,IAAI,OAAO,gBAAgB;EACzB,OAAO,MAAM,yDAAyD;EACtE,OAAO;CACT;CACA,OAAO,MACL,gEACF;CAEA,IAAI,KAAK,MAAM,SAAS,OAAO;EAC7B,YAAY,OAAO;EACnB,SAAS,OAAO;EAChB,OAAO;EACP,cAAc,OAAO;CACvB,CAAC;CAED,IAAI,CAAC,MAAM,OAAO,iBAAiB,OAAO,iBAAiB;EACzD,KAAK,MAAM,SAAS,OAAO;GACzB,YAAY,OAAO,WAAW,QAC5B,OAAO,cACP,OAAO,eACT;GACA,SAAS,OAAO;GAChB,OAAO;GACP,cAAc,OAAO;EACvB,CAAC;EACD,IAAI,IACF,OAAO,MAAM,sCAAsC;CAEvD;CAEA,IAAI,IAAI;EACN,OAAO,MAAM,oCAAoC;;EAGjD,KAAI,MAFoB,SAAS,MAAM,GAAG,MAAM,EAAA,CAEjC,UAAU,QAAQ;GAC/B,OAAO,MAAM,4BAA4B;GACzC,MAAM,IAAI,MAAM,kBAAkB;EACpC;EACA,OAAO;CACT;CACA,OAAO,MAAM,wBAAwB;CACrC,OAAO;AACT"}
1
+ {"version":3,"file":"check-existing.js","names":[],"sources":["../../../../../lib/workers/repository/update/branch/check-existing.ts"],"sourcesContent":["// TODO #22198\nimport { GlobalConfig } from '../../../../config/global.ts';\nimport type { RenovateConfig } from '../../../../config/types.ts';\nimport { REPOSITORY_CHANGED } from '../../../../constants/error-messages.ts';\nimport { logger } from '../../../../logger/index.ts';\nimport type { Pr } from '../../../../modules/platform/index.ts';\nimport { platform } from '../../../../modules/platform/index.ts';\nimport { scm } from '../../../../modules/platform/scm.ts';\nimport type { BranchConfig } from '../../../types.ts';\n\nexport async function prAlreadyExisted(\n config: BranchConfig,\n): Promise<Pr | null> {\n logger.trace({ config }, 'prAlreadyExisted');\n if (config.recreateClosed) {\n logger.debug('recreateClosed is true. No need to check for closed PR.');\n return null;\n }\n logger.debug(\n 'Check for closed PR because recreating closed PRs is disabled.',\n );\n // Return if same PR already existed\n let pr = await platform.findPr({\n branchName: config.branchName,\n prTitle: config.prTitle,\n state: '!open',\n targetBranch: config.baseBranch,\n });\n\n if (!pr && config.branchPrefix !== config.branchPrefixOld) {\n pr = await platform.findPr({\n branchName: config.branchName.replace(\n config.branchPrefix!,\n config.branchPrefixOld!,\n ),\n prTitle: config.prTitle,\n state: '!open',\n targetBranch: config.baseBranch,\n });\n if (pr) {\n logger.debug('Found closed PR with branchPrefixOld');\n }\n }\n\n if (pr) {\n logger.debug('Found closed PR with current title');\n const prDetails = await platform.getPr(pr.number);\n // istanbul ignore if\n if (prDetails!.state === 'open') {\n logger.debug('PR reopened - aborting run');\n throw new Error(REPOSITORY_CHANGED);\n }\n return pr;\n }\n logger.debug('prAlreadyExisted=false');\n return null;\n}\n\n/**\n * Finds the closed PR which a modified branch without an open PR may still be\n * overridden from. Returns `null` if the branch must be left alone, either\n * because no closed PR matches it or because that PR points at another commit.\n */\nexport async function findClosedPrForModifiedBranch(\n config: BranchConfig,\n): Promise<Pr | null> {\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 null;\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 return oldPr;\n }\n logger.debug(\n { oldPrNumber: oldPr.number, oldPrSha, branchSha },\n 'Found old PR but the SHA is different',\n );\n return null;\n}\n\n/**\n * Checks whether the user requested a rebase of the branch, either via the PR\n * title, a PR label or the rebase checkbox in the PR body.\n */\nexport async 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 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\nexport function 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"],"mappings":";;;;;;AAUA,eAAsB,iBACpB,QACoB;CACpB,OAAO,MAAM,EAAE,OAAO,GAAG,kBAAkB;CAC3C,IAAI,OAAO,gBAAgB;EACzB,OAAO,MAAM,yDAAyD;EACtE,OAAO;CACT;CACA,OAAO,MACL,gEACF;CAEA,IAAI,KAAK,MAAM,SAAS,OAAO;EAC7B,YAAY,OAAO;EACnB,SAAS,OAAO;EAChB,OAAO;EACP,cAAc,OAAO;CACvB,CAAC;CAED,IAAI,CAAC,MAAM,OAAO,iBAAiB,OAAO,iBAAiB;EACzD,KAAK,MAAM,SAAS,OAAO;GACzB,YAAY,OAAO,WAAW,QAC5B,OAAO,cACP,OAAO,eACT;GACA,SAAS,OAAO;GAChB,OAAO;GACP,cAAc,OAAO;EACvB,CAAC;EACD,IAAI,IACF,OAAO,MAAM,sCAAsC;CAEvD;CAEA,IAAI,IAAI;EACN,OAAO,MAAM,oCAAoC;;EAGjD,KAAI,MAFoB,SAAS,MAAM,GAAG,MAAM,EAAA,CAEjC,UAAU,QAAQ;GAC/B,OAAO,MAAM,4BAA4B;GACzC,MAAM,IAAI,MAAM,kBAAkB;EACpC;EACA,OAAO;CACT;CACA,OAAO,MAAM,wBAAwB;CACrC,OAAO;AACT;;;;;;AAOA,eAAsB,8BACpB,QACoB;CACpB,MAAM,QAAQ,MAAM,SAAS,OAAO;EAClC,YAAY,OAAO;EACnB,OAAO;EACP,cAAc,OAAO;CACvB,CAAC;CACD,IAAI,CAAC,OAAO;EACV,OAAO,MAAM,mDAAmD;EAChE,OAAO;CACT;CACA,MAAM,YAAY,MAAM,IAAI,gBAAgB,OAAO,UAAU;CAC7D,MAAM,WAAW,MAAM;CACvB,IAAI,CAAC,YAAY,aAAa,WAAW;EACvC,OAAO,MACL;GAAE,aAAa,MAAM;GAAQ;GAAU;EAAU,GACjD,sDACF;EACA,OAAO;CACT;CACA,OAAO,MACL;EAAE,aAAa,MAAM;EAAQ;EAAU;CAAU,GACjD,uCACF;CACA,OAAO;AACT;;;;;AAMA,eAAsB,YACpB,QACA,UACkB;CAElB,IADoB,SAAS,OAAO,WAAW,SAAS,GACvC;EACf,OAAO,MACL,6CAA6C,SAAS,QACxD;EACA,OAAO;CACT;CAEA,IAAI,CADiB,CAAC,SAAS,QAAQ,SAAS,OAAO,WAAY,GAClD;EACf,OAAO,MACL,8CAA8C,SAAS,QACzD;EACA,IAAI,aAAa,IAAI,QAAQ,GAC3B,OAAO,KACL,+BAA+B,OAAO,YAAa,SACjD,SAAS,QAEb;OAEA,MAAM,SAAS,YAAY,SAAS,QAAQ,OAAO,WAAY;EAEjE,OAAO;CACT;CAEA,IAAI,CADqB,CAAC,SAAS,YAAY,iBAC1B;EACnB,OAAO,MACL,gDAAgD,SAAS,QAC3D;EACA,OAAO;CACT;CAEA,OAAO;AACT;AAEA,SAAgB,wBAAwB,IAAiB;CACvD,MAAM,kBAAkB,GAAG,YAAY,WAAW;CAClD,IAAI,mBAAmB,GAAG,cACxB,OAAO,GAAG,iBAAiB;CAE7B,OAAO;AACT"}
@@ -0,0 +1,90 @@
1
+ import { PLATFORM_AUTHENTICATION_ERROR, PLATFORM_BAD_CREDENTIALS, REPOSITORY_CHANGED, SYSTEM_INSUFFICIENT_DISK_SPACE } from "../../../../constants/error-messages.js";
2
+ import { logger } from "../../../../logger/index.js";
3
+ import { ExternalHostError } from "../../../../types/errors/external-host-error.js";
4
+ //#region lib/workers/repository/update/branch/errors.ts
5
+ /**
6
+ * Decides how an error thrown while updating a branch is handled: errors which
7
+ * must abort the run are (re)thrown, all others are mapped to a branch result
8
+ * so that the remaining branches can still be processed.
9
+ */
10
+ function handleBranchError(err, { branchExists, prNo, commitSha, updatesVerified }) {
11
+ if (err.statusCode === 404) {
12
+ logger.debug({ err }, "Received a 404 error - aborting run");
13
+ throw new Error(REPOSITORY_CHANGED);
14
+ }
15
+ if (err.message === "rate-limit-exceeded") {
16
+ logger.debug("Passing rate-limit-exceeded error up");
17
+ throw err;
18
+ }
19
+ if (err.message === "repository-changed") {
20
+ logger.debug("Passing repository-changed error up");
21
+ throw err;
22
+ }
23
+ if (err.message?.startsWith("remote: Invalid username or password")) {
24
+ logger.debug("Throwing bad credentials");
25
+ throw new Error(PLATFORM_BAD_CREDENTIALS);
26
+ }
27
+ if (err.message?.startsWith("ssh_exchange_identification: Connection closed by remote host")) {
28
+ logger.debug("Throwing bad credentials");
29
+ throw new Error(PLATFORM_BAD_CREDENTIALS);
30
+ }
31
+ if (err.message === "bad-credentials") {
32
+ logger.debug("Passing bad-credentials error up");
33
+ throw err;
34
+ }
35
+ if (err.message === "integration-unauthorized") {
36
+ logger.debug("Passing integration-unauthorized error up");
37
+ throw err;
38
+ }
39
+ if (err.message === "lockfile-error") {
40
+ logger.debug("Passing lockfile-error up");
41
+ throw err;
42
+ }
43
+ if (err.message === "pr-already-in-merge-queue") {
44
+ logger.debug("Branch PR is in the merge queue - skipping branch update");
45
+ return {
46
+ branchExists,
47
+ prNo,
48
+ result: "done",
49
+ commitSha
50
+ };
51
+ }
52
+ if (err.message?.includes("space left on device")) throw new Error(SYSTEM_INSUFFICIENT_DISK_SPACE);
53
+ if (err.message === "disk-space") {
54
+ logger.debug("Passing disk-space error up");
55
+ throw err;
56
+ }
57
+ if (err.message.startsWith("Resource not accessible by integration")) {
58
+ logger.debug("Passing 403 error up");
59
+ throw err;
60
+ }
61
+ if (err.message === "update-failure") logger.warn("Error updating branch: update failure");
62
+ else if (err.message.startsWith("bundler-")) return {
63
+ branchExists: true,
64
+ updatesVerified,
65
+ prNo,
66
+ result: "error",
67
+ commitSha
68
+ };
69
+ else if (err.message?.includes("fatal: Authentication failed")) throw new Error(PLATFORM_AUTHENTICATION_ERROR);
70
+ else if (err.message?.includes("fatal: bad revision")) {
71
+ logger.debug({ err }, "Aborting job due to bad revision error");
72
+ throw new Error(REPOSITORY_CHANGED);
73
+ } else if (err.message === "config-validation") {
74
+ logger.debug("Passing config validation error up");
75
+ throw err;
76
+ } else if (err.message === "temporary-error") {
77
+ logger.debug("Passing TEMPORARY_ERROR error up");
78
+ throw err;
79
+ } else if (!(err instanceof ExternalHostError)) logger.warn({ err }, `Error updating branch`);
80
+ return {
81
+ branchExists,
82
+ prNo,
83
+ result: "error",
84
+ commitSha
85
+ };
86
+ }
87
+ //#endregion
88
+ export { handleBranchError };
89
+
90
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","names":[],"sources":["../../../../../lib/workers/repository/update/branch/errors.ts"],"sourcesContent":["import {\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 } from '../../../../logger/index.ts';\nimport { ExternalHostError } from '../../../../types/errors/external-host-error.ts';\nimport type { ProcessBranchResult } from './types.ts';\n\nexport interface BranchErrorContext {\n branchExists: boolean;\n prNo?: number;\n commitSha: string | null;\n updatesVerified: boolean;\n}\n\n/**\n * Decides how an error thrown while updating a branch is handled: errors which\n * must abort the run are (re)thrown, all others are mapped to a branch result\n * so that the remaining branches can still be processed.\n */\nexport function handleBranchError(\n err: any,\n { branchExists, prNo, commitSha, updatesVerified }: BranchErrorContext,\n): ProcessBranchResult {\n if (err.statusCode === 404) {\n logger.debug({ err }, 'Received a 404 error - aborting run');\n throw new Error(REPOSITORY_CHANGED);\n }\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 if (err.message?.startsWith('remote: Invalid username or password')) {\n logger.debug('Throwing bad credentials');\n throw new Error(PLATFORM_BAD_CREDENTIALS);\n }\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 if (err.message === PLATFORM_BAD_CREDENTIALS) {\n logger.debug('Passing bad-credentials error up');\n throw err;\n }\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,\n result: 'done',\n commitSha,\n };\n }\n if (err.message?.includes('space left on device')) {\n throw new Error(SYSTEM_INSUFFICIENT_DISK_SPACE);\n }\n if (err.message === SYSTEM_INSUFFICIENT_DISK_SPACE) {\n logger.debug('Passing disk-space error up');\n throw err;\n }\n if (err.message.startsWith('Resource not accessible by integration')) {\n logger.debug('Passing 403 error up');\n throw err;\n }\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,\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,\n result: 'error',\n commitSha,\n };\n}\n"],"mappings":";;;;;;;;;AA6BA,SAAgB,kBACd,KACA,EAAE,cAAc,MAAM,WAAW,mBACZ;CACrB,IAAI,IAAI,eAAe,KAAK;EAC1B,OAAO,MAAM,EAAE,IAAI,GAAG,qCAAqC;EAC3D,MAAM,IAAI,MAAM,kBAAkB;CACpC;CACA,IAAI,IAAI,YAAA,uBAA0C;EAChD,OAAO,MAAM,sCAAsC;EACnD,MAAM;CACR;CACA,IAAI,IAAI,YAAA,sBAAgC;EACtC,OAAO,MAAM,qCAAqC;EAClD,MAAM;CACR;CACA,IAAI,IAAI,SAAS,WAAW,sCAAsC,GAAG;EACnE,OAAO,MAAM,0BAA0B;EACvC,MAAM,IAAI,MAAM,wBAAwB;CAC1C;CACA,IACE,IAAI,SAAS,WACX,+DACF,GACA;EACA,OAAO,MAAM,0BAA0B;EACvC,MAAM,IAAI,MAAM,wBAAwB;CAC1C;CACA,IAAI,IAAI,YAAA,mBAAsC;EAC5C,OAAO,MAAM,kCAAkC;EAC/C,MAAM;CACR;CACA,IAAI,IAAI,YAAA,4BAA+C;EACrD,OAAO,MAAM,2CAA2C;EACxD,MAAM;CACR;CACA,IAAI,IAAI,YAAA,kBAAoC;EAC1C,OAAO,MAAM,2BAA2B;EACxC,MAAM;CACR;CACA,IAAI,IAAI,YAAA,6BAAuC;EAC7C,OAAO,MAAM,0DAA0D;EACvE,OAAO;GACL;GACA;GACA,QAAQ;GACR;EACF;CACF;CACA,IAAI,IAAI,SAAS,SAAS,sBAAsB,GAC9C,MAAM,IAAI,MAAM,8BAA8B;CAEhD,IAAI,IAAI,YAAA,cAA4C;EAClD,OAAO,MAAM,6BAA6B;EAC1C,MAAM;CACR;CACA,IAAI,IAAI,QAAQ,WAAW,wCAAwC,GAAG;EACpE,OAAO,MAAM,sBAAsB;EACnC,MAAM;CACR;CACA,IAAI,IAAI,YAAA,kBACN,OAAO,KAAK,uCAAuC;MAC9C,IAAI,IAAI,QAAQ,WAAW,UAAU,GAE1C,OAAO;EACL,cAAc;EACd;EACA;EACA,QAAQ;EACR;CACF;MACK,IAAI,IAAI,SAAS,SAAS,8BAA8B,GAC7D,MAAM,IAAI,MAAM,6BAA6B;MACxC,IAAI,IAAI,SAAS,SAAS,qBAAqB,GAAG;EACvD,OAAO,MAAM,EAAE,IAAI,GAAG,wCAAwC;EAC9D,MAAM,IAAI,MAAM,kBAAkB;CACpC,OAAO,IAAI,IAAI,YAAA,qBAA+B;EAC5C,OAAO,MAAM,oCAAoC;EACjD,MAAM;CACR,OAAO,IAAI,IAAI,YAAA,mBAA6B;EAC1C,OAAO,MAAM,kCAAkC;EAC/C,MAAM;CACR,OAAO,IAAI,EAAE,eAAe,oBAC1B,OAAO,KAAK,EAAE,IAAI,GAAG,uBAAuB;CAG9C,OAAO;EACL;EACA;EACA,QAAQ;EACR;CACF;AACF"}
@@ -7,7 +7,7 @@ import { getFile } from "../../../../util/git/index.js";
7
7
  import { extractPackageFile, get } from "../../../../modules/manager/index.js";
8
8
  import { normalizeDepNames } from "../../extract/manager-files.js";
9
9
  import { doAutoReplace } from "./auto-replace.js";
10
- import { isNonEmptyArray } from "@sindresorhus/is";
10
+ import { isNonEmptyArray, isObject } from "@sindresorhus/is";
11
11
  //#region lib/workers/repository/update/branch/get-updated.ts
12
12
  async function getFileContent(updatedFileContents, filePath, config) {
13
13
  let fileContent = updatedFileContents[filePath];
@@ -205,12 +205,16 @@ async function getUpdatedPackageFiles(config) {
205
205
  }, "Could not autoReplace");
206
206
  throw new Error(WORKER_FILE_UPDATE_FAILED);
207
207
  }
208
- let newContent = await updateDependency({
208
+ const result = await updateDependency({
209
209
  packageFile,
210
210
  fileContent: packageFileContent,
211
211
  upgrade
212
212
  });
213
- newContent = await applyManagerBumpPackageVersion(newContent, upgrade);
213
+ const { content, updatedOutOfBand } = isObject(result) ? result : {
214
+ content: result,
215
+ updatedOutOfBand: false
216
+ };
217
+ const newContent = await applyManagerBumpPackageVersion(content, upgrade);
214
218
  if (!newContent) {
215
219
  if (reuseExistingBranch) {
216
220
  logger.debug({
@@ -242,8 +246,7 @@ async function getUpdatedPackageFiles(config) {
242
246
  logger.debug(`Updating ${depName} in ${coerceString(packageFile, lockFile)}`);
243
247
  updatedFileContents[packageFile] = newContent;
244
248
  delete nonUpdatedFileContents[packageFile];
245
- }
246
- if (newContent === packageFileContent && upgrade.manager === "git-submodules") {
249
+ } else if (updatedOutOfBand) {
247
250
  updatedFileContents[packageFile] = newContent;
248
251
  delete nonUpdatedFileContents[packageFile];
249
252
  }
@@ -1 +1 @@
1
- {"version":3,"file":"get-updated.js","names":[],"sources":["../../../../../lib/workers/repository/update/branch/get-updated.ts"],"sourcesContent":["import { isNonEmptyArray } from '@sindresorhus/is';\nimport { GlobalConfig } from '../../../../config/global.ts';\nimport { WORKER_FILE_UPDATE_FAILED } from '../../../../constants/error-messages.ts';\nimport { logger } from '../../../../logger/index.ts';\nimport { extractPackageFile, get } from '../../../../modules/manager/index.ts';\nimport type {\n ArtifactError,\n ArtifactNotice,\n PackageFile,\n UpdateArtifact,\n UpdateArtifactsConfig,\n UpdateArtifactsResult,\n} from '../../../../modules/manager/types.ts';\nimport { coerceArray } from '../../../../util/array.ts';\nimport { getFile } from '../../../../util/git/index.ts';\nimport type { FileAddition, FileChange } from '../../../../util/git/types.ts';\nimport { coerceString } from '../../../../util/string.ts';\nimport type { BranchConfig, BranchUpgradeConfig } from '../../../types.ts';\nimport { normalizeDepNames } from '../../extract/manager-files.ts';\nimport { doAutoReplace } from './auto-replace.ts';\n\nexport interface PackageFilesResult {\n artifactErrors: ArtifactError[];\n reuseExistingBranch?: boolean;\n updatedPackageFiles: FileChange[];\n updatedArtifacts: FileChange[];\n artifactNotices: ArtifactNotice[];\n}\n\nasync function getFileContent(\n updatedFileContents: Record<string, string>,\n filePath: string,\n config: BranchConfig,\n): Promise<string | null> {\n let fileContent: string | null = updatedFileContents[filePath];\n if (!fileContent) {\n fileContent = await getFile(\n filePath,\n config.reuseExistingBranch ? config.branchName : config.baseBranch,\n );\n }\n return fileContent;\n}\n\nfunction sortPackageFiles(\n config: BranchConfig,\n manager: string,\n packageFiles: FilePath[],\n): void {\n const managerPackageFiles = config.packageFiles?.[manager];\n if (!managerPackageFiles) {\n return;\n }\n packageFiles.sort((lhs, rhs) => {\n const lhsIndex = managerPackageFiles.findIndex(\n (entry) => entry.packageFile === lhs.path,\n );\n const rhsIndex = managerPackageFiles.findIndex(\n (entry) => entry.packageFile === rhs.path,\n );\n return lhsIndex - rhsIndex;\n });\n}\n\nfunction hasAny(set: Set<string>, targets: Iterable<string>): boolean {\n for (const target of targets) {\n if (set.has(target)) {\n return true;\n }\n }\n return false;\n}\n\nfunction getUpdatedLockFileContent(\n updatedDeps: BranchUpgradeConfig[],\n updatedFileContents: Record<string, string>,\n): string | undefined {\n for (const upgrade of updatedDeps) {\n const lockFiles = [upgrade.lockFile, ...coerceArray(upgrade.lockFiles)];\n for (const lockFile of lockFiles) {\n if (lockFile && updatedFileContents[lockFile] !== undefined) {\n return updatedFileContents[lockFile];\n }\n }\n }\n\n return undefined;\n}\n\nfunction removeUnrefreshedLockfileOnlyChanges(\n packageFiles: FileChange[],\n updatedDeps: BranchUpgradeConfig[],\n results: UpdateArtifactsResult[] | null,\n): string[] {\n const removedLockFiles: string[] = [];\n const refreshedFiles = new Set(\n coerceArray(results).flatMap((result) =>\n result.file ? [result.file.path] : [],\n ),\n );\n const lockFiles = new Set(\n updatedDeps\n .filter((upgrade) => upgrade.isLockfileOnly)\n .flatMap((upgrade) => [\n upgrade.lockFile,\n ...coerceArray(upgrade.lockFiles),\n ]),\n );\n for (let index = packageFiles.length - 1; index >= 0; index -= 1) {\n const path = packageFiles[index].path;\n if (lockFiles.has(path) && !refreshedFiles.has(path)) {\n packageFiles.splice(index, 1);\n removedLockFiles.push(path);\n }\n }\n return removedLockFiles;\n}\n\nfunction reportUnrefreshedLockfileOnlyChanges(\n removedLockFiles: string[],\n results: UpdateArtifactsResult[] | null,\n artifactErrors: ArtifactError[],\n): void {\n const artifactErrorFiles = new Set(\n coerceArray(results).flatMap((result) =>\n result.artifactError ? [result.artifactError.fileName] : [],\n ),\n );\n for (const lockFile of removedLockFiles) {\n if (!artifactErrorFiles.has(lockFile)) {\n artifactErrors.push({\n fileName: lockFile,\n stderr: 'Lockfile-only update could not be refreshed',\n });\n }\n }\n}\n\nfunction removeSupersededLockFileChanges(\n packageFiles: FileChange[],\n updatedDeps: BranchUpgradeConfig[],\n results: UpdateArtifactsResult[] | null,\n): void {\n const artifactFiles = new Set(\n coerceArray(results).flatMap((result) =>\n result.file ? [result.file.path] : [],\n ),\n );\n const lockFiles = new Set(\n updatedDeps\n .filter((upgrade) => upgrade.isLockfileOnly)\n .flatMap((upgrade) => [\n upgrade.lockFile,\n ...coerceArray(upgrade.lockFiles),\n ]),\n );\n for (let index = packageFiles.length - 1; index >= 0; index -= 1) {\n const path = packageFiles[index].path;\n if (lockFiles.has(path) && artifactFiles.has(path)) {\n packageFiles.splice(index, 1);\n }\n }\n}\n\ntype FilePath = Pick<FileChange, 'path'>;\n\nfunction getManagersForPackageFiles<T extends FilePath>(\n packageFiles: T[],\n managerPackageFiles: Record<string, Set<string>>,\n): Set<string> {\n const packageFileNames = packageFiles.map((packageFile) => packageFile.path);\n return new Set(\n Object.keys(managerPackageFiles).filter((manager) =>\n hasAny(managerPackageFiles[manager], packageFileNames),\n ),\n );\n}\n\nfunction getPackageFilesForManager<T extends FilePath>(\n packageFiles: T[],\n managerPackageFiles: Set<string>,\n): T[] {\n return packageFiles.filter((packageFile) =>\n managerPackageFiles.has(packageFile.path),\n );\n}\n\nexport async function getUpdatedPackageFiles(\n config: BranchConfig,\n): Promise<PackageFilesResult> {\n logger.trace({ config });\n const reuseExistingBranch = config.reuseExistingBranch!;\n logger.debug(\n `manager.getUpdatedPackageFiles() reuseExistingBranch=${reuseExistingBranch}`,\n );\n let updatedFileContents: Record<string, string> = {};\n const nonUpdatedFileContents: Record<string, string> = {};\n const managerPackageFiles: Record<string, Set<string>> = {};\n const packageFileUpdatedDeps: Record<string, BranchUpgradeConfig[]> = {};\n const lockFileMaintenanceFiles: string[] = [];\n let firstUpdate = true;\n for (const upgrade of config.upgrades) {\n const manager = upgrade.manager;\n const packageFile = upgrade.packageFile!;\n const depName = upgrade.depName!;\n // TODO: fix types, can be undefined (#22198)\n const newVersion = upgrade.newVersion!;\n const currentVersion = upgrade.currentVersion!;\n const updateLockedDependency = get(manager, 'updateLockedDependency')!;\n managerPackageFiles[manager] ??= new Set<string>();\n managerPackageFiles[manager].add(packageFile);\n packageFileUpdatedDeps[packageFile] ??= [];\n packageFileUpdatedDeps[packageFile].push({ ...upgrade });\n const packageFileContent = await getFileContent(\n updatedFileContents,\n packageFile,\n config,\n );\n let lockFileContent: string | null = null;\n const lockFile = upgrade.lockFile ?? upgrade.lockFiles?.[0] ?? '';\n if (lockFile) {\n lockFileContent = await getFileContent(\n updatedFileContents,\n lockFile,\n config,\n );\n }\n // istanbul ignore if\n if (\n reuseExistingBranch &&\n (!packageFileContent || (lockFile && !lockFileContent))\n ) {\n logger.debug(\n { packageFile, depName },\n 'Rebasing branch after file not found',\n );\n return getUpdatedPackageFiles({\n ...config,\n reuseExistingBranch: false,\n });\n }\n if (upgrade.updateType === 'lockFileMaintenance') {\n lockFileMaintenanceFiles.push(packageFile);\n } else if (upgrade.isRemediation) {\n const { status, files } = await updateLockedDependency({\n ...upgrade,\n depName,\n newVersion,\n currentVersion,\n packageFile,\n packageFileContent: packageFileContent!,\n lockFile,\n lockFileContent: lockFileContent!,\n allowParentUpdates: true,\n allowHigherOrRemoved: true,\n });\n if (reuseExistingBranch && status !== 'already-updated') {\n logger.debug(\n { lockFile, depName, status },\n 'Need to retry branch as it is not already up-to-date',\n );\n return getUpdatedPackageFiles({\n ...config,\n reuseExistingBranch: false,\n });\n }\n if (files) {\n updatedFileContents = { ...updatedFileContents, ...files };\n Object.keys(files).forEach(\n (file) => delete nonUpdatedFileContents[file],\n );\n }\n if (status === 'update-failed' || status === 'unsupported') {\n upgrade.remediationNotPossible = true;\n }\n } else if (upgrade.isLockfileUpdate) {\n if (updateLockedDependency) {\n const { status, files } = await updateLockedDependency({\n ...upgrade,\n depName,\n newVersion,\n currentVersion,\n packageFile,\n packageFileContent: packageFileContent!,\n lockFile,\n lockFileContent: lockFileContent!,\n allowParentUpdates: false,\n });\n if (status === 'unsupported') {\n // incompatible lock file\n if (!updatedFileContents[packageFile]) {\n nonUpdatedFileContents[packageFile] = packageFileContent!;\n }\n } else if (status === 'already-updated') {\n logger.debug(\n `Upgrade of ${depName} to ${newVersion} is already done in existing branch`,\n );\n } else {\n // something changed\n if (reuseExistingBranch) {\n logger.debug(\n { lockFile, depName, status },\n 'Need to retry branch as upgrade requirements are not mets',\n );\n return getUpdatedPackageFiles({\n ...config,\n reuseExistingBranch: false,\n });\n }\n if (files) {\n updatedFileContents = { ...updatedFileContents, ...files };\n Object.keys(files).forEach(\n (file) => delete nonUpdatedFileContents[file],\n );\n }\n }\n } else {\n logger.debug(\n { manager },\n 'isLockFileUpdate without updateLockedDependency',\n );\n if (!updatedFileContents[packageFile]) {\n nonUpdatedFileContents[packageFile] = packageFileContent!;\n }\n }\n } else {\n const updateDependency = get(manager, 'updateDependency');\n if (!updateDependency) {\n let res = await doAutoReplace(\n upgrade,\n packageFileContent!,\n reuseExistingBranch,\n firstUpdate,\n );\n firstUpdate = false;\n if (res) {\n res = await applyManagerBumpPackageVersion(res, upgrade);\n if (res === packageFileContent) {\n logger.debug({ packageFile, depName }, 'No content changed');\n } else {\n logger.debug({ packageFile, depName }, 'Contents updated');\n updatedFileContents[packageFile] = res!;\n delete nonUpdatedFileContents[packageFile];\n }\n continue;\n } else if (reuseExistingBranch) {\n return getUpdatedPackageFiles({\n ...config,\n reuseExistingBranch: false,\n });\n }\n logger.error({ packageFile, depName }, 'Could not autoReplace');\n throw new Error(WORKER_FILE_UPDATE_FAILED);\n }\n let newContent = await updateDependency({\n packageFile,\n fileContent: packageFileContent!,\n upgrade,\n });\n newContent = await applyManagerBumpPackageVersion(newContent, upgrade);\n if (!newContent) {\n if (reuseExistingBranch) {\n logger.debug(\n { packageFile, depName },\n 'Rebasing branch after error updating content',\n );\n return getUpdatedPackageFiles({\n ...config,\n reuseExistingBranch: false,\n });\n }\n logger.debug(\n { existingContent: packageFileContent, config: upgrade },\n 'Error updating file',\n );\n throw new Error(WORKER_FILE_UPDATE_FAILED);\n }\n if (newContent !== packageFileContent) {\n if (reuseExistingBranch) {\n // This ensure it's always 1 commit from Renovate\n logger.debug(\n { packageFile, depName },\n 'Need to update package file so will rebase first',\n );\n return getUpdatedPackageFiles({\n ...config,\n reuseExistingBranch: false,\n });\n }\n logger.debug(\n `Updating ${depName} in ${coerceString(packageFile, lockFile)}`,\n );\n updatedFileContents[packageFile] = newContent;\n delete nonUpdatedFileContents[packageFile];\n }\n if (\n newContent === packageFileContent &&\n upgrade.manager === 'git-submodules'\n ) {\n updatedFileContents[packageFile] = newContent;\n delete nonUpdatedFileContents[packageFile];\n }\n }\n }\n const updatedPackageFiles: FileAddition[] = Object.keys(\n updatedFileContents,\n ).map((name) => ({\n type: 'addition',\n path: name,\n contents: updatedFileContents[name],\n }));\n const updatedArtifacts: FileChange[] = [];\n const artifactErrors: ArtifactError[] = [];\n const artifactNotices: ArtifactNotice[] = [];\n if (isNonEmptyArray(updatedPackageFiles)) {\n logger.debug('updateArtifacts for updatedPackageFiles');\n const updatedPackageFileManagers = getManagersForPackageFiles(\n updatedPackageFiles,\n managerPackageFiles,\n );\n for (const manager of updatedPackageFileManagers) {\n const packageFilesForManager = getPackageFilesForManager(\n updatedPackageFiles,\n managerPackageFiles[manager],\n );\n sortPackageFiles(config, manager, packageFilesForManager);\n for (const packageFile of packageFilesForManager) {\n const updatedDeps = packageFileUpdatedDeps[packageFile.path];\n const results = await managerUpdateArtifacts(manager, {\n packageFileName: packageFile.path,\n updatedDeps,\n // TODO #22198\n newPackageFileContent: packageFile.contents!.toString(),\n newLockFileContent: getUpdatedLockFileContent(\n updatedDeps,\n updatedFileContents,\n ),\n config: patchConfigForArtifactsUpdate(\n config,\n manager,\n packageFile.path,\n ),\n });\n if (manager === 'mise') {\n const removedLockFiles = removeUnrefreshedLockfileOnlyChanges(\n updatedPackageFiles,\n updatedDeps,\n results,\n );\n reportUnrefreshedLockfileOnlyChanges(\n removedLockFiles,\n results,\n artifactErrors,\n );\n removeSupersededLockFileChanges(\n updatedPackageFiles,\n updatedDeps,\n results,\n );\n }\n processUpdateArtifactResults(\n results,\n updatedArtifacts,\n artifactErrors,\n artifactNotices,\n );\n if (isNonEmptyArray(results)) {\n await checkForPendingVersions(\n manager,\n packageFile.path,\n packageFile.contents!.toString(),\n updatedDeps,\n artifactErrors,\n config,\n );\n }\n }\n }\n }\n const nonUpdatedPackageFiles: FileAddition[] = Object.keys(\n nonUpdatedFileContents,\n ).map((name) => ({\n type: 'addition',\n path: name,\n contents: nonUpdatedFileContents[name],\n }));\n if (isNonEmptyArray(nonUpdatedPackageFiles)) {\n logger.debug('updateArtifacts for nonUpdatedPackageFiles');\n const nonUpdatedPackageFileManagers = getManagersForPackageFiles(\n nonUpdatedPackageFiles,\n managerPackageFiles,\n );\n for (const manager of nonUpdatedPackageFileManagers) {\n const packageFilesForManager = getPackageFilesForManager(\n nonUpdatedPackageFiles,\n managerPackageFiles[manager],\n );\n sortPackageFiles(config, manager, packageFilesForManager);\n for (const packageFile of packageFilesForManager) {\n const updatedDeps = packageFileUpdatedDeps[packageFile.path];\n const results = await managerUpdateArtifacts(manager, {\n packageFileName: packageFile.path,\n updatedDeps,\n // TODO #22198\n newPackageFileContent: packageFile.contents!.toString(),\n newLockFileContent: getUpdatedLockFileContent(\n updatedDeps,\n updatedFileContents,\n ),\n config: patchConfigForArtifactsUpdate(\n config,\n manager,\n packageFile.path,\n ),\n });\n processUpdateArtifactResults(\n results,\n updatedArtifacts,\n artifactErrors,\n artifactNotices,\n );\n if (isNonEmptyArray(results)) {\n updatedPackageFiles.push(packageFile);\n await checkForPendingVersions(\n manager,\n packageFile.path,\n packageFile.contents!.toString(),\n updatedDeps,\n artifactErrors,\n config,\n );\n }\n }\n }\n }\n if (!reuseExistingBranch) {\n const lockFileMaintenancePackageFiles: FilePath[] =\n lockFileMaintenanceFiles.map((name) => ({\n path: name,\n }));\n // Only perform lock file maintenance if it's a fresh commit\n if (isNonEmptyArray(lockFileMaintenanceFiles)) {\n logger.debug('updateArtifacts for lockFileMaintenanceFiles');\n const lockFileMaintenanceManagers = getManagersForPackageFiles(\n lockFileMaintenancePackageFiles,\n managerPackageFiles,\n );\n for (const manager of lockFileMaintenanceManagers) {\n const packageFilesForManager = getPackageFilesForManager(\n lockFileMaintenancePackageFiles,\n managerPackageFiles[manager],\n );\n sortPackageFiles(config, manager, packageFilesForManager);\n for (const packageFile of packageFilesForManager) {\n const contents =\n updatedFileContents[packageFile.path] ||\n (await getFile(packageFile.path, config.baseBranch));\n const results = await managerUpdateArtifacts(manager, {\n packageFileName: packageFile.path,\n updatedDeps: [],\n newPackageFileContent: contents!,\n config: patchConfigForArtifactsUpdate(\n config,\n manager,\n packageFile.path,\n ),\n });\n processUpdateArtifactResults(\n results,\n updatedArtifacts,\n artifactErrors,\n artifactNotices,\n );\n }\n }\n }\n }\n return {\n reuseExistingBranch, // Need to overwrite original config\n updatedPackageFiles,\n updatedArtifacts,\n artifactErrors,\n artifactNotices,\n };\n}\n\n// workaround, see #27319\nfunction patchConfigForArtifactsUpdate(\n config: BranchConfig,\n manager: string,\n packageFileName: string,\n): UpdateArtifactsConfig {\n // drop any lockFiles that happen to be defined on the branch config\n const updatedConfig = { ...config };\n delete updatedConfig.lockFiles;\n if (isNonEmptyArray(updatedConfig.packageFiles?.[manager])) {\n const managerPackageFiles: PackageFile[] =\n updatedConfig.packageFiles?.[manager];\n const packageFile = managerPackageFiles.find(\n (p) => p.packageFile === packageFileName,\n );\n if (packageFile && isNonEmptyArray(packageFile.lockFiles)) {\n updatedConfig.lockFiles = packageFile.lockFiles;\n }\n }\n return updatedConfig;\n}\n\nasync function managerUpdateArtifacts(\n manager: string,\n updateArtifact: UpdateArtifact,\n): Promise<UpdateArtifactsResult[] | null> {\n const updateArtifacts = get(manager, 'updateArtifacts');\n if (!updateArtifacts) {\n return null;\n }\n\n if (updateArtifact.config.skipArtifactsUpdate) {\n logger.debug(\n { manager, packageFileName: updateArtifact.packageFileName },\n 'Skipping artifact update',\n );\n return null;\n }\n\n return await updateArtifacts(updateArtifact);\n}\n\nfunction processUpdateArtifactResults(\n results: UpdateArtifactsResult[] | null,\n updatedArtifacts: FileChange[],\n artifactErrors: ArtifactError[],\n artifactNotices: ArtifactNotice[],\n): void {\n if (isNonEmptyArray(results)) {\n for (const res of results) {\n const { file, notice, artifactError } = res;\n if (file) {\n // several updateArtifacts() calls can return the same file, keep only the latest\n const existingIndex = updatedArtifacts.findIndex(\n (artifact) => artifact.path === file.path,\n );\n if (existingIndex === -1) {\n updatedArtifacts.push(file);\n } else {\n updatedArtifacts[existingIndex] = file;\n }\n }\n\n if (artifactError) {\n artifactErrors.push(artifactError);\n }\n\n if (notice) {\n artifactNotices.push(notice);\n }\n }\n }\n}\n\n/**\n * When using Minimum Release Age, and a package manager that doesn't support being told an explicit version to update to (#41624) it is possible that an artifact update leads to a different version of a dependency being used compared to what Renovate is expecting.\n *\n * We should report these cases more explicitly with an Artifact Error, to allow the reviewers to decide what to do with the changes.\n */\nasync function checkForPendingVersions(\n manager: string,\n packageFileName: string,\n packageFileContent: string,\n updatedDeps: BranchUpgradeConfig[],\n artifactErrors: ArtifactError[],\n config: BranchConfig,\n): Promise<void> {\n const depNameToUpgradeInfo = new Map<\n string,\n {\n pendingVersions: Set<string>;\n newVersion: string | undefined;\n }\n >();\n for (const dep of updatedDeps) {\n if (dep.depName && isNonEmptyArray(dep.pendingVersions)) {\n depNameToUpgradeInfo.set(dep.depName, {\n pendingVersions: new Set(dep.pendingVersions),\n newVersion: dep.newVersion,\n });\n }\n }\n if (!depNameToUpgradeInfo.size) {\n return;\n }\n\n const extracted = await extractPackageFile(\n manager,\n packageFileContent,\n packageFileName,\n config,\n );\n if (!extracted) {\n logger.warn(\n { packageFile: packageFileName, manager },\n 'Could not re-extract the packageFile after updating it',\n );\n return;\n }\n\n for (const dep of extracted.deps) {\n // the re-extracted deps have not been through the extract phase, so their names need normalizing before they can be matched against the upgrades\n normalizeDepNames(dep);\n const { depName } = dep;\n // shouldn't ever happen\n if (!depName) {\n logger.error(\n {\n packageFile: packageFileName,\n manager,\n branchName: config.branchName,\n depName: dep.depName,\n },\n 'No depName found after updating package file',\n );\n throw new Error(WORKER_FILE_UPDATE_FAILED);\n }\n\n const upgradeInfo = depNameToUpgradeInfo.get(depName);\n if (!upgradeInfo) {\n continue;\n }\n const resolvedVersion =\n dep.lockedVersion ??\n dep.newVersion ??\n dep.currentVersion ??\n dep.currentValue;\n if (!resolvedVersion) {\n logger.warn(\n {\n packageFile: packageFileName,\n manager,\n branchName: config.branchName,\n depName,\n },\n 'Could not determine resolved version after updating package file; skipping pending-version check',\n );\n continue;\n }\n\n if (resolvedVersion && upgradeInfo.pendingVersions.has(resolvedVersion)) {\n const expectedVersion = upgradeInfo.newVersion;\n /* v8 ignore next if -- should not happen */\n if (!expectedVersion) {\n logger.error(\n {\n packageFile: packageFileName,\n manager,\n branchName: config.branchName,\n depName,\n newVersion: resolvedVersion,\n expectedVersion,\n },\n 'No expectedVersion found after updating package file',\n );\n continue;\n }\n\n if (config.minimumReleaseAgeBehaviour === 'timestamp-optional') {\n logger.once.warn(\n {\n packageFileName,\n depName,\n expectedVersion,\n resolvedVersion,\n },\n \"Artifact error would be reported due to a pending version in use which hasn't passed Minimum Release Age, but as we're running with minimumReleaseAgeBehaviour=timestamp-optional, proceeding. See debug logs for more information\",\n );\n continue;\n }\n\n logger.debug(\n {\n packageFileName,\n depName,\n expectedVersion,\n resolvedVersion,\n },\n 'Artifact update introduced a pending version',\n );\n let stderr = `Artifact update for ${depName} resolved to version ${resolvedVersion}, which is a pending version that has not yet passed the Minimum Release Age threshold.`;\n stderr += `\\nRenovate was attempting to update to ${expectedVersion}`;\n stderr += `\\nThis is (likely) not a bug in Renovate, but due to the way your project pins dependencies, _and_ how Renovate calls your package manager to update them.\\nUntil Renovate supports specifying an exact update to your package manager (https://github.com/renovatebot/renovate/issues/41624), it is recommended to directly pin your dependencies (with \\`rangeStrategy=pin\\` for apps, or \\`rangeStrategy=widen\\` for libraries)\\nSee also: ${GlobalConfig.get('productLinks').documentation}dependency-pinning/`;\n\n artifactErrors.push({\n fileName: packageFileName,\n stderr,\n });\n }\n }\n}\n\nasync function applyManagerBumpPackageVersion(\n packageFileContent: string | null,\n upgrade: BranchUpgradeConfig,\n): Promise<string | null> {\n const bumpPackageVersion = get(upgrade.manager, 'bumpPackageVersion');\n if (\n !bumpPackageVersion ||\n !packageFileContent ||\n !upgrade.bumpVersion ||\n !upgrade.packageFileVersion\n ) {\n return packageFileContent;\n }\n\n const result = await bumpPackageVersion(\n packageFileContent,\n upgrade.packageFileVersion,\n upgrade.bumpVersion,\n upgrade.packageFile!,\n );\n\n return result.bumpedContent;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"get-updated.js","names":[],"sources":["../../../../../lib/workers/repository/update/branch/get-updated.ts"],"sourcesContent":["import { isNonEmptyArray, isObject } from '@sindresorhus/is';\nimport { GlobalConfig } from '../../../../config/global.ts';\nimport { WORKER_FILE_UPDATE_FAILED } from '../../../../constants/error-messages.ts';\nimport { logger } from '../../../../logger/index.ts';\nimport { extractPackageFile, get } from '../../../../modules/manager/index.ts';\nimport type {\n ArtifactError,\n ArtifactNotice,\n PackageFile,\n UpdateArtifact,\n UpdateArtifactsConfig,\n UpdateArtifactsResult,\n} from '../../../../modules/manager/types.ts';\nimport { coerceArray } from '../../../../util/array.ts';\nimport { getFile } from '../../../../util/git/index.ts';\nimport type { FileAddition, FileChange } from '../../../../util/git/types.ts';\nimport { coerceString } from '../../../../util/string.ts';\nimport type { BranchConfig, BranchUpgradeConfig } from '../../../types.ts';\nimport { normalizeDepNames } from '../../extract/manager-files.ts';\nimport { doAutoReplace } from './auto-replace.ts';\n\nexport interface PackageFilesResult {\n artifactErrors: ArtifactError[];\n reuseExistingBranch?: boolean;\n updatedPackageFiles: FileChange[];\n updatedArtifacts: FileChange[];\n artifactNotices: ArtifactNotice[];\n}\n\nasync function getFileContent(\n updatedFileContents: Record<string, string>,\n filePath: string,\n config: BranchConfig,\n): Promise<string | null> {\n let fileContent: string | null = updatedFileContents[filePath];\n if (!fileContent) {\n fileContent = await getFile(\n filePath,\n config.reuseExistingBranch ? config.branchName : config.baseBranch,\n );\n }\n return fileContent;\n}\n\nfunction sortPackageFiles(\n config: BranchConfig,\n manager: string,\n packageFiles: FilePath[],\n): void {\n const managerPackageFiles = config.packageFiles?.[manager];\n if (!managerPackageFiles) {\n return;\n }\n packageFiles.sort((lhs, rhs) => {\n const lhsIndex = managerPackageFiles.findIndex(\n (entry) => entry.packageFile === lhs.path,\n );\n const rhsIndex = managerPackageFiles.findIndex(\n (entry) => entry.packageFile === rhs.path,\n );\n return lhsIndex - rhsIndex;\n });\n}\n\nfunction hasAny(set: Set<string>, targets: Iterable<string>): boolean {\n for (const target of targets) {\n if (set.has(target)) {\n return true;\n }\n }\n return false;\n}\n\nfunction getUpdatedLockFileContent(\n updatedDeps: BranchUpgradeConfig[],\n updatedFileContents: Record<string, string>,\n): string | undefined {\n for (const upgrade of updatedDeps) {\n const lockFiles = [upgrade.lockFile, ...coerceArray(upgrade.lockFiles)];\n for (const lockFile of lockFiles) {\n if (lockFile && updatedFileContents[lockFile] !== undefined) {\n return updatedFileContents[lockFile];\n }\n }\n }\n\n return undefined;\n}\n\nfunction removeUnrefreshedLockfileOnlyChanges(\n packageFiles: FileChange[],\n updatedDeps: BranchUpgradeConfig[],\n results: UpdateArtifactsResult[] | null,\n): string[] {\n const removedLockFiles: string[] = [];\n const refreshedFiles = new Set(\n coerceArray(results).flatMap((result) =>\n result.file ? [result.file.path] : [],\n ),\n );\n const lockFiles = new Set(\n updatedDeps\n .filter((upgrade) => upgrade.isLockfileOnly)\n .flatMap((upgrade) => [\n upgrade.lockFile,\n ...coerceArray(upgrade.lockFiles),\n ]),\n );\n for (let index = packageFiles.length - 1; index >= 0; index -= 1) {\n const path = packageFiles[index].path;\n if (lockFiles.has(path) && !refreshedFiles.has(path)) {\n packageFiles.splice(index, 1);\n removedLockFiles.push(path);\n }\n }\n return removedLockFiles;\n}\n\nfunction reportUnrefreshedLockfileOnlyChanges(\n removedLockFiles: string[],\n results: UpdateArtifactsResult[] | null,\n artifactErrors: ArtifactError[],\n): void {\n const artifactErrorFiles = new Set(\n coerceArray(results).flatMap((result) =>\n result.artifactError ? [result.artifactError.fileName] : [],\n ),\n );\n for (const lockFile of removedLockFiles) {\n if (!artifactErrorFiles.has(lockFile)) {\n artifactErrors.push({\n fileName: lockFile,\n stderr: 'Lockfile-only update could not be refreshed',\n });\n }\n }\n}\n\nfunction removeSupersededLockFileChanges(\n packageFiles: FileChange[],\n updatedDeps: BranchUpgradeConfig[],\n results: UpdateArtifactsResult[] | null,\n): void {\n const artifactFiles = new Set(\n coerceArray(results).flatMap((result) =>\n result.file ? [result.file.path] : [],\n ),\n );\n const lockFiles = new Set(\n updatedDeps\n .filter((upgrade) => upgrade.isLockfileOnly)\n .flatMap((upgrade) => [\n upgrade.lockFile,\n ...coerceArray(upgrade.lockFiles),\n ]),\n );\n for (let index = packageFiles.length - 1; index >= 0; index -= 1) {\n const path = packageFiles[index].path;\n if (lockFiles.has(path) && artifactFiles.has(path)) {\n packageFiles.splice(index, 1);\n }\n }\n}\n\ntype FilePath = Pick<FileChange, 'path'>;\n\nfunction getManagersForPackageFiles<T extends FilePath>(\n packageFiles: T[],\n managerPackageFiles: Record<string, Set<string>>,\n): Set<string> {\n const packageFileNames = packageFiles.map((packageFile) => packageFile.path);\n return new Set(\n Object.keys(managerPackageFiles).filter((manager) =>\n hasAny(managerPackageFiles[manager], packageFileNames),\n ),\n );\n}\n\nfunction getPackageFilesForManager<T extends FilePath>(\n packageFiles: T[],\n managerPackageFiles: Set<string>,\n): T[] {\n return packageFiles.filter((packageFile) =>\n managerPackageFiles.has(packageFile.path),\n );\n}\n\nexport async function getUpdatedPackageFiles(\n config: BranchConfig,\n): Promise<PackageFilesResult> {\n logger.trace({ config });\n const reuseExistingBranch = config.reuseExistingBranch!;\n logger.debug(\n `manager.getUpdatedPackageFiles() reuseExistingBranch=${reuseExistingBranch}`,\n );\n let updatedFileContents: Record<string, string> = {};\n const nonUpdatedFileContents: Record<string, string> = {};\n const managerPackageFiles: Record<string, Set<string>> = {};\n const packageFileUpdatedDeps: Record<string, BranchUpgradeConfig[]> = {};\n const lockFileMaintenanceFiles: string[] = [];\n let firstUpdate = true;\n for (const upgrade of config.upgrades) {\n const manager = upgrade.manager;\n const packageFile = upgrade.packageFile!;\n const depName = upgrade.depName!;\n // TODO: fix types, can be undefined (#22198)\n const newVersion = upgrade.newVersion!;\n const currentVersion = upgrade.currentVersion!;\n const updateLockedDependency = get(manager, 'updateLockedDependency')!;\n managerPackageFiles[manager] ??= new Set<string>();\n managerPackageFiles[manager].add(packageFile);\n packageFileUpdatedDeps[packageFile] ??= [];\n packageFileUpdatedDeps[packageFile].push({ ...upgrade });\n const packageFileContent = await getFileContent(\n updatedFileContents,\n packageFile,\n config,\n );\n let lockFileContent: string | null = null;\n const lockFile = upgrade.lockFile ?? upgrade.lockFiles?.[0] ?? '';\n if (lockFile) {\n lockFileContent = await getFileContent(\n updatedFileContents,\n lockFile,\n config,\n );\n }\n // istanbul ignore if\n if (\n reuseExistingBranch &&\n (!packageFileContent || (lockFile && !lockFileContent))\n ) {\n logger.debug(\n { packageFile, depName },\n 'Rebasing branch after file not found',\n );\n return getUpdatedPackageFiles({\n ...config,\n reuseExistingBranch: false,\n });\n }\n if (upgrade.updateType === 'lockFileMaintenance') {\n lockFileMaintenanceFiles.push(packageFile);\n } else if (upgrade.isRemediation) {\n const { status, files } = await updateLockedDependency({\n ...upgrade,\n depName,\n newVersion,\n currentVersion,\n packageFile,\n packageFileContent: packageFileContent!,\n lockFile,\n lockFileContent: lockFileContent!,\n allowParentUpdates: true,\n allowHigherOrRemoved: true,\n });\n if (reuseExistingBranch && status !== 'already-updated') {\n logger.debug(\n { lockFile, depName, status },\n 'Need to retry branch as it is not already up-to-date',\n );\n return getUpdatedPackageFiles({\n ...config,\n reuseExistingBranch: false,\n });\n }\n if (files) {\n updatedFileContents = { ...updatedFileContents, ...files };\n Object.keys(files).forEach(\n (file) => delete nonUpdatedFileContents[file],\n );\n }\n if (status === 'update-failed' || status === 'unsupported') {\n upgrade.remediationNotPossible = true;\n }\n } else if (upgrade.isLockfileUpdate) {\n if (updateLockedDependency) {\n const { status, files } = await updateLockedDependency({\n ...upgrade,\n depName,\n newVersion,\n currentVersion,\n packageFile,\n packageFileContent: packageFileContent!,\n lockFile,\n lockFileContent: lockFileContent!,\n allowParentUpdates: false,\n });\n if (status === 'unsupported') {\n // incompatible lock file\n if (!updatedFileContents[packageFile]) {\n nonUpdatedFileContents[packageFile] = packageFileContent!;\n }\n } else if (status === 'already-updated') {\n logger.debug(\n `Upgrade of ${depName} to ${newVersion} is already done in existing branch`,\n );\n } else {\n // something changed\n if (reuseExistingBranch) {\n logger.debug(\n { lockFile, depName, status },\n 'Need to retry branch as upgrade requirements are not mets',\n );\n return getUpdatedPackageFiles({\n ...config,\n reuseExistingBranch: false,\n });\n }\n if (files) {\n updatedFileContents = { ...updatedFileContents, ...files };\n Object.keys(files).forEach(\n (file) => delete nonUpdatedFileContents[file],\n );\n }\n }\n } else {\n logger.debug(\n { manager },\n 'isLockFileUpdate without updateLockedDependency',\n );\n if (!updatedFileContents[packageFile]) {\n nonUpdatedFileContents[packageFile] = packageFileContent!;\n }\n }\n } else {\n const updateDependency = get(manager, 'updateDependency');\n if (!updateDependency) {\n let res = await doAutoReplace(\n upgrade,\n packageFileContent!,\n reuseExistingBranch,\n firstUpdate,\n );\n firstUpdate = false;\n if (res) {\n res = await applyManagerBumpPackageVersion(res, upgrade);\n if (res === packageFileContent) {\n logger.debug({ packageFile, depName }, 'No content changed');\n } else {\n logger.debug({ packageFile, depName }, 'Contents updated');\n updatedFileContents[packageFile] = res!;\n delete nonUpdatedFileContents[packageFile];\n }\n continue;\n } else if (reuseExistingBranch) {\n return getUpdatedPackageFiles({\n ...config,\n reuseExistingBranch: false,\n });\n }\n logger.error({ packageFile, depName }, 'Could not autoReplace');\n throw new Error(WORKER_FILE_UPDATE_FAILED);\n }\n const result = await updateDependency({\n packageFile,\n fileContent: packageFileContent!,\n upgrade,\n });\n const { content, updatedOutOfBand } = isObject(result)\n ? result\n : { content: result, updatedOutOfBand: false };\n const newContent = await applyManagerBumpPackageVersion(content, upgrade);\n if (!newContent) {\n if (reuseExistingBranch) {\n logger.debug(\n { packageFile, depName },\n 'Rebasing branch after error updating content',\n );\n return getUpdatedPackageFiles({\n ...config,\n reuseExistingBranch: false,\n });\n }\n logger.debug(\n { existingContent: packageFileContent, config: upgrade },\n 'Error updating file',\n );\n throw new Error(WORKER_FILE_UPDATE_FAILED);\n }\n if (newContent !== packageFileContent) {\n if (reuseExistingBranch) {\n // This ensure it's always 1 commit from Renovate\n logger.debug(\n { packageFile, depName },\n 'Need to update package file so will rebase first',\n );\n return getUpdatedPackageFiles({\n ...config,\n reuseExistingBranch: false,\n });\n }\n logger.debug(\n `Updating ${depName} in ${coerceString(packageFile, lockFile)}`,\n );\n updatedFileContents[packageFile] = newContent;\n delete nonUpdatedFileContents[packageFile];\n } else if (updatedOutOfBand) {\n updatedFileContents[packageFile] = newContent;\n delete nonUpdatedFileContents[packageFile];\n }\n }\n }\n const updatedPackageFiles: FileAddition[] = Object.keys(\n updatedFileContents,\n ).map((name) => ({\n type: 'addition',\n path: name,\n contents: updatedFileContents[name],\n }));\n const updatedArtifacts: FileChange[] = [];\n const artifactErrors: ArtifactError[] = [];\n const artifactNotices: ArtifactNotice[] = [];\n if (isNonEmptyArray(updatedPackageFiles)) {\n logger.debug('updateArtifacts for updatedPackageFiles');\n const updatedPackageFileManagers = getManagersForPackageFiles(\n updatedPackageFiles,\n managerPackageFiles,\n );\n for (const manager of updatedPackageFileManagers) {\n const packageFilesForManager = getPackageFilesForManager(\n updatedPackageFiles,\n managerPackageFiles[manager],\n );\n sortPackageFiles(config, manager, packageFilesForManager);\n for (const packageFile of packageFilesForManager) {\n const updatedDeps = packageFileUpdatedDeps[packageFile.path];\n const results = await managerUpdateArtifacts(manager, {\n packageFileName: packageFile.path,\n updatedDeps,\n // TODO #22198\n newPackageFileContent: packageFile.contents!.toString(),\n newLockFileContent: getUpdatedLockFileContent(\n updatedDeps,\n updatedFileContents,\n ),\n config: patchConfigForArtifactsUpdate(\n config,\n manager,\n packageFile.path,\n ),\n });\n if (manager === 'mise') {\n const removedLockFiles = removeUnrefreshedLockfileOnlyChanges(\n updatedPackageFiles,\n updatedDeps,\n results,\n );\n reportUnrefreshedLockfileOnlyChanges(\n removedLockFiles,\n results,\n artifactErrors,\n );\n removeSupersededLockFileChanges(\n updatedPackageFiles,\n updatedDeps,\n results,\n );\n }\n processUpdateArtifactResults(\n results,\n updatedArtifacts,\n artifactErrors,\n artifactNotices,\n );\n if (isNonEmptyArray(results)) {\n await checkForPendingVersions(\n manager,\n packageFile.path,\n packageFile.contents!.toString(),\n updatedDeps,\n artifactErrors,\n config,\n );\n }\n }\n }\n }\n const nonUpdatedPackageFiles: FileAddition[] = Object.keys(\n nonUpdatedFileContents,\n ).map((name) => ({\n type: 'addition',\n path: name,\n contents: nonUpdatedFileContents[name],\n }));\n if (isNonEmptyArray(nonUpdatedPackageFiles)) {\n logger.debug('updateArtifacts for nonUpdatedPackageFiles');\n const nonUpdatedPackageFileManagers = getManagersForPackageFiles(\n nonUpdatedPackageFiles,\n managerPackageFiles,\n );\n for (const manager of nonUpdatedPackageFileManagers) {\n const packageFilesForManager = getPackageFilesForManager(\n nonUpdatedPackageFiles,\n managerPackageFiles[manager],\n );\n sortPackageFiles(config, manager, packageFilesForManager);\n for (const packageFile of packageFilesForManager) {\n const updatedDeps = packageFileUpdatedDeps[packageFile.path];\n const results = await managerUpdateArtifacts(manager, {\n packageFileName: packageFile.path,\n updatedDeps,\n // TODO #22198\n newPackageFileContent: packageFile.contents!.toString(),\n newLockFileContent: getUpdatedLockFileContent(\n updatedDeps,\n updatedFileContents,\n ),\n config: patchConfigForArtifactsUpdate(\n config,\n manager,\n packageFile.path,\n ),\n });\n processUpdateArtifactResults(\n results,\n updatedArtifacts,\n artifactErrors,\n artifactNotices,\n );\n if (isNonEmptyArray(results)) {\n updatedPackageFiles.push(packageFile);\n await checkForPendingVersions(\n manager,\n packageFile.path,\n packageFile.contents!.toString(),\n updatedDeps,\n artifactErrors,\n config,\n );\n }\n }\n }\n }\n if (!reuseExistingBranch) {\n const lockFileMaintenancePackageFiles: FilePath[] =\n lockFileMaintenanceFiles.map((name) => ({\n path: name,\n }));\n // Only perform lock file maintenance if it's a fresh commit\n if (isNonEmptyArray(lockFileMaintenanceFiles)) {\n logger.debug('updateArtifacts for lockFileMaintenanceFiles');\n const lockFileMaintenanceManagers = getManagersForPackageFiles(\n lockFileMaintenancePackageFiles,\n managerPackageFiles,\n );\n for (const manager of lockFileMaintenanceManagers) {\n const packageFilesForManager = getPackageFilesForManager(\n lockFileMaintenancePackageFiles,\n managerPackageFiles[manager],\n );\n sortPackageFiles(config, manager, packageFilesForManager);\n for (const packageFile of packageFilesForManager) {\n const contents =\n updatedFileContents[packageFile.path] ||\n (await getFile(packageFile.path, config.baseBranch));\n const results = await managerUpdateArtifacts(manager, {\n packageFileName: packageFile.path,\n updatedDeps: [],\n newPackageFileContent: contents!,\n config: patchConfigForArtifactsUpdate(\n config,\n manager,\n packageFile.path,\n ),\n });\n processUpdateArtifactResults(\n results,\n updatedArtifacts,\n artifactErrors,\n artifactNotices,\n );\n }\n }\n }\n }\n return {\n reuseExistingBranch, // Need to overwrite original config\n updatedPackageFiles,\n updatedArtifacts,\n artifactErrors,\n artifactNotices,\n };\n}\n\n// workaround, see #27319\nfunction patchConfigForArtifactsUpdate(\n config: BranchConfig,\n manager: string,\n packageFileName: string,\n): UpdateArtifactsConfig {\n // drop any lockFiles that happen to be defined on the branch config\n const updatedConfig = { ...config };\n delete updatedConfig.lockFiles;\n if (isNonEmptyArray(updatedConfig.packageFiles?.[manager])) {\n const managerPackageFiles: PackageFile[] =\n updatedConfig.packageFiles?.[manager];\n const packageFile = managerPackageFiles.find(\n (p) => p.packageFile === packageFileName,\n );\n if (packageFile && isNonEmptyArray(packageFile.lockFiles)) {\n updatedConfig.lockFiles = packageFile.lockFiles;\n }\n }\n return updatedConfig;\n}\n\nasync function managerUpdateArtifacts(\n manager: string,\n updateArtifact: UpdateArtifact,\n): Promise<UpdateArtifactsResult[] | null> {\n const updateArtifacts = get(manager, 'updateArtifacts');\n if (!updateArtifacts) {\n return null;\n }\n\n if (updateArtifact.config.skipArtifactsUpdate) {\n logger.debug(\n { manager, packageFileName: updateArtifact.packageFileName },\n 'Skipping artifact update',\n );\n return null;\n }\n\n return await updateArtifacts(updateArtifact);\n}\n\nfunction processUpdateArtifactResults(\n results: UpdateArtifactsResult[] | null,\n updatedArtifacts: FileChange[],\n artifactErrors: ArtifactError[],\n artifactNotices: ArtifactNotice[],\n): void {\n if (isNonEmptyArray(results)) {\n for (const res of results) {\n const { file, notice, artifactError } = res;\n if (file) {\n // several updateArtifacts() calls can return the same file, keep only the latest\n const existingIndex = updatedArtifacts.findIndex(\n (artifact) => artifact.path === file.path,\n );\n if (existingIndex === -1) {\n updatedArtifacts.push(file);\n } else {\n updatedArtifacts[existingIndex] = file;\n }\n }\n\n if (artifactError) {\n artifactErrors.push(artifactError);\n }\n\n if (notice) {\n artifactNotices.push(notice);\n }\n }\n }\n}\n\n/**\n * When using Minimum Release Age, and a package manager that doesn't support being told an explicit version to update to (#41624) it is possible that an artifact update leads to a different version of a dependency being used compared to what Renovate is expecting.\n *\n * We should report these cases more explicitly with an Artifact Error, to allow the reviewers to decide what to do with the changes.\n */\nasync function checkForPendingVersions(\n manager: string,\n packageFileName: string,\n packageFileContent: string,\n updatedDeps: BranchUpgradeConfig[],\n artifactErrors: ArtifactError[],\n config: BranchConfig,\n): Promise<void> {\n const depNameToUpgradeInfo = new Map<\n string,\n {\n pendingVersions: Set<string>;\n newVersion: string | undefined;\n }\n >();\n for (const dep of updatedDeps) {\n if (dep.depName && isNonEmptyArray(dep.pendingVersions)) {\n depNameToUpgradeInfo.set(dep.depName, {\n pendingVersions: new Set(dep.pendingVersions),\n newVersion: dep.newVersion,\n });\n }\n }\n if (!depNameToUpgradeInfo.size) {\n return;\n }\n\n const extracted = await extractPackageFile(\n manager,\n packageFileContent,\n packageFileName,\n config,\n );\n if (!extracted) {\n logger.warn(\n { packageFile: packageFileName, manager },\n 'Could not re-extract the packageFile after updating it',\n );\n return;\n }\n\n for (const dep of extracted.deps) {\n // the re-extracted deps have not been through the extract phase, so their names need normalizing before they can be matched against the upgrades\n normalizeDepNames(dep);\n const { depName } = dep;\n // shouldn't ever happen\n if (!depName) {\n logger.error(\n {\n packageFile: packageFileName,\n manager,\n branchName: config.branchName,\n depName: dep.depName,\n },\n 'No depName found after updating package file',\n );\n throw new Error(WORKER_FILE_UPDATE_FAILED);\n }\n\n const upgradeInfo = depNameToUpgradeInfo.get(depName);\n if (!upgradeInfo) {\n continue;\n }\n const resolvedVersion =\n dep.lockedVersion ??\n dep.newVersion ??\n dep.currentVersion ??\n dep.currentValue;\n if (!resolvedVersion) {\n logger.warn(\n {\n packageFile: packageFileName,\n manager,\n branchName: config.branchName,\n depName,\n },\n 'Could not determine resolved version after updating package file; skipping pending-version check',\n );\n continue;\n }\n\n if (resolvedVersion && upgradeInfo.pendingVersions.has(resolvedVersion)) {\n const expectedVersion = upgradeInfo.newVersion;\n /* v8 ignore next if -- should not happen */\n if (!expectedVersion) {\n logger.error(\n {\n packageFile: packageFileName,\n manager,\n branchName: config.branchName,\n depName,\n newVersion: resolvedVersion,\n expectedVersion,\n },\n 'No expectedVersion found after updating package file',\n );\n continue;\n }\n\n if (config.minimumReleaseAgeBehaviour === 'timestamp-optional') {\n logger.once.warn(\n {\n packageFileName,\n depName,\n expectedVersion,\n resolvedVersion,\n },\n \"Artifact error would be reported due to a pending version in use which hasn't passed Minimum Release Age, but as we're running with minimumReleaseAgeBehaviour=timestamp-optional, proceeding. See debug logs for more information\",\n );\n continue;\n }\n\n logger.debug(\n {\n packageFileName,\n depName,\n expectedVersion,\n resolvedVersion,\n },\n 'Artifact update introduced a pending version',\n );\n let stderr = `Artifact update for ${depName} resolved to version ${resolvedVersion}, which is a pending version that has not yet passed the Minimum Release Age threshold.`;\n stderr += `\\nRenovate was attempting to update to ${expectedVersion}`;\n stderr += `\\nThis is (likely) not a bug in Renovate, but due to the way your project pins dependencies, _and_ how Renovate calls your package manager to update them.\\nUntil Renovate supports specifying an exact update to your package manager (https://github.com/renovatebot/renovate/issues/41624), it is recommended to directly pin your dependencies (with \\`rangeStrategy=pin\\` for apps, or \\`rangeStrategy=widen\\` for libraries)\\nSee also: ${GlobalConfig.get('productLinks').documentation}dependency-pinning/`;\n\n artifactErrors.push({\n fileName: packageFileName,\n stderr,\n });\n }\n }\n}\n\nasync function applyManagerBumpPackageVersion(\n packageFileContent: string | null,\n upgrade: BranchUpgradeConfig,\n): Promise<string | null> {\n const bumpPackageVersion = get(upgrade.manager, 'bumpPackageVersion');\n if (\n !bumpPackageVersion ||\n !packageFileContent ||\n !upgrade.bumpVersion ||\n !upgrade.packageFileVersion\n ) {\n return packageFileContent;\n }\n\n const result = await bumpPackageVersion(\n packageFileContent,\n upgrade.packageFileVersion,\n upgrade.bumpVersion,\n upgrade.packageFile!,\n );\n\n return result.bumpedContent;\n}\n"],"mappings":"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"}