renovate 44.95.0 → 44.96.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/dist/config/options/index.js +6 -0
  2. package/dist/config/options/index.js.map +1 -1
  3. package/dist/config/types.d.ts +1 -0
  4. package/dist/config/types.js.map +1 -1
  5. package/dist/modules/manager/dockerfile/apk.js +176 -0
  6. package/dist/modules/manager/dockerfile/apk.js.map +1 -0
  7. package/dist/modules/manager/dockerfile/dep-types.js +4 -0
  8. package/dist/modules/manager/dockerfile/dep-types.js.map +1 -1
  9. package/dist/modules/manager/dockerfile/extract.js +5 -0
  10. package/dist/modules/manager/dockerfile/extract.js.map +1 -1
  11. package/dist/modules/manager/dockerfile/index.js +2 -1
  12. package/dist/modules/manager/dockerfile/index.js.map +1 -1
  13. package/dist/modules/manager/fingerprint.generated.js +1 -1
  14. package/dist/modules/manager/fingerprint.generated.js.map +1 -1
  15. package/dist/modules/platform/github/index.js +4 -0
  16. package/dist/modules/platform/github/index.js.map +1 -1
  17. package/dist/modules/versioning/conda/index.js +3 -1
  18. package/dist/modules/versioning/conda/index.js.map +1 -1
  19. package/dist/modules/versioning/index.js +2 -1
  20. package/dist/modules/versioning/index.js.map +1 -1
  21. package/dist/modules/versioning/ruby/version.js +1 -0
  22. package/dist/modules/versioning/ruby/version.js.map +1 -1
  23. package/dist/util/minimum-release-age.js +14 -3
  24. package/dist/util/minimum-release-age.js.map +1 -1
  25. package/dist/workers/repository/config-migration/branch/rebase.js +1 -0
  26. package/dist/workers/repository/config-migration/branch/rebase.js.map +1 -1
  27. package/dist/workers/repository/index.js +1 -0
  28. package/dist/workers/repository/index.js.map +1 -1
  29. package/dist/workers/repository/init/merge.js +1 -0
  30. package/dist/workers/repository/init/merge.js.map +1 -1
  31. package/dist/workers/repository/onboarding/pr/pr-list.js +2 -3
  32. package/dist/workers/repository/onboarding/pr/pr-list.js.map +1 -1
  33. package/dist/workers/repository/reconfigure/index.js +1 -3
  34. package/dist/workers/repository/reconfigure/index.js.map +1 -1
  35. package/dist/workers/repository/update/branch/index.js +2 -3
  36. package/dist/workers/repository/update/branch/index.js.map +1 -1
  37. package/dist/workers/repository/update/pr/changelog/release-notes.js +3 -1
  38. package/dist/workers/repository/update/pr/changelog/release-notes.js.map +1 -1
  39. package/dist/workers/repository/update/pr/changelog/source.js +1 -0
  40. package/dist/workers/repository/update/pr/changelog/source.js.map +1 -1
  41. package/dist/workers/repository/updates/flatten.js +1 -1
  42. package/dist/workers/repository/updates/flatten.js.map +1 -1
  43. package/package.json +1 -1
  44. package/renovate-schema.json +11 -2
@@ -1 +1 @@
1
- {"version":3,"file":"release-notes.js","names":["bitbucket.getReleaseList","forgejo.getReleaseList","gitea.getReleaseList","github.getReleaseList","gitlab.getReleaseList","memCache.get","bitbucket.getReleaseNotesMd","bitbucketServer.getReleaseNotesMd","forgejo.getReleaseNotesMd","gitea.getReleaseNotesMd","github.getReleaseNotesMd","gitlab.getReleaseNotesMd","packageCache.get","packageCache.set"],"sources":["../../../../../../lib/workers/repository/update/pr/changelog/release-notes.ts"],"sourcesContent":["import {\n isDate,\n isNonEmptyString,\n isTruthy,\n isUndefined,\n} from '@sindresorhus/is';\nimport { DateTime } from 'luxon';\nimport MarkdownIt from 'markdown-it';\nimport { instrument } from '../../../../../instrumentation/index.ts';\nimport { logger } from '../../../../../logger/index.ts';\nimport { platform } from '../../../../../modules/platform/index.ts';\nimport * as memCache from '../../../../../util/cache/memory/index.ts';\nimport * as packageCache from '../../../../../util/cache/package/index.ts';\nimport type { PackageCacheNamespace } from '../../../../../util/cache/package/types.ts';\nimport { detectPlatform } from '../../../../../util/common.ts';\nimport { linkify } from '../../../../../util/markdown.ts';\nimport { newlineRegex, regEx } from '../../../../../util/regex.ts';\nimport { coerceString } from '../../../../../util/string.ts';\nimport { isHttpUrl } from '../../../../../util/url.ts';\nimport type { BranchUpgradeConfig } from '../../../../types.ts';\nimport * as bitbucket from './bitbucket/index.ts';\nimport * as bitbucketServer from './bitbucket-server/index.ts';\nimport * as forgejo from './forgejo/index.ts';\nimport * as gitea from './gitea/index.ts';\nimport * as github from './github/index.ts';\nimport * as gitlab from './gitlab/index.ts';\nimport type { ChangeLogSource } from './source.ts';\nimport type {\n ChangeLogFile,\n ChangeLogNotes,\n ChangeLogProject,\n ChangeLogRelease,\n ChangeLogResult,\n} from './types.ts';\n\nconst markdown = new MarkdownIt('zero');\nmarkdown.enable(['heading', 'lheading', 'fence']);\n\nconst repositoriesToSkipMdFetching = [\n 'facebook/react-native',\n 'react/react-native',\n];\n\n// Per the OCI distribution reference grammar a leading path segment is a host\n// when it contains a `.` or a `:`. Go module paths are qualified the same way.\nconst hostQualifiedNameRegex = regEx(\n /^(?:localhost(?::\\d+)?|[^/]+[.:][^/]*)\\/(?<unqualifiedName>.+)$/,\n);\n\nexport async function getReleaseList(\n project: ChangeLogProject,\n release: ChangeLogRelease,\n): Promise<ChangeLogNotes[]> {\n logger.trace('getReleaseList()');\n const { apiBaseUrl, repository, type } = project;\n try {\n switch (type) {\n case 'bitbucket':\n return bitbucket.getReleaseList(project, release);\n case 'bitbucket-server':\n logger.trace(\n 'Unsupported Bitbucket Server feature. Skipping release fetching.',\n );\n return [];\n case 'forgejo':\n return await forgejo.getReleaseList(project, release);\n case 'gitea':\n return await gitea.getReleaseList(project, release);\n case 'github':\n return await github.getReleaseList(project, release);\n case 'gitlab':\n return await gitlab.getReleaseList(project, release);\n default:\n logger.warn({ apiBaseUrl, repository, type }, 'Invalid project type');\n return [];\n }\n } catch (err) /* istanbul ignore next */ {\n if (err.statusCode === 404) {\n logger.debug({ repository, type, apiBaseUrl }, 'getReleaseList 404');\n } else {\n logger.debug(\n { repository, type, apiBaseUrl, err },\n 'getReleaseList error',\n );\n }\n }\n return [];\n}\n\nexport function getCachedReleaseList(\n project: ChangeLogProject,\n release: ChangeLogRelease,\n): Promise<ChangeLogNotes[]> {\n const { repository, apiBaseUrl } = project;\n // TODO: types (#22198)\n const cacheKey = `getReleaseList-${apiBaseUrl}-${repository}`;\n const cachedResult = memCache.get<Promise<ChangeLogNotes[]>>(cacheKey);\n // istanbul ignore if\n if (cachedResult !== undefined) {\n return cachedResult;\n }\n const promisedRes = getReleaseList(project, release);\n memCache.set(cacheKey, promisedRes);\n return promisedRes;\n}\n\nexport function massageBody(\n input: string | undefined | null,\n baseUrl: string,\n): string {\n let body = coerceString(input);\n // Convert line returns\n body = body.replace(regEx(/\\r\\n/g), '\\n');\n // semantic-release cleanup\n body = body.replace(regEx(/^<a name=\"[^\"]*\"><\\/a>\\n/), '');\n body = body.replace(\n regEx(\n `^##? \\\\[[^\\\\]]*\\\\]\\\\(${baseUrl}[^/]*/[^/]*/compare/.*?\\\\n`,\n undefined,\n false,\n ),\n '',\n );\n // Clean-up unnecessary commits link\n body = `\\n${body}\\n`.replace(\n regEx(`\\\\n${baseUrl}[^/]+/[^/]+/compare/[^\\\\n]+(\\\\n|$)`),\n '\\n',\n );\n // Reduce headings size\n body = body\n .split(regEx(/(?<codeBlock>```[\\s\\S]*?```)/g))\n .map((part) =>\n part.startsWith('```') // do not modify # inside of codeblocks\n ? part\n : part\n .replace(regEx(/\\n\\s*####? /g), '\\n##### ')\n .replace(regEx(/\\n\\s*## /g), '\\n#### ')\n .replace(regEx(/\\n\\s*# /g), '\\n### '),\n )\n .join('');\n // Trim whitespace\n return body.trim();\n}\n\nexport function massageName(\n input: string | undefined | null,\n version: string | undefined,\n): string | undefined {\n let name = input ?? '';\n\n if (version) {\n name = name.replace(RegExp(`^(Release )?v?${version}`, 'i'), '').trim();\n }\n\n name = name.trim();\n if (!name.length) {\n return undefined;\n }\n\n return name;\n}\n\nexport async function getReleaseNotes(\n project: ChangeLogProject,\n release: ChangeLogRelease,\n config: BranchUpgradeConfig,\n): Promise<ChangeLogNotes | null> {\n return await instrument('getReleaseNotes', async () => {\n const { packageName, depName, repository } = project;\n const { version, gitRef } = release;\n // TODO: types (#22198)\n logger.trace(\n `getReleaseNotes(${repository}, ${version}, ${packageName!}, ${depName!})`,\n );\n const releases = await getCachedReleaseList(project, release);\n logger.trace({ releases }, 'Release list from getReleaseList');\n let releaseNotes: ChangeLogNotes | null = null;\n\n let matchedRelease = getExactReleaseMatch(\n packageName,\n depName,\n version,\n releases,\n );\n if (isUndefined(matchedRelease)) {\n // no exact match of a release then check other cases\n matchedRelease = releases.find(\n (r) =>\n r.tag === version ||\n r.tag === `v${version}` ||\n r.tag === gitRef ||\n r.tag === `v${gitRef}`,\n );\n }\n if (isUndefined(matchedRelease) && config.extractVersion) {\n const extractVersionRegEx = regEx(config.extractVersion);\n matchedRelease = releases.find((r) => {\n const extractedVersion = extractVersionRegEx.exec(r.tag!)?.groups\n ?.version;\n return version === extractedVersion;\n });\n }\n releaseNotes = await releaseNotesResult(matchedRelease, project);\n logger.trace({ releaseNotes });\n return releaseNotes;\n });\n}\n\nfunction getExactReleaseMatch(\n packageName: string | undefined,\n depName: string | undefined,\n version: string,\n releases: ChangeLogNotes[],\n): ChangeLogNotes | undefined {\n const namePatterns = getNamePatterns(packageName, depName);\n if (!namePatterns.length) {\n return undefined;\n }\n\n const exactReleaseReg = regEx(\n `(?:^|/)(?:${namePatterns.join('|')})[@_/-]v?${RegExp.escape(version)}`,\n );\n const candidateReleases = releases.filter((r) => r.tag?.endsWith(version));\n const matchedRelease = candidateReleases.find((r) =>\n exactReleaseReg.test(r.tag!),\n );\n return matchedRelease;\n}\n\n/**\n * A registry host never appears in a Git tag, so a host-qualified name such as\n * an OCI chart `<registry>/<org>/<repo>/<chart>` can never match the tag that\n * publishes it, which is scoped by the chart name alone: `<chart>-<version>`.\n * For those names, also match against the name with its host stripped, and\n * against the trailing path segment alone. Names that are not host-qualified,\n * such as scoped npm packages, keep matching in full only, so their tag\n * prefixes stay as specific as they are today.\n */\nfunction getNamePatterns(\n packageName: string | undefined,\n depName: string | undefined,\n): string[] {\n const names = new Set<string>();\n for (const name of [packageName, depName]) {\n if (!isNonEmptyString(name)) {\n continue;\n }\n names.add(name);\n\n const unqualifiedName =\n hostQualifiedNameRegex.exec(name)?.groups?.unqualifiedName;\n if (isNonEmptyString(unqualifiedName)) {\n names.add(unqualifiedName);\n\n const trailingName = unqualifiedName.split('/').pop();\n if (isNonEmptyString(trailingName)) {\n names.add(trailingName);\n }\n }\n }\n return [...names].map((name) => RegExp.escape(name));\n}\n\nasync function releaseNotesResult(\n releaseMatch: ChangeLogNotes | undefined,\n project: ChangeLogProject,\n): Promise<ChangeLogNotes | null> {\n if (!releaseMatch) {\n return null;\n }\n const { baseUrl, repository } = project;\n const releaseNotes: ChangeLogNotes = releaseMatch;\n if (detectPlatform(baseUrl) === 'gitlab') {\n releaseNotes.url = `${baseUrl}${repository}/tags/${releaseMatch.tag!}`;\n } else {\n releaseNotes.url = releaseMatch.url\n ? releaseMatch.url\n : /* istanbul ignore next */\n `${baseUrl}${repository}/releases/${releaseMatch.tag!}`;\n }\n // set body for release notes\n releaseNotes.body = massageBody(releaseNotes.body, baseUrl);\n releaseNotes.name = massageName(releaseNotes.name, releaseNotes.tag);\n if (releaseNotes.body.length || releaseNotes.name?.length) {\n try {\n if (baseUrl !== 'https://gitlab.com/') {\n releaseNotes.body = await linkify(releaseNotes.body, {\n repository: `${baseUrl}${repository}`,\n });\n }\n } catch (err) /* istanbul ignore next */ {\n logger.warn({ err, baseUrl, repository }, 'Error linkifying');\n }\n } else {\n return null;\n }\n\n return releaseNotes;\n}\n\nfunction sectionize(text: string, level: number): string[] {\n const sections: [number, number][] = [];\n const lines = text.split(newlineRegex);\n const tokens = markdown.parse(text, {});\n tokens.forEach((token) => {\n if (token.type === 'heading_open') {\n const lev = +token.tag.substring(1);\n if (lev <= level) {\n sections.push([lev, token.map![0]]);\n }\n }\n });\n sections.push([-1, lines.length]);\n const result: string[] = [];\n for (let i = 1; i < sections.length; i += 1) {\n const [lev, start] = sections[i - 1];\n const [, end] = sections[i];\n if (lev === level) {\n result.push(lines.slice(start, end).join('\\n'));\n }\n }\n return result;\n}\n\nexport async function getReleaseNotesMdFileInner(\n project: ChangeLogProject,\n): Promise<ChangeLogFile | null> {\n const { repository, type } = project;\n const apiBaseUrl = project.apiBaseUrl;\n const sourceDirectory = project.sourceDirectory!;\n try {\n switch (type) {\n case 'bitbucket':\n return await bitbucket.getReleaseNotesMd(\n repository,\n apiBaseUrl,\n sourceDirectory,\n );\n case 'bitbucket-server':\n return await bitbucketServer.getReleaseNotesMd(\n repository,\n apiBaseUrl,\n sourceDirectory,\n );\n case 'forgejo':\n return await forgejo.getReleaseNotesMd(\n repository,\n apiBaseUrl,\n sourceDirectory,\n );\n case 'gitea':\n return await gitea.getReleaseNotesMd(\n repository,\n apiBaseUrl,\n sourceDirectory,\n );\n case 'github':\n return await github.getReleaseNotesMd(\n repository,\n apiBaseUrl,\n sourceDirectory,\n );\n case 'gitlab':\n return await gitlab.getReleaseNotesMd(\n repository,\n apiBaseUrl,\n sourceDirectory,\n );\n default:\n logger.warn({ apiBaseUrl, repository, type }, 'Invalid project type');\n return null;\n }\n } catch (err) /* istanbul ignore next */ {\n if (err.statusCode === 404) {\n logger.debug(\n { repository, type, apiBaseUrl },\n 'Error 404 getting changelog md',\n );\n } else {\n logger.debug(\n { err, repository, type, apiBaseUrl },\n 'Error getting changelog md',\n );\n }\n }\n return null;\n}\n\nexport function getReleaseNotesMdFile(\n project: ChangeLogProject,\n): Promise<ChangeLogFile | null> {\n const { sourceDirectory, repository, apiBaseUrl } = project;\n // TODO: types (#22198)\n const cacheKey = sourceDirectory\n ? `getReleaseNotesMdFile@v2-${repository}-${sourceDirectory}-${apiBaseUrl}`\n : `getReleaseNotesMdFile@v2-${repository}-${apiBaseUrl}`;\n const cachedResult = memCache.get<Promise<ChangeLogFile | null>>(cacheKey);\n // istanbul ignore if\n if (cachedResult !== undefined) {\n return cachedResult;\n }\n const promisedRes = getReleaseNotesMdFileInner(project);\n memCache.set(cacheKey, promisedRes);\n return promisedRes;\n}\n\nexport async function getReleaseNotesMd(\n project: ChangeLogProject,\n release: ChangeLogRelease,\n source: ChangeLogSource,\n): Promise<ChangeLogNotes | null> {\n const { baseUrl, repository, packageName } = project;\n const version = release.version;\n logger.trace(`getReleaseNotesMd(${repository}, ${version})`);\n\n if (shouldSkipChangelogMd(repository)) {\n return null;\n }\n\n const changelog = await getReleaseNotesMdFile(project);\n if (!changelog) {\n return null;\n }\n const { changelogFile } = changelog;\n const changelogMd = changelog.changelogMd.replace(\n regEx(/\\n\\s*<a name=\"[^\"]*\">.*?<\\/a>\\n/g),\n '\\n',\n );\n for (const level of [1, 2, 3, 4, 5, 6, 7]) {\n const changelogParsed = sectionize(changelogMd, level);\n if (changelogParsed.length >= 2) {\n for (const section of changelogParsed) {\n try {\n // replace brackets and parenthesis with space\n const deParenthesizedSection = section.replace(\n regEx(/[[\\]()]/g),\n ' ',\n );\n const [heading] = deParenthesizedSection.split(newlineRegex);\n const [parenthesizedHeading] = section.split(newlineRegex);\n const title = heading\n .replace(regEx(/^\\s*#*\\s*/), '')\n .split(' ')\n .filter(isTruthy);\n const body = section.replace(regEx(/.*?\\n(?:-{3,}\\n)?/), '').trim();\n const notesSourceUrl = source.getNotesSourceUrl(\n baseUrl,\n repository,\n changelogFile,\n );\n const url = source.getReleaseNotesMdAnchorUrl(\n notesSourceUrl,\n parenthesizedHeading,\n );\n // Look for version in title\n for (const word of title) {\n if (word.includes(version) && !isHttpUrl(word)) {\n logger.trace({ body }, `Found release notes for v${version}`);\n return {\n body: await linkifyBody(project, body),\n url,\n notesSourceUrl,\n };\n }\n }\n // Look for version in body - useful for monorepos. First check for heading with \"(yyyy-mm-dd)\"\n const releasesRegex = regEx(/(?:[0-9]{4}-[0-9]{2}-[0-9]{2})/);\n if (packageName && heading.search(releasesRegex) !== -1) {\n // Now check if any line contains both the package name and the version\n // Skip Markdown link reference definitions (e.g. `[1.2.3]: https://…/compare/...`)\n // which Keep-a-Changelog files list at the bottom and would otherwise match every version.\n const linkRefDefRegex = regEx(/^\\s*\\[[^\\]]+\\]:\\s*\\S+/);\n const bodyLines = body.split('\\n');\n if (\n bodyLines.some(\n (line) =>\n line.includes(packageName) &&\n line.includes(version) &&\n !isHttpUrl(line) &&\n !linkRefDefRegex.test(line),\n )\n ) {\n logger.trace({ body }, `Found release notes for v${version}`);\n return {\n body: await linkifyBody(project, body),\n url,\n notesSourceUrl,\n };\n }\n }\n } catch (err) /* istanbul ignore next */ {\n logger.warn(\n { file: changelogFile, err },\n `Error parsing changelog file`,\n );\n }\n }\n }\n logger.trace({ repository }, `No level ${level} changelogs headings found`);\n }\n logger.trace({ repository, version }, `No entry found in ${changelogFile}`);\n return null;\n}\n\n/**\n * Determine how long to cache release notes based on when the version was released.\n *\n * It's not uncommon for release notes to be updated shortly after the release itself,\n * so only cache for about an hour when the release is less than a week old. Otherwise,\n * cache for days.\n */\nexport function releaseNotesCacheMinutes(releaseDate?: string | Date): number {\n const dt = isDate(releaseDate)\n ? DateTime.fromJSDate(releaseDate)\n : DateTime.fromISO(releaseDate!);\n\n const now = DateTime.local();\n\n if (!dt.isValid || now.diff(dt, 'days').days < 7) {\n return 55;\n }\n\n if (now.diff(dt, 'months').months < 6) {\n return 1435; // 5 minutes shy of one day\n }\n\n return 14495; // 5 minutes shy of 10 days\n}\n\nexport async function addReleaseNotes(\n input: ChangeLogResult | null | undefined,\n config: BranchUpgradeConfig,\n source: ChangeLogSource,\n): Promise<ChangeLogResult | null> {\n return await instrument(`addReleaseNotes`, async () => {\n if (!input?.versions || !input.project?.type) {\n logger.debug('Missing project or versions');\n return input ?? null;\n }\n const output: ChangeLogResult = {\n ...input,\n versions: [],\n hasReleaseNotes: false,\n };\n\n const { repository, sourceDirectory, type: projectType } = input.project;\n const cacheNamespace: PackageCacheNamespace = `changelog-${projectType}-notes@v2`;\n const cacheKeyPrefix = sourceDirectory\n ? `${repository}:${sourceDirectory}`\n : `${repository}`;\n\n const shouldTruncateToPlatformLimit = config.fetchChangeLogs === 'pr';\n const maxBodyLength = shouldTruncateToPlatformLimit\n ? platform.maxBodyLength()\n : 0;\n let fetchedNotesLength = 0;\n\n for (const v of input.versions) {\n let releaseNotes: ChangeLogNotes | null | undefined;\n\n if (\n !shouldTruncateToPlatformLimit ||\n fetchedNotesLength < maxBodyLength\n ) {\n const gitRefCachePart = v.gitRef ? `:${v.gitRef}` : '';\n const cacheKey = `${cacheKeyPrefix}:${v.version}${gitRefCachePart}`;\n releaseNotes = await packageCache.get(cacheNamespace, cacheKey);\n releaseNotes ??= await getReleaseNotesMd(input.project, v, source);\n releaseNotes ??= await getReleaseNotes(input.project, v, config);\n\n // If there is no release notes, at least try to show the compare URL\n if (!releaseNotes && v.compare.url) {\n releaseNotes = { url: v.compare.url, notesSourceUrl: '' };\n }\n\n const cacheMinutes = releaseNotesCacheMinutes(v.date);\n await packageCache.set(\n cacheNamespace,\n cacheKey,\n releaseNotes,\n cacheMinutes,\n );\n\n // when we have received enough changelog content to exceed the platform's limit, we should stop trying to look up more changelog entries, as we fetch newest releases first, so the most recent changelog entries will be visible in the PR\n if (shouldTruncateToPlatformLimit) {\n fetchedNotesLength += releaseNotes?.body?.length ?? 0;\n if (fetchedNotesLength >= maxBodyLength) {\n logger.debug(\n {\n repository,\n project: input.project,\n skippingVersionFrom: v.version,\n maxBodyLength,\n },\n `Already fetched enough changelogs to hit the platform PR body limit, skipping version ${v.version} and below`,\n );\n }\n }\n } else if (v.compare.url) {\n releaseNotes = { url: v.compare.url, notesSourceUrl: '' };\n }\n\n output.versions!.push({\n ...v,\n releaseNotes: releaseNotes!,\n });\n\n if (releaseNotes) {\n output.hasReleaseNotes = true;\n }\n }\n return output;\n });\n}\n\n/**\n * Skip fetching changelog/release-notes markdown files.\n * Will force a fallback to using GitHub release notes\n */\nexport function shouldSkipChangelogMd(repository: string): boolean {\n return repositoriesToSkipMdFetching.includes(repository);\n}\n\nasync function linkifyBody(\n { baseUrl, repository }: ChangeLogProject,\n bodyStr: string,\n): Promise<string> {\n const body = massageBody(bodyStr, baseUrl);\n if (body?.length) {\n try {\n return await linkify(body, {\n repository: `${baseUrl}${repository}`,\n });\n } catch (err) /* istanbul ignore next */ {\n logger.warn({ body, err }, 'linkify error');\n }\n }\n return body;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"release-notes.js","names":["bitbucket.getReleaseList","forgejo.getReleaseList","gitea.getReleaseList","github.getReleaseList","gitlab.getReleaseList","memCache.get","bitbucket.getReleaseNotesMd","bitbucketServer.getReleaseNotesMd","forgejo.getReleaseNotesMd","gitea.getReleaseNotesMd","github.getReleaseNotesMd","gitlab.getReleaseNotesMd","packageCache.get","packageCache.set"],"sources":["../../../../../../lib/workers/repository/update/pr/changelog/release-notes.ts"],"sourcesContent":["import {\n isDate,\n isNonEmptyString,\n isTruthy,\n isUndefined,\n} from '@sindresorhus/is';\nimport { DateTime } from 'luxon';\nimport MarkdownIt from 'markdown-it';\nimport { instrument } from '../../../../../instrumentation/index.ts';\nimport { logger } from '../../../../../logger/index.ts';\nimport { platform } from '../../../../../modules/platform/index.ts';\nimport * as memCache from '../../../../../util/cache/memory/index.ts';\nimport * as packageCache from '../../../../../util/cache/package/index.ts';\nimport type { PackageCacheNamespace } from '../../../../../util/cache/package/types.ts';\nimport { detectPlatform } from '../../../../../util/common.ts';\nimport { linkify } from '../../../../../util/markdown.ts';\nimport { newlineRegex, regEx } from '../../../../../util/regex.ts';\nimport { coerceString } from '../../../../../util/string.ts';\nimport { isHttpUrl } from '../../../../../util/url.ts';\nimport type { BranchUpgradeConfig } from '../../../../types.ts';\nimport * as bitbucket from './bitbucket/index.ts';\nimport * as bitbucketServer from './bitbucket-server/index.ts';\nimport * as forgejo from './forgejo/index.ts';\nimport * as gitea from './gitea/index.ts';\nimport * as github from './github/index.ts';\nimport * as gitlab from './gitlab/index.ts';\nimport type { ChangeLogSource } from './source.ts';\nimport type {\n ChangeLogFile,\n ChangeLogNotes,\n ChangeLogProject,\n ChangeLogRelease,\n ChangeLogResult,\n} from './types.ts';\n\nconst markdown = new MarkdownIt('zero');\nmarkdown.enable(['heading', 'lheading', 'fence']);\n\nconst repositoriesToSkipMdFetching = [\n 'facebook/react-native',\n 'react/react-native',\n];\n\n// Per the OCI distribution reference grammar a leading path segment is a host\n// when it contains a `.` or a `:`. Go module paths are qualified the same way.\nconst hostQualifiedNameRegex = regEx(\n /^(?:localhost(?::\\d+)?|[^/]+[.:][^/]*)\\/(?<unqualifiedName>.+)$/,\n);\n\nexport async function getReleaseList(\n project: ChangeLogProject,\n release: ChangeLogRelease,\n): Promise<ChangeLogNotes[]> {\n logger.trace('getReleaseList()');\n const { apiBaseUrl, repository, type } = project;\n try {\n switch (type) {\n case 'bitbucket':\n return bitbucket.getReleaseList(project, release);\n case 'bitbucket-server':\n logger.trace(\n 'Unsupported Bitbucket Server feature. Skipping release fetching.',\n );\n return [];\n case 'forgejo':\n return await forgejo.getReleaseList(project, release);\n case 'gitea':\n return await gitea.getReleaseList(project, release);\n case 'github':\n return await github.getReleaseList(project, release);\n case 'gitlab':\n return await gitlab.getReleaseList(project, release);\n default:\n logger.warn({ apiBaseUrl, repository, type }, 'Invalid project type');\n return [];\n }\n } catch (err) /* istanbul ignore next */ {\n if (err.statusCode === 404) {\n logger.debug({ repository, type, apiBaseUrl }, 'getReleaseList 404');\n } else {\n logger.debug(\n { repository, type, apiBaseUrl, err },\n 'getReleaseList error',\n );\n }\n }\n return [];\n}\n\nexport function getCachedReleaseList(\n project: ChangeLogProject,\n release: ChangeLogRelease,\n): Promise<ChangeLogNotes[]> {\n const { repository, apiBaseUrl } = project;\n // TODO: types (#22198)\n const cacheKey = `getReleaseList-${apiBaseUrl}-${repository}`;\n const cachedResult = memCache.get<Promise<ChangeLogNotes[]>>(cacheKey);\n // istanbul ignore if\n if (cachedResult !== undefined) {\n return cachedResult;\n }\n const promisedRes = getReleaseList(project, release);\n memCache.set(cacheKey, promisedRes);\n return promisedRes;\n}\n\nexport function massageBody(\n input: string | undefined | null,\n baseUrl: string,\n): string {\n let body = coerceString(input);\n // Convert line returns\n body = body.replace(regEx(/\\r\\n/g), '\\n');\n // semantic-release cleanup\n body = body.replace(regEx(/^<a name=\"[^\"]*\"><\\/a>\\n/), '');\n body = body.replace(\n regEx(\n `^##? \\\\[[^\\\\]]*\\\\]\\\\(${baseUrl}[^/]*/[^/]*/compare/.*?\\\\n`,\n undefined,\n false,\n ),\n '',\n );\n // Clean-up unnecessary commits link\n body = `\\n${body}\\n`.replace(\n regEx(`\\\\n${baseUrl}[^/]+/[^/]+/compare/[^\\\\n]+(\\\\n|$)`),\n '\\n',\n );\n // Reduce headings size\n body = body\n .split(regEx(/(?<codeBlock>```[\\s\\S]*?```)/g))\n .map((part) =>\n part.startsWith('```') // do not modify # inside of codeblocks\n ? part\n : part\n .replace(regEx(/\\n\\s*####? /g), '\\n##### ')\n .replace(regEx(/\\n\\s*## /g), '\\n#### ')\n .replace(regEx(/\\n\\s*# /g), '\\n### '),\n )\n .join('');\n // Trim whitespace\n return body.trim();\n}\n\nexport function massageName(\n input: string | undefined | null,\n version: string | undefined,\n): string | undefined {\n let name = input ?? '';\n\n if (version) {\n name = name.replace(RegExp(`^(Release )?v?${version}`, 'i'), '').trim();\n }\n\n name = name.trim();\n if (!name.length) {\n return undefined;\n }\n\n return name;\n}\n\nexport async function getReleaseNotes(\n project: ChangeLogProject,\n release: ChangeLogRelease,\n config: BranchUpgradeConfig,\n): Promise<ChangeLogNotes | null> {\n return await instrument('getReleaseNotes', async () => {\n const { packageName, depName, repository } = project;\n const { version, gitRef } = release;\n // TODO: types (#22198)\n logger.trace(\n `getReleaseNotes(${repository}, ${version}, ${packageName!}, ${depName!})`,\n );\n const releases = await getCachedReleaseList(project, release);\n logger.trace({ releases }, 'Release list from getReleaseList');\n let releaseNotes: ChangeLogNotes | null = null;\n\n let matchedRelease = getExactReleaseMatch(\n packageName,\n depName,\n version,\n releases,\n );\n if (isUndefined(matchedRelease)) {\n // no exact match of a release then check other cases\n matchedRelease = releases.find(\n (r) =>\n r.tag === version ||\n r.tag === `v${version}` ||\n r.tag === gitRef ||\n r.tag === `v${gitRef}`,\n );\n }\n if (isUndefined(matchedRelease) && config.extractVersion) {\n const extractVersionRegEx = regEx(config.extractVersion);\n matchedRelease = releases.find((r) => {\n const extractedVersion = extractVersionRegEx.exec(r.tag!)?.groups\n ?.version;\n return version === extractedVersion;\n });\n }\n releaseNotes = await releaseNotesResult(matchedRelease, project);\n logger.trace({ releaseNotes });\n return releaseNotes;\n });\n}\n\nfunction getExactReleaseMatch(\n packageName: string | undefined,\n depName: string | undefined,\n version: string,\n releases: ChangeLogNotes[],\n): ChangeLogNotes | undefined {\n const namePatterns = getNamePatterns(packageName, depName);\n if (!namePatterns.length) {\n return undefined;\n }\n\n const exactReleaseReg = regEx(\n `(?:^|/)(?:${namePatterns.join('|')})[@_/-]v?${RegExp.escape(version)}`,\n );\n const candidateReleases = releases.filter((r) => r.tag?.endsWith(version));\n const matchedRelease = candidateReleases.find((r) =>\n exactReleaseReg.test(r.tag!),\n );\n return matchedRelease;\n}\n\n/**\n * A registry host never appears in a Git tag, so a host-qualified name such as\n * an OCI chart `<registry>/<org>/<repo>/<chart>` can never match the tag that\n * publishes it, which is scoped by the chart name alone: `<chart>-<version>`.\n * For those names, also match against the name with its host stripped, and\n * against the trailing path segment alone. Names that are not host-qualified,\n * such as scoped npm packages, keep matching in full only, so their tag\n * prefixes stay as specific as they are today.\n */\nfunction getNamePatterns(\n packageName: string | undefined,\n depName: string | undefined,\n): string[] {\n const names = new Set<string>();\n for (const name of [packageName, depName]) {\n if (!isNonEmptyString(name)) {\n continue;\n }\n names.add(name);\n\n const unqualifiedName =\n hostQualifiedNameRegex.exec(name)?.groups?.unqualifiedName;\n if (isNonEmptyString(unqualifiedName)) {\n names.add(unqualifiedName);\n\n const trailingName = unqualifiedName.split('/').pop();\n if (isNonEmptyString(trailingName)) {\n names.add(trailingName);\n }\n }\n }\n return [...names].map((name) => RegExp.escape(name));\n}\n\nasync function releaseNotesResult(\n releaseMatch: ChangeLogNotes | undefined,\n project: ChangeLogProject,\n): Promise<ChangeLogNotes | null> {\n if (!releaseMatch) {\n return null;\n }\n const { baseUrl, repository } = project;\n const releaseNotes: ChangeLogNotes = releaseMatch;\n if (detectPlatform(baseUrl) === 'gitlab') {\n releaseNotes.url = `${baseUrl}${repository}/tags/${releaseMatch.tag!}`;\n } else {\n // v8 ignore next -- a matched release always carries its own url\n releaseNotes.url = releaseMatch.url\n ? releaseMatch.url\n : /* istanbul ignore next */\n `${baseUrl}${repository}/releases/${releaseMatch.tag!}`;\n }\n // set body for release notes\n releaseNotes.body = massageBody(releaseNotes.body, baseUrl);\n releaseNotes.name = massageName(releaseNotes.name, releaseNotes.tag);\n if (releaseNotes.body.length || releaseNotes.name?.length) {\n try {\n if (baseUrl !== 'https://gitlab.com/') {\n releaseNotes.body = await linkify(releaseNotes.body, {\n repository: `${baseUrl}${repository}`,\n });\n }\n } catch (err) /* istanbul ignore next */ {\n logger.warn({ err, baseUrl, repository }, 'Error linkifying');\n }\n } else {\n return null;\n }\n\n return releaseNotes;\n}\n\nfunction sectionize(text: string, level: number): string[] {\n const sections: [number, number][] = [];\n const lines = text.split(newlineRegex);\n const tokens = markdown.parse(text, {});\n tokens.forEach((token) => {\n if (token.type === 'heading_open') {\n const lev = +token.tag.substring(1);\n if (lev <= level) {\n sections.push([lev, token.map![0]]);\n }\n }\n });\n sections.push([-1, lines.length]);\n const result: string[] = [];\n for (let i = 1; i < sections.length; i += 1) {\n const [lev, start] = sections[i - 1];\n const [, end] = sections[i];\n if (lev === level) {\n result.push(lines.slice(start, end).join('\\n'));\n }\n }\n return result;\n}\n\nexport async function getReleaseNotesMdFileInner(\n project: ChangeLogProject,\n): Promise<ChangeLogFile | null> {\n const { repository, type } = project;\n const apiBaseUrl = project.apiBaseUrl;\n const sourceDirectory = project.sourceDirectory!;\n try {\n switch (type) {\n case 'bitbucket':\n return await bitbucket.getReleaseNotesMd(\n repository,\n apiBaseUrl,\n sourceDirectory,\n );\n case 'bitbucket-server':\n return await bitbucketServer.getReleaseNotesMd(\n repository,\n apiBaseUrl,\n sourceDirectory,\n );\n case 'forgejo':\n return await forgejo.getReleaseNotesMd(\n repository,\n apiBaseUrl,\n sourceDirectory,\n );\n case 'gitea':\n return await gitea.getReleaseNotesMd(\n repository,\n apiBaseUrl,\n sourceDirectory,\n );\n case 'github':\n return await github.getReleaseNotesMd(\n repository,\n apiBaseUrl,\n sourceDirectory,\n );\n case 'gitlab':\n return await gitlab.getReleaseNotesMd(\n repository,\n apiBaseUrl,\n sourceDirectory,\n );\n default:\n logger.warn({ apiBaseUrl, repository, type }, 'Invalid project type');\n return null;\n }\n } catch (err) /* istanbul ignore next */ {\n if (err.statusCode === 404) {\n logger.debug(\n { repository, type, apiBaseUrl },\n 'Error 404 getting changelog md',\n );\n } else {\n logger.debug(\n { err, repository, type, apiBaseUrl },\n 'Error getting changelog md',\n );\n }\n }\n return null;\n}\n\nexport function getReleaseNotesMdFile(\n project: ChangeLogProject,\n): Promise<ChangeLogFile | null> {\n const { sourceDirectory, repository, apiBaseUrl } = project;\n // TODO: types (#22198)\n const cacheKey = sourceDirectory\n ? `getReleaseNotesMdFile@v2-${repository}-${sourceDirectory}-${apiBaseUrl}`\n : `getReleaseNotesMdFile@v2-${repository}-${apiBaseUrl}`;\n const cachedResult = memCache.get<Promise<ChangeLogFile | null>>(cacheKey);\n // istanbul ignore if\n if (cachedResult !== undefined) {\n return cachedResult;\n }\n const promisedRes = getReleaseNotesMdFileInner(project);\n memCache.set(cacheKey, promisedRes);\n return promisedRes;\n}\n\nexport async function getReleaseNotesMd(\n project: ChangeLogProject,\n release: ChangeLogRelease,\n source: ChangeLogSource,\n): Promise<ChangeLogNotes | null> {\n const { baseUrl, repository, packageName } = project;\n const version = release.version;\n logger.trace(`getReleaseNotesMd(${repository}, ${version})`);\n\n if (shouldSkipChangelogMd(repository)) {\n return null;\n }\n\n const changelog = await getReleaseNotesMdFile(project);\n if (!changelog) {\n return null;\n }\n const { changelogFile } = changelog;\n const changelogMd = changelog.changelogMd.replace(\n regEx(/\\n\\s*<a name=\"[^\"]*\">.*?<\\/a>\\n/g),\n '\\n',\n );\n for (const level of [1, 2, 3, 4, 5, 6, 7]) {\n const changelogParsed = sectionize(changelogMd, level);\n if (changelogParsed.length >= 2) {\n for (const section of changelogParsed) {\n try {\n // replace brackets and parenthesis with space\n const deParenthesizedSection = section.replace(\n regEx(/[[\\]()]/g),\n ' ',\n );\n const [heading] = deParenthesizedSection.split(newlineRegex);\n const [parenthesizedHeading] = section.split(newlineRegex);\n const title = heading\n .replace(regEx(/^\\s*#*\\s*/), '')\n .split(' ')\n .filter(isTruthy);\n const body = section.replace(regEx(/.*?\\n(?:-{3,}\\n)?/), '').trim();\n const notesSourceUrl = source.getNotesSourceUrl(\n baseUrl,\n repository,\n changelogFile,\n );\n const url = source.getReleaseNotesMdAnchorUrl(\n notesSourceUrl,\n parenthesizedHeading,\n );\n // Look for version in title\n for (const word of title) {\n if (word.includes(version) && !isHttpUrl(word)) {\n logger.trace({ body }, `Found release notes for v${version}`);\n return {\n body: await linkifyBody(project, body),\n url,\n notesSourceUrl,\n };\n }\n }\n // Look for version in body - useful for monorepos. First check for heading with \"(yyyy-mm-dd)\"\n const releasesRegex = regEx(/(?:[0-9]{4}-[0-9]{2}-[0-9]{2})/);\n if (packageName && heading.search(releasesRegex) !== -1) {\n // Now check if any line contains both the package name and the version\n // Skip Markdown link reference definitions (e.g. `[1.2.3]: https://…/compare/...`)\n // which Keep-a-Changelog files list at the bottom and would otherwise match every version.\n const linkRefDefRegex = regEx(/^\\s*\\[[^\\]]+\\]:\\s*\\S+/);\n const bodyLines = body.split('\\n');\n if (\n bodyLines.some(\n (line) =>\n line.includes(packageName) &&\n line.includes(version) &&\n !isHttpUrl(line) &&\n !linkRefDefRegex.test(line),\n )\n ) {\n logger.trace({ body }, `Found release notes for v${version}`);\n return {\n body: await linkifyBody(project, body),\n url,\n notesSourceUrl,\n };\n }\n }\n } catch (err) /* istanbul ignore next */ {\n logger.warn(\n { file: changelogFile, err },\n `Error parsing changelog file`,\n );\n }\n }\n }\n logger.trace({ repository }, `No level ${level} changelogs headings found`);\n }\n logger.trace({ repository, version }, `No entry found in ${changelogFile}`);\n return null;\n}\n\n/**\n * Determine how long to cache release notes based on when the version was released.\n *\n * It's not uncommon for release notes to be updated shortly after the release itself,\n * so only cache for about an hour when the release is less than a week old. Otherwise,\n * cache for days.\n */\nexport function releaseNotesCacheMinutes(releaseDate?: string | Date): number {\n const dt = isDate(releaseDate)\n ? DateTime.fromJSDate(releaseDate)\n : DateTime.fromISO(releaseDate!);\n\n const now = DateTime.local();\n\n if (!dt.isValid || now.diff(dt, 'days').days < 7) {\n return 55;\n }\n\n if (now.diff(dt, 'months').months < 6) {\n return 1435; // 5 minutes shy of one day\n }\n\n return 14495; // 5 minutes shy of 10 days\n}\n\nexport async function addReleaseNotes(\n input: ChangeLogResult | null | undefined,\n config: BranchUpgradeConfig,\n source: ChangeLogSource,\n): Promise<ChangeLogResult | null> {\n return await instrument(`addReleaseNotes`, async () => {\n if (!input?.versions || !input.project?.type) {\n logger.debug('Missing project or versions');\n return input ?? null;\n }\n const output: ChangeLogResult = {\n ...input,\n versions: [],\n hasReleaseNotes: false,\n };\n\n const { repository, sourceDirectory, type: projectType } = input.project;\n const cacheNamespace: PackageCacheNamespace = `changelog-${projectType}-notes@v2`;\n const cacheKeyPrefix = sourceDirectory\n ? `${repository}:${sourceDirectory}`\n : `${repository}`;\n\n const shouldTruncateToPlatformLimit = config.fetchChangeLogs === 'pr';\n const maxBodyLength = shouldTruncateToPlatformLimit\n ? platform.maxBodyLength()\n : 0;\n let fetchedNotesLength = 0;\n\n for (const v of input.versions) {\n let releaseNotes: ChangeLogNotes | null | undefined;\n\n if (\n !shouldTruncateToPlatformLimit ||\n fetchedNotesLength < maxBodyLength\n ) {\n const gitRefCachePart = v.gitRef ? `:${v.gitRef}` : '';\n const cacheKey = `${cacheKeyPrefix}:${v.version}${gitRefCachePart}`;\n releaseNotes = await packageCache.get(cacheNamespace, cacheKey);\n releaseNotes ??= await getReleaseNotesMd(input.project, v, source);\n releaseNotes ??= await getReleaseNotes(input.project, v, config);\n\n // If there is no release notes, at least try to show the compare URL\n if (!releaseNotes && v.compare.url) {\n releaseNotes = { url: v.compare.url, notesSourceUrl: '' };\n }\n\n const cacheMinutes = releaseNotesCacheMinutes(v.date);\n await packageCache.set(\n cacheNamespace,\n cacheKey,\n releaseNotes,\n cacheMinutes,\n );\n\n // when we have received enough changelog content to exceed the platform's limit, we should stop trying to look up more changelog entries, as we fetch newest releases first, so the most recent changelog entries will be visible in the PR\n if (shouldTruncateToPlatformLimit) {\n fetchedNotesLength += releaseNotes?.body?.length ?? 0;\n if (fetchedNotesLength >= maxBodyLength) {\n logger.debug(\n {\n repository,\n project: input.project,\n skippingVersionFrom: v.version,\n maxBodyLength,\n },\n `Already fetched enough changelogs to hit the platform PR body limit, skipping version ${v.version} and below`,\n );\n }\n }\n } else if (v.compare.url) {\n releaseNotes = { url: v.compare.url, notesSourceUrl: '' };\n }\n\n output.versions!.push({\n ...v,\n releaseNotes: releaseNotes!,\n });\n\n if (releaseNotes) {\n output.hasReleaseNotes = true;\n }\n }\n return output;\n });\n}\n\n/**\n * Skip fetching changelog/release-notes markdown files.\n * Will force a fallback to using GitHub release notes\n */\nexport function shouldSkipChangelogMd(repository: string): boolean {\n return repositoriesToSkipMdFetching.includes(repository);\n}\n\nasync function linkifyBody(\n { baseUrl, repository }: ChangeLogProject,\n bodyStr: string,\n): Promise<string> {\n const body = massageBody(bodyStr, baseUrl);\n if (body?.length) {\n try {\n return await linkify(body, {\n repository: `${baseUrl}${repository}`,\n });\n } catch (err) /* istanbul ignore next */ {\n logger.warn({ body, err }, 'linkify error');\n }\n }\n return body;\n}\n"],"mappings":"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"}
@@ -61,6 +61,7 @@ var ChangeLogSource = class {
61
61
  return null;
62
62
  }
63
63
  const releases = config.releases ?? await getInRangeReleases(config);
64
+ // v8 ignore next -- `getInRangeReleases` only returns null on paths it already ignores
64
65
  if (!releases?.length) {
65
66
  logger.debug("No releases");
66
67
  return null;
@@ -1 +1 @@
1
- {"version":3,"file":"source.js","names":["allVersioning.get","packageCache.get","packageCache.set"],"sources":["../../../../../../lib/workers/repository/update/pr/changelog/source.ts"],"sourcesContent":["import {\n isEmptyArray,\n isFalsy,\n isNonEmptyString,\n isNullOrUndefined,\n isTruthy,\n} from '@sindresorhus/is';\nimport { instrument } from '../../../../../instrumentation/index.ts';\nimport { logger } from '../../../../../logger/index.ts';\nimport { getPkgReleases } from '../../../../../modules/datasource/index.ts';\nimport type { Release } from '../../../../../modules/datasource/types.ts';\nimport * as allVersioning from '../../../../../modules/versioning/index.ts';\nimport * as packageCache from '../../../../../util/cache/package/index.ts';\nimport type { PackageCacheNamespace } from '../../../../../util/cache/package/types.ts';\nimport { memoize } from '../../../../../util/memoize.ts';\nimport { regEx } from '../../../../../util/regex.ts';\nimport {\n isHttpUrl,\n joinUrlParts,\n parseUrl,\n trimSlashes,\n} from '../../../../../util/url.ts';\nimport type { BranchUpgradeConfig } from '../../../../types.ts';\nimport { slugifyUrl } from './common.ts';\nimport { addReleaseNotes } from './release-notes.ts';\nimport { getInRangeReleases } from './releases.ts';\nimport type {\n ChangeLogError,\n ChangeLogPlatform,\n ChangeLogRelease,\n ChangeLogResult,\n} from './types.ts';\n\n// Number of dot-separated segments, used as a proxy for how precise a tag is,\n// e.g. `v7` (0) < `v7.0` (1) < `v7.0.0` (2).\nfunction tagPrecision(tag: string): number {\n return tag.split('.').length - 1;\n}\n\nexport abstract class ChangeLogSource {\n private readonly cacheNamespace: PackageCacheNamespace;\n private readonly platform: ChangeLogPlatform;\n private readonly datasource:\n | 'bitbucket-tags'\n | 'bitbucket-server-tags'\n | 'forgejo-tags'\n | 'gitea-tags'\n | 'github-tags'\n | 'gitlab-tags';\n\n constructor(\n platform: ChangeLogPlatform,\n datasource:\n | 'bitbucket-tags'\n | 'bitbucket-server-tags'\n | 'forgejo-tags'\n | 'gitea-tags'\n | 'github-tags'\n | 'gitlab-tags',\n ) {\n this.platform = platform;\n this.datasource = datasource;\n this.cacheNamespace = `changelog-${platform}-release`;\n }\n\n abstract getCompareURL(\n baseUrl: string,\n repository: string,\n prevHead: string,\n nextHead: string,\n ): string;\n\n abstract getAPIBaseUrl(config: BranchUpgradeConfig): string;\n\n async getAllTags(endpoint: string, repository: string): Promise<string[]> {\n const tags = (\n await getPkgReleases({\n registryUrls: [endpoint],\n datasource: this.datasource,\n packageName: repository,\n versioning:\n 'regex:(?<major>\\\\d+)(\\\\.(?<minor>\\\\d+))?(\\\\.(?<patch>\\\\d+))?',\n })\n )?.releases;\n\n if (isNullOrUndefined(tags) || isEmptyArray(tags)) {\n logger.debug(\n `No ${this.datasource} tags found for repository: ${repository}`,\n );\n\n return [];\n }\n\n return tags.map(({ version }) => version);\n }\n\n public async getChangeLogJSON(\n config: BranchUpgradeConfig,\n ): Promise<ChangeLogResult | null> {\n return await instrument(\n `source.getChangeLogJSON(${this.platform})`,\n async () => {\n logger.trace(`getChangeLogJSON for ${this.platform}`);\n\n const versioning = config.versioning!;\n const currentVersion = config.currentVersion!;\n const newVersion = config.newVersion!;\n const sourceUrl = config.sourceUrl!;\n const packageName = config.packageName!;\n const depName = config.depName!;\n const sourceDirectory = config.sourceDirectory;\n const versioningApi = allVersioning.get(versioning);\n\n if (this.shouldSkipPackage(config)) {\n return null;\n }\n\n const baseUrl = this.getBaseUrl(config);\n const apiBaseUrl = this.getAPIBaseUrl(config);\n const repository = this.getRepositoryFromUrl(config);\n\n const tokenResponse = this.hasValidToken(config);\n if (!tokenResponse.isValid) {\n if (tokenResponse.error) {\n return {\n error: tokenResponse.error,\n };\n }\n return null;\n }\n\n if (isFalsy(this.hasValidRepository(repository))) {\n logger.debug(`Invalid ${this.platform} URL found: ${sourceUrl}`);\n return null;\n }\n\n const releases = config.releases ?? (await getInRangeReleases(config));\n if (!releases?.length) {\n logger.debug('No releases');\n return null;\n }\n // This extra filter/sort should not be necessary, but better safe than sorry\n const validReleases = [...releases]\n .filter((release) => versioningApi.isVersion(release.version))\n .sort((a, b) => versioningApi.sortVersions(a.version, b.version))\n // Drop versions equal under this versioning, e.g. the Docker tags\n // `3.7.12` and `v3.7.12`, else their notes are rendered twice\n .filter(\n (release, index, sorted) =>\n index === sorted.length - 1 ||\n !versioningApi.equals(release.version, sorted[index + 1].version),\n );\n\n if (validReleases.length < 2) {\n logger.debug(\n `Not enough valid releases for dep ${depName} (${packageName})`,\n );\n return null;\n }\n\n const changelogReleases: ChangeLogRelease[] = [];\n\n // Check if `v` belongs to the range (currentVersion, newVersion]\n function inRange(v: string): boolean {\n return (\n versioningApi.isGreaterThan(v, currentVersion) &&\n !versioningApi.isGreaterThan(v, newVersion)\n );\n }\n\n const getTags = memoize(() => this.getAllTags(apiBaseUrl, repository));\n // Fetch releases newest-first, matching the order they're shown in the PR body.\n for (let i = validReleases.length - 1; i >= 1; i -= 1) {\n const prev = validReleases[i - 1];\n const next = validReleases[i];\n if (!inRange(next.version)) {\n continue;\n }\n let release = await packageCache.get(\n this.cacheNamespace,\n this.getCacheKey(\n sourceUrl,\n packageName,\n prev.version,\n next.version,\n ),\n );\n if (!release) {\n release = {\n version: next.version,\n date: next.releaseTimestamp,\n gitRef: next.gitRef,\n // put empty changes so that existing templates won't break\n changes: [],\n compare: {},\n };\n const tags = await getTags();\n const prevHead = this.getRef(\n versioningApi,\n packageName,\n depName,\n prev,\n tags,\n );\n const nextHead = this.getRef(\n versioningApi,\n packageName,\n depName,\n next,\n tags,\n );\n if (isNonEmptyString(prevHead) && isNonEmptyString(nextHead)) {\n release.compare.url = this.getCompareURL(\n baseUrl,\n repository,\n prevHead,\n nextHead,\n );\n }\n const cacheMinutes = 55;\n await packageCache.set(\n this.cacheNamespace,\n this.getCacheKey(\n sourceUrl,\n packageName,\n prev.version,\n next.version,\n ),\n release,\n cacheMinutes,\n );\n }\n changelogReleases.push(release);\n }\n\n let res: ChangeLogResult | null = {\n project: {\n apiBaseUrl,\n baseUrl,\n type: this.platform,\n repository,\n sourceUrl,\n sourceDirectory,\n packageName,\n depName,\n },\n versions: changelogReleases,\n };\n\n res = await addReleaseNotes(res, config, this);\n\n return res;\n },\n );\n }\n\n private findTagOfRelease(\n versioningApi: allVersioning.VersioningApi,\n packageName: string,\n depName: string,\n depNewVersion: string,\n tags: string[],\n ): string | undefined {\n const releaseRegexPrefix = `^(?:${packageName}|${depName}|release)[@_-]v?`;\n const regex = regEx(releaseRegexPrefix, undefined, false);\n const exactReleaseRegex = regEx(`${releaseRegexPrefix}${depNewVersion}`);\n const exactTagsList = tags.filter((tag) => {\n return exactReleaseRegex.test(tag);\n });\n const tagList = exactTagsList.length ? exactTagsList : tags;\n const candidates = tagList\n .filter((tag) => versioningApi.isVersion(tag.replace(regex, '')))\n .filter((tag) =>\n versioningApi.equals(tag.replace(regex, ''), depNewVersion),\n );\n if (!candidates.length) {\n return undefined;\n }\n // Some versioning schemes (e.g. `github-actions`) treat a floating tag\n // like `v7` as equal to a precise one like `v7.0.0` via coercion, so more\n // than one tag can match the same release. Prefer the most precise tag\n // (most dot-separated segments), else keep the first match found.\n return candidates.reduce((mostPrecise, candidate) =>\n tagPrecision(candidate) > tagPrecision(mostPrecise)\n ? candidate\n : mostPrecise,\n );\n }\n\n private getRef(\n versioningApi: allVersioning.VersioningApi,\n packageName: string,\n depName: string,\n release: Release,\n tags: string[],\n ): string | null {\n const tagName = this.findTagOfRelease(\n versioningApi,\n packageName,\n depName,\n release.version,\n tags,\n );\n if (isNonEmptyString(tagName)) {\n return tagName;\n }\n if (isNonEmptyString(release.gitRef)) {\n return release.gitRef;\n }\n return null;\n }\n\n private getCacheKey(\n sourceUrl: string,\n packageName: string,\n prev: string,\n next: string,\n ): string {\n return `${slugifyUrl(sourceUrl)}:${packageName}:${prev}:${next}`;\n }\n\n getBaseUrl(config: BranchUpgradeConfig): string {\n const parsedUrl = parseUrl(config.sourceUrl);\n if (isNullOrUndefined(parsedUrl)) {\n return '';\n }\n const protocol = parsedUrl.protocol.replace(regEx(/^git\\+/), '');\n const host = parsedUrl.host;\n return `${protocol}//${host}/`;\n }\n\n getRepositoryFromUrl(config: BranchUpgradeConfig): string {\n const parsedUrl = parseUrl(config.sourceUrl);\n if (isNullOrUndefined(parsedUrl)) {\n return '';\n }\n const pathname = parsedUrl.pathname;\n return trimSlashes(pathname).replace(regEx(/\\.git$/), '');\n }\n\n protected hasValidToken(_config: BranchUpgradeConfig): {\n isValid: boolean;\n error?: ChangeLogError;\n } {\n return { isValid: true };\n }\n\n protected shouldSkipPackage(_config: BranchUpgradeConfig): boolean {\n return false;\n }\n\n hasValidRepository(repository: string): boolean {\n return repository.split('/').length === 2;\n }\n\n /**\n * Build the URL to the changelog markdown file for the release notes.\n * Platform sources can override this to match their web UI conventions.\n */\n getNotesSourceUrl(\n baseUrl: string,\n repository: string,\n changelogFile: string,\n ): string {\n return joinUrlParts(baseUrl, repository, 'blob', 'HEAD', changelogFile);\n }\n\n /**\n * Build the URL pointing to a specific heading within the changelog markdown\n * file. Platform sources can override this to match their anchor conventions.\n */\n getReleaseNotesMdAnchorUrl(notesSourceUrl: string, heading: string): string {\n const mdHeadingLink = heading\n .replace(regEx(/[[\\]()]/g), ' ')\n .replace(regEx(/^\\s*#*\\s*/), '')\n .split(' ')\n .filter(isTruthy)\n .filter((word) => !isHttpUrl(word))\n .join('-')\n .replace(regEx(/[^A-Za-z0-9-]/g), '');\n return `${notesSourceUrl}#${mdHeadingLink}`;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"source.js","names":["allVersioning.get","packageCache.get","packageCache.set"],"sources":["../../../../../../lib/workers/repository/update/pr/changelog/source.ts"],"sourcesContent":["import {\n isEmptyArray,\n isFalsy,\n isNonEmptyString,\n isNullOrUndefined,\n isTruthy,\n} from '@sindresorhus/is';\nimport { instrument } from '../../../../../instrumentation/index.ts';\nimport { logger } from '../../../../../logger/index.ts';\nimport { getPkgReleases } from '../../../../../modules/datasource/index.ts';\nimport type { Release } from '../../../../../modules/datasource/types.ts';\nimport * as allVersioning from '../../../../../modules/versioning/index.ts';\nimport * as packageCache from '../../../../../util/cache/package/index.ts';\nimport type { PackageCacheNamespace } from '../../../../../util/cache/package/types.ts';\nimport { memoize } from '../../../../../util/memoize.ts';\nimport { regEx } from '../../../../../util/regex.ts';\nimport {\n isHttpUrl,\n joinUrlParts,\n parseUrl,\n trimSlashes,\n} from '../../../../../util/url.ts';\nimport type { BranchUpgradeConfig } from '../../../../types.ts';\nimport { slugifyUrl } from './common.ts';\nimport { addReleaseNotes } from './release-notes.ts';\nimport { getInRangeReleases } from './releases.ts';\nimport type {\n ChangeLogError,\n ChangeLogPlatform,\n ChangeLogRelease,\n ChangeLogResult,\n} from './types.ts';\n\n// Number of dot-separated segments, used as a proxy for how precise a tag is,\n// e.g. `v7` (0) < `v7.0` (1) < `v7.0.0` (2).\nfunction tagPrecision(tag: string): number {\n return tag.split('.').length - 1;\n}\n\nexport abstract class ChangeLogSource {\n private readonly cacheNamespace: PackageCacheNamespace;\n private readonly platform: ChangeLogPlatform;\n private readonly datasource:\n | 'bitbucket-tags'\n | 'bitbucket-server-tags'\n | 'forgejo-tags'\n | 'gitea-tags'\n | 'github-tags'\n | 'gitlab-tags';\n\n constructor(\n platform: ChangeLogPlatform,\n datasource:\n | 'bitbucket-tags'\n | 'bitbucket-server-tags'\n | 'forgejo-tags'\n | 'gitea-tags'\n | 'github-tags'\n | 'gitlab-tags',\n ) {\n this.platform = platform;\n this.datasource = datasource;\n this.cacheNamespace = `changelog-${platform}-release`;\n }\n\n abstract getCompareURL(\n baseUrl: string,\n repository: string,\n prevHead: string,\n nextHead: string,\n ): string;\n\n abstract getAPIBaseUrl(config: BranchUpgradeConfig): string;\n\n async getAllTags(endpoint: string, repository: string): Promise<string[]> {\n const tags = (\n await getPkgReleases({\n registryUrls: [endpoint],\n datasource: this.datasource,\n packageName: repository,\n versioning:\n 'regex:(?<major>\\\\d+)(\\\\.(?<minor>\\\\d+))?(\\\\.(?<patch>\\\\d+))?',\n })\n )?.releases;\n\n if (isNullOrUndefined(tags) || isEmptyArray(tags)) {\n logger.debug(\n `No ${this.datasource} tags found for repository: ${repository}`,\n );\n\n return [];\n }\n\n return tags.map(({ version }) => version);\n }\n\n public async getChangeLogJSON(\n config: BranchUpgradeConfig,\n ): Promise<ChangeLogResult | null> {\n return await instrument(\n `source.getChangeLogJSON(${this.platform})`,\n async () => {\n logger.trace(`getChangeLogJSON for ${this.platform}`);\n\n const versioning = config.versioning!;\n const currentVersion = config.currentVersion!;\n const newVersion = config.newVersion!;\n const sourceUrl = config.sourceUrl!;\n const packageName = config.packageName!;\n const depName = config.depName!;\n const sourceDirectory = config.sourceDirectory;\n const versioningApi = allVersioning.get(versioning);\n\n if (this.shouldSkipPackage(config)) {\n return null;\n }\n\n const baseUrl = this.getBaseUrl(config);\n const apiBaseUrl = this.getAPIBaseUrl(config);\n const repository = this.getRepositoryFromUrl(config);\n\n const tokenResponse = this.hasValidToken(config);\n if (!tokenResponse.isValid) {\n if (tokenResponse.error) {\n return {\n error: tokenResponse.error,\n };\n }\n return null;\n }\n\n if (isFalsy(this.hasValidRepository(repository))) {\n logger.debug(`Invalid ${this.platform} URL found: ${sourceUrl}`);\n return null;\n }\n\n const releases = config.releases ?? (await getInRangeReleases(config));\n // v8 ignore next -- `getInRangeReleases` only returns null on paths it already ignores\n if (!releases?.length) {\n logger.debug('No releases');\n return null;\n }\n // This extra filter/sort should not be necessary, but better safe than sorry\n const validReleases = [...releases]\n .filter((release) => versioningApi.isVersion(release.version))\n .sort((a, b) => versioningApi.sortVersions(a.version, b.version))\n // Drop versions equal under this versioning, e.g. the Docker tags\n // `3.7.12` and `v3.7.12`, else their notes are rendered twice\n .filter(\n (release, index, sorted) =>\n index === sorted.length - 1 ||\n !versioningApi.equals(release.version, sorted[index + 1].version),\n );\n\n if (validReleases.length < 2) {\n logger.debug(\n `Not enough valid releases for dep ${depName} (${packageName})`,\n );\n return null;\n }\n\n const changelogReleases: ChangeLogRelease[] = [];\n\n // Check if `v` belongs to the range (currentVersion, newVersion]\n function inRange(v: string): boolean {\n return (\n versioningApi.isGreaterThan(v, currentVersion) &&\n !versioningApi.isGreaterThan(v, newVersion)\n );\n }\n\n const getTags = memoize(() => this.getAllTags(apiBaseUrl, repository));\n // Fetch releases newest-first, matching the order they're shown in the PR body.\n for (let i = validReleases.length - 1; i >= 1; i -= 1) {\n const prev = validReleases[i - 1];\n const next = validReleases[i];\n if (!inRange(next.version)) {\n continue;\n }\n let release = await packageCache.get(\n this.cacheNamespace,\n this.getCacheKey(\n sourceUrl,\n packageName,\n prev.version,\n next.version,\n ),\n );\n if (!release) {\n release = {\n version: next.version,\n date: next.releaseTimestamp,\n gitRef: next.gitRef,\n // put empty changes so that existing templates won't break\n changes: [],\n compare: {},\n };\n const tags = await getTags();\n const prevHead = this.getRef(\n versioningApi,\n packageName,\n depName,\n prev,\n tags,\n );\n const nextHead = this.getRef(\n versioningApi,\n packageName,\n depName,\n next,\n tags,\n );\n if (isNonEmptyString(prevHead) && isNonEmptyString(nextHead)) {\n release.compare.url = this.getCompareURL(\n baseUrl,\n repository,\n prevHead,\n nextHead,\n );\n }\n const cacheMinutes = 55;\n await packageCache.set(\n this.cacheNamespace,\n this.getCacheKey(\n sourceUrl,\n packageName,\n prev.version,\n next.version,\n ),\n release,\n cacheMinutes,\n );\n }\n changelogReleases.push(release);\n }\n\n let res: ChangeLogResult | null = {\n project: {\n apiBaseUrl,\n baseUrl,\n type: this.platform,\n repository,\n sourceUrl,\n sourceDirectory,\n packageName,\n depName,\n },\n versions: changelogReleases,\n };\n\n res = await addReleaseNotes(res, config, this);\n\n return res;\n },\n );\n }\n\n private findTagOfRelease(\n versioningApi: allVersioning.VersioningApi,\n packageName: string,\n depName: string,\n depNewVersion: string,\n tags: string[],\n ): string | undefined {\n const releaseRegexPrefix = `^(?:${packageName}|${depName}|release)[@_-]v?`;\n const regex = regEx(releaseRegexPrefix, undefined, false);\n const exactReleaseRegex = regEx(`${releaseRegexPrefix}${depNewVersion}`);\n const exactTagsList = tags.filter((tag) => {\n return exactReleaseRegex.test(tag);\n });\n const tagList = exactTagsList.length ? exactTagsList : tags;\n const candidates = tagList\n .filter((tag) => versioningApi.isVersion(tag.replace(regex, '')))\n .filter((tag) =>\n versioningApi.equals(tag.replace(regex, ''), depNewVersion),\n );\n if (!candidates.length) {\n return undefined;\n }\n // Some versioning schemes (e.g. `github-actions`) treat a floating tag\n // like `v7` as equal to a precise one like `v7.0.0` via coercion, so more\n // than one tag can match the same release. Prefer the most precise tag\n // (most dot-separated segments), else keep the first match found.\n return candidates.reduce((mostPrecise, candidate) =>\n tagPrecision(candidate) > tagPrecision(mostPrecise)\n ? candidate\n : mostPrecise,\n );\n }\n\n private getRef(\n versioningApi: allVersioning.VersioningApi,\n packageName: string,\n depName: string,\n release: Release,\n tags: string[],\n ): string | null {\n const tagName = this.findTagOfRelease(\n versioningApi,\n packageName,\n depName,\n release.version,\n tags,\n );\n if (isNonEmptyString(tagName)) {\n return tagName;\n }\n if (isNonEmptyString(release.gitRef)) {\n return release.gitRef;\n }\n return null;\n }\n\n private getCacheKey(\n sourceUrl: string,\n packageName: string,\n prev: string,\n next: string,\n ): string {\n return `${slugifyUrl(sourceUrl)}:${packageName}:${prev}:${next}`;\n }\n\n getBaseUrl(config: BranchUpgradeConfig): string {\n const parsedUrl = parseUrl(config.sourceUrl);\n if (isNullOrUndefined(parsedUrl)) {\n return '';\n }\n const protocol = parsedUrl.protocol.replace(regEx(/^git\\+/), '');\n const host = parsedUrl.host;\n return `${protocol}//${host}/`;\n }\n\n getRepositoryFromUrl(config: BranchUpgradeConfig): string {\n const parsedUrl = parseUrl(config.sourceUrl);\n if (isNullOrUndefined(parsedUrl)) {\n return '';\n }\n const pathname = parsedUrl.pathname;\n return trimSlashes(pathname).replace(regEx(/\\.git$/), '');\n }\n\n protected hasValidToken(_config: BranchUpgradeConfig): {\n isValid: boolean;\n error?: ChangeLogError;\n } {\n return { isValid: true };\n }\n\n protected shouldSkipPackage(_config: BranchUpgradeConfig): boolean {\n return false;\n }\n\n hasValidRepository(repository: string): boolean {\n return repository.split('/').length === 2;\n }\n\n /**\n * Build the URL to the changelog markdown file for the release notes.\n * Platform sources can override this to match their web UI conventions.\n */\n getNotesSourceUrl(\n baseUrl: string,\n repository: string,\n changelogFile: string,\n ): string {\n return joinUrlParts(baseUrl, repository, 'blob', 'HEAD', changelogFile);\n }\n\n /**\n * Build the URL pointing to a specific heading within the changelog markdown\n * file. Platform sources can override this to match their anchor conventions.\n */\n getReleaseNotesMdAnchorUrl(notesSourceUrl: string, heading: string): string {\n const mdHeadingLink = heading\n .replace(regEx(/[[\\]()]/g), ' ')\n .replace(regEx(/^\\s*#*\\s*/), '')\n .split(' ')\n .filter(isTruthy)\n .filter((word) => !isHttpUrl(word))\n .join('-')\n .replace(regEx(/[^A-Za-z0-9-]/g), '');\n return `${notesSourceUrl}#${mdHeadingLink}`;\n }\n}\n"],"mappings":"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"}
@@ -53,7 +53,7 @@ async function flattenUpdates(config, packageFiles) {
53
53
  for (const packageFile of files) {
54
54
  const packageFileConfig = mergeChildConfig(managerConfig, packageFile);
55
55
  const packagePath = packageFile.packageFile?.split("/");
56
- if (packagePath.length > 0) packagePath.splice(-1, 1);
56
+ packagePath.splice(-1, 1);
57
57
  if (packagePath.length > 0) {
58
58
  packageFileConfig.parentDir = packagePath.at(-1);
59
59
  packageFileConfig.packageFileDir = packagePath.join("/");
@@ -1 +1 @@
1
- {"version":3,"file":"flatten.js","names":["template.compile"],"sources":["../../../../lib/workers/repository/updates/flatten.ts"],"sourcesContent":["import { isUndefined } from '@sindresorhus/is';\nimport {\n filterConfig,\n getManagerConfig,\n mergeChildConfig,\n} from '../../../config/index.ts';\nimport type { RenovateConfig } from '../../../config/types.ts';\nimport { logger } from '../../../logger/index.ts';\nimport { getDefaultConfig } from '../../../modules/datasource/index.ts';\nimport { get } from '../../../modules/manager/index.ts';\nimport type { PackageFile } from '../../../modules/manager/types.ts';\nimport { coerceArray } from '../../../util/array.ts';\nimport { detectSemanticCommits } from '../../../util/git/semantic.ts';\nimport { applyPackageRules } from '../../../util/package-rules/index.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport * as template from '../../../util/template/index.ts';\nimport { parseUrl } from '../../../util/url.ts';\nimport type { BranchUpgradeConfig } from '../../types.ts';\nimport { replacementAlreadyExists } from '../common.ts';\nimport { generateBranchName } from './branch-name.ts';\n\nfunction upper(str: string): string {\n return str.charAt(0).toUpperCase() + str.substring(1);\n}\n\nexport function sanitizeDepName(depName: string): string {\n return depName\n .replace(regEx(/\\$\\{[^}]+\\}\\/?/g), '')\n .replace(regEx(/[${}]/g), '')\n .replace('@types/', '')\n .replace('@', '')\n .replace(regEx(/\\//g), '-')\n .replace(regEx(/\\s+/g), '-')\n .replace(regEx(/:/g), '-')\n .replace(regEx(/-+/), '-')\n .toLowerCase();\n}\n\nexport function applyUpdateConfig(input: BranchUpgradeConfig): any {\n const updateConfig = { ...input };\n delete updateConfig.packageRules;\n // TODO: Remove next line once #8075 is complete\n updateConfig.depNameSanitized = updateConfig.depName\n ? sanitizeDepName(updateConfig.depName)\n : undefined;\n updateConfig.newNameSanitized = updateConfig.newName\n ? sanitizeDepName(updateConfig.newName)\n : undefined;\n if (updateConfig.sourceUrl) {\n const parsedSourceUrl = parseUrl(updateConfig.sourceUrl);\n if (parsedSourceUrl?.pathname) {\n updateConfig.sourceRepoSlug = parsedSourceUrl.pathname\n .replace(regEx(/^\\//), '') // remove leading slash\n .replace(regEx(/\\//g), '-') // change slashes to hyphens\n .replace(regEx(/-+/g), '-'); // remove multiple hyphens\n updateConfig.sourceRepo = parsedSourceUrl.pathname.replace(\n regEx(/^\\//),\n '',\n ); // remove leading slash\n updateConfig.sourceRepoOrg = updateConfig.sourceRepo.replace(\n regEx(/\\/.*/g),\n '',\n ); // remove everything after first slash\n updateConfig.sourceRepoName = updateConfig.sourceRepo.replace(\n regEx(/.*\\//g),\n '',\n ); // remove everything up to the last slash\n }\n }\n if (updateConfig.sourceDirectory) {\n updateConfig.sourceDirectory = template.compile(\n updateConfig.sourceDirectory,\n updateConfig,\n );\n }\n generateBranchName(updateConfig);\n return updateConfig;\n}\n\nexport async function flattenUpdates(\n config: RenovateConfig,\n packageFiles: Record<string, PackageFile[]>,\n): Promise<BranchUpgradeConfig[]> {\n const updates = [];\n const updateTypes = [\n 'major',\n 'minor',\n 'patch',\n 'pin',\n 'digest',\n 'lockFileMaintenance',\n 'replacement',\n ];\n for (const [manager, files] of Object.entries(packageFiles)) {\n const managerConfig = getManagerConfig(config, manager);\n for (const packageFile of files) {\n const packageFileConfig: BranchUpgradeConfig = mergeChildConfig(\n managerConfig,\n packageFile,\n ) as never;\n const packagePath = packageFile.packageFile?.split('/');\n if (packagePath.length > 0) {\n packagePath.splice(-1, 1);\n }\n if (packagePath.length > 0) {\n packageFileConfig.parentDir = packagePath.at(-1);\n packageFileConfig.packageFileDir = packagePath.join('/');\n } else {\n packageFileConfig.parentDir = '';\n packageFileConfig.packageFileDir = '';\n }\n let depIndex = 0;\n for (const dep of packageFile.deps) {\n if (dep.updates!.length) {\n const depConfig = mergeChildConfig(packageFileConfig, dep);\n // @ts-expect-error -- not easily typed\n delete depConfig.deps;\n depConfig.depIndex = depIndex; // used for autoreplace\n for (const update of dep.updates!) {\n if (\n update.updateType === 'replacement' &&\n update.newName &&\n replacementAlreadyExists(packageFile.deps, dep, update.newName)\n ) {\n logger.debug(\n { fileName: packageFile.packageFile },\n `Skipping replacement of ${dep.depName} with ${update.newName}: replacement already exists in ${packageFile.packageFile}`,\n );\n continue;\n }\n let updateConfig = mergeChildConfig(depConfig, update);\n delete updateConfig.updates;\n if (updateConfig.updateType) {\n // @ts-expect-error -- not easily typed\n updateConfig[`is${upper(updateConfig.updateType)}`] = true;\n }\n if (updateConfig.updateTypes) {\n updateConfig.updateTypes.forEach((updateType: string) => {\n // @ts-expect-error -- not easily typed\n updateConfig[`is${upper(updateType)}`] = true;\n });\n }\n // apply config from datasource\n const datasourceConfig = await getDefaultConfig(\n depConfig.datasource!,\n );\n updateConfig = mergeChildConfig(updateConfig, datasourceConfig);\n updateConfig = await applyPackageRules(\n updateConfig,\n 'datasource-merge',\n );\n // apply major/minor/patch/pin/digest\n updateConfig = mergeChildConfig(\n updateConfig,\n // @ts-expect-error -- not easily typed\n updateConfig[updateConfig.updateType],\n );\n for (const updateType of updateTypes) {\n // @ts-expect-error -- not easily typed\n delete updateConfig[updateType];\n }\n // Apply again in case any were added by the updateType config\n updateConfig = await applyPackageRules(\n updateConfig,\n 'update-type-merge',\n );\n updateConfig = applyUpdateConfig(updateConfig);\n updateConfig.baseDeps = packageFile.deps;\n update.branchName = updateConfig.branchName;\n\n // make sure that we use the dependency's current state of attestation, rather than using the new update's value\n updateConfig.hasAttestation = depConfig.hasAttestation;\n\n updates.push(updateConfig);\n }\n }\n depIndex += 1;\n }\n if (\n get(manager, 'supportsLockFileMaintenance') &&\n packageFileConfig.lockFileMaintenance!.enabled\n ) {\n // Apply lockFileMaintenance config before packageRules\n let lockFileConfig = mergeChildConfig(\n packageFileConfig,\n packageFileConfig.lockFileMaintenance!,\n );\n lockFileConfig.updateType = 'lockFileMaintenance';\n lockFileConfig.isLockFileMaintenance = true;\n lockFileConfig = await applyPackageRules(\n lockFileConfig,\n 'lock-file-maintenance-merge',\n );\n // Apply lockFileMaintenance and packageRules again\n lockFileConfig = mergeChildConfig(\n lockFileConfig,\n lockFileConfig.lockFileMaintenance!,\n );\n lockFileConfig = await applyPackageRules(\n lockFileConfig,\n 'lock-file-maintenance-merge-2',\n );\n // Remove unnecessary objects\n for (const updateType of updateTypes) {\n // @ts-expect-error -- not easily typed\n delete lockFileConfig[updateType];\n }\n delete lockFileConfig.packageRules;\n // @ts-expect-error -- not easily typed\n delete lockFileConfig.deps;\n generateBranchName(lockFileConfig);\n updates.push(lockFileConfig);\n }\n if (get(manager, 'updateLockedDependency')) {\n for (const lockFile of coerceArray(packageFileConfig.lockFiles)) {\n const lockfileRemediations = config.remediations as Record<\n string,\n Record<string, any>[]\n >;\n const remediations = lockfileRemediations?.[lockFile];\n if (remediations) {\n for (const remediation of remediations) {\n let updateConfig = mergeChildConfig(\n packageFileConfig,\n remediation,\n );\n updateConfig = mergeChildConfig(\n updateConfig,\n config.vulnerabilityAlerts,\n );\n delete updateConfig.vulnerabilityAlerts;\n updateConfig.isVulnerabilityAlert = true;\n updateConfig.isRemediation = true;\n updateConfig.lockFile = lockFile;\n updateConfig.currentValue = updateConfig.currentVersion;\n updateConfig.newValue = updateConfig.newVersion;\n updateConfig = applyUpdateConfig(updateConfig);\n updateConfig.enabled = true;\n updates.push(updateConfig);\n }\n }\n }\n }\n }\n }\n if (config.semanticCommits === 'auto') {\n const semanticCommits = await detectSemanticCommits();\n for (const update of updates) {\n update.semanticCommits = semanticCommits;\n }\n }\n const filteredUpdates = updates\n .filter((update) => update.enabled !== false)\n .filter((update) => isUndefined(update.skipReason))\n .map(({ vulnerabilityAlerts: _, ...update }) => update)\n .map((update) => filterConfig(update, 'branch'));\n if (filteredUpdates.length < updates.length) {\n logger.debug(\n `Filtered out ${updates.length - filteredUpdates.length} disabled update(s). ${filteredUpdates.length} update(s) remaining.`,\n );\n }\n return filteredUpdates;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"flatten.js","names":["template.compile"],"sources":["../../../../lib/workers/repository/updates/flatten.ts"],"sourcesContent":["import { isUndefined } from '@sindresorhus/is';\nimport {\n filterConfig,\n getManagerConfig,\n mergeChildConfig,\n} from '../../../config/index.ts';\nimport type { RenovateConfig } from '../../../config/types.ts';\nimport { logger } from '../../../logger/index.ts';\nimport { getDefaultConfig } from '../../../modules/datasource/index.ts';\nimport { get } from '../../../modules/manager/index.ts';\nimport type { PackageFile } from '../../../modules/manager/types.ts';\nimport { coerceArray } from '../../../util/array.ts';\nimport { detectSemanticCommits } from '../../../util/git/semantic.ts';\nimport { applyPackageRules } from '../../../util/package-rules/index.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport * as template from '../../../util/template/index.ts';\nimport { parseUrl } from '../../../util/url.ts';\nimport type { BranchUpgradeConfig } from '../../types.ts';\nimport { replacementAlreadyExists } from '../common.ts';\nimport { generateBranchName } from './branch-name.ts';\n\nfunction upper(str: string): string {\n return str.charAt(0).toUpperCase() + str.substring(1);\n}\n\nexport function sanitizeDepName(depName: string): string {\n return depName\n .replace(regEx(/\\$\\{[^}]+\\}\\/?/g), '')\n .replace(regEx(/[${}]/g), '')\n .replace('@types/', '')\n .replace('@', '')\n .replace(regEx(/\\//g), '-')\n .replace(regEx(/\\s+/g), '-')\n .replace(regEx(/:/g), '-')\n .replace(regEx(/-+/), '-')\n .toLowerCase();\n}\n\nexport function applyUpdateConfig(input: BranchUpgradeConfig): any {\n const updateConfig = { ...input };\n delete updateConfig.packageRules;\n // TODO: Remove next line once #8075 is complete\n updateConfig.depNameSanitized = updateConfig.depName\n ? sanitizeDepName(updateConfig.depName)\n : undefined;\n updateConfig.newNameSanitized = updateConfig.newName\n ? sanitizeDepName(updateConfig.newName)\n : undefined;\n if (updateConfig.sourceUrl) {\n const parsedSourceUrl = parseUrl(updateConfig.sourceUrl);\n if (parsedSourceUrl?.pathname) {\n updateConfig.sourceRepoSlug = parsedSourceUrl.pathname\n .replace(regEx(/^\\//), '') // remove leading slash\n .replace(regEx(/\\//g), '-') // change slashes to hyphens\n .replace(regEx(/-+/g), '-'); // remove multiple hyphens\n updateConfig.sourceRepo = parsedSourceUrl.pathname.replace(\n regEx(/^\\//),\n '',\n ); // remove leading slash\n updateConfig.sourceRepoOrg = updateConfig.sourceRepo.replace(\n regEx(/\\/.*/g),\n '',\n ); // remove everything after first slash\n updateConfig.sourceRepoName = updateConfig.sourceRepo.replace(\n regEx(/.*\\//g),\n '',\n ); // remove everything up to the last slash\n }\n }\n if (updateConfig.sourceDirectory) {\n updateConfig.sourceDirectory = template.compile(\n updateConfig.sourceDirectory,\n updateConfig,\n );\n }\n generateBranchName(updateConfig);\n return updateConfig;\n}\n\nexport async function flattenUpdates(\n config: RenovateConfig,\n packageFiles: Record<string, PackageFile[]>,\n): Promise<BranchUpgradeConfig[]> {\n const updates = [];\n const updateTypes = [\n 'major',\n 'minor',\n 'patch',\n 'pin',\n 'digest',\n 'lockFileMaintenance',\n 'replacement',\n ];\n for (const [manager, files] of Object.entries(packageFiles)) {\n const managerConfig = getManagerConfig(config, manager);\n for (const packageFile of files) {\n const packageFileConfig: BranchUpgradeConfig = mergeChildConfig(\n managerConfig,\n packageFile,\n ) as never;\n const packagePath = packageFile.packageFile?.split('/');\n // `split` always yields at least one element, so there is always a file\n // name to drop here\n packagePath.splice(-1, 1);\n if (packagePath.length > 0) {\n packageFileConfig.parentDir = packagePath.at(-1);\n packageFileConfig.packageFileDir = packagePath.join('/');\n } else {\n packageFileConfig.parentDir = '';\n packageFileConfig.packageFileDir = '';\n }\n let depIndex = 0;\n for (const dep of packageFile.deps) {\n if (dep.updates!.length) {\n const depConfig = mergeChildConfig(packageFileConfig, dep);\n // @ts-expect-error -- not easily typed\n delete depConfig.deps;\n depConfig.depIndex = depIndex; // used for autoreplace\n for (const update of dep.updates!) {\n if (\n update.updateType === 'replacement' &&\n update.newName &&\n replacementAlreadyExists(packageFile.deps, dep, update.newName)\n ) {\n logger.debug(\n { fileName: packageFile.packageFile },\n `Skipping replacement of ${dep.depName} with ${update.newName}: replacement already exists in ${packageFile.packageFile}`,\n );\n continue;\n }\n let updateConfig = mergeChildConfig(depConfig, update);\n delete updateConfig.updates;\n if (updateConfig.updateType) {\n // @ts-expect-error -- not easily typed\n updateConfig[`is${upper(updateConfig.updateType)}`] = true;\n }\n if (updateConfig.updateTypes) {\n updateConfig.updateTypes.forEach((updateType: string) => {\n // @ts-expect-error -- not easily typed\n updateConfig[`is${upper(updateType)}`] = true;\n });\n }\n // apply config from datasource\n const datasourceConfig = await getDefaultConfig(\n depConfig.datasource!,\n );\n updateConfig = mergeChildConfig(updateConfig, datasourceConfig);\n updateConfig = await applyPackageRules(\n updateConfig,\n 'datasource-merge',\n );\n // apply major/minor/patch/pin/digest\n updateConfig = mergeChildConfig(\n updateConfig,\n // @ts-expect-error -- not easily typed\n updateConfig[updateConfig.updateType],\n );\n for (const updateType of updateTypes) {\n // @ts-expect-error -- not easily typed\n delete updateConfig[updateType];\n }\n // Apply again in case any were added by the updateType config\n updateConfig = await applyPackageRules(\n updateConfig,\n 'update-type-merge',\n );\n updateConfig = applyUpdateConfig(updateConfig);\n updateConfig.baseDeps = packageFile.deps;\n update.branchName = updateConfig.branchName;\n\n // make sure that we use the dependency's current state of attestation, rather than using the new update's value\n updateConfig.hasAttestation = depConfig.hasAttestation;\n\n updates.push(updateConfig);\n }\n }\n depIndex += 1;\n }\n if (\n get(manager, 'supportsLockFileMaintenance') &&\n packageFileConfig.lockFileMaintenance!.enabled\n ) {\n // Apply lockFileMaintenance config before packageRules\n let lockFileConfig = mergeChildConfig(\n packageFileConfig,\n packageFileConfig.lockFileMaintenance!,\n );\n lockFileConfig.updateType = 'lockFileMaintenance';\n lockFileConfig.isLockFileMaintenance = true;\n lockFileConfig = await applyPackageRules(\n lockFileConfig,\n 'lock-file-maintenance-merge',\n );\n // Apply lockFileMaintenance and packageRules again\n lockFileConfig = mergeChildConfig(\n lockFileConfig,\n lockFileConfig.lockFileMaintenance!,\n );\n lockFileConfig = await applyPackageRules(\n lockFileConfig,\n 'lock-file-maintenance-merge-2',\n );\n // Remove unnecessary objects\n for (const updateType of updateTypes) {\n // @ts-expect-error -- not easily typed\n delete lockFileConfig[updateType];\n }\n delete lockFileConfig.packageRules;\n // @ts-expect-error -- not easily typed\n delete lockFileConfig.deps;\n generateBranchName(lockFileConfig);\n updates.push(lockFileConfig);\n }\n if (get(manager, 'updateLockedDependency')) {\n for (const lockFile of coerceArray(packageFileConfig.lockFiles)) {\n const lockfileRemediations = config.remediations as Record<\n string,\n Record<string, any>[]\n >;\n const remediations = lockfileRemediations?.[lockFile];\n if (remediations) {\n for (const remediation of remediations) {\n let updateConfig = mergeChildConfig(\n packageFileConfig,\n remediation,\n );\n updateConfig = mergeChildConfig(\n updateConfig,\n config.vulnerabilityAlerts,\n );\n delete updateConfig.vulnerabilityAlerts;\n updateConfig.isVulnerabilityAlert = true;\n updateConfig.isRemediation = true;\n updateConfig.lockFile = lockFile;\n updateConfig.currentValue = updateConfig.currentVersion;\n updateConfig.newValue = updateConfig.newVersion;\n updateConfig = applyUpdateConfig(updateConfig);\n updateConfig.enabled = true;\n updates.push(updateConfig);\n }\n }\n }\n }\n }\n }\n if (config.semanticCommits === 'auto') {\n const semanticCommits = await detectSemanticCommits();\n for (const update of updates) {\n update.semanticCommits = semanticCommits;\n }\n }\n const filteredUpdates = updates\n .filter((update) => update.enabled !== false)\n .filter((update) => isUndefined(update.skipReason))\n .map(({ vulnerabilityAlerts: _, ...update }) => update)\n .map((update) => filterConfig(update, 'branch'));\n if (filteredUpdates.length < updates.length) {\n logger.debug(\n `Filtered out ${updates.length - filteredUpdates.length} disabled update(s). ${filteredUpdates.length} update(s) remaining.`,\n );\n }\n return filteredUpdates;\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "renovate",
3
3
  "description": "Automated dependency updates. Flexible so you don't need to be.",
4
- "version": "44.95.0",
4
+ "version": "44.96.0",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "renovate": "dist/renovate.js",
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "$id": "https://docs.renovatebot.com/renovate-schema.json",
3
- "title": "JSON schema for Renovate 44.95.0 config files (https://renovatebot.com/)",
3
+ "title": "JSON schema for Renovate 44.96.0 config files (https://renovatebot.com/)",
4
4
  "$schema": "http://json-schema.org/draft-07/schema#",
5
- "x-renovate-version": "44.95.0",
5
+ "x-renovate-version": "44.96.0",
6
6
  "allowComments": true,
7
7
  "type": "object",
8
8
  "definitions": {
@@ -6476,6 +6476,12 @@
6476
6476
  ],
6477
6477
  "default": "timestamp-required"
6478
6478
  },
6479
+ "minimumReleaseAgeBuffer": {
6480
+ "description": "Extra time added to `minimumReleaseAge` before an update is considered stable.\nSee also: https://docs.renovatebot.com/configuration-options/#minimumreleaseagebuffer",
6481
+ "markdownDescription": "Extra time added to `minimumReleaseAge` before an update is considered stable.\n\nSee also: [minimumReleaseAgeBuffer](https://docs.renovatebot.com/configuration-options/#minimumreleaseagebuffer)",
6482
+ "type": "string",
6483
+ "default": "30 minutes"
6484
+ },
6479
6485
  "minor": {
6480
6486
  "description": "Configuration to apply when an update type is `minor`.\nSee also: https://docs.renovatebot.com/configuration-options/#minor",
6481
6487
  "markdownDescription": "Configuration to apply when an update type is `minor`.\n\nSee also: [minor](https://docs.renovatebot.com/configuration-options/#minor)",
@@ -11120,6 +11126,9 @@
11120
11126
  "minimumReleaseAgeBehaviour": {
11121
11127
  "$ref": "#/definitions/minimumReleaseAgeBehaviour"
11122
11128
  },
11129
+ "minimumReleaseAgeBuffer": {
11130
+ "$ref": "#/definitions/minimumReleaseAgeBuffer"
11131
+ },
11123
11132
  "minor": {
11124
11133
  "$ref": "#/definitions/minor"
11125
11134
  },