renovate 44.152.0 → 44.153.1

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.
@@ -9,22 +9,23 @@ import { isEmptyString, isNullOrUndefined, isString, isUndefined } from "@sindre
9
9
  import parse from "github-url-from-git";
10
10
  //#region lib/modules/datasource/metadata.ts
11
11
  const githubPages = regEx("^https://([^.]+).github.com/([^/]+)$");
12
+ const gitPlusPrefix = regEx("^git\\+");
12
13
  const gitPrefix = regEx("^git:/?/?");
13
14
  function massageUrl(sourceUrl) {
14
- const massagedUrl = massageGitAtUrl(sourceUrl);
15
+ const massagedUrl = massageGitPrefixes(sourceUrl);
15
16
  if (!parseUrl(massagedUrl)) return "";
16
17
  if (detectPlatform(massagedUrl) === "gitlab") return massageGitlabUrl(sourceUrl);
17
18
  return massageGithubUrl(sourceUrl);
18
19
  }
19
20
  function massageGithubUrl(url) {
20
- return massageGitAtUrl(url).replace("http:", "https:").replace("http+git:", "https:").replace("https+git:", "https:").replace("ssh://git@", "https://").replace(gitPrefix, "https://").replace(githubPages, "https://github.com/$1/$2").replace("www.github.com", "github.com").split("/").slice(0, 5).join("/");
21
+ return massageGitPrefixes(url).replace("http:", "https:").replace("http+git:", "https:").replace("https+git:", "https:").replace("ssh://git@", "https://").replace(gitPrefix, "https://").replace(githubPages, "https://github.com/$1/$2").replace("www.github.com", "github.com").split("/").slice(0, 5).join("/");
21
22
  }
22
23
  function massageGitlabUrl(url) {
23
- return massageGitAtUrl(url).replace("http:", "https:").replace(gitPrefix, "https://").replace(regEx(/\/tree\/.*$/i), "").replace(regEx(/\/$/i), "").replace(regEx(/\.git$/i), "");
24
+ return massageGitPrefixes(url).replace("http:", "https:").replace("ssh://git@", "https://").replace(gitPrefix, "https://").replace(regEx(/\/tree\/.*$/i), "").replace(regEx(/\/$/i), "").replace(regEx(/\.git$/i), "");
24
25
  }
25
- function massageGitAtUrl(url) {
26
- let massagedUrl = url;
27
- if (url.startsWith("git@")) massagedUrl = url.replace(":", "/").replace("git@", "https://");
26
+ function massageGitPrefixes(url) {
27
+ let massagedUrl = url.replace(gitPlusPrefix, "");
28
+ if (massagedUrl.startsWith("git@")) massagedUrl = massagedUrl.replace(":", "/").replace("git@", "https://");
28
29
  return massagedUrl;
29
30
  }
30
31
  function massageTimestamps(dep) {
@@ -1 +1 @@
1
- {"version":3,"file":"metadata.js","names":[],"sources":["../../../lib/modules/datasource/metadata.ts"],"sourcesContent":["import {\n isEmptyString,\n isNullOrUndefined,\n isString,\n isUndefined,\n} from '@sindresorhus/is';\nimport parse from 'github-url-from-git';\nimport { detectPlatform } from '../../util/common.ts';\nimport { parseGitUrl } from '../../util/git/url.ts';\nimport * as hostRules from '../../util/host-rules.ts';\nimport { regEx } from '../../util/regex.ts';\nimport { asTimestamp } from '../../util/timestamp.ts';\nimport { isHttpUrl, parseUrl, trimTrailingSlash } from '../../util/url.ts';\nimport { manualChangelogUrls, manualSourceUrls } from './metadata-manual.ts';\nimport type { ReleaseResult } from './types.ts';\n\nconst githubPages = regEx('^https://([^.]+).github.com/([^/]+)$');\nconst gitPrefix = regEx('^git:/?/?');\n\nexport function massageUrl(sourceUrl: string): string {\n // Replace git@ sourceUrl with https so hostname can be parsed\n const massagedUrl = massageGitAtUrl(sourceUrl);\n\n // Check if URL is valid\n const parsedUrl = parseUrl(massagedUrl);\n if (!parsedUrl) {\n return '';\n }\n\n if (detectPlatform(massagedUrl) === 'gitlab') {\n return massageGitlabUrl(sourceUrl);\n }\n return massageGithubUrl(sourceUrl);\n}\n\nexport function massageGithubUrl(url: string): string {\n const massagedUrl = massageGitAtUrl(url);\n\n return massagedUrl\n .replace('http:', 'https:')\n .replace('http+git:', 'https:')\n .replace('https+git:', 'https:')\n .replace('ssh://git@', 'https://')\n .replace(gitPrefix, 'https://')\n .replace(githubPages, 'https://github.com/$1/$2')\n .replace('www.github.com', 'github.com')\n .split('/')\n .slice(0, 5)\n .join('/');\n}\n\nexport function massageGitlabUrl(url: string): string {\n const massagedUrl = massageGitAtUrl(url);\n\n return massagedUrl\n .replace('http:', 'https:')\n .replace(gitPrefix, 'https://')\n .replace(regEx(/\\/tree\\/.*$/i), '')\n .replace(regEx(/\\/$/i), '')\n .replace(regEx(/\\.git$/i), '');\n}\n\nfunction massageGitAtUrl(url: string): string {\n let massagedUrl = url;\n\n if (url.startsWith('git@')) {\n massagedUrl = url.replace(':', '/').replace('git@', 'https://');\n }\n return massagedUrl;\n}\n\nfunction massageTimestamps(dep: ReleaseResult): void {\n for (const release of dep.releases || []) {\n let { releaseTimestamp } = release;\n delete release.releaseTimestamp;\n releaseTimestamp = asTimestamp(releaseTimestamp);\n if (releaseTimestamp) {\n release.releaseTimestamp = releaseTimestamp;\n }\n }\n}\n\nexport function addMetaData(\n dep: ReleaseResult,\n datasource: string,\n packageName: string,\n): void {\n massageTimestamps(dep);\n\n const packageNameLowercase = packageName.toLowerCase();\n const manualChangelogUrl =\n manualChangelogUrls[datasource]?.[packageNameLowercase];\n if (manualChangelogUrl) {\n dep.changelogUrl = manualChangelogUrl;\n }\n\n const manualSourceUrl = manualSourceUrls[datasource]?.[packageNameLowercase];\n if (manualSourceUrl) {\n dep.sourceUrl = manualSourceUrl;\n }\n\n if (dep.sourceUrl && !dep.sourceDirectory) {\n try {\n const parsed = parseGitUrl(dep.sourceUrl);\n if (parsed.filepathtype === 'tree' && parsed.filepath !== '') {\n dep.sourceUrl = parsed.toString();\n dep.sourceDirectory = parsed.filepath;\n }\n } catch {\n // ignore invalid urls\n }\n }\n\n if (\n !dep.sourceUrl &&\n dep.changelogUrl &&\n detectPlatform(dep.changelogUrl) === 'github'\n ) {\n dep.sourceUrl = dep.changelogUrl;\n }\n\n if (!dep.sourceUrl && dep.homepage) {\n const platform = detectPlatform(dep.homepage);\n if (platform === 'github' || platform === 'gitlab') {\n dep.sourceUrl = dep.homepage;\n }\n }\n const extraBaseUrls = [];\n // istanbul ignore next\n hostRules.hosts({ hostType: 'github' }).forEach((host) => {\n extraBaseUrls.push(host, `gist.${host}`);\n });\n extraBaseUrls.push('gitlab.com');\n if (dep.sourceUrl) {\n // try massaging it\n const massagedUrl = massageUrl(dep.sourceUrl);\n if (isEmptyString(massagedUrl)) {\n delete dep.sourceUrl;\n } else {\n // parse from github-url-from-git only supports Github URLs as its name implies\n dep.sourceUrl =\n parse(massagedUrl, {\n extraBaseUrls,\n }) || dep.sourceUrl;\n // prefer massaged URL to source URL if the latter does not start with http:// or https://\n // (e.g. git@somehost.com) and the detected platform is gitlab.\n // this allows to retrieve changelogs from git hosts other than Github\n if (\n !isHttpUrl(dep.sourceUrl) &&\n detectPlatform(massagedUrl) === 'gitlab'\n ) {\n dep.sourceUrl = massagedUrl;\n }\n }\n }\n if (shouldDeleteHomepage(dep.sourceUrl, dep.homepage)) {\n delete dep.homepage;\n }\n // Clean up any empty urls\n const urlKeys: (keyof ReleaseResult)[] = [\n 'homepage',\n 'sourceUrl',\n 'changelogUrl',\n 'dependencyUrl',\n ];\n for (const urlKey of urlKeys) {\n const urlVal = dep[urlKey];\n if (isString(urlVal) && isHttpUrl(urlVal.trim())) {\n dep[urlKey] = urlVal.trim() as never;\n } else {\n delete dep[urlKey];\n }\n }\n}\n\n/**\n * Returns true if\n * 1. it's a github or gitlab url and not a path within the repo.\n * 2. it's equal to sourceURl\n * @param sourceUrl\n * @param homepage\n */\nexport function shouldDeleteHomepage(\n sourceUrl: string | null | undefined,\n homepage: string | undefined,\n): boolean {\n if (isNullOrUndefined(sourceUrl) || isUndefined(homepage)) {\n return false;\n }\n const massagedSourceUrl = massageUrl(sourceUrl);\n const platform = detectPlatform(homepage);\n if (platform === 'github' || platform === 'gitlab') {\n const sourceUrlParsed = parseUrl(massagedSourceUrl);\n if (isNullOrUndefined(sourceUrlParsed)) {\n return false;\n }\n const homepageParsed = parseUrl(homepage);\n return (\n homepageParsed !== null &&\n trimTrailingSlash(homepageParsed.pathname) ===\n trimTrailingSlash(sourceUrlParsed.pathname)\n );\n }\n return massagedSourceUrl === homepage;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"metadata.js","names":[],"sources":["../../../lib/modules/datasource/metadata.ts"],"sourcesContent":["import {\n isEmptyString,\n isNullOrUndefined,\n isString,\n isUndefined,\n} from '@sindresorhus/is';\nimport parse from 'github-url-from-git';\nimport { detectPlatform } from '../../util/common.ts';\nimport { parseGitUrl } from '../../util/git/url.ts';\nimport * as hostRules from '../../util/host-rules.ts';\nimport { regEx } from '../../util/regex.ts';\nimport { asTimestamp } from '../../util/timestamp.ts';\nimport { isHttpUrl, parseUrl, trimTrailingSlash } from '../../util/url.ts';\nimport { manualChangelogUrls, manualSourceUrls } from './metadata-manual.ts';\nimport type { ReleaseResult } from './types.ts';\n\nconst githubPages = regEx('^https://([^.]+).github.com/([^/]+)$');\nconst gitPlusPrefix = regEx('^git\\\\+');\nconst gitPrefix = regEx('^git:/?/?');\n\nexport function massageUrl(sourceUrl: string): string {\n // Replace git@ sourceUrl with https so hostname can be parsed\n const massagedUrl = massageGitPrefixes(sourceUrl);\n\n // Check if URL is valid\n const parsedUrl = parseUrl(massagedUrl);\n if (!parsedUrl) {\n return '';\n }\n\n if (detectPlatform(massagedUrl) === 'gitlab') {\n return massageGitlabUrl(sourceUrl);\n }\n return massageGithubUrl(sourceUrl);\n}\n\nexport function massageGithubUrl(url: string): string {\n const massagedUrl = massageGitPrefixes(url);\n\n return massagedUrl\n .replace('http:', 'https:')\n .replace('http+git:', 'https:')\n .replace('https+git:', 'https:')\n .replace('ssh://git@', 'https://')\n .replace(gitPrefix, 'https://')\n .replace(githubPages, 'https://github.com/$1/$2')\n .replace('www.github.com', 'github.com')\n .split('/')\n .slice(0, 5)\n .join('/');\n}\n\nexport function massageGitlabUrl(url: string): string {\n const massagedUrl = massageGitPrefixes(url);\n\n return massagedUrl\n .replace('http:', 'https:')\n .replace('ssh://git@', 'https://')\n .replace(gitPrefix, 'https://')\n .replace(regEx(/\\/tree\\/.*$/i), '')\n .replace(regEx(/\\/$/i), '')\n .replace(regEx(/\\.git$/i), '');\n}\n\nfunction massageGitPrefixes(url: string): string {\n let massagedUrl = url.replace(gitPlusPrefix, '');\n\n if (massagedUrl.startsWith('git@')) {\n massagedUrl = massagedUrl.replace(':', '/').replace('git@', 'https://');\n }\n\n return massagedUrl;\n}\n\nfunction massageTimestamps(dep: ReleaseResult): void {\n for (const release of dep.releases || []) {\n let { releaseTimestamp } = release;\n delete release.releaseTimestamp;\n releaseTimestamp = asTimestamp(releaseTimestamp);\n if (releaseTimestamp) {\n release.releaseTimestamp = releaseTimestamp;\n }\n }\n}\n\nexport function addMetaData(\n dep: ReleaseResult,\n datasource: string,\n packageName: string,\n): void {\n massageTimestamps(dep);\n\n const packageNameLowercase = packageName.toLowerCase();\n const manualChangelogUrl =\n manualChangelogUrls[datasource]?.[packageNameLowercase];\n if (manualChangelogUrl) {\n dep.changelogUrl = manualChangelogUrl;\n }\n\n const manualSourceUrl = manualSourceUrls[datasource]?.[packageNameLowercase];\n if (manualSourceUrl) {\n dep.sourceUrl = manualSourceUrl;\n }\n\n if (dep.sourceUrl && !dep.sourceDirectory) {\n try {\n const parsed = parseGitUrl(dep.sourceUrl);\n if (parsed.filepathtype === 'tree' && parsed.filepath !== '') {\n dep.sourceUrl = parsed.toString();\n dep.sourceDirectory = parsed.filepath;\n }\n } catch {\n // ignore invalid urls\n }\n }\n\n if (\n !dep.sourceUrl &&\n dep.changelogUrl &&\n detectPlatform(dep.changelogUrl) === 'github'\n ) {\n dep.sourceUrl = dep.changelogUrl;\n }\n\n if (!dep.sourceUrl && dep.homepage) {\n const platform = detectPlatform(dep.homepage);\n if (platform === 'github' || platform === 'gitlab') {\n dep.sourceUrl = dep.homepage;\n }\n }\n const extraBaseUrls = [];\n // istanbul ignore next\n hostRules.hosts({ hostType: 'github' }).forEach((host) => {\n extraBaseUrls.push(host, `gist.${host}`);\n });\n extraBaseUrls.push('gitlab.com');\n if (dep.sourceUrl) {\n // try massaging it\n const massagedUrl = massageUrl(dep.sourceUrl);\n if (isEmptyString(massagedUrl)) {\n delete dep.sourceUrl;\n } else {\n // parse from github-url-from-git only supports Github URLs as its name implies\n dep.sourceUrl =\n parse(massagedUrl, {\n extraBaseUrls,\n }) || dep.sourceUrl;\n // prefer massaged URL to source URL if the latter does not start with http:// or https://\n // (e.g. git@somehost.com) and the detected platform is gitlab.\n // this allows to retrieve changelogs from git hosts other than Github\n if (\n !isHttpUrl(dep.sourceUrl) &&\n detectPlatform(massagedUrl) === 'gitlab'\n ) {\n dep.sourceUrl = massagedUrl;\n }\n }\n }\n if (shouldDeleteHomepage(dep.sourceUrl, dep.homepage)) {\n delete dep.homepage;\n }\n // Clean up any empty urls\n const urlKeys: (keyof ReleaseResult)[] = [\n 'homepage',\n 'sourceUrl',\n 'changelogUrl',\n 'dependencyUrl',\n ];\n for (const urlKey of urlKeys) {\n const urlVal = dep[urlKey];\n if (isString(urlVal) && isHttpUrl(urlVal.trim())) {\n dep[urlKey] = urlVal.trim() as never;\n } else {\n delete dep[urlKey];\n }\n }\n}\n\n/**\n * Returns true if\n * 1. it's a github or gitlab url and not a path within the repo.\n * 2. it's equal to sourceURl\n * @param sourceUrl\n * @param homepage\n */\nexport function shouldDeleteHomepage(\n sourceUrl: string | null | undefined,\n homepage: string | undefined,\n): boolean {\n if (isNullOrUndefined(sourceUrl) || isUndefined(homepage)) {\n return false;\n }\n const massagedSourceUrl = massageUrl(sourceUrl);\n const platform = detectPlatform(homepage);\n if (platform === 'github' || platform === 'gitlab') {\n const sourceUrlParsed = parseUrl(massagedSourceUrl);\n if (isNullOrUndefined(sourceUrlParsed)) {\n return false;\n }\n const homepageParsed = parseUrl(homepage);\n return (\n homepageParsed !== null &&\n trimTrailingSlash(homepageParsed.pathname) ===\n trimTrailingSlash(sourceUrlParsed.pathname)\n );\n }\n return massagedSourceUrl === homepage;\n}\n"],"mappings":"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"}
@@ -43,6 +43,13 @@ const commentTagRegex = regEx(/^\s+#\s*(?<tag>\S.*?)\s*$/);
43
43
  */
44
44
  const autoReplaceStringTemplate = "{{depName}}#{{#if newDigest}}{{newDigest}} # {{newValue}}{{else}}{{newValue}}{{/if}}";
45
45
  /**
46
+ * Match `<name>--v<version>`, `<name>-v<version>`, and `<name>_v<version>` tags.
47
+ */
48
+ const packageTagRegex = regEx(/^(?<compatibility>.+?[-_])v(?<version>\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?)$/);
49
+ function packageTagConfig(currentValue) {
50
+ return packageTagRegex.test(currentValue) ? { versionCompatibility: packageTagRegex.source } : {};
51
+ }
52
+ /**
46
53
  * APM virtual-package subpaths (skills/prompts/etc.) begin at one of these
47
54
  * "primitive" directories or at a file with a virtual extension. APM only uses
48
55
  * these to find where a repo path ends for hosts with nested namespaces; see
@@ -158,13 +165,15 @@ function parseApmDependency(entry, depType, findPinnedTail) {
158
165
  ...dep,
159
166
  currentValue: tail.currentValue,
160
167
  currentDigest: ref,
161
- replaceString: tail.replaceString
168
+ replaceString: tail.replaceString,
169
+ ...packageTagConfig(tail.currentValue)
162
170
  };
163
171
  }
164
172
  return {
165
173
  ...dep,
166
174
  currentValue: ref,
167
- replaceString: entry
175
+ replaceString: entry,
176
+ ...packageTagConfig(ref)
168
177
  };
169
178
  }
170
179
  function extractSection(entries, depType, findPinnedTail) {
@@ -1 +1 @@
1
- {"version":3,"file":"extract.js","names":[],"sources":["../../../../lib/modules/manager/apm/extract.ts"],"sourcesContent":["import { isTruthy } from '@sindresorhus/is';\nimport { logger } from '../../../logger/index.ts';\nimport { coerceArray } from '../../../util/array.ts';\nimport { detectPlatform } from '../../../util/common.ts';\nimport { newlineRegex, regEx } from '../../../util/regex.ts';\nimport { isLongCommitSha } from '../../../util/schema-utils/git.ts';\nimport { parseSingleYaml } from '../../../util/yaml.ts';\nimport { GitTagsDatasource } from '../../datasource/git-tags/index.ts';\nimport { GithubTagsDatasource } from '../../datasource/github-tags/index.ts';\nimport { GitlabTagsDatasource } from '../../datasource/gitlab-tags/index.ts';\nimport type { PackageDependency, PackageFileContent } from '../types.ts';\nimport { ApmManifest } from './schema.ts';\n\ninterface DatasourceResult {\n datasource: string;\n packageName: string;\n registryUrls?: string[];\n}\n\n/**\n * Determine which Renovate datasource to use for an APM dependency, based on\n * the git host `platform` (already resolved via `detectPlatform`, which honors\n * `hostRules`). github/gitlab (and their self-hosted variants) map to the\n * `github-tags` / `gitlab-tags` datasources; every other host (Bitbucket, Azure\n * DevOps, etc.) falls back to the generic `git-tags` datasource.\n */\nfunction determineDatasource(\n host: string,\n platform: string | null,\n repoPath: string,\n): DatasourceResult {\n if (platform === 'github') {\n return {\n datasource: GithubTagsDatasource.id,\n packageName: repoPath,\n ...(host === 'github.com' ? {} : { registryUrls: [`https://${host}`] }),\n };\n }\n\n if (platform === 'gitlab') {\n return {\n datasource: GitlabTagsDatasource.id,\n packageName: repoPath,\n ...(host === 'gitlab.com' ? {} : { registryUrls: [`https://${host}`] }),\n };\n }\n\n return {\n datasource: GitTagsDatasource.id,\n packageName: `https://${host}/${repoPath}`,\n };\n}\n\n/** A trailing ` # <tag>` comment on a manifest line. */\nconst commentTagRegex = regEx(/^\\s+#\\s*(?<tag>\\S.*?)\\s*$/);\n\n/**\n * Renders both `owner/repo#<tag>` and the digest-pinned\n * `owner/repo#<sha> # <tag>` form, mirroring the github-actions\n * `uses: owner/action@<sha> # v4` behaviour so `pinDigests` can pin a bare tag\n * to a SHA and keep the trailing tag comment current.\n */\nconst autoReplaceStringTemplate =\n '{{depName}}#{{#if newDigest}}{{newDigest}} # {{newValue}}{{else}}{{newValue}}{{/if}}';\n\n/**\n * APM virtual-package subpaths (skills/prompts/etc.) begin at one of these\n * \"primitive\" directories or at a file with a virtual extension. APM only uses\n * these to find where a repo path ends for hosts with nested namespaces; see\n * `_GITLAB_VIRTUAL_ROOT_SEGMENTS` / `VIRTUAL_FILE_EXTENSIONS` in apm.\n */\nconst virtualRootSegments = new Set(['prompts', 'instructions', 'collections']);\nconst virtualFileRegex = regEx(/\\.(?:prompt|instructions|chatmode|agent)\\.md$/);\n\n/**\n * Resolve the repository path from the host-stripped path segments.\n *\n * GitHub repos are always `owner/repo`. GitLab (and other hosts) allow nested\n * groups, so the project slug can span 3+ segments; the virtual-package subpath,\n * if any, begins at a primitive directory or virtual file (index >= 2). Returns\n * `null` when there is no `owner/repo` (fewer than two segments).\n */\nfunction resolveRepoPath(\n platform: string | null,\n segments: string[],\n): string | null {\n if (segments.length < 2) {\n return null;\n }\n if (platform === 'github') {\n return segments.slice(0, 2).join('/');\n }\n let boundary = segments.length;\n for (let i = 2; i < segments.length; i++) {\n if (\n virtualRootSegments.has(segments[i]) ||\n virtualFileRegex.test(segments[i])\n ) {\n boundary = i;\n break;\n }\n }\n return segments.slice(0, boundary).join('/');\n}\n\ninterface PinnedTail {\n replaceString: string;\n currentValue: string;\n}\n\n/**\n * APM keeps the release tag for a SHA-pinned dependency in a trailing YAML\n * comment (`owner/repo#<sha> # v2.0.0`), which the structured parse strips.\n *\n * Returns a matcher that scans the raw manifest for the (unquoted) entry to\n * recover the tag as `currentValue` and the exact text to replace, so\n * `pinDigests` can update both the SHA and the tag. Each line is consumed at\n * most once (in file order), so the same `owner/repo#<sha>` pinned in more than\n * one section maps to distinct lines rather than all resolving to the first\n * match. Yields `undefined` for a bare SHA (no tag comment) or a form we can't\n * recover verbatim (e.g. quoted), which the caller then skips.\n */\nfunction createPinnedTailFinder(\n content: string,\n): (value: string) => PinnedTail | undefined {\n const lines = content.split(newlineRegex);\n const consumed = new Set<number>();\n return (value) => {\n for (let i = 0; i < lines.length; i++) {\n if (consumed.has(i)) {\n continue;\n }\n const item = lines[i].trimStart();\n if (!item.startsWith('-')) {\n continue;\n }\n const afterDash = item.slice(1).trimStart();\n if (!afterDash.startsWith(value)) {\n continue;\n }\n consumed.add(i);\n const tail = commentTagRegex.exec(afterDash.slice(value.length));\n if (!tail?.groups?.tag) {\n return undefined;\n }\n return {\n replaceString: afterDash.trimEnd(),\n currentValue: tail.groups.tag,\n };\n }\n return undefined;\n };\n}\n\n/**\n * Parse a single APM dependency string of the form\n * `[host/]owner/repo[/subpath...][#<ref>]`, where `<ref>` is a semver tag/range,\n * a branch, or a commit SHA.\n *\n * For a SHA-pinned entry the release tag lives in a trailing YAML comment; when\n * present it is recovered from `content` so the entry updates as a digest\n * (`currentDigest` + `currentValue`). A bare SHA with no tag comment has no\n * version to track and is skipped.\n */\nexport function parseApmDependency(\n entry: string,\n depType: string,\n findPinnedTail: (value: string) => PinnedTail | undefined,\n): PackageDependency {\n const hashIndex = entry.indexOf('#');\n const pathPart = hashIndex === -1 ? entry : entry.slice(0, hashIndex);\n const ref = hashIndex === -1 ? '' : entry.slice(hashIndex + 1).trim();\n\n const base: PackageDependency = {\n depName: pathPart,\n depType,\n };\n\n if (!ref) {\n // Unpinned dependency (no `#ref`) - nothing for Renovate to update.\n return { ...base, skipReason: 'unspecified-version' };\n }\n\n // The optional host prefix is a hostname (so it contains a dot); git host\n // owner names never do, which disambiguates the leading segment.\n const segments = pathPart.split('/').filter(isTruthy);\n const hasHost = (segments[0] ?? '').includes('.');\n const host = hasHost ? segments[0] : 'github.com';\n const platform = detectPlatform(`https://${host}`);\n const repoPath = resolveRepoPath(\n platform,\n hasHost ? segments.slice(1) : segments,\n );\n\n if (!repoPath) {\n logger.debug({ entry }, 'apm: could not determine owner/repo');\n return {\n ...base,\n currentValue: ref,\n skipReason: 'invalid-dependency-specification',\n };\n }\n\n const { datasource, packageName, registryUrls } = determineDatasource(\n host,\n platform,\n repoPath,\n );\n const dep: PackageDependency = {\n ...base,\n datasource,\n packageName,\n ...(registryUrls ? { registryUrls } : {}),\n autoReplaceStringTemplate,\n };\n\n if (isLongCommitSha(ref)) {\n const tail = findPinnedTail(entry);\n if (!tail) {\n // Bare SHA with no recoverable tag comment - no version to track.\n return {\n ...base,\n currentDigest: ref,\n skipReason: 'unversioned-reference',\n };\n }\n return {\n ...dep,\n currentValue: tail.currentValue,\n currentDigest: ref,\n replaceString: tail.replaceString,\n };\n }\n\n return {\n ...dep,\n currentValue: ref,\n replaceString: entry,\n };\n}\n\nfunction extractSection(\n entries: string[] | undefined,\n depType: string,\n findPinnedTail: (value: string) => PinnedTail | undefined,\n): PackageDependency[] {\n return coerceArray(entries).map((entry) =>\n parseApmDependency(entry, depType, findPinnedTail),\n );\n}\n\nexport function extractPackageFile(\n content: string,\n packageFile: string,\n): PackageFileContent | null {\n let manifest: ApmManifest;\n try {\n manifest = parseSingleYaml(content, { customSchema: ApmManifest });\n } catch (err) {\n logger.debug({ packageFile, err }, 'apm: failed to parse manifest');\n return null;\n }\n\n const findPinnedTail = createPinnedTailFinder(content);\n const deps = [\n ...extractSection(manifest.dependencies?.apm, 'apm', findPinnedTail),\n ...extractSection(manifest.devDependencies?.apm, 'apm-dev', findPinnedTail),\n ];\n\n if (!deps.length) {\n return null;\n }\n\n return { deps };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"extract.js","names":[],"sources":["../../../../lib/modules/manager/apm/extract.ts"],"sourcesContent":["import { isTruthy } from '@sindresorhus/is';\nimport { logger } from '../../../logger/index.ts';\nimport { coerceArray } from '../../../util/array.ts';\nimport { detectPlatform } from '../../../util/common.ts';\nimport { newlineRegex, regEx } from '../../../util/regex.ts';\nimport { isLongCommitSha } from '../../../util/schema-utils/git.ts';\nimport { parseSingleYaml } from '../../../util/yaml.ts';\nimport { GitTagsDatasource } from '../../datasource/git-tags/index.ts';\nimport { GithubTagsDatasource } from '../../datasource/github-tags/index.ts';\nimport { GitlabTagsDatasource } from '../../datasource/gitlab-tags/index.ts';\nimport type { PackageDependency, PackageFileContent } from '../types.ts';\nimport { ApmManifest } from './schema.ts';\n\ninterface DatasourceResult {\n datasource: string;\n packageName: string;\n registryUrls?: string[];\n}\n\n/**\n * Determine which Renovate datasource to use for an APM dependency, based on\n * the git host `platform` (already resolved via `detectPlatform`, which honors\n * `hostRules`). github/gitlab (and their self-hosted variants) map to the\n * `github-tags` / `gitlab-tags` datasources; every other host (Bitbucket, Azure\n * DevOps, etc.) falls back to the generic `git-tags` datasource.\n */\nfunction determineDatasource(\n host: string,\n platform: string | null,\n repoPath: string,\n): DatasourceResult {\n if (platform === 'github') {\n return {\n datasource: GithubTagsDatasource.id,\n packageName: repoPath,\n ...(host === 'github.com' ? {} : { registryUrls: [`https://${host}`] }),\n };\n }\n\n if (platform === 'gitlab') {\n return {\n datasource: GitlabTagsDatasource.id,\n packageName: repoPath,\n ...(host === 'gitlab.com' ? {} : { registryUrls: [`https://${host}`] }),\n };\n }\n\n return {\n datasource: GitTagsDatasource.id,\n packageName: `https://${host}/${repoPath}`,\n };\n}\n\n/** A trailing ` # <tag>` comment on a manifest line. */\nconst commentTagRegex = regEx(/^\\s+#\\s*(?<tag>\\S.*?)\\s*$/);\n\n/**\n * Renders both `owner/repo#<tag>` and the digest-pinned\n * `owner/repo#<sha> # <tag>` form, mirroring the github-actions\n * `uses: owner/action@<sha> # v4` behaviour so `pinDigests` can pin a bare tag\n * to a SHA and keep the trailing tag comment current.\n */\nconst autoReplaceStringTemplate =\n '{{depName}}#{{#if newDigest}}{{newDigest}} # {{newValue}}{{else}}{{newValue}}{{/if}}';\n\n/**\n * Match `<name>--v<version>`, `<name>-v<version>`, and `<name>_v<version>` tags.\n */\nconst packageTagRegex = regEx(\n /^(?<compatibility>.+?[-_])v(?<version>\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?(?:\\+[0-9A-Za-z.-]+)?)$/,\n);\n\nfunction packageTagConfig(\n currentValue: string,\n): Pick<PackageDependency, 'versionCompatibility'> {\n return packageTagRegex.test(currentValue)\n ? { versionCompatibility: packageTagRegex.source }\n : {};\n}\n\n/**\n * APM virtual-package subpaths (skills/prompts/etc.) begin at one of these\n * \"primitive\" directories or at a file with a virtual extension. APM only uses\n * these to find where a repo path ends for hosts with nested namespaces; see\n * `_GITLAB_VIRTUAL_ROOT_SEGMENTS` / `VIRTUAL_FILE_EXTENSIONS` in apm.\n */\nconst virtualRootSegments = new Set(['prompts', 'instructions', 'collections']);\nconst virtualFileRegex = regEx(/\\.(?:prompt|instructions|chatmode|agent)\\.md$/);\n\n/**\n * Resolve the repository path from the host-stripped path segments.\n *\n * GitHub repos are always `owner/repo`. GitLab (and other hosts) allow nested\n * groups, so the project slug can span 3+ segments; the virtual-package subpath,\n * if any, begins at a primitive directory or virtual file (index >= 2). Returns\n * `null` when there is no `owner/repo` (fewer than two segments).\n */\nfunction resolveRepoPath(\n platform: string | null,\n segments: string[],\n): string | null {\n if (segments.length < 2) {\n return null;\n }\n if (platform === 'github') {\n return segments.slice(0, 2).join('/');\n }\n let boundary = segments.length;\n for (let i = 2; i < segments.length; i++) {\n if (\n virtualRootSegments.has(segments[i]) ||\n virtualFileRegex.test(segments[i])\n ) {\n boundary = i;\n break;\n }\n }\n return segments.slice(0, boundary).join('/');\n}\n\ninterface PinnedTail {\n replaceString: string;\n currentValue: string;\n}\n\n/**\n * APM keeps the release tag for a SHA-pinned dependency in a trailing YAML\n * comment (`owner/repo#<sha> # v2.0.0`), which the structured parse strips.\n *\n * Returns a matcher that scans the raw manifest for the (unquoted) entry to\n * recover the tag as `currentValue` and the exact text to replace, so\n * `pinDigests` can update both the SHA and the tag. Each line is consumed at\n * most once (in file order), so the same `owner/repo#<sha>` pinned in more than\n * one section maps to distinct lines rather than all resolving to the first\n * match. Yields `undefined` for a bare SHA (no tag comment) or a form we can't\n * recover verbatim (e.g. quoted), which the caller then skips.\n */\nfunction createPinnedTailFinder(\n content: string,\n): (value: string) => PinnedTail | undefined {\n const lines = content.split(newlineRegex);\n const consumed = new Set<number>();\n return (value) => {\n for (let i = 0; i < lines.length; i++) {\n if (consumed.has(i)) {\n continue;\n }\n const item = lines[i].trimStart();\n if (!item.startsWith('-')) {\n continue;\n }\n const afterDash = item.slice(1).trimStart();\n if (!afterDash.startsWith(value)) {\n continue;\n }\n consumed.add(i);\n const tail = commentTagRegex.exec(afterDash.slice(value.length));\n if (!tail?.groups?.tag) {\n return undefined;\n }\n return {\n replaceString: afterDash.trimEnd(),\n currentValue: tail.groups.tag,\n };\n }\n return undefined;\n };\n}\n\n/**\n * Parse a single APM dependency string of the form\n * `[host/]owner/repo[/subpath...][#<ref>]`, where `<ref>` is a semver tag/range,\n * a branch, or a commit SHA.\n *\n * For a SHA-pinned entry the release tag lives in a trailing YAML comment; when\n * present it is recovered from `content` so the entry updates as a digest\n * (`currentDigest` + `currentValue`). A bare SHA with no tag comment has no\n * version to track and is skipped.\n */\nexport function parseApmDependency(\n entry: string,\n depType: string,\n findPinnedTail: (value: string) => PinnedTail | undefined,\n): PackageDependency {\n const hashIndex = entry.indexOf('#');\n const pathPart = hashIndex === -1 ? entry : entry.slice(0, hashIndex);\n const ref = hashIndex === -1 ? '' : entry.slice(hashIndex + 1).trim();\n\n const base: PackageDependency = {\n depName: pathPart,\n depType,\n };\n\n if (!ref) {\n // Unpinned dependency (no `#ref`) - nothing for Renovate to update.\n return { ...base, skipReason: 'unspecified-version' };\n }\n\n // The optional host prefix is a hostname (so it contains a dot); git host\n // owner names never do, which disambiguates the leading segment.\n const segments = pathPart.split('/').filter(isTruthy);\n const hasHost = (segments[0] ?? '').includes('.');\n const host = hasHost ? segments[0] : 'github.com';\n const platform = detectPlatform(`https://${host}`);\n const repoPath = resolveRepoPath(\n platform,\n hasHost ? segments.slice(1) : segments,\n );\n\n if (!repoPath) {\n logger.debug({ entry }, 'apm: could not determine owner/repo');\n return {\n ...base,\n currentValue: ref,\n skipReason: 'invalid-dependency-specification',\n };\n }\n\n const { datasource, packageName, registryUrls } = determineDatasource(\n host,\n platform,\n repoPath,\n );\n const dep: PackageDependency = {\n ...base,\n datasource,\n packageName,\n ...(registryUrls ? { registryUrls } : {}),\n autoReplaceStringTemplate,\n };\n\n if (isLongCommitSha(ref)) {\n const tail = findPinnedTail(entry);\n if (!tail) {\n // Bare SHA with no recoverable tag comment - no version to track.\n return {\n ...base,\n currentDigest: ref,\n skipReason: 'unversioned-reference',\n };\n }\n return {\n ...dep,\n currentValue: tail.currentValue,\n currentDigest: ref,\n replaceString: tail.replaceString,\n ...packageTagConfig(tail.currentValue),\n };\n }\n\n return {\n ...dep,\n currentValue: ref,\n replaceString: entry,\n ...packageTagConfig(ref),\n };\n}\n\nfunction extractSection(\n entries: string[] | undefined,\n depType: string,\n findPinnedTail: (value: string) => PinnedTail | undefined,\n): PackageDependency[] {\n return coerceArray(entries).map((entry) =>\n parseApmDependency(entry, depType, findPinnedTail),\n );\n}\n\nexport function extractPackageFile(\n content: string,\n packageFile: string,\n): PackageFileContent | null {\n let manifest: ApmManifest;\n try {\n manifest = parseSingleYaml(content, { customSchema: ApmManifest });\n } catch (err) {\n logger.debug({ packageFile, err }, 'apm: failed to parse manifest');\n return null;\n }\n\n const findPinnedTail = createPinnedTailFinder(content);\n const deps = [\n ...extractSection(manifest.dependencies?.apm, 'apm', findPinnedTail),\n ...extractSection(manifest.devDependencies?.apm, 'apm-dev', findPinnedTail),\n ];\n\n if (!deps.length) {\n return null;\n }\n\n return { deps };\n}\n"],"mappings":"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"}
@@ -3,7 +3,7 @@ const hashMap = /* @__PURE__ */ new Map();
3
3
  hashMap.set("ansible", "a52394a36ac5517f7330473c31d93aa05b2ce607c5e951b48f25a4693cd20a81");
4
4
  hashMap.set("ansible-galaxy", "8e11293c8f61b4cbae77a3b1634a47213031c59df2c9833d89db65bf4e6edc64");
5
5
  hashMap.set("ant", "2df5943cf0ed19a21b94df13729dbb925655548130caf37e3e22bebaed518e17");
6
- hashMap.set("apm", "bdb6931cc03f4ac02ebfdb56c4b3483bb6c5250fa952545f1a25584d502bbffd");
6
+ hashMap.set("apm", "66c207983960b1a1f49b972f77efe3bfd3097e19b0ee4034ccf9ac6c0d13e05b");
7
7
  hashMap.set("argocd", "cff9cd22257bc460ae4b9936570bf0ed5585f280a55d26629deaeeb0bfee8eb5");
8
8
  hashMap.set("asdf", "430eb99b58171700c8a59c78b9e648575e9b176b781d90dd10a710f7b69015bb");
9
9
  hashMap.set("azure-pipelines", "04a13dec4e08ba21004961c718072fde976226d65809fa3c838bf66ba93e5d5a");
@@ -1 +1 @@
1
- {"version":3,"file":"fingerprint.generated.js","names":[],"sources":["../../../lib/modules/manager/fingerprint.generated.ts"],"sourcesContent":["export const hashMap = new Map<string, string>();\n\nhashMap.set('ansible','a52394a36ac5517f7330473c31d93aa05b2ce607c5e951b48f25a4693cd20a81');\nhashMap.set('ansible-galaxy','8e11293c8f61b4cbae77a3b1634a47213031c59df2c9833d89db65bf4e6edc64');\nhashMap.set('ant','2df5943cf0ed19a21b94df13729dbb925655548130caf37e3e22bebaed518e17');\nhashMap.set('apm','bdb6931cc03f4ac02ebfdb56c4b3483bb6c5250fa952545f1a25584d502bbffd');\nhashMap.set('argocd','cff9cd22257bc460ae4b9936570bf0ed5585f280a55d26629deaeeb0bfee8eb5');\nhashMap.set('asdf','430eb99b58171700c8a59c78b9e648575e9b176b781d90dd10a710f7b69015bb');\nhashMap.set('azure-pipelines','04a13dec4e08ba21004961c718072fde976226d65809fa3c838bf66ba93e5d5a');\nhashMap.set('batect','375d39b432013bedb1330cf40a2199dd822751b28578214f219e7bab98594b8d');\nhashMap.set('batect-wrapper','d999355511ea7f4053325a18b8cfc8d2b586c61e6760c35e557d383a673e3939');\nhashMap.set('bazel','4d4f1d9a6519ba552b316b396db13ff0654a2663d8ed976188899a2d57d306a2');\nhashMap.set('bazel-module','9fbba0339f9f7785d52ab85c5f0f6385003093c063483c13feccba13ae438bef');\nhashMap.set('bazelisk','770f75a746dc6ba90c518788d5987d7df4243ef9eee122d1bb0556a93d6e1b11');\nhashMap.set('bicep','7246e0bfc06e0e28cbb03ac088c5591f648956b086e106aeb251fe5d628329db');\nhashMap.set('bitbucket-pipelines','59c0503494ab1442b127914503c01b97ac17b6742b19c632292d5aa24de115cd');\nhashMap.set('bitrise','478dfd316221fad7c29e177c70d1018d832fb2626b53308a5d0f1f0380e69f42');\nhashMap.set('buildkite','b8b404f53cd5d61c39153fddf93945e621471c4ac6aa9960c881cd868922bb4c');\nhashMap.set('buildpacks','6bef3cb04d66b5cfbb195adb4829bcbccae6408518706744d291bacf0610421f');\nhashMap.set('bun','6789cc6499c77cdf44d4fb306198274bb72241e6d0ef7ceda7e916d7022d864c');\nhashMap.set('bun-version','df3ae8e4a5de1fa1b4544f3d7fc8117e80adb1e151c46d1ede54a4dbea6521e4');\nhashMap.set('bundler','6e4784dd98c1f86ef64cc8cbf3128df48aebf920032d7792b54fdedd3dd9d4d5');\nhashMap.set('cake','9ebd8b481220b30a8860121d26184540a1a2fcc05ef780df9295dea39b386fad');\nhashMap.set('cargo','32bddfcf1201495289921a2bf5f9b256b985b8b63a3985190676fb9f9f0f9b23');\nhashMap.set('cdnurl','9a81c8e3c6ad6c788498c99fc1067ffdfcd92a427c3afaf8c0130975d83131f2');\nhashMap.set('circleci','91cbeb33ea20f9838e2c81a1195eb806f0b38fa282bc3679f62552f20575ca85');\nhashMap.set('cloudbuild','f4e40388944652c8a19f8518771ac8d3f3c4ccf81ddef0e68b463aca833cb73c');\nhashMap.set('cocoapods','f832e2beef885bb3fd697ed9bb3e8cd742926bfec37ff41212edd2dbb4edb3ba');\nhashMap.set('composer','3976117beb9adeade088187965929d42f21f5da12c4614fd22aa92cad1083b19');\nhashMap.set('conan','8d46e9a30ae628e26118aea10a98d1b846f7c5d96d51ce24693437d555f6d125');\nhashMap.set('copier','197219e93857ad7e6701755ede245824329da08913ebdb23d1e5e854a169aafe');\nhashMap.set('cpanfile','07813fec3f3c2197056500e9266a0553b9774c02f2c74d5ca2e213188c7c12d3');\nhashMap.set('crossplane','5c26b1201a1a51454ffb94d829e223a76a781569bf79cdb1e47087c30233ec40');\nhashMap.set('crow','eb9a5f9f95041855dded67bcce3dd54724f690995ed6268d272e8a666ff28fd0');\nhashMap.set('deno','41e6a8b7b8bae08f07b3e4b69c8c095db5da984bb23c004cd1ebf755a6317794');\nhashMap.set('deps-edn','06783dbc8b9c7bb84e162d1f75b7db56dfa021cc6f809dfd2314cee8b64af08d');\nhashMap.set('devbox','a40050cc61bd9b5d500ec111abb17bb15d5f82ab5b7699f66f628307ba8382c9');\nhashMap.set('devcontainer','24320ed1cb6191d04cb8b2707214d82c08c682597aed1d84f250aa00ad1632ec');\nhashMap.set('docker-compose','fba87b82cb0f2bfd66526631fbe928b8153e7ca701a5790d02b944df17417bb9');\nhashMap.set('dockerfile','b5faeb8f31d238e0d05a4aeebf9a837273687908ab8078b34e738bb0e369c80c');\nhashMap.set('droneci','661d2a2d7295af8dd7a1234c7090c42a89306bd574c3adf1fc67782efaad3998');\nhashMap.set('fleet','ffa222820f72c4eb4cdc4c229ae8c50433bee96f3b974f0633d5a7d1f6427c97');\nhashMap.set('flux','842597c9083d82af99ef3d526101a3a53c4448414d2f53f7e969074757124811');\nhashMap.set('fvm','9b161df0f14bc6e536368952adf373e343630097121a913cea60ee284027fb90');\nhashMap.set('git-submodules','f4e2c6ddf2fa93241665c5176faafb358eecfcb701e7478790c4d58853ed827a');\nhashMap.set('github-actions','f2d9007071541c4fc4a78aab44049c3a7553b34b699d4beaa27039d2a85082c3');\nhashMap.set('gitlabci','a5e1e66ef461e1c1e71062f85f35a212417e23627f4b002810f9a98295d6e672');\nhashMap.set('gitlabci-include','8860a15ab516fde00694f9bd9bf56fce4addafe5a55b5ddb9a4ec477d301d351');\nhashMap.set('glasskube','93e7b9000a17efa15a1abaaf320b5af9169b1ecd828fc0c881d98570ef9d9e30');\nhashMap.set('gleam','5e9b9f5f914afe5ed7b526c06c65111e3716d2dea9b0cbe7907bbc96db1064a3');\nhashMap.set('gomod','89899292f917777b79f8ce1714e54c4e61cf151fb75f87f1ddb1d1ccd6a4e6f7');\nhashMap.set('gradle','14ffeecba62452d47d3796e68753da745de2614b6e5ecc346da4f0067ed4bc6e');\nhashMap.set('gradle-wrapper','73ba30c34955fab7737454b5cff9aca6d1b5607d53c17c9e13d8ad96f6eaae87');\nhashMap.set('haskell-cabal','f158b7725e3143dfd2950e3de0bbccc2a61cd7eba87f7a54c5057e01252348e2');\nhashMap.set('helm-requirements','22f61344565f87ca3512c0ba8fac32627fde8ee919b7badae07b2116e285f049');\nhashMap.set('helm-values','0aa79bb0257d0d72e54dfd2653e59bfef63b97e46c035b7443593bdf6e6382aa');\nhashMap.set('helmfile','ab63e5bc2bb381939a6b75911947e3fc79d31827423ded07f61ea1c98d95a542');\nhashMap.set('helmsman','951deeb3355da751ef39c9e932b26ea749450e32e75759e4b5fc29359e100b37');\nhashMap.set('helmv3','927798e082caf46a0da703389ba07e9e61fa73ef571ab551301b8fc6b06957d1');\nhashMap.set('hermit','0fb25b7766c3a264fbb765ff75b1542b24136c4c9f933696d4a5aecfed637071');\nhashMap.set('homeassistant-manifest','05043c6db870cffbb6f8f3e351c025e3de227eaae0b24134b796aec46f84b65f');\nhashMap.set('homebrew','dffe954a4e18c2dc4bfdaa12222fe8ddc3395869afd5afa603fc2b6264747984');\nhashMap.set('html','81fa6c2bf2b868596584a48b949645207a2aa3081951ed99183ee50b70b77d5f');\nhashMap.set('jenkins','7fda0e7e0f3d5e18088ccb3594f727f4cfc48b064706bdaaf1a0a075b6a2cff5');\nhashMap.set('jsonnet-bundler','4cedeb0394e5c38361d1868ff45b4f34747ab8c492378b6e63dcaf1f4f3c024d');\nhashMap.set('kotlin-script','95ebc844c040ca047321b207d525220e29774a2a1fe06f9639e8353c66908564');\nhashMap.set('kubernetes','321e7d77fb3600dd4c00a86eaa1294927e7f92300b74fa2977d813dcaa3bb4de');\nhashMap.set('kustomize','4a4321595a55de36669f3bcc6fb54236ad81c8f80ec9cbd3888f49a45fbe70e7');\nhashMap.set('leiningen','c8397e376f1717c2f771ae9ea3ba6b720d2422b133cf937e762c44e42be146a2');\nhashMap.set('maven','c110b99291c2a5bc82cf7a69330275e9bbd7dc8ba3e9e987611dfcffbe002d8d');\nhashMap.set('maven-wrapper','6e53b6e4abf1d20b75094c7a70d66b4a5ac39954f009aa401f5e55dada8be4d0');\nhashMap.set('meteor','4636a47ba4dcfff19fe662572ef7a40d17146be3c966e00ef437e1fc8de92776');\nhashMap.set('mint','248fe4f1ea5c985921c286785792c97e06fc41f402b2d45df82f6aecd17f710e');\nhashMap.set('mise','59c691024c34cb4be4d9b4f811019ae9b22410df0da54977cdcecea261fbbbf5');\nhashMap.set('mix','0f79163dc2a1c896599d152be635c23beaf16812ae3d8fbfffec98c7bd0de872');\nhashMap.set('nix','9cbd96a29fe96e3df7418e422256380202f07970cf7f00b08388c181224a2b85');\nhashMap.set('nodenv','ac652c28481b001f7471f4183eac07b45d98ecbe83efc275830b0a1b2e0459b8');\nhashMap.set('npm','9686302b38f9d6ff899cc69590ec2b9677fd5451f52d227649c0e0812b15c6f9');\nhashMap.set('nuget','fb02247c67a198ffe414a44d23c7894bd114dcc53803334f82e39479e7b27f6f');\nhashMap.set('nvm','3eb77c7b0acf6d64753de78fad2499b352719853aa6872878c40675d14152322');\nhashMap.set('ocb','032b216684c14b0954e0bb019513a2aca3faaee5748587acb668d377d7c891ca');\nhashMap.set('osgi','d6567a733ef3983112b46fdccd7ceebfcd48411104e0c6b6e714d4310db48024');\nhashMap.set('pep621','5a01837b4bc0b575073d1d3d44d9cb030ad66ea2bfb0be830f83f53c30bdb277');\nhashMap.set('pep723','77022a0eae6a3cbb74a1e6d596db1276e379768e40448192b3fa81edd14ca73f');\nhashMap.set('pip-compile','a98dc76a002e1dc21662237f009ff8fea36236bb4e24cb82ee30c6a78f57271f');\nhashMap.set('pip_requirements','bf3a407f72abf711230247bef94ba5dc84c08a35107b0f017912fad66afa716a');\nhashMap.set('pip_setup','df18fba2bdcf48f3ca12a8f7e5cd28df31e2368d5528127277038ef4206eca79');\nhashMap.set('pipenv','baf237cd77173c1a7a9c7fa2a8bfb214f3c488ba0cc27f0e8f334df192e3a398');\nhashMap.set('pixi','e31c397982ffa34222b061f23f3b3683f42523dd5dca45ecce2448b0ebc55ea2');\nhashMap.set('poetry','e9dea5d591c87956b9f018414cb3dab8f2e13580a13be00550fdce198fdf08e6');\nhashMap.set('pre-commit','760f2c291ae084db889f722390798a0e2d431ccdc3bc676e73b14901ebea19ac');\nhashMap.set('proto','412053d4550026b4ace490b46e970915b87ec1abf0b0a0c6c8c58ccf1fc16843');\nhashMap.set('pub','8e7c65dfd1999de4f7c44392e949a4d8f4701eb86df59d550e4657feb06b1872');\nhashMap.set('puppet','ba58ab689e44acc8f61c3569ab8b40fde01b8a9d3aad712708e2a419e57d8b45');\nhashMap.set('pyenv','9ede8becc97774f9040b40f4472d3e933534b596e04c360bfe0f3c6f95f25182');\nhashMap.set('quadlet','40927b98dd2bac45dba60e66b5fd0e6b84b61d02db8be536fda7b14546a4feb7');\nhashMap.set('renovate-config','dfaf3f03ddaf70c332f7916106648f36dbfa6a36dd76d15dd27fa116ab3c174c');\nhashMap.set('ruby-version','2db2140d9eee8c555e729a4de0396fa2d78846d3149890ee12fa515bd654be97');\nhashMap.set('runtime-version','b582b168c0cc595e39010feb10f4b97a82683eb269e9598216fbb11cc186e160');\nhashMap.set('rust-toolchain','6ace53db02874d73620d2d872291839820a512a9529c42d174358c692e5db720');\nhashMap.set('sbt','e1eb5c7f0171a9bb1b6bd4a36a91039a31b6c84e0983d91d930be31a69506d9e');\nhashMap.set('scalafmt','9d36159b56835e96498af026a1fb0543200db0581681ef95ec54988f411e180f');\nhashMap.set('setup-cfg','4a3a7c812d34739c07685691e7e64c7d3127f9d7d4aff99dc45a25df97ed9745');\nhashMap.set('smithy','9641b91d065ffb63be0dd888139a0402dba41e550f8b44c592db9daf52109100');\nhashMap.set('sveltos','60dd75bb53ace31217211100d622fdb65068c6162758b6ae7103a6ce8bdc9f90');\nhashMap.set('swift','cdf063debdbf36888523ff8cec6d2d1b0ec6f49b37b2fbcd80b0d4f6a31114e1');\nhashMap.set('tekton','33948f5bdf7553909fa63744adb26da97ddf366e9499bccab1250879570267c9');\nhashMap.set('terraform','6788a8569ba9c50c763ffa2bed952a4314ae8e696c29f93d3eb7c4a12d99ce20');\nhashMap.set('terraform-version','ec8f786b9731d47f2c2fe0307caf64d7ddd83046fe7ff1f7d8423239f8b0f2aa');\nhashMap.set('terragrunt','300f8fb3c09667654412d2f5dd8ab4882e0f5d1d7a8bc39794993d2e7e58d1b7');\nhashMap.set('terragrunt-version','eea6087b33717d22ede2fc68c2f64df8390b75abe82110ed831a180648feb51d');\nhashMap.set('tflint-plugin','f423bfa2b42a2bfc0e38a33ebd4f9d452473e7ed4e7ad6384a99eb9a35d97479');\nhashMap.set('travis','f3e2f38e699c390b00ff481be5e91dceaa81609e93caf9a4214933de759c84fc');\nhashMap.set('typst','d080a79fbd961c6e21fcc505d544b7e0ff2126142acb1dcabdf6abbcd9339248');\nhashMap.set('unity3d','f13e25e115e3443f4e16cf31578acffa78fb1a5e23339680a92d8d6de6052920');\nhashMap.set('velaci','fda00ddb7cc23e9a37e0a8a253151df0a6930b4276d3e4f78cc54b9ac09af7de');\nhashMap.set('vendir','48e2bff8d3a96e8011ee12776fe9c6e8aac4718ff47e891c294a8f12660cb1bb');\nhashMap.set('woodpecker','6110d3bec33aaeb3511d4bbfa896cec3c8e02fb04a6cff50c9ba81061c851045');\nhashMap.set('xcodegen','dad511d88a9ce1dbdde8b9731f3da7f2bdaa4ca8a083294ee58d56da62ab1683');\nhashMap.set('jsonata','416bcf61144b276b3112814c6e6d261aa29608f46fbb0516c471d35c16f8f0d7');\nhashMap.set('regex','20be5247fdc164173871a051acb0527da017d0c155c653d7563601f55e7b3ff5');"],"mappings":";AAAA,MAAa,0BAAU,IAAI,IAAoB;AAE/C,QAAQ,IAAI,WAAU,kEAAkE;AACxF,QAAQ,IAAI,kBAAiB,kEAAkE;AAC/F,QAAQ,IAAI,OAAM,kEAAkE;AACpF,QAAQ,IAAI,OAAM,kEAAkE;AACpF,QAAQ,IAAI,UAAS,kEAAkE;AACvF,QAAQ,IAAI,QAAO,kEAAkE;AACrF,QAAQ,IAAI,mBAAkB,kEAAkE;AAChG,QAAQ,IAAI,UAAS,kEAAkE;AACvF,QAAQ,IAAI,kBAAiB,kEAAkE;AAC/F,QAAQ,IAAI,SAAQ,kEAAkE;AACtF,QAAQ,IAAI,gBAAe,kEAAkE;AAC7F,QAAQ,IAAI,YAAW,kEAAkE;AACzF,QAAQ,IAAI,SAAQ,kEAAkE;AACtF,QAAQ,IAAI,uBAAsB,kEAAkE;AACpG,QAAQ,IAAI,WAAU,kEAAkE;AACxF,QAAQ,IAAI,aAAY,kEAAkE;AAC1F,QAAQ,IAAI,cAAa,kEAAkE;AAC3F,QAAQ,IAAI,OAAM,kEAAkE;AACpF,QAAQ,IAAI,eAAc,kEAAkE;AAC5F,QAAQ,IAAI,WAAU,kEAAkE;AACxF,QAAQ,IAAI,QAAO,kEAAkE;AACrF,QAAQ,IAAI,SAAQ,kEAAkE;AACtF,QAAQ,IAAI,UAAS,kEAAkE;AACvF,QAAQ,IAAI,YAAW,kEAAkE;AACzF,QAAQ,IAAI,cAAa,kEAAkE;AAC3F,QAAQ,IAAI,aAAY,kEAAkE;AAC1F,QAAQ,IAAI,YAAW,kEAAkE;AACzF,QAAQ,IAAI,SAAQ,kEAAkE;AACtF,QAAQ,IAAI,UAAS,kEAAkE;AACvF,QAAQ,IAAI,YAAW,kEAAkE;AACzF,QAAQ,IAAI,cAAa,kEAAkE;AAC3F,QAAQ,IAAI,QAAO,kEAAkE;AACrF,QAAQ,IAAI,QAAO,kEAAkE;AACrF,QAAQ,IAAI,YAAW,kEAAkE;AACzF,QAAQ,IAAI,UAAS,kEAAkE;AACvF,QAAQ,IAAI,gBAAe,kEAAkE;AAC7F,QAAQ,IAAI,kBAAiB,kEAAkE;AAC/F,QAAQ,IAAI,cAAa,kEAAkE;AAC3F,QAAQ,IAAI,WAAU,kEAAkE;AACxF,QAAQ,IAAI,SAAQ,kEAAkE;AACtF,QAAQ,IAAI,QAAO,kEAAkE;AACrF,QAAQ,IAAI,OAAM,kEAAkE;AACpF,QAAQ,IAAI,kBAAiB,kEAAkE;AAC/F,QAAQ,IAAI,kBAAiB,kEAAkE;AAC/F,QAAQ,IAAI,YAAW,kEAAkE;AACzF,QAAQ,IAAI,oBAAmB,kEAAkE;AACjG,QAAQ,IAAI,aAAY,kEAAkE;AAC1F,QAAQ,IAAI,SAAQ,kEAAkE;AACtF,QAAQ,IAAI,SAAQ,kEAAkE;AACtF,QAAQ,IAAI,UAAS,kEAAkE;AACvF,QAAQ,IAAI,kBAAiB,kEAAkE;AAC/F,QAAQ,IAAI,iBAAgB,kEAAkE;AAC9F,QAAQ,IAAI,qBAAoB,kEAAkE;AAClG,QAAQ,IAAI,eAAc,kEAAkE;AAC5F,QAAQ,IAAI,YAAW,kEAAkE;AACzF,QAAQ,IAAI,YAAW,kEAAkE;AACzF,QAAQ,IAAI,UAAS,kEAAkE;AACvF,QAAQ,IAAI,UAAS,kEAAkE;AACvF,QAAQ,IAAI,0BAAyB,kEAAkE;AACvG,QAAQ,IAAI,YAAW,kEAAkE;AACzF,QAAQ,IAAI,QAAO,kEAAkE;AACrF,QAAQ,IAAI,WAAU,kEAAkE;AACxF,QAAQ,IAAI,mBAAkB,kEAAkE;AAChG,QAAQ,IAAI,iBAAgB,kEAAkE;AAC9F,QAAQ,IAAI,cAAa,kEAAkE;AAC3F,QAAQ,IAAI,aAAY,kEAAkE;AAC1F,QAAQ,IAAI,aAAY,kEAAkE;AAC1F,QAAQ,IAAI,SAAQ,kEAAkE;AACtF,QAAQ,IAAI,iBAAgB,kEAAkE;AAC9F,QAAQ,IAAI,UAAS,kEAAkE;AACvF,QAAQ,IAAI,QAAO,kEAAkE;AACrF,QAAQ,IAAI,QAAO,kEAAkE;AACrF,QAAQ,IAAI,OAAM,kEAAkE;AACpF,QAAQ,IAAI,OAAM,kEAAkE;AACpF,QAAQ,IAAI,UAAS,kEAAkE;AACvF,QAAQ,IAAI,OAAM,kEAAkE;AACpF,QAAQ,IAAI,SAAQ,kEAAkE;AACtF,QAAQ,IAAI,OAAM,kEAAkE;AACpF,QAAQ,IAAI,OAAM,kEAAkE;AACpF,QAAQ,IAAI,QAAO,kEAAkE;AACrF,QAAQ,IAAI,UAAS,kEAAkE;AACvF,QAAQ,IAAI,UAAS,kEAAkE;AACvF,QAAQ,IAAI,eAAc,kEAAkE;AAC5F,QAAQ,IAAI,oBAAmB,kEAAkE;AACjG,QAAQ,IAAI,aAAY,kEAAkE;AAC1F,QAAQ,IAAI,UAAS,kEAAkE;AACvF,QAAQ,IAAI,QAAO,kEAAkE;AACrF,QAAQ,IAAI,UAAS,kEAAkE;AACvF,QAAQ,IAAI,cAAa,kEAAkE;AAC3F,QAAQ,IAAI,SAAQ,kEAAkE;AACtF,QAAQ,IAAI,OAAM,kEAAkE;AACpF,QAAQ,IAAI,UAAS,kEAAkE;AACvF,QAAQ,IAAI,SAAQ,kEAAkE;AACtF,QAAQ,IAAI,WAAU,kEAAkE;AACxF,QAAQ,IAAI,mBAAkB,kEAAkE;AAChG,QAAQ,IAAI,gBAAe,kEAAkE;AAC7F,QAAQ,IAAI,mBAAkB,kEAAkE;AAChG,QAAQ,IAAI,kBAAiB,kEAAkE;AAC/F,QAAQ,IAAI,OAAM,kEAAkE;AACpF,QAAQ,IAAI,YAAW,kEAAkE;AACzF,QAAQ,IAAI,aAAY,kEAAkE;AAC1F,QAAQ,IAAI,UAAS,kEAAkE;AACvF,QAAQ,IAAI,WAAU,kEAAkE;AACxF,QAAQ,IAAI,SAAQ,kEAAkE;AACtF,QAAQ,IAAI,UAAS,kEAAkE;AACvF,QAAQ,IAAI,aAAY,kEAAkE;AAC1F,QAAQ,IAAI,qBAAoB,kEAAkE;AAClG,QAAQ,IAAI,cAAa,kEAAkE;AAC3F,QAAQ,IAAI,sBAAqB,kEAAkE;AACnG,QAAQ,IAAI,iBAAgB,kEAAkE;AAC9F,QAAQ,IAAI,UAAS,kEAAkE;AACvF,QAAQ,IAAI,SAAQ,kEAAkE;AACtF,QAAQ,IAAI,WAAU,kEAAkE;AACxF,QAAQ,IAAI,UAAS,kEAAkE;AACvF,QAAQ,IAAI,UAAS,kEAAkE;AACvF,QAAQ,IAAI,cAAa,kEAAkE;AAC3F,QAAQ,IAAI,YAAW,kEAAkE;AACzF,QAAQ,IAAI,WAAU,kEAAkE;AACxF,QAAQ,IAAI,SAAQ,kEAAkE"}
1
+ {"version":3,"file":"fingerprint.generated.js","names":[],"sources":["../../../lib/modules/manager/fingerprint.generated.ts"],"sourcesContent":["export const hashMap = new Map<string, string>();\n\nhashMap.set('ansible','a52394a36ac5517f7330473c31d93aa05b2ce607c5e951b48f25a4693cd20a81');\nhashMap.set('ansible-galaxy','8e11293c8f61b4cbae77a3b1634a47213031c59df2c9833d89db65bf4e6edc64');\nhashMap.set('ant','2df5943cf0ed19a21b94df13729dbb925655548130caf37e3e22bebaed518e17');\nhashMap.set('apm','66c207983960b1a1f49b972f77efe3bfd3097e19b0ee4034ccf9ac6c0d13e05b');\nhashMap.set('argocd','cff9cd22257bc460ae4b9936570bf0ed5585f280a55d26629deaeeb0bfee8eb5');\nhashMap.set('asdf','430eb99b58171700c8a59c78b9e648575e9b176b781d90dd10a710f7b69015bb');\nhashMap.set('azure-pipelines','04a13dec4e08ba21004961c718072fde976226d65809fa3c838bf66ba93e5d5a');\nhashMap.set('batect','375d39b432013bedb1330cf40a2199dd822751b28578214f219e7bab98594b8d');\nhashMap.set('batect-wrapper','d999355511ea7f4053325a18b8cfc8d2b586c61e6760c35e557d383a673e3939');\nhashMap.set('bazel','4d4f1d9a6519ba552b316b396db13ff0654a2663d8ed976188899a2d57d306a2');\nhashMap.set('bazel-module','9fbba0339f9f7785d52ab85c5f0f6385003093c063483c13feccba13ae438bef');\nhashMap.set('bazelisk','770f75a746dc6ba90c518788d5987d7df4243ef9eee122d1bb0556a93d6e1b11');\nhashMap.set('bicep','7246e0bfc06e0e28cbb03ac088c5591f648956b086e106aeb251fe5d628329db');\nhashMap.set('bitbucket-pipelines','59c0503494ab1442b127914503c01b97ac17b6742b19c632292d5aa24de115cd');\nhashMap.set('bitrise','478dfd316221fad7c29e177c70d1018d832fb2626b53308a5d0f1f0380e69f42');\nhashMap.set('buildkite','b8b404f53cd5d61c39153fddf93945e621471c4ac6aa9960c881cd868922bb4c');\nhashMap.set('buildpacks','6bef3cb04d66b5cfbb195adb4829bcbccae6408518706744d291bacf0610421f');\nhashMap.set('bun','6789cc6499c77cdf44d4fb306198274bb72241e6d0ef7ceda7e916d7022d864c');\nhashMap.set('bun-version','df3ae8e4a5de1fa1b4544f3d7fc8117e80adb1e151c46d1ede54a4dbea6521e4');\nhashMap.set('bundler','6e4784dd98c1f86ef64cc8cbf3128df48aebf920032d7792b54fdedd3dd9d4d5');\nhashMap.set('cake','9ebd8b481220b30a8860121d26184540a1a2fcc05ef780df9295dea39b386fad');\nhashMap.set('cargo','32bddfcf1201495289921a2bf5f9b256b985b8b63a3985190676fb9f9f0f9b23');\nhashMap.set('cdnurl','9a81c8e3c6ad6c788498c99fc1067ffdfcd92a427c3afaf8c0130975d83131f2');\nhashMap.set('circleci','91cbeb33ea20f9838e2c81a1195eb806f0b38fa282bc3679f62552f20575ca85');\nhashMap.set('cloudbuild','f4e40388944652c8a19f8518771ac8d3f3c4ccf81ddef0e68b463aca833cb73c');\nhashMap.set('cocoapods','f832e2beef885bb3fd697ed9bb3e8cd742926bfec37ff41212edd2dbb4edb3ba');\nhashMap.set('composer','3976117beb9adeade088187965929d42f21f5da12c4614fd22aa92cad1083b19');\nhashMap.set('conan','8d46e9a30ae628e26118aea10a98d1b846f7c5d96d51ce24693437d555f6d125');\nhashMap.set('copier','197219e93857ad7e6701755ede245824329da08913ebdb23d1e5e854a169aafe');\nhashMap.set('cpanfile','07813fec3f3c2197056500e9266a0553b9774c02f2c74d5ca2e213188c7c12d3');\nhashMap.set('crossplane','5c26b1201a1a51454ffb94d829e223a76a781569bf79cdb1e47087c30233ec40');\nhashMap.set('crow','eb9a5f9f95041855dded67bcce3dd54724f690995ed6268d272e8a666ff28fd0');\nhashMap.set('deno','41e6a8b7b8bae08f07b3e4b69c8c095db5da984bb23c004cd1ebf755a6317794');\nhashMap.set('deps-edn','06783dbc8b9c7bb84e162d1f75b7db56dfa021cc6f809dfd2314cee8b64af08d');\nhashMap.set('devbox','a40050cc61bd9b5d500ec111abb17bb15d5f82ab5b7699f66f628307ba8382c9');\nhashMap.set('devcontainer','24320ed1cb6191d04cb8b2707214d82c08c682597aed1d84f250aa00ad1632ec');\nhashMap.set('docker-compose','fba87b82cb0f2bfd66526631fbe928b8153e7ca701a5790d02b944df17417bb9');\nhashMap.set('dockerfile','b5faeb8f31d238e0d05a4aeebf9a837273687908ab8078b34e738bb0e369c80c');\nhashMap.set('droneci','661d2a2d7295af8dd7a1234c7090c42a89306bd574c3adf1fc67782efaad3998');\nhashMap.set('fleet','ffa222820f72c4eb4cdc4c229ae8c50433bee96f3b974f0633d5a7d1f6427c97');\nhashMap.set('flux','842597c9083d82af99ef3d526101a3a53c4448414d2f53f7e969074757124811');\nhashMap.set('fvm','9b161df0f14bc6e536368952adf373e343630097121a913cea60ee284027fb90');\nhashMap.set('git-submodules','f4e2c6ddf2fa93241665c5176faafb358eecfcb701e7478790c4d58853ed827a');\nhashMap.set('github-actions','f2d9007071541c4fc4a78aab44049c3a7553b34b699d4beaa27039d2a85082c3');\nhashMap.set('gitlabci','a5e1e66ef461e1c1e71062f85f35a212417e23627f4b002810f9a98295d6e672');\nhashMap.set('gitlabci-include','8860a15ab516fde00694f9bd9bf56fce4addafe5a55b5ddb9a4ec477d301d351');\nhashMap.set('glasskube','93e7b9000a17efa15a1abaaf320b5af9169b1ecd828fc0c881d98570ef9d9e30');\nhashMap.set('gleam','5e9b9f5f914afe5ed7b526c06c65111e3716d2dea9b0cbe7907bbc96db1064a3');\nhashMap.set('gomod','89899292f917777b79f8ce1714e54c4e61cf151fb75f87f1ddb1d1ccd6a4e6f7');\nhashMap.set('gradle','14ffeecba62452d47d3796e68753da745de2614b6e5ecc346da4f0067ed4bc6e');\nhashMap.set('gradle-wrapper','73ba30c34955fab7737454b5cff9aca6d1b5607d53c17c9e13d8ad96f6eaae87');\nhashMap.set('haskell-cabal','f158b7725e3143dfd2950e3de0bbccc2a61cd7eba87f7a54c5057e01252348e2');\nhashMap.set('helm-requirements','22f61344565f87ca3512c0ba8fac32627fde8ee919b7badae07b2116e285f049');\nhashMap.set('helm-values','0aa79bb0257d0d72e54dfd2653e59bfef63b97e46c035b7443593bdf6e6382aa');\nhashMap.set('helmfile','ab63e5bc2bb381939a6b75911947e3fc79d31827423ded07f61ea1c98d95a542');\nhashMap.set('helmsman','951deeb3355da751ef39c9e932b26ea749450e32e75759e4b5fc29359e100b37');\nhashMap.set('helmv3','927798e082caf46a0da703389ba07e9e61fa73ef571ab551301b8fc6b06957d1');\nhashMap.set('hermit','0fb25b7766c3a264fbb765ff75b1542b24136c4c9f933696d4a5aecfed637071');\nhashMap.set('homeassistant-manifest','05043c6db870cffbb6f8f3e351c025e3de227eaae0b24134b796aec46f84b65f');\nhashMap.set('homebrew','dffe954a4e18c2dc4bfdaa12222fe8ddc3395869afd5afa603fc2b6264747984');\nhashMap.set('html','81fa6c2bf2b868596584a48b949645207a2aa3081951ed99183ee50b70b77d5f');\nhashMap.set('jenkins','7fda0e7e0f3d5e18088ccb3594f727f4cfc48b064706bdaaf1a0a075b6a2cff5');\nhashMap.set('jsonnet-bundler','4cedeb0394e5c38361d1868ff45b4f34747ab8c492378b6e63dcaf1f4f3c024d');\nhashMap.set('kotlin-script','95ebc844c040ca047321b207d525220e29774a2a1fe06f9639e8353c66908564');\nhashMap.set('kubernetes','321e7d77fb3600dd4c00a86eaa1294927e7f92300b74fa2977d813dcaa3bb4de');\nhashMap.set('kustomize','4a4321595a55de36669f3bcc6fb54236ad81c8f80ec9cbd3888f49a45fbe70e7');\nhashMap.set('leiningen','c8397e376f1717c2f771ae9ea3ba6b720d2422b133cf937e762c44e42be146a2');\nhashMap.set('maven','c110b99291c2a5bc82cf7a69330275e9bbd7dc8ba3e9e987611dfcffbe002d8d');\nhashMap.set('maven-wrapper','6e53b6e4abf1d20b75094c7a70d66b4a5ac39954f009aa401f5e55dada8be4d0');\nhashMap.set('meteor','4636a47ba4dcfff19fe662572ef7a40d17146be3c966e00ef437e1fc8de92776');\nhashMap.set('mint','248fe4f1ea5c985921c286785792c97e06fc41f402b2d45df82f6aecd17f710e');\nhashMap.set('mise','59c691024c34cb4be4d9b4f811019ae9b22410df0da54977cdcecea261fbbbf5');\nhashMap.set('mix','0f79163dc2a1c896599d152be635c23beaf16812ae3d8fbfffec98c7bd0de872');\nhashMap.set('nix','9cbd96a29fe96e3df7418e422256380202f07970cf7f00b08388c181224a2b85');\nhashMap.set('nodenv','ac652c28481b001f7471f4183eac07b45d98ecbe83efc275830b0a1b2e0459b8');\nhashMap.set('npm','9686302b38f9d6ff899cc69590ec2b9677fd5451f52d227649c0e0812b15c6f9');\nhashMap.set('nuget','fb02247c67a198ffe414a44d23c7894bd114dcc53803334f82e39479e7b27f6f');\nhashMap.set('nvm','3eb77c7b0acf6d64753de78fad2499b352719853aa6872878c40675d14152322');\nhashMap.set('ocb','032b216684c14b0954e0bb019513a2aca3faaee5748587acb668d377d7c891ca');\nhashMap.set('osgi','d6567a733ef3983112b46fdccd7ceebfcd48411104e0c6b6e714d4310db48024');\nhashMap.set('pep621','5a01837b4bc0b575073d1d3d44d9cb030ad66ea2bfb0be830f83f53c30bdb277');\nhashMap.set('pep723','77022a0eae6a3cbb74a1e6d596db1276e379768e40448192b3fa81edd14ca73f');\nhashMap.set('pip-compile','a98dc76a002e1dc21662237f009ff8fea36236bb4e24cb82ee30c6a78f57271f');\nhashMap.set('pip_requirements','bf3a407f72abf711230247bef94ba5dc84c08a35107b0f017912fad66afa716a');\nhashMap.set('pip_setup','df18fba2bdcf48f3ca12a8f7e5cd28df31e2368d5528127277038ef4206eca79');\nhashMap.set('pipenv','baf237cd77173c1a7a9c7fa2a8bfb214f3c488ba0cc27f0e8f334df192e3a398');\nhashMap.set('pixi','e31c397982ffa34222b061f23f3b3683f42523dd5dca45ecce2448b0ebc55ea2');\nhashMap.set('poetry','e9dea5d591c87956b9f018414cb3dab8f2e13580a13be00550fdce198fdf08e6');\nhashMap.set('pre-commit','760f2c291ae084db889f722390798a0e2d431ccdc3bc676e73b14901ebea19ac');\nhashMap.set('proto','412053d4550026b4ace490b46e970915b87ec1abf0b0a0c6c8c58ccf1fc16843');\nhashMap.set('pub','8e7c65dfd1999de4f7c44392e949a4d8f4701eb86df59d550e4657feb06b1872');\nhashMap.set('puppet','ba58ab689e44acc8f61c3569ab8b40fde01b8a9d3aad712708e2a419e57d8b45');\nhashMap.set('pyenv','9ede8becc97774f9040b40f4472d3e933534b596e04c360bfe0f3c6f95f25182');\nhashMap.set('quadlet','40927b98dd2bac45dba60e66b5fd0e6b84b61d02db8be536fda7b14546a4feb7');\nhashMap.set('renovate-config','dfaf3f03ddaf70c332f7916106648f36dbfa6a36dd76d15dd27fa116ab3c174c');\nhashMap.set('ruby-version','2db2140d9eee8c555e729a4de0396fa2d78846d3149890ee12fa515bd654be97');\nhashMap.set('runtime-version','b582b168c0cc595e39010feb10f4b97a82683eb269e9598216fbb11cc186e160');\nhashMap.set('rust-toolchain','6ace53db02874d73620d2d872291839820a512a9529c42d174358c692e5db720');\nhashMap.set('sbt','e1eb5c7f0171a9bb1b6bd4a36a91039a31b6c84e0983d91d930be31a69506d9e');\nhashMap.set('scalafmt','9d36159b56835e96498af026a1fb0543200db0581681ef95ec54988f411e180f');\nhashMap.set('setup-cfg','4a3a7c812d34739c07685691e7e64c7d3127f9d7d4aff99dc45a25df97ed9745');\nhashMap.set('smithy','9641b91d065ffb63be0dd888139a0402dba41e550f8b44c592db9daf52109100');\nhashMap.set('sveltos','60dd75bb53ace31217211100d622fdb65068c6162758b6ae7103a6ce8bdc9f90');\nhashMap.set('swift','cdf063debdbf36888523ff8cec6d2d1b0ec6f49b37b2fbcd80b0d4f6a31114e1');\nhashMap.set('tekton','33948f5bdf7553909fa63744adb26da97ddf366e9499bccab1250879570267c9');\nhashMap.set('terraform','6788a8569ba9c50c763ffa2bed952a4314ae8e696c29f93d3eb7c4a12d99ce20');\nhashMap.set('terraform-version','ec8f786b9731d47f2c2fe0307caf64d7ddd83046fe7ff1f7d8423239f8b0f2aa');\nhashMap.set('terragrunt','300f8fb3c09667654412d2f5dd8ab4882e0f5d1d7a8bc39794993d2e7e58d1b7');\nhashMap.set('terragrunt-version','eea6087b33717d22ede2fc68c2f64df8390b75abe82110ed831a180648feb51d');\nhashMap.set('tflint-plugin','f423bfa2b42a2bfc0e38a33ebd4f9d452473e7ed4e7ad6384a99eb9a35d97479');\nhashMap.set('travis','f3e2f38e699c390b00ff481be5e91dceaa81609e93caf9a4214933de759c84fc');\nhashMap.set('typst','d080a79fbd961c6e21fcc505d544b7e0ff2126142acb1dcabdf6abbcd9339248');\nhashMap.set('unity3d','f13e25e115e3443f4e16cf31578acffa78fb1a5e23339680a92d8d6de6052920');\nhashMap.set('velaci','fda00ddb7cc23e9a37e0a8a253151df0a6930b4276d3e4f78cc54b9ac09af7de');\nhashMap.set('vendir','48e2bff8d3a96e8011ee12776fe9c6e8aac4718ff47e891c294a8f12660cb1bb');\nhashMap.set('woodpecker','6110d3bec33aaeb3511d4bbfa896cec3c8e02fb04a6cff50c9ba81061c851045');\nhashMap.set('xcodegen','dad511d88a9ce1dbdde8b9731f3da7f2bdaa4ca8a083294ee58d56da62ab1683');\nhashMap.set('jsonata','416bcf61144b276b3112814c6e6d261aa29608f46fbb0516c471d35c16f8f0d7');\nhashMap.set('regex','20be5247fdc164173871a051acb0527da017d0c155c653d7563601f55e7b3ff5');"],"mappings":"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"}
@@ -226,6 +226,7 @@ export interface PackageDependency<T = unknown, DepType extends string = string>
226
226
  editFile?: string;
227
227
  separateMinorPatch?: boolean;
228
228
  extractVersion?: string;
229
+ versionCompatibility?: string;
229
230
  isInternal?: boolean;
230
231
  variableName?: string;
231
232
  indentation?: string;
@@ -88,6 +88,10 @@ let config;
88
88
  let platformConfig;
89
89
  const defaultGithubApiUrl = "https://api.github.com/";
90
90
  const GitHubMaxPrBodyLen = 58e3;
91
+ const noteAlertRegex = regEx(/> ℹ️? \*\*Note\*\*\n> ?\n/g);
92
+ const warningAlertRegex = regEx(/> ⚠️? \*\*Warning\*\*\n> ?\n/g);
93
+ const cautionAlertRegex = regEx(/> 🛑 \*\*Caution\*\*\n> ?\n/g);
94
+ const importantAlertRegex = regEx(/> ❗ \*\*Important\*\*\n> ?\n/g);
91
95
  function resetConfigs() {
92
96
  config = {};
93
97
  platformConfig = { host: {
@@ -1448,8 +1452,8 @@ async function directMergePr(prNo, strategy) {
1448
1452
  }
1449
1453
  function massageMarkdown(input) {
1450
1454
  if (platformConfig.host.type !== "github") return smartTruncate(input, maxBodyLength());
1451
- const massagedInput = massageMarkdownLinks(input).replace(regEx(/href="https?:\/\/github.com\//g), "href=\"https://redirect.github.com/").replace(regEx(/]\(https:\/\/github\.com\//g), "](https://redirect.github.com/").replace(regEx(/]: https:\/\/github\.com\//g), "]: https://redirect.github.com/").replaceAll("> ℹ **Note**\n> \n", "> [!NOTE]\n").replaceAll("> ℹ️ **Note**\n> \n", "> [!NOTE]\n").replaceAll("> ⚠ **Warning**\n> \n", "> [!WARNING]\n").replaceAll("> ⚠️ **Warning**\n> \n", "> [!WARNING]\n").replaceAll("> ❗ **Caution**\n> \n", "> [!CAUTION]\n").replaceAll("> ❗ **Important**\n> \n", "> [!IMPORTANT]\n");
1452
- return smartTruncate(massagedInput, maxBodyLength());
1455
+ const linkifiedInput = massageMarkdownLinks(input).replace(regEx(/href="https?:\/\/github.com\//g), "href=\"https://redirect.github.com/").replace(regEx(/]\(https:\/\/github\.com\//g), "](https://redirect.github.com/").replace(regEx(/]: https:\/\/github\.com\//g), "]: https://redirect.github.com/");
1456
+ return smartTruncate(linkifiedInput, maxBodyLength()).replaceAll(noteAlertRegex, "> [!NOTE]\n").replaceAll(warningAlertRegex, "> [!WARNING]\n").replaceAll(cautionAlertRegex, "> [!CAUTION]\n").replaceAll(importantAlertRegex, "> [!IMPORTANT]\n");
1453
1457
  }
1454
1458
  function maxBodyLength() {
1455
1459
  return GitHubMaxPrBodyLen;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["hostRules.find","Issue","git.initRepo","git.getBranchCommit","git.forcePushToRemote","checkPrInMergeQueue","git.prepareCommit","git.resetToCommit","git.fetchBranch"],"sources":["../../../../lib/modules/platform/github/index.ts"],"sourcesContent":["import { setTimeout } from 'node:timers/promises';\nimport { isArray, isNonEmptyObject, isNonEmptyString } from '@sindresorhus/is';\nimport semver from 'semver';\nimport { GlobalConfig } from '../../../config/global.ts';\nimport type { MergeStrategy } from '../../../config/types.ts';\nimport {\n PLATFORM_INTEGRATION_UNAUTHORIZED,\n PLATFORM_RATE_LIMIT_EXCEEDED,\n PLATFORM_UNKNOWN_ERROR,\n PR_ALREADY_IN_MERGE_QUEUE,\n REPOSITORY_ACCESS_FORBIDDEN,\n REPOSITORY_ARCHIVED,\n REPOSITORY_BLOCKED,\n REPOSITORY_CANNOT_FORK,\n REPOSITORY_CHANGED,\n REPOSITORY_DISABLED,\n REPOSITORY_EMPTY,\n REPOSITORY_FORKED,\n REPOSITORY_FORK_MISSING,\n REPOSITORY_FORK_MODE_FORKED,\n REPOSITORY_NOT_FOUND,\n REPOSITORY_RENAMED,\n} from '../../../constants/error-messages.ts';\nimport { instrument } from '../../../instrumentation/index.ts';\nimport { logger } from '../../../logger/index.ts';\nimport { ExternalHostError } from '../../../types/errors/external-host-error.ts';\nimport type { BranchStatus } from '../../../types/index.ts';\nimport { coerceArray } from '../../../util/array.ts';\nimport { isGithubFineGrainedPersonalAccessToken } from '../../../util/check-token.ts';\nimport { coerceToNull } from '../../../util/coerce.ts';\nimport { parseJson } from '../../../util/common.ts';\nimport { getEnv } from '../../../util/env.ts';\nimport { formatCommitMessage } from '../../../util/git/commit-trailers.ts';\nimport * as git from '../../../util/git/index.ts';\nimport {\n diffCommitTree,\n getCommitTreeSha,\n pushCommitToRenovateRef,\n} from '../../../util/git/index.ts';\nimport type {\n CommitFilesConfig,\n CommitResult,\n} from '../../../util/git/types.ts';\nimport * as hostRules from '../../../util/host-rules.ts';\nimport { memCacheProvider } from '../../../util/http/cache/memory-http-cache-provider.ts';\nimport { repoCacheProvider } from '../../../util/http/cache/repository-http-cache-provider.ts';\nimport type { GithubHttpOptions } from '../../../util/http/github.ts';\nimport * as githubHttp from '../../../util/http/github.ts';\nimport type { HttpResponse } from '../../../util/http/types.ts';\nimport { coerceObject } from '../../../util/object.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport { sanitize } from '../../../util/sanitize.ts';\nimport type { LongCommitSha } from '../../../util/schema-utils/git.ts';\nimport { toLongCommitSha } from '../../../util/schema-utils/git.ts';\nimport { looseEquals } from '../../../util/string.ts';\nimport { ensureTrailingSlash, isHttpUrl, parseUrl } from '../../../util/url.ts';\nimport { incLimitedValue } from '../../../workers/global/limits.ts';\nimport { normalizePythonDepName } from '../../datasource/pypi/common.ts';\nimport type {\n AutodiscoverConfig,\n BranchStatusConfig,\n CreatePRConfig,\n EnsureCommentConfig,\n EnsureCommentRemovalConfig,\n EnsureIssueConfig,\n EnsureIssueResult,\n FindPRConfig,\n MergePRConfig,\n PlatformParams,\n PlatformPrOptions,\n PlatformResult,\n Pr,\n ReattemptPlatformAutomergeConfig,\n RepoParams,\n RepoResult,\n UpdatePrConfig,\n} from '../types.ts';\nimport { repoFingerprint } from '../util.ts';\nimport { smartTruncate } from '../utils/pr-body.ts';\nimport { remoteBranchExists } from './branch.ts';\nimport { coerceRestPr, githubApi, mapMergeStartegy } from './common.ts';\nimport { getRepoFile } from './files.ts';\nimport {\n enableAutoMergeMutation,\n enqueuePullRequestMutation,\n getIssuesQuery,\n repoInfoQuery,\n repoMergeQueueQuery,\n} from './graphql.ts';\nimport { GithubIssueCache } from './issue.ts';\nimport { massageMarkdownLinks } from './massage-markdown-links.ts';\nimport {\n isPrInMergeQueue as checkPrInMergeQueue,\n getPrCache,\n updatePrCache,\n} from './pr.ts';\nimport {\n GithubBranchProtection,\n GithubBranchRulesets,\n GithubVulnerabilityAlerts,\n GithubIssue as Issue,\n} from './schema.ts';\nimport type {\n AggregatedVulnerabilities,\n CombinedBranchStatus,\n Comment,\n GhAutomergeResponse,\n GhBranchStatus,\n GhEnqueuePullRequestResponse,\n GhPr,\n GhRepo,\n GhRestPr,\n GhRestRepo,\n GithubHost,\n LocalRepoConfig,\n PlatformConfig,\n} from './types.ts';\nimport { getAppDetails, getUserDetails, getUserEmail } from './user.ts';\nimport {\n getRepoUrl,\n isGithubEnterpriseServer,\n warnIfDefaultGitAuthorEmail,\n} from './utils.ts';\n\nexport const id = 'github';\n\nlet config: LocalRepoConfig;\nlet platformConfig: PlatformConfig;\n\nconst defaultGithubApiUrl = 'https://api.github.com/';\n\n// GitHub's max is 60k but in the hosted app we've observed that content-length is ~1k longer\nconst GitHubMaxPrBodyLen = 58000;\n\nexport function resetConfigs(): void {\n config = {} as never;\n platformConfig = {\n host: {\n type: 'github',\n apiUrl: parseUrl(defaultGithubApiUrl)!,\n },\n };\n}\n\nresetConfigs();\n\nfunction escapeHash(input: string): string {\n return input?.replace(regEx(/#/g), '%23');\n}\n\nexport function isGHApp(): boolean {\n return !!platformConfig.isGHApp;\n}\n\nasync function detectGithubHost(\n apiUrl: URL,\n token: string,\n): Promise<GithubHost> {\n const { hostname } = apiUrl;\n\n if (hostname === 'api.github.com') {\n return { type: 'github', apiUrl };\n }\n\n if (hostname.endsWith('.ghe.com')) {\n logger.debug('Detected GitHub Enterprise Cloud');\n return { type: 'ghec', apiUrl };\n }\n\n const gheHeaderKey = 'x-github-enterprise-version';\n const gheQueryRes = await githubApi.headJson('/', { token });\n const gheHeaders = coerceObject(gheQueryRes?.headers);\n const gheVersionHeader = Object.entries(gheHeaders).find(\n ([k]) => k.toLowerCase() === gheHeaderKey,\n );\n\n const version = semver.valid(gheVersionHeader?.[1] as string) ?? null;\n logger.debug(`Detected GitHub Enterprise Server, version: ${version}`);\n return { type: 'ghes', apiUrl, version };\n}\n\nexport async function initPlatform({\n endpoint,\n token: originalToken,\n username,\n gitAuthor,\n}: PlatformParams): Promise<PlatformResult> {\n let token = originalToken;\n if (!token) {\n throw new Error('Init: You must configure a GitHub token');\n }\n token = token.replace(regEx(/^ghs_/), 'x-access-token:ghs_');\n platformConfig.isGHApp = token.startsWith('x-access-token:');\n\n let githubApiUrl = platformConfig.host.apiUrl;\n if (endpoint) {\n const parsedApiUrl = parseUrl(ensureTrailingSlash(endpoint));\n if (!parsedApiUrl || !isHttpUrl(parsedApiUrl)) {\n throw new Error(`Init: Invalid GitHub endpoint URL: ${endpoint}`);\n }\n githubApiUrl = parsedApiUrl;\n githubHttp.setBaseUrl(githubApiUrl.href);\n } else {\n logger.debug(`Using default github endpoint: ${githubApiUrl.href}`);\n }\n\n platformConfig.host = await detectGithubHost(githubApiUrl, token);\n /**\n * GHE requires version >=3.10 to support fine-grained access tokens\n * https://docs.github.com/en/enterprise-server@3.10/admin/release-notes#authentication\n */\n if (\n isGithubFineGrainedPersonalAccessToken(token) &&\n isGithubEnterpriseServer(platformConfig.host) &&\n (!platformConfig.host.version ||\n semver.lt(platformConfig.host.version, '3.10.0'))\n ) {\n throw new Error(\n 'Init: Fine-grained Personal Access Tokens do not support GitHub Enterprise Server API version <3.10 and cannot be used with Renovate.',\n );\n }\n\n let renovateUsername: string;\n if (username) {\n renovateUsername = username;\n } else if (platformConfig.isGHApp) {\n platformConfig.userDetails ??= await getAppDetails(token);\n renovateUsername = platformConfig.userDetails.username;\n } else {\n platformConfig.userDetails ??= await getUserDetails(\n platformConfig.host.apiUrl.href,\n token,\n );\n renovateUsername = platformConfig.userDetails.username;\n }\n\n let ghHostname: string;\n if (platformConfig.host.type === 'ghec') {\n ghHostname = 'ghe.com';\n } else if (platformConfig.host.type === 'ghes') {\n ghHostname = platformConfig.host.apiUrl.hostname;\n } else {\n ghHostname = 'github.com';\n }\n\n let discoveredGitAuthor: string | undefined;\n if (!gitAuthor) {\n if (platformConfig.isGHApp) {\n platformConfig.userDetails ??= await getAppDetails(token);\n // v8 ignore next -- TODO: coverage error #40625\n discoveredGitAuthor = `${platformConfig.userDetails.name} <${platformConfig.userDetails.id}+${platformConfig.userDetails.username}@users.noreply.${ghHostname}>`;\n } else {\n platformConfig.userDetails ??= await getUserDetails(\n platformConfig.host.apiUrl.href,\n token,\n );\n // v8 ignore next -- TODO: coverage error #40625\n platformConfig.userEmail =\n platformConfig.userDetails.email ??\n (await getUserEmail(platformConfig.host.apiUrl.href, token));\n if (platformConfig.userEmail) {\n discoveredGitAuthor = `${platformConfig.userDetails.name} <${platformConfig.userEmail}>`;\n }\n }\n }\n\n git.setPlatformIgnoredAuthors([`noreply@${ghHostname}`]);\n\n logger.debug({ platformConfig, renovateUsername }, 'Platform config');\n const platformResult: PlatformResult = {\n endpoint: platformConfig.host.apiUrl.href,\n gitAuthor: gitAuthor ?? discoveredGitAuthor,\n renovateUsername,\n token,\n };\n\n warnIfDefaultGitAuthorEmail(\n platformResult.gitAuthor,\n platformConfig.host.type !== 'github',\n );\n\n if (\n getEnv().RENOVATE_X_GITHUB_HOST_RULES &&\n platformResult.endpoint === 'https://api.github.com/'\n ) {\n logger.debug('Adding GitHub token as GHCR password');\n platformResult.hostRules = [\n {\n matchHost: 'ghcr.io',\n hostType: 'docker',\n username: 'USERNAME',\n password: token.replace(regEx(/^x-access-token:/), ''),\n },\n ];\n logger.debug('Adding GitHub token as npm.pkg.github.com Basic token');\n platformResult.hostRules.push({\n matchHost: 'npm.pkg.github.com',\n hostType: 'npm',\n token: token.replace(regEx(/^x-access-token:/), ''),\n });\n const usernamePasswordHostTypes = ['rubygems', 'maven', 'nuget'];\n for (const hostType of usernamePasswordHostTypes) {\n logger.debug(\n `Adding GitHub token as ${hostType}.pkg.github.com password`,\n );\n platformResult.hostRules.push({\n hostType,\n matchHost: `${hostType}.pkg.github.com`,\n username: renovateUsername,\n password: token.replace(regEx(/^x-access-token:/), ''),\n });\n }\n }\n return platformResult;\n}\n\nasync function fetchRepositories(): Promise<GhRestRepo[]> {\n try {\n if (isGHApp()) {\n const res = await githubApi.getJsonUnchecked<{\n repositories: GhRestRepo[];\n }>(`installation/repositories?per_page=100`, {\n paginationField: 'repositories',\n paginate: 'all',\n });\n return res.body.repositories;\n }\n const res = await githubApi.getJsonUnchecked<GhRestRepo[]>(\n `user/repos?per_page=100`,\n { paginate: 'all' },\n );\n return res.body;\n } catch (err) /* v8 ignore next -- defensive: repo listing failures are logged and rethrown, not simulated in specs */ {\n logger.error({ err }, `GitHub getRepos error`);\n throw err;\n }\n}\n\n// Get all repositories that the user has access to\nexport async function getRepos(config?: AutodiscoverConfig): Promise<string[]> {\n logger.debug('Autodiscovering GitHub repositories');\n const nonEmptyRepositories = (await fetchRepositories()).filter(\n isNonEmptyObject,\n );\n const nonArchivedRepositories = nonEmptyRepositories.filter(\n (repo) => !repo.archived,\n );\n if (nonArchivedRepositories.length < nonEmptyRepositories.length) {\n logger.debug(\n `Filtered out ${\n nonEmptyRepositories.length - nonArchivedRepositories.length\n } archived repositories`,\n );\n }\n if (!config?.topics) {\n return nonArchivedRepositories.map((repo) => repo.full_name);\n }\n\n logger.debug({ topics: config.topics }, 'Filtering by topics');\n const topicRepositories = nonArchivedRepositories.filter((repo) =>\n repo.topics?.some((topic) => config?.topics?.includes(topic)),\n );\n\n // v8 ignore else -- TODO: add test #40625\n if (topicRepositories.length < nonArchivedRepositories.length) {\n logger.debug(\n `Filtered out ${\n nonArchivedRepositories.length - topicRepositories.length\n } repositories not matching topic filters`,\n );\n }\n return topicRepositories.map((repo) => repo.full_name);\n}\n\nasync function getBranchProtection(\n branchName: string,\n): Promise<GithubBranchProtection> {\n if (config.parentRepo) {\n return {};\n }\n\n const res = await githubApi.getJson(\n `repos/${config.repository}/branches/${escapeHash(branchName)}/protection`,\n { cacheProvider: repoCacheProvider },\n GithubBranchProtection,\n );\n return res.body;\n}\n\nasync function getBranchRulesets(\n branchName: string,\n): Promise<GithubBranchRulesets> {\n if (config.parentRepo) {\n return [];\n }\n\n try {\n const res = await githubApi.getJson(\n `repos/${config.repository}/rules/branches/${escapeHash(branchName)}`,\n { cacheProvider: repoCacheProvider },\n GithubBranchRulesets,\n );\n return res.body;\n } catch (err) {\n if (err.statusCode === 404) {\n logger.debug(`No branch rulesets found for ${branchName}`);\n return [];\n }\n throw err;\n }\n}\n\nexport async function getRawFile(\n fileName: string,\n repoName?: string,\n branchOrTag?: string,\n): Promise<string | null> {\n const repo = repoName ?? config.repository;\n\n // only use cache for the same org\n const httpOptions: GithubHttpOptions = {};\n const isSameOrg = repo?.split('/')?.[0] === config.repositoryOwner;\n // v8 ignore else -- TODO: add test #40625\n if (isSameOrg) {\n httpOptions.cacheProvider = repoCacheProvider;\n }\n\n return await getRepoFile(\n githubApi,\n // TODO #22198\n repo!,\n fileName,\n branchOrTag,\n httpOptions,\n );\n}\n\nexport async function getJsonFile(\n fileName: string,\n repoName?: string,\n branchOrTag?: string,\n): Promise<any> {\n const raw = await getRawFile(fileName, repoName, branchOrTag);\n return parseJson(raw, fileName);\n}\n\nexport async function listForks(\n token: string,\n repository: string,\n): Promise<GhRestRepo[]> {\n try {\n // Get list of existing repos\n const url = `repos/${repository}/forks?per_page=100`;\n const repos = (\n await githubApi.getJsonUnchecked<GhRestRepo[]>(url, {\n token,\n paginate: true,\n pageLimit: 100,\n })\n ).body;\n logger.debug(`Found ${repos.length} forked repo(s)`);\n return repos;\n } catch (err) {\n if (err.statusCode === 404) {\n logger.debug('Cannot list repo forks - it is likely private');\n } else {\n logger.debug({ err }, 'Unknown error listing repository forks');\n }\n throw new Error(REPOSITORY_CANNOT_FORK);\n }\n}\n\nexport async function findFork(\n token: string,\n repository: string,\n forkOrg?: string,\n): Promise<GhRestRepo | null> {\n const forks = await listForks(token, repository);\n if (forkOrg) {\n logger.debug(`Searching for forked repo in forkOrg (${forkOrg})`);\n const forkedRepo = forks.find((repo) => repo.owner.login === forkOrg);\n if (forkedRepo) {\n logger.debug(`Found repo in forkOrg: ${forkedRepo.full_name}`);\n return forkedRepo;\n }\n logger.debug(`No repo found in forkOrg`);\n }\n logger.debug(`Searching for forked repo in user account`);\n try {\n const { username } = await getUserDetails(\n platformConfig.host.apiUrl.href,\n token,\n );\n const forkedRepo = forks.find((repo) => repo.owner.login === username);\n if (forkedRepo) {\n logger.debug(`Found repo in user account: ${forkedRepo.full_name}`);\n return forkedRepo;\n }\n } catch {\n throw new Error(REPOSITORY_CANNOT_FORK);\n }\n logger.debug(`No repo found in user account`);\n return null;\n}\n\nexport async function createFork(\n token: string,\n repository: string,\n forkOrg?: string,\n): Promise<GhRestRepo> {\n let forkedRepo: GhRestRepo | undefined;\n try {\n forkedRepo = (\n await githubApi.postJson<GhRestRepo>(`repos/${repository}/forks`, {\n token,\n body: {\n organization: forkOrg ?? undefined,\n name: config.parentRepo!.replace('/', '-_-'),\n default_branch_only: true, // no baseBranchPatterns support yet\n },\n })\n ).body;\n } catch (err) {\n logger.debug({ err }, 'Error creating fork');\n }\n if (!forkedRepo) {\n throw new Error(REPOSITORY_CANNOT_FORK);\n }\n logger.info({ forkedRepo: forkedRepo.full_name }, 'Created forked repo');\n logger.debug(`Sleeping 30s after creating fork`);\n await setTimeout(30000);\n return forkedRepo;\n}\n\n// Initialize GitHub by getting base branch and SHA\nexport async function initRepo({\n repository,\n forkCreation,\n forkOrg,\n forkToken,\n gitUrl,\n renovateUsername,\n cloneSubmodules,\n cloneSubmodulesFilter,\n}: RepoParams): Promise<RepoResult> {\n logger.debug(`initRepo(\"${repository}\")`);\n // config is used by the platform api itself, not necessary for the app layer to know\n config = {\n repository,\n cloneSubmodules,\n cloneSubmodulesFilter,\n ignorePrAuthor: GlobalConfig.get('ignorePrAuthor'),\n mergeQueueEnabled: {},\n } as any;\n const opts = hostRules.find({\n hostType: 'github',\n url: platformConfig.host.apiUrl.href,\n readOnly: true,\n });\n config.renovateUsername = renovateUsername;\n [config.repositoryOwner, config.repositoryName] = repository.split('/');\n let repo: GhRepo | undefined;\n let forkSshUrl: string | null = null;\n try {\n let infoQuery = repoInfoQuery;\n\n // GitHub Enterprise Server <3.3.0 doesn't support autoMergeAllowed and hasIssuesEnabled objects\n // TODO #22198\n if (\n isGithubEnterpriseServer(platformConfig.host) &&\n semver.satisfies(platformConfig.host.version ?? '', '<3.3.0')\n ) {\n infoQuery = infoQuery.replace(regEx(/\\n\\s*autoMergeAllowed\\s*\\n/), '\\n');\n infoQuery = infoQuery.replace(regEx(/\\n\\s*hasIssuesEnabled\\s*\\n/), '\\n');\n }\n\n // GitHub Enterprise Server <3.9.0 doesn't support hasVulnerabilityAlertsEnabled objects\n if (\n isGithubEnterpriseServer(platformConfig.host) &&\n semver.satisfies(platformConfig.host.version ?? '', '<3.9.0')\n ) {\n infoQuery = infoQuery.replace(\n regEx(/\\n\\s*hasVulnerabilityAlertsEnabled\\s*\\n/),\n '\\n',\n );\n }\n\n // GitHub Enterprise Server <3.12.0 doesn't support merge queues\n if (\n isGithubEnterpriseServer(platformConfig.host) &&\n semver.satisfies(platformConfig.host.version ?? '', '<3.12.0')\n ) {\n infoQuery = infoQuery.replace(\n regEx(/\\n\\s*mergeQueue\\s*\\{\\s*id\\s*\\}\\s*\\n/),\n '\\n',\n );\n }\n\n const res = await githubApi.requestGraphql<{\n repository: GhRepo;\n }>(infoQuery, {\n variables: {\n owner: config.repositoryOwner,\n name: config.repositoryName,\n ...(!config.ignorePrAuthor && { user: renovateUsername }),\n },\n readOnly: true,\n count: 1, // bypass graphql check\n });\n\n if (res?.errors) {\n logger.debug({ res }, 'Unexpected GraphQL errors');\n throw new Error(PLATFORM_UNKNOWN_ERROR);\n }\n\n repo = res?.data?.repository;\n /* v8 ignore next -- defensive: GraphQL errors are handled above, a null repository is not mocked in specs */\n if (!repo) {\n logger.debug({ res }, 'No repository returned');\n throw new Error(REPOSITORY_NOT_FOUND);\n }\n /* v8 ignore next -- empty-repo detection via missing defaultBranchRef is not mocked in specs */\n if (!repo.defaultBranchRef?.name) {\n logger.debug(\n { res },\n 'No default branch returned - treating repo as empty',\n );\n throw new Error(REPOSITORY_EMPTY);\n }\n if (\n repo.nameWithOwner &&\n repo.nameWithOwner.toUpperCase() !== repository.toUpperCase()\n ) {\n logger.debug(\n { desiredRepo: repository, foundRepo: repo.nameWithOwner },\n 'Repository has been renamed',\n );\n throw new Error(REPOSITORY_RENAMED);\n }\n if (repo.isArchived) {\n logger.debug(\n 'Repository is archived - throwing error to abort renovation',\n );\n throw new Error(REPOSITORY_ARCHIVED);\n }\n // Use default branch as PR target unless later overridden.\n config.defaultBranch = repo.defaultBranchRef.name;\n // Base branch may be configured but defaultBranch is always fixed\n logger.debug(`${repository} default branch = ${config.defaultBranch}`);\n // GitHub allows administrators to block certain types of merge, so we need to check it\n if (repo.squashMergeAllowed) {\n config.mergeMethod = 'squash';\n } else if (repo.mergeCommitAllowed) {\n config.mergeMethod = 'merge';\n } else if (repo.rebaseMergeAllowed) {\n config.mergeMethod = 'rebase';\n } else {\n // This happens if we don't have Administrator read access, it is not a critical error\n logger.debug('Could not find allowed merge methods for repo');\n }\n config.autoMergeAllowed = repo.autoMergeAllowed;\n config.hasIssuesEnabled = repo.hasIssuesEnabled;\n config.hasVulnerabilityAlertsEnabled = repo.hasVulnerabilityAlertsEnabled;\n config.mergeQueueEnabled[config.defaultBranch] = isNonEmptyObject(\n repo.mergeQueue,\n );\n\n const recentIssues = Issue.array()\n .catch([])\n .parse(res?.data?.repository?.issues?.nodes);\n GithubIssueCache.addIssuesToReconcile(recentIssues);\n } catch (err) /* v8 ignore next -- initRepo error mapping needs failure shapes not mocked in specs */ {\n logger.debug({ err }, 'Caught initRepo error');\n if (\n err.message === REPOSITORY_ARCHIVED ||\n err.message === REPOSITORY_RENAMED ||\n err.message === REPOSITORY_NOT_FOUND\n ) {\n throw err;\n }\n if (err.statusCode === 403) {\n throw new Error(REPOSITORY_ACCESS_FORBIDDEN);\n }\n if (err.statusCode === 404) {\n throw new Error(REPOSITORY_NOT_FOUND);\n }\n if (err.message.startsWith('Repository access blocked')) {\n throw new Error(REPOSITORY_BLOCKED);\n }\n if (err.message === REPOSITORY_FORK_MODE_FORKED) {\n throw err;\n }\n if (err.message === REPOSITORY_FORKED) {\n throw err;\n }\n if (err.message === REPOSITORY_DISABLED) {\n throw err;\n }\n if (err.message === 'Response code 451 (Unavailable for Legal Reasons)') {\n throw new Error(REPOSITORY_ACCESS_FORBIDDEN);\n }\n logger.debug({ err }, 'Unknown GitHub initRepo error');\n throw err;\n }\n // This shouldn't be necessary, but occasional strange errors happened until it was added\n config.prList = null;\n\n if (forkToken) {\n logger.debug('Renovate is in fork mode');\n if (repo.isFork) {\n logger.debug(\n `Forked repos cannot be processed when running with a forkToken, so this repo will be skipped`,\n );\n logger.debug(\n `Parent repo for this forked repo is ${repo.parent?.nameWithOwner}`,\n );\n throw new Error(REPOSITORY_FORKED);\n }\n config.forkOrg = forkOrg;\n config.forkToken = forkToken;\n // save parent name then delete\n config.parentRepo = config.repository;\n config.repository = null;\n let forkedRepo = await findFork(forkToken, repository, forkOrg);\n if (forkedRepo) {\n config.repository = forkedRepo.full_name;\n forkSshUrl = forkedRepo.ssh_url;\n const forkDefaultBranch = forkedRepo.default_branch;\n if (forkDefaultBranch !== config.defaultBranch) {\n const body = {\n ref: `refs/heads/${config.defaultBranch}`,\n sha: repo.defaultBranchRef.target.oid,\n };\n logger.debug(\n {\n defaultBranch: config.defaultBranch,\n forkDefaultBranch,\n body,\n },\n 'Fork has different default branch to parent, attempting to create branch',\n );\n try {\n await githubApi.postJson(`repos/${config.repository}/git/refs`, {\n body,\n token: forkToken,\n });\n logger.debug('Created new default branch in fork');\n } catch (err) /* v8 ignore next -- fork default-branch creation failures are not mocked in specs */ {\n if (err.response?.body?.message === 'Reference already exists') {\n logger.debug(\n `Branch ${config.defaultBranch} already exists in the fork`,\n );\n } else {\n logger.warn(\n { err, body: err.response?.body },\n 'Could not create parent defaultBranch in fork',\n );\n }\n }\n logger.debug(\n `Setting ${config.defaultBranch} as default branch for ${config.repository}`,\n );\n try {\n await githubApi.patchJson(`repos/${config.repository}`, {\n body: {\n name: config.repository.split('/')[1],\n default_branch: config.defaultBranch,\n },\n token: forkToken,\n });\n logger.debug('Successfully changed default branch for fork');\n } catch (err) /* v8 ignore next -- defensive: fork default-branch update failures are logged and swallowed, not simulated in specs */ {\n logger.warn({ err }, 'Could not set default branch');\n }\n }\n } else if (forkCreation) {\n logger.debug('Forked repo is not found - attempting to create it');\n forkedRepo = await createFork(forkToken, repository, forkOrg);\n config.repository = forkedRepo.full_name;\n forkSshUrl = forkedRepo.ssh_url;\n } else {\n logger.debug('Forked repo is not found and forkCreation is disabled');\n throw new Error(REPOSITORY_FORK_MISSING);\n }\n }\n\n let authToken: string | null;\n if (forkToken) {\n logger.debug('Using forkToken for git init');\n authToken = coerceToNull(config.forkToken);\n } /* v8 ignore next -- token-type detection depends on opts.token shapes not varied in specs */ else {\n const tokenType = opts.token?.startsWith('x-access-token:')\n ? 'app'\n : 'personal access';\n logger.debug(`Using ${tokenType} token for git init`);\n authToken = opts.token ?? null;\n }\n const workingSshUrl = forkToken ? forkSshUrl : repo.sshUrl;\n const url = getRepoUrl(\n config.repository!,\n gitUrl,\n workingSshUrl,\n platformConfig.host.apiUrl,\n authToken,\n );\n let upstreamUrl: string | undefined;\n if (forkCreation && config.parentRepo) {\n upstreamUrl = getRepoUrl(\n config.parentRepo,\n gitUrl,\n repo.sshUrl,\n platformConfig.host.apiUrl,\n authToken,\n );\n }\n await git.initRepo({\n ...config,\n url,\n upstreamUrl,\n });\n const repoConfig: RepoResult = {\n defaultBranch: config.defaultBranch,\n isFork: repo.isFork === true,\n repoFingerprint: repoFingerprint(repo.id, platformConfig.host.apiUrl.href),\n };\n return repoConfig;\n}\n\nasync function checkRulesetsForForceRebase(\n branchName: string,\n): Promise<boolean> {\n try {\n const rulesets = await getBranchRulesets(branchName);\n logger.trace(\n `Ruleset: Found ${rulesets.length} rulesets for branch ${branchName}`,\n );\n\n return rulesets.some((rule) => {\n if (\n rule.type === 'required_status_checks' &&\n rule.parameters?.strict_required_status_checks_policy === true\n ) {\n logger.debug(\n `Ruleset: strict required status checks found for ${branchName}`,\n );\n return true;\n }\n\n return false;\n });\n } catch (err) {\n handleBranchProtectionError('rulesets', err, branchName);\n return false;\n }\n}\n\nasync function checkBranchProtectionForForceRebase(\n branchName: string,\n): Promise<boolean> {\n try {\n const branchProtection = await getBranchProtection(branchName);\n logger.trace(`Found branch protection for branch ${branchName}`);\n\n const strictStatusChecks = branchProtection?.required_status_checks?.strict;\n if (strictStatusChecks) {\n logger.debug(\n `Branch protection: PRs must be up-to-date before merging for ${branchName}`,\n );\n return true;\n }\n return false;\n } catch (err) {\n handleBranchProtectionError('branch-protection', err, branchName);\n return false;\n }\n}\n\nexport async function getBranchForceRebase(\n branchName: string,\n): Promise<boolean> {\n config.branchForceRebase ??= {};\n\n const cachedResult = config.branchForceRebase[branchName];\n if (cachedResult !== undefined) {\n return cachedResult;\n }\n\n // Initialize to false before checking branch protection\n config.branchForceRebase[branchName] = false;\n\n // Check rulesets first (newer API)\n const hasRulesetForceRebase = await checkRulesetsForForceRebase(branchName);\n if (hasRulesetForceRebase) {\n config.branchForceRebase[branchName] = true;\n return true;\n }\n\n // Fall back to legacy branch protection\n const hasBranchProtectionForceRebase =\n await checkBranchProtectionForForceRebase(branchName);\n if (hasBranchProtectionForceRebase) {\n config.branchForceRebase[branchName] = true;\n }\n\n return config.branchForceRebase[branchName];\n}\n\nfunction handleBranchProtectionError(\n protection: 'branch-protection' | 'rulesets',\n err: any,\n branchName: string,\n): void {\n if (err.statusCode === 404) {\n logger.debug(`No ${protection} found for ${branchName}`);\n return;\n }\n\n const isUnauthorized =\n err.message === PLATFORM_INTEGRATION_UNAUTHORIZED || err.statusCode === 403;\n\n if (isUnauthorized) {\n logger.once.debug(\n `Branch protection: Do not have permissions to detect ${protection} for ${branchName}`,\n );\n return;\n }\n\n throw err;\n}\n\nfunction cachePr(pr?: GhPr | null): void {\n config.prList ??= [];\n // v8 ignore else -- TODO: add test #40625\n if (pr) {\n updatePrCache(pr);\n for (let idx = 0; idx < config.prList.length; idx += 1) {\n const cachedPr = config.prList[idx];\n if (cachedPr.number === pr.number) {\n config.prList[idx] = pr;\n return;\n }\n }\n config.prList.push(pr);\n }\n}\n\n// Fetch fresh Pull Request and cache it when possible\nasync function fetchPr(prNo: number): Promise<GhPr | null> {\n try {\n const { body: ghRestPr } = await githubApi.getJsonUnchecked<GhRestPr>(\n `repos/${config.parentRepo ?? config.repository}/pulls/${prNo}`,\n );\n const result = coerceRestPr(ghRestPr);\n cachePr(result);\n return result;\n } catch (err) {\n logger.warn({ err, prNo }, `GitHub fetchPr error`);\n return null;\n }\n}\n\n// Gets details for a PR\nexport async function getPr(prNo: number): Promise<GhPr | null> {\n if (!prNo) {\n return null;\n }\n const prList = await getPrList();\n let pr = prList.find(({ number }) => number === prNo) ?? null;\n if (pr) {\n logger.debug('Returning PR from cache');\n }\n pr ??= await fetchPr(prNo);\n return pr;\n}\n\nfunction matchesState(state: string, desiredState: string): boolean {\n if (desiredState === 'all') {\n return true;\n }\n if (desiredState.startsWith('!')) {\n return state !== desiredState.substring(1);\n }\n return state === desiredState;\n}\n\nexport async function getPrList(): Promise<GhPr[]> {\n if (!config.prList) {\n const repo = config.parentRepo ?? config.repository;\n\n let username = config.renovateUsername;\n if (config.forkToken || config.ignorePrAuthor) {\n username = undefined;\n }\n\n // TODO: check null `repo` (#22198)\n const prCache = await instrument('getPrCache', () =>\n getPrCache(githubApi, repo!, username),\n );\n config.prList = Object.values(prCache).sort(\n ({ number: a }, { number: b }) => b - a,\n );\n }\n\n return config.prList;\n}\n\nexport async function findPr({\n branchName,\n prTitle,\n state = 'all',\n includeOtherAuthors,\n}: FindPRConfig): Promise<GhPr | null> {\n logger.debug(`findPr(${branchName}, ${prTitle}, ${state})`);\n\n if (includeOtherAuthors) {\n const repo = config.parentRepo ?? config.repository;\n const org = repo?.split('/')[0];\n // PR might have been created by anyone, so don't use the cached Renovate PR list\n const { body: prList } = await githubApi.getJsonUnchecked<GhRestPr[]>(\n `repos/${repo}/pulls?head=${org}:${branchName}&state=open`,\n { cacheProvider: repoCacheProvider },\n );\n\n if (!prList.length) {\n logger.debug(`No PR found for branch ${branchName}`);\n return null;\n }\n\n return coerceRestPr(prList[0]);\n }\n\n const prList = await getPrList();\n const pr = prList.find((p) => {\n if (p.sourceBranch !== branchName) {\n return false;\n }\n\n if (prTitle && prTitle.toUpperCase() !== p.title.toUpperCase()) {\n return false;\n }\n\n if (!matchesState(p.state, state)) {\n return false;\n }\n\n if (!config.forkToken && !looseEquals(config.repository, p.sourceRepo)) {\n return false;\n }\n\n return true;\n });\n if (pr) {\n logger.debug(`Found PR #${pr.number}`);\n }\n return pr ?? null;\n}\n\nasync function ensureBranchSha(\n branchName: string,\n sha: LongCommitSha,\n): Promise<void> {\n const repository = config.repository!;\n try {\n const commitUrl = `/repos/${repository}/git/commits/${sha}`;\n await githubApi.head(commitUrl, { memCache: false });\n } catch (err) {\n logger.error({ err, sha, branchName }, 'Commit not found');\n throw err;\n }\n\n const refUrl = `/repos/${config.repository}/git/refs/heads/${branchName}`;\n const branchExists = await remoteBranchExists(repository, branchName);\n\n if (branchExists) {\n try {\n await githubApi.patchJson(refUrl, { body: { sha, force: true } });\n return;\n } catch (err) {\n if (err.err?.response?.statusCode === 422) {\n logger.debug(\n { err },\n 'Branch update failed due to reference not existing - will try to create',\n );\n } else {\n logger.warn({ refUrl, err }, 'Error updating branch');\n throw err;\n }\n }\n }\n\n await githubApi.postJson(`/repos/${repository}/git/refs`, {\n body: { sha, ref: `refs/heads/${branchName}` },\n });\n}\n\n// Returns the Pull Request for a branch. Null if not exists.\nexport async function getBranchPr(branchName: string): Promise<GhPr | null> {\n logger.debug(`getBranchPr(${branchName})`);\n\n const openPr = await findPr({\n branchName,\n state: 'open',\n });\n\n if (openPr) {\n return openPr;\n }\n\n return null;\n}\n\nexport async function tryReuseAutoclosedPr(\n autoclosedPr: Pr,\n newTitle: string,\n): Promise<Pr | null> {\n const { sha, number, sourceBranch: branchName } = autoclosedPr;\n try {\n await ensureBranchSha(branchName, sha!);\n logger.debug(`Recreated autoclosed branch ${branchName} with sha ${sha}`);\n } catch (err) {\n logger.debug(\n { err, branchName, sha, autoclosedPr },\n 'Could not recreate autoclosed branch - skipping reopen',\n );\n return null;\n }\n\n try {\n const { body: ghPr } = await githubApi.patchJson<GhRestPr>(\n `repos/${config.repository}/pulls/${number}`,\n {\n body: {\n state: 'open',\n title: newTitle,\n },\n },\n );\n logger.info(\n { branchName, oldTitle: autoclosedPr.title, newTitle, number },\n 'Successfully reopened autoclosed PR',\n );\n\n const result = coerceRestPr(ghPr);\n\n const localSha = git.getBranchCommit(branchName);\n // v8 ignore else -- TODO: add test #40625\n if (localSha && localSha !== sha) {\n await git.forcePushToRemote(branchName, 'origin');\n result.sha = localSha;\n }\n\n cachePr(result);\n return result;\n } catch {\n logger.debug('Could not reopen autoclosed PR');\n return null;\n }\n}\n\nasync function getStatus(\n branchName: string,\n useCache = true,\n): Promise<CombinedBranchStatus> {\n const branch = escapeHash(branchName);\n const url = `repos/${config.repository}/commits/${branch}/status`;\n\n const { body: status } =\n await githubApi.getJsonUnchecked<CombinedBranchStatus>(url, {\n memCache: useCache,\n cacheProvider: repoCacheProvider,\n });\n\n return status;\n}\n\n// Returns the combined status for a branch.\nexport async function getBranchStatus(\n branchName: string,\n internalChecksAsSuccess: boolean,\n): Promise<BranchStatus> {\n logger.debug(`getBranchStatus(${branchName})`);\n let commitStatus: CombinedBranchStatus;\n try {\n commitStatus = await getStatus(branchName);\n } catch (err) /* v8 ignore next -- 404-to-REPOSITORY_CHANGED mapping for deleted branches is not mocked in specs */ {\n if (err.statusCode === 404) {\n logger.debug(\n 'Received 404 when checking branch status, assuming that branch has been deleted',\n );\n throw new Error(REPOSITORY_CHANGED);\n }\n logger.debug('Unknown error when checking branch status');\n throw err;\n }\n logger.debug(\n { state: commitStatus.state, statuses: commitStatus.statuses },\n 'branch status check result',\n );\n if (commitStatus.statuses && !internalChecksAsSuccess) {\n commitStatus.statuses = commitStatus.statuses.filter(\n (status) =>\n status.state !== 'success' || !status.context?.startsWith('renovate/'),\n );\n // v8 ignore else -- TODO: add test #40625\n if (!commitStatus.statuses.length) {\n logger.debug(\n 'Successful checks are all internal renovate/ checks, so returning \"pending\" branch status',\n );\n commitStatus.state = 'pending';\n }\n }\n let checkRuns: { name: string; status: string; conclusion: string }[] = [];\n // API is supported in oldest available GHE version 2.19\n try {\n const checkRunsUrl = `repos/${config.repository}/commits/${escapeHash(\n branchName,\n )}/check-runs?per_page=100`;\n const opts = {\n headers: {\n accept: 'application/vnd.github.antiope-preview+json',\n },\n paginate: true,\n paginationField: 'check_runs',\n cacheProvider: memCacheProvider,\n };\n const checkRunsRaw = (\n await githubApi.getJsonUnchecked<{\n check_runs: { name: string; status: string; conclusion: string }[];\n }>(checkRunsUrl, opts)\n ).body;\n if (checkRunsRaw.check_runs?.length) {\n checkRuns = checkRunsRaw.check_runs.map((run) => ({\n name: run.name,\n status: run.status,\n conclusion: run.conclusion,\n }));\n logger.debug({ checkRuns }, 'check runs result');\n } /* v8 ignore next -- specs always mock a non-empty check_runs response */ else {\n logger.debug({ result: checkRunsRaw }, 'No check runs found');\n }\n } catch (err) /* v8 ignore next -- check-run permission errors (403) are mapped to empty results, not mocked in specs */ {\n if (err instanceof ExternalHostError) {\n throw err;\n }\n if (\n err.statusCode === 403 ||\n err.message === PLATFORM_INTEGRATION_UNAUTHORIZED\n ) {\n logger.debug('No permission to view check runs');\n } else {\n logger.warn({ err }, 'Error retrieving check runs');\n }\n }\n if (checkRuns.length === 0) {\n if (commitStatus.state === 'success') {\n return 'green';\n }\n if (commitStatus.state === 'failure') {\n return 'red';\n }\n return 'yellow';\n }\n if (\n commitStatus.state === 'failure' ||\n checkRuns.some((run) => run.conclusion === 'failure')\n ) {\n return 'red';\n }\n if (\n (commitStatus.state === 'success' || commitStatus.statuses.length === 0) &&\n checkRuns.every((run) =>\n ['skipped', 'neutral', 'success'].includes(run.conclusion),\n )\n ) {\n return 'green';\n }\n return 'yellow';\n}\n\nasync function getStatusCheck(\n branchName: string,\n useCache = true,\n): Promise<GhBranchStatus[]> {\n const branchCommit = git.getBranchCommit(branchName);\n\n const url = `repos/${config.repository}/commits/${branchCommit}/statuses`;\n\n const opts: GithubHttpOptions = useCache\n ? { cacheProvider: memCacheProvider }\n : { memCache: false };\n\n return (await githubApi.getJsonUnchecked<GhBranchStatus[]>(url, opts)).body;\n}\n\ntype GithubToRenovateStatusMapping = Record<string, BranchStatus>;\nconst githubToRenovateStatusMapping: GithubToRenovateStatusMapping = {\n success: 'green',\n error: 'red',\n failure: 'red',\n pending: 'yellow',\n};\n\nexport async function getBranchStatusCheck(\n branchName: string,\n context: string,\n): Promise<BranchStatus | null> {\n try {\n const res = await getStatusCheck(branchName);\n for (const check of res) {\n if (check.context === context) {\n return githubToRenovateStatusMapping[check.state] || 'yellow';\n }\n }\n return null;\n } catch (err) /* v8 ignore next -- 404-to-REPOSITORY_CHANGED mapping for missing commits is not mocked in specs */ {\n if (err.statusCode === 404) {\n logger.debug('Commit not found when checking statuses');\n throw new Error(REPOSITORY_CHANGED);\n }\n throw err;\n }\n}\n\nexport async function setBranchStatus({\n branchName,\n context,\n description,\n state,\n url: targetUrl,\n}: BranchStatusConfig): Promise<void> {\n /* v8 ignore next -- specs do not run setBranchStatus in forking mode */\n if (config.parentRepo) {\n logger.debug('Cannot set branch status when in forking mode');\n return;\n }\n const existingStatus = await getBranchStatusCheck(branchName, context);\n if (existingStatus === state) {\n return;\n }\n logger.debug({ branch: branchName, context, state }, 'Setting branch status');\n let url: string | undefined;\n try {\n const branchCommit = git.getBranchCommit(branchName);\n url = `repos/${config.repository}/statuses/${branchCommit}`;\n const renovateToGitHubStateMapping = {\n green: 'success',\n yellow: 'pending',\n red: 'failure',\n };\n const options: any = {\n state: renovateToGitHubStateMapping[state],\n description,\n context,\n };\n // v8 ignore else -- TODO: add test #40625\n if (targetUrl) {\n options.target_url = targetUrl;\n }\n await githubApi.postJson(url, { body: options });\n\n // update status cache\n await getStatus(branchName, false);\n await getStatusCheck(branchName, false);\n } catch (err) /* v8 ignore next -- defensive: status POST failures abort with REPOSITORY_CHANGED, not simulated in specs */ {\n logger.debug({ err, url }, 'Caught error setting branch status - aborting');\n throw new Error(REPOSITORY_CHANGED);\n }\n}\n\n// Issue\n\nasync function getIssues(): Promise<Issue[]> {\n const result = await githubApi.queryRepoField<unknown>(\n getIssuesQuery,\n 'issues',\n {\n variables: {\n owner: config.repositoryOwner,\n name: config.repositoryName,\n ...(!config.ignorePrAuthor && { user: config.renovateUsername }),\n },\n readOnly: true,\n },\n );\n\n logger.debug(`Retrieved ${result.length} issues`);\n return Issue.array().parse(result);\n}\n\nexport async function getIssueList(): Promise<Issue[]> {\n /* v8 ignore next -- specs initialize repos with issues enabled */\n if (config.hasIssuesEnabled === false) {\n return [];\n }\n let issueList = GithubIssueCache.getIssues();\n // v8 ignore else -- TODO: add test #40625\n if (!issueList) {\n logger.debug('Retrieving issueList');\n issueList = await getIssues();\n GithubIssueCache.setIssues(issueList);\n }\n return issueList;\n}\n\nexport async function getIssue(number: number): Promise<Issue | null> {\n if (config.hasIssuesEnabled === false) {\n return null;\n }\n try {\n const repo = config.parentRepo ?? config.repository;\n const { body: issue } = await githubApi.getJson(\n `repos/${repo}/issues/${number}`,\n {\n cacheProvider: repoCacheProvider,\n },\n Issue,\n );\n GithubIssueCache.updateIssue(issue);\n return issue;\n } catch (err) {\n logger.debug({ err, number }, 'Error getting issue');\n if (err.response?.statusCode === 410) {\n logger.debug(`Issue #${number} has been deleted`);\n GithubIssueCache.deleteIssue(number);\n }\n return null;\n }\n}\n\nexport async function findIssue(title: string): Promise<Issue | null> {\n logger.debug(`findIssue(${title})`);\n const [issue] = (await getIssueList()).filter(\n (i) => i.state === 'open' && i.title === title,\n );\n if (!issue) {\n return null;\n }\n logger.debug(`Found issue ${issue.number}`);\n return getIssue(issue.number);\n}\n\nasync function closeIssue(issueNumber: number): Promise<void> {\n logger.debug(`closeIssue(${issueNumber})`);\n const repo = config.parentRepo ?? config.repository;\n try {\n const { body: closedIssue } = await githubApi.patchJson(\n `repos/${repo}/issues/${issueNumber}`,\n { body: { state: 'closed' } },\n Issue,\n );\n GithubIssueCache.updateIssue(closedIssue);\n } catch (err) {\n const statusCode = err.response?.statusCode;\n if (statusCode === 404 || statusCode === 410) {\n logger.debug(\n `Issue #${issueNumber} no longer exists on the platform, removing from cache`,\n );\n GithubIssueCache.deleteIssue(issueNumber);\n return;\n }\n throw err;\n }\n}\n\nexport async function ensureIssue({\n title,\n reuseTitle,\n body: rawBody,\n labels,\n once = false,\n shouldReOpen = true,\n}: EnsureIssueConfig): Promise<EnsureIssueResult | null> {\n logger.debug(`ensureIssue(${title})`);\n /* v8 ignore next -- specs initialize repos with issues enabled */\n if (config.hasIssuesEnabled === false) {\n logger.info(\n 'Cannot ensure issue because issues are disabled in this repository',\n );\n return null;\n }\n const body = sanitize(rawBody);\n try {\n const issueList = await getIssueList();\n let issues = issueList.filter((i) => i.title === title);\n if (!issues.length) {\n issues = issueList.filter((i) => i.title === reuseTitle);\n if (issues.length) {\n logger.debug(`Reusing issue title: \"${reuseTitle}\"`);\n }\n }\n if (issues.length) {\n let issue = issues.find((i) => i.state === 'open');\n if (!issue) {\n if (once) {\n logger.debug('Issue already closed - skipping recreation');\n return null;\n }\n if (shouldReOpen) {\n logger.debug('Reopening previously closed issue');\n }\n issue = issues.at(-1)!;\n }\n for (const i of issues) {\n if (i.state === 'open' && i.number !== issue.number) {\n logger.warn({ issueNo: i.number }, 'Closing duplicate issue');\n await closeIssue(i.number);\n }\n }\n\n const repo = config.parentRepo ?? config.repository;\n const { body: serverIssue } = await githubApi.getJson(\n `repos/${repo}/issues/${issue.number}`,\n { cacheProvider: repoCacheProvider },\n Issue,\n );\n GithubIssueCache.updateIssue(serverIssue);\n\n if (\n issue.title === title &&\n serverIssue.body === body &&\n issue.state === 'open'\n ) {\n logger.debug('Issue is open and up to date - nothing to do');\n return null;\n }\n if (shouldReOpen || issue.state === 'open') {\n logger.debug('Patching issue');\n const data: Record<string, unknown> = { body, state: 'open', title };\n if (labels) {\n data.labels = labels;\n }\n const repo = config.parentRepo ?? config.repository;\n const { body: updatedIssue } = await githubApi.patchJson(\n `repos/${repo}/issues/${issue.number}`,\n { body: data },\n Issue,\n );\n GithubIssueCache.updateIssue(updatedIssue);\n logger.debug('Issue updated');\n return 'updated';\n }\n }\n const { body: createdIssue } = await githubApi.postJson(\n `repos/${config.parentRepo ?? config.repository}/issues`,\n {\n body: {\n title,\n body,\n labels: coerceArray(labels),\n },\n },\n Issue,\n );\n logger.info('Issue created');\n // reset issueList so that it will be fetched again as-needed\n GithubIssueCache.updateIssue(createdIssue);\n return 'created';\n } catch (err) {\n if (err instanceof Error && err.message === PLATFORM_RATE_LIMIT_EXCEEDED) {\n throw err;\n }\n if (err.body?.message?.startsWith('Issues are disabled for this repo')) {\n logger.debug(`Issues are disabled, so could not create issue: ${title}`);\n } else {\n logger.warn({ err }, 'Could not ensure issue');\n }\n }\n return null;\n}\n\nexport async function ensureIssueClosing(title: string): Promise<void> {\n logger.trace(`ensureIssueClosing(${title})`);\n /* v8 ignore next -- specs initialize repos with issues enabled */\n if (config.hasIssuesEnabled === false) {\n return;\n }\n const issueList = await getIssueList();\n for (const issue of issueList) {\n if (issue.state === 'open' && issue.title === title) {\n await closeIssue(issue.number);\n logger.debug(`Issue closed, issueNo: ${issue.number}`);\n }\n }\n}\n\nasync function tryAddMilestone(\n issueNo: number,\n milestoneNo: number | undefined,\n): Promise<void> {\n if (!milestoneNo) {\n return;\n }\n\n logger.debug(\n {\n milestone: milestoneNo,\n pr: issueNo,\n },\n 'Adding milestone to PR',\n );\n try {\n const repo = config.parentRepo ?? config.repository;\n const { body: updatedIssue } = await githubApi.patchJson(\n `repos/${repo}/issues/${issueNo}`,\n { body: { milestone: milestoneNo } },\n Issue,\n );\n GithubIssueCache.updateIssue(updatedIssue);\n } catch (err) {\n /* v8 ignore next -- defensive: the raw-error fallback is for non-HTTP failures not seen in specs */\n const actualError = err.response?.body ?? err;\n logger.warn(\n {\n milestone: milestoneNo,\n pr: issueNo,\n err: actualError,\n },\n 'Unable to add milestone to PR',\n );\n }\n}\n\nexport async function addAssignees(\n issueNo: number,\n assignees: string[],\n): Promise<void> {\n logger.debug(`Adding assignees '${assignees.join(', ')}' to #${issueNo}`);\n const repository = config.parentRepo ?? config.repository;\n const url = `repos/${repository}/issues/${issueNo}/assignees`;\n let lastErr: Error | undefined;\n for (let attempt = 0; attempt < 3; attempt += 1) {\n try {\n const { body: updatedIssue } = await githubApi.postJson(\n url,\n { body: { assignees } },\n Issue,\n );\n GithubIssueCache.updateIssue(updatedIssue);\n return;\n } catch (err) {\n if (err.statusCode !== 404) {\n throw err;\n }\n lastErr = err;\n logger.debug(\n { attempt: attempt + 1 },\n `Retrying addAssignees for #${issueNo} after 404`,\n );\n await setTimeout(1000);\n }\n }\n throw lastErr!;\n}\n\nexport async function addReviewers(\n prNo: number,\n reviewers: string[],\n): Promise<void> {\n logger.debug(`Adding reviewers '${reviewers.join(', ')}' to #${prNo}`);\n\n const userReviewers = reviewers.filter((e) => !e.startsWith('team:'));\n const teamReviewers = reviewers\n .filter((e) => e.startsWith('team:'))\n .map((e) => e.replace(regEx(/^team:/), ''));\n try {\n await githubApi.postJson(\n `repos/${\n config.parentRepo ?? config.repository\n }/pulls/${prNo}/requested_reviewers`,\n {\n body: {\n reviewers: userReviewers,\n team_reviewers: teamReviewers,\n },\n },\n );\n } catch (err) /* v8 ignore next -- defensive: reviewer assignment failures are logged and swallowed, not simulated in specs */ {\n logger.warn({ err }, 'Failed to assign reviewer');\n }\n}\n\nexport async function addLabels(\n issueNo: number,\n labels: string[] | null | undefined,\n): Promise<void> {\n logger.debug(`Adding labels '${labels?.join(', ')}' to #${issueNo}`);\n try {\n const repository = config.parentRepo ?? config.repository;\n if (isArray(labels) && labels.length) {\n await githubApi.postJson(`repos/${repository}/issues/${issueNo}/labels`, {\n body: labels,\n });\n }\n } catch (err) /* v8 ignore next -- defensive: label-adding failures are logged and swallowed, not simulated in specs */ {\n logger.warn(\n { err, issueNo, labels },\n 'Error while adding labels. Skipping',\n );\n }\n}\n\nexport async function deleteLabel(\n issueNo: number,\n label: string,\n): Promise<void> {\n logger.debug(`Deleting label ${label} from #${issueNo}`);\n const repository = config.parentRepo ?? config.repository;\n try {\n await githubApi.deleteJson(\n `repos/${repository}/issues/${issueNo}/labels/${label}`,\n );\n } catch (err) /* v8 ignore next -- defensive: label deletion failures are logged and swallowed, not simulated in specs */ {\n logger.warn({ err, issueNo, label }, 'Failed to delete label');\n }\n}\n\nasync function addComment(issueNo: number, body: string): Promise<void> {\n // POST /repos/:owner/:repo/issues/:number/comments\n await githubApi.postJson(\n `repos/${\n config.parentRepo ?? config.repository\n }/issues/${issueNo}/comments`,\n {\n body: { body },\n },\n );\n}\n\nasync function editComment(commentId: number, body: string): Promise<void> {\n // PATCH /repos/:owner/:repo/issues/comments/:id\n await githubApi.patchJson(\n `repos/${\n config.parentRepo ?? config.repository\n }/issues/comments/${commentId}`,\n {\n body: { body },\n },\n );\n}\n\nasync function deleteComment(commentId: number): Promise<void> {\n // DELETE /repos/:owner/:repo/issues/comments/:id\n await githubApi.deleteJson(\n `repos/${\n config.parentRepo ?? config.repository\n }/issues/comments/${commentId}`,\n );\n}\n\nasync function getComments(issueNo: number): Promise<Comment[]> {\n // GET /repos/:owner/:repo/issues/:number/comments\n logger.debug(`Getting comments for #${issueNo}`);\n const repo = config.parentRepo ?? config.repository;\n const url = `repos/${repo}/issues/${issueNo}/comments?per_page=100`;\n try {\n const { body: comments } = await githubApi.getJsonUnchecked<Comment[]>(\n url,\n {\n paginate: true,\n cacheProvider: repoCacheProvider,\n },\n );\n logger.debug(`Found ${comments.length} comments`);\n return comments;\n } catch (err) /* v8 ignore next -- comment-fetch 404s are wrapped as ExternalHostError, not mocked in specs */ {\n if (err.statusCode === 404) {\n logger.debug('404 response when retrieving comments');\n throw new ExternalHostError(err, 'github');\n }\n throw err;\n }\n}\n\nexport async function ensureComment({\n number,\n topic,\n content,\n}: EnsureCommentConfig): Promise<boolean> {\n const sanitizedContent = sanitize(content);\n try {\n const comments = await getComments(number);\n let body: string;\n let commentId: number | null = null;\n let commentNeedsUpdating = false;\n if (topic) {\n logger.debug(`Ensuring comment \"${topic}\" in #${number}`);\n body = `### ${topic}\\n\\n${sanitizedContent}`;\n comments.forEach((comment) => {\n if (comment.body.startsWith(`### ${topic}\\n\\n`)) {\n commentId = comment.id;\n commentNeedsUpdating = comment.body !== body;\n }\n });\n } else {\n logger.debug(`Ensuring content-only comment in #${number}`);\n body = `${sanitizedContent}`;\n comments.forEach((comment) => {\n // v8 ignore else -- TODO: add test #40625\n if (comment.body === body) {\n commentId = comment.id;\n commentNeedsUpdating = false;\n }\n });\n }\n if (!commentId) {\n await addComment(number, body);\n logger.info(\n { repository: config.repository, issueNo: number, topic },\n 'Comment added',\n );\n } else if (commentNeedsUpdating) {\n await editComment(commentId, body);\n logger.debug(\n { repository: config.repository, issueNo: number },\n 'Comment updated',\n );\n } else {\n logger.debug('Comment is already up-to-date');\n }\n return true;\n } catch (err) /* v8 ignore next -- comment API failure handling (locked issues) is not mocked in specs */ {\n if (err instanceof ExternalHostError) {\n throw err;\n }\n if (err.body?.message?.includes('is locked')) {\n logger.debug('Issue is locked - cannot add comment');\n } else {\n logger.warn({ err }, 'Error ensuring comment');\n }\n return false;\n }\n}\n\nfunction byTopic(comment: Comment, topic: string): boolean {\n return comment.body.startsWith(`### ${topic}\\n\\n`);\n}\n\nfunction byContent(comment: Comment, content: string): boolean {\n return comment.body.trim() === content;\n}\n\nexport async function ensureCommentRemoval(\n deleteConfig: EnsureCommentRemovalConfig,\n): Promise<void> {\n const { number: issueNo } = deleteConfig;\n const key =\n deleteConfig.type === 'by-topic'\n ? deleteConfig.topic\n : deleteConfig.content;\n logger.trace(`Ensuring comment \"${key}\" in #${issueNo} is removed`);\n const comments = await getComments(issueNo);\n let commentId: number | null | undefined = null;\n\n // v8 ignore else -- TODO: add test #40625\n if (deleteConfig.type === 'by-topic') {\n const topic = deleteConfig.topic;\n commentId = comments.find((comment) => byTopic(comment, topic))?.id;\n } else if (deleteConfig.type === 'by-content') {\n const content = deleteConfig.content;\n commentId = comments.find((comment) => byContent(comment, content))?.id;\n }\n\n try {\n // v8 ignore else -- TODO: add test #40625\n if (commentId) {\n logger.debug(`Removing comment from issueNo: ${issueNo}`);\n await deleteComment(commentId);\n }\n } catch (err) /* v8 ignore next -- defensive: comment deletion failures are logged and swallowed, not simulated in specs */ {\n logger.warn({ err }, 'Error deleting comment');\n }\n}\n\n// Pull Request\n\nasync function tryPrAutomerge(\n prNumber: number,\n prNodeId: string,\n platformPrOptions: PlatformPrOptions | undefined,\n): Promise<void> {\n if (!platformPrOptions?.usePlatformAutomerge) {\n return;\n }\n\n // If GitHub Enterprise Server <3.3.0 it doesn't support automerge\n // TODO #22198\n if (\n isGithubEnterpriseServer(platformConfig.host) &&\n semver.satisfies(platformConfig.host.version ?? '', '<3.3.0')\n ) {\n logger.debug(\n { prNumber },\n 'GitHub-native automerge: not supported on this version of GHE. Use 3.3.0 or newer.',\n );\n return;\n }\n\n if (!config.autoMergeAllowed) {\n logger.debug(\n { prNumber },\n 'GitHub-native automerge: not enabled in repo settings',\n );\n return;\n }\n\n try {\n const mergeMethod =\n (\n mapMergeStartegy(platformPrOptions.automergeStrategy) ??\n config.mergeMethod\n )?.toUpperCase() || 'MERGE';\n\n let commitHeadline: string | undefined;\n let commitBody: string | undefined;\n // For SQUASH and MERGE methods, pass the commit message explicitly to avoid\n // GitHub using the PR description as the commit body when \"Use PR title and\n // body as commit message\" is enabled in repository settings.\n const automergeCommitMessage = platformPrOptions?.automergeCommitMessage;\n if (mergeMethod !== 'REBASE' && automergeCommitMessage) {\n const newlineIndex = automergeCommitMessage.indexOf('\\n');\n if (newlineIndex === -1) {\n commitHeadline = automergeCommitMessage;\n } else {\n commitHeadline = automergeCommitMessage.slice(0, newlineIndex);\n commitBody = automergeCommitMessage.slice(newlineIndex + 1).trim();\n }\n\n // Add PR number to the commit headline to match the default GitHub behavior\n commitHeadline = `${commitHeadline} (#${prNumber})`;\n }\n\n const variables = {\n pullRequestId: prNodeId,\n mergeMethod,\n commitHeadline,\n commitBody,\n };\n // set count to one bypass graphql check\n const queryOptions = { variables, count: 1 };\n\n const res = await githubApi.requestGraphql<GhAutomergeResponse>(\n enableAutoMergeMutation,\n queryOptions,\n );\n\n if (res?.errors) {\n logger.debug(\n { prNumber, errors: res.errors },\n 'GitHub-native automerge: fail',\n );\n return;\n }\n\n logger.debug(`GitHub-native automerge: success...PrNo: ${prNumber}`);\n } catch (err) {\n if (err instanceof Error && err.message === PLATFORM_RATE_LIMIT_EXCEEDED) {\n throw err;\n }\n logger.warn({ prNumber, err }, 'GitHub-native automerge: REST API error');\n }\n}\n\n// Creates PR and returns PR number\nexport async function createPr({\n sourceBranch,\n targetBranch,\n prTitle: title,\n prBody: rawBody,\n labels,\n draftPR = false,\n platformPrOptions,\n milestone,\n}: CreatePRConfig): Promise<GhPr | null> {\n const body = sanitize(rawBody);\n const base = targetBranch;\n // Include the repository owner to handle forkToken and regular mode\n // TODO: can `repository` be null? (#22198)\n\n const head = `${config.repository!.split('/')[0]}:${sourceBranch}`;\n const options: any = {\n body: {\n title,\n head,\n base,\n body,\n draft: draftPR,\n },\n };\n /* v8 ignore next -- fork mode is not exercised in createPr specs */\n if (config.forkToken) {\n options.token = config.forkToken;\n options.body.maintainer_can_modify =\n !config.forkOrg &&\n platformPrOptions?.forkModeDisallowMaintainerEdits !== true;\n }\n logger.debug({ title, head, base, draft: draftPR }, 'Creating PR');\n const ghPr = (\n await githubApi.postJson<GhRestPr>(\n `repos/${config.parentRepo ?? config.repository}/pulls`,\n options,\n )\n ).body;\n logger.debug(\n { branch: sourceBranch, pr: ghPr.number, draft: draftPR },\n 'PR created',\n );\n\n const result = coerceRestPr(ghPr);\n const { number, node_id } = result;\n\n await addLabels(number, labels);\n await tryAddMilestone(number, milestone);\n await tryPrAutomerge(number, node_id, platformPrOptions);\n\n cachePr(result);\n return result;\n}\n\nexport async function isBranchMergeQueueEnabled(\n baseBranch: string,\n): Promise<boolean> {\n const cachedResult = config.mergeQueueEnabled[baseBranch];\n if (cachedResult !== undefined) {\n return cachedResult;\n }\n\n // TODO #22198\n if (\n isGithubEnterpriseServer(platformConfig.host) &&\n semver.satisfies(platformConfig.host.version ?? '', '<3.12.0')\n ) {\n // Merge queues are only supported on GHES >=3.12.0\n config.mergeQueueEnabled[baseBranch] = false;\n return false;\n }\n\n // Assume enabled unless proven otherwise, so the merge queue check is not\n // skipped by mistake\n let result = true;\n try {\n const res = await githubApi.requestGraphql<{\n repository: { mergeQueue: { id: string } | null };\n }>(repoMergeQueueQuery, {\n variables: {\n owner: config.repositoryOwner,\n name: config.repositoryName,\n branch: baseBranch,\n },\n readOnly: true,\n count: 1, // bypass graphql check\n });\n if (res?.errors) {\n logger.debug(\n { baseBranch, errors: res.errors },\n 'Failed to fetch merge queue status - assuming merge queue is enabled',\n );\n } else {\n result = isNonEmptyObject(res?.data?.repository?.mergeQueue);\n }\n } catch (err) {\n if (err instanceof Error && err.message === PLATFORM_RATE_LIMIT_EXCEEDED) {\n throw err;\n }\n logger.debug(\n { baseBranch, err },\n 'Error fetching merge queue status - assuming merge queue is enabled',\n );\n }\n\n config.mergeQueueEnabled[baseBranch] = result;\n return result;\n}\n\nexport function isPrInMergeQueue(prNo: number): Promise<boolean> {\n return checkPrInMergeQueue(\n githubApi,\n config.repositoryOwner,\n config.repositoryName,\n prNo,\n );\n}\n\nexport async function assertPrNotInMergeQueue(\n branchName: string,\n baseBranch?: string,\n): Promise<void> {\n if (!(await isBranchMergeQueueEnabled(baseBranch ?? config.defaultBranch))) {\n return;\n }\n\n const pr = await findPr({ branchName, state: 'open' });\n if (!pr) {\n return;\n }\n\n if (await isPrInMergeQueue(pr.number)) {\n logger.debug(`PR #${pr.number} is in the merge queue - aborting push`);\n throw new Error(PR_ALREADY_IN_MERGE_QUEUE);\n }\n}\n\nexport async function updatePr({\n number: prNo,\n prTitle: title,\n prBody: rawBody,\n addLabels: labelsToAdd,\n removeLabels,\n state,\n targetBranch,\n}: UpdatePrConfig): Promise<void> {\n logger.debug(`updatePr(${prNo}, ${title}, body)`);\n const body = sanitize(rawBody);\n const patchBody: any = { title };\n // v8 ignore else -- TODO: add test #40625\n if (body) {\n patchBody.body = body;\n }\n if (targetBranch) {\n patchBody.base = targetBranch;\n }\n if (state) {\n patchBody.state = state;\n }\n const options: any = {\n body: patchBody,\n };\n /* v8 ignore next -- fork mode is not exercised in updatePr specs */\n if (config.forkToken) {\n options.token = config.forkToken;\n }\n\n // Update PR labels\n try {\n if (labelsToAdd) {\n await addLabels(prNo, labelsToAdd);\n }\n\n if (removeLabels) {\n for (const label of removeLabels) {\n await deleteLabel(prNo, label);\n }\n }\n\n const { body: ghPr } = await githubApi.patchJson<GhRestPr>(\n `repos/${config.parentRepo ?? config.repository}/pulls/${prNo}`,\n options,\n );\n const result = coerceRestPr(ghPr);\n cachePr(result);\n logger.debug(`PR updated...prNo: ${prNo}`);\n } catch (err) /* v8 ignore next -- non-host update failures are logged and swallowed, not mocked in specs */ {\n if (err instanceof ExternalHostError) {\n throw err;\n }\n logger.warn({ err }, 'Error updating PR');\n }\n}\n\nexport async function reattemptPlatformAutomerge({\n number,\n platformPrOptions,\n}: ReattemptPlatformAutomergeConfig): Promise<void> {\n try {\n const result = (await getPr(number))!;\n const { node_id } = result;\n\n await tryPrAutomerge(number, node_id, platformPrOptions);\n\n logger.debug(`PR platform automerge re-attempted...prNo: ${number}`);\n } catch (err) {\n if (err instanceof Error && err.message === PLATFORM_RATE_LIMIT_EXCEEDED) {\n throw err;\n }\n logger.warn({ err }, 'Error re-attempting PR platform automerge');\n }\n}\n\nasync function tryEnqueuePr(pr: GhPr): Promise<boolean> {\n const prNo = pr.number;\n try {\n const res = await githubApi.requestGraphql<GhEnqueuePullRequestResponse>(\n enqueuePullRequestMutation,\n {\n variables: { pullRequestId: pr.node_id },\n count: 1, // set count to one to bypass graphql check\n },\n );\n\n if (res?.errors) {\n // GitHub does not document the exact message, so match loosely.\n // \"enqueue\" contains \"queue\", so both wordings are covered.\n if (\n res.errors.some((error) => regEx(/already.*queue/i).test(error.message))\n ) {\n logger.debug(`PR #${prNo} is already in the merge queue`);\n return true;\n }\n logger.debug(\n { prNumber: prNo, errors: res.errors },\n 'Failed to add PR to the merge queue',\n );\n return false;\n }\n\n logger.debug(`PR #${prNo} added to the merge queue`);\n return true;\n } catch (err) {\n logger.warn({ prNumber: prNo, err }, 'Failed to add PR to the merge queue');\n return false;\n }\n}\n\nexport async function mergePr({\n branchName,\n id: prNo,\n strategy,\n}: MergePRConfig): Promise<boolean> {\n logger.debug(`mergePr(${prNo}, ${branchName})`);\n\n const pr = await getPr(prNo);\n if (await directMergePr(prNo, strategy)) {\n return true;\n }\n if (pr?.targetBranch && (await isBranchMergeQueueEnabled(pr.targetBranch))) {\n // The direct merge was refused - fall back to adding the PR to the merge\n // queue, so it must not be cached as merged nor may its branch be deleted\n return tryEnqueuePr(pr);\n }\n return false;\n}\n\nasync function directMergePr(\n prNo: number,\n strategy?: MergeStrategy,\n): Promise<boolean> {\n const url = `repos/${\n config.parentRepo ?? config.repository\n }/pulls/${prNo}/merge`;\n const options: GithubHttpOptions = {\n body: {},\n };\n /* v8 ignore next -- fork mode is not exercised in mergePr specs */\n if (config.forkToken) {\n options.token = config.forkToken;\n }\n let automerged = false;\n let automergeResult: HttpResponse<unknown>;\n const mergeStrategy = mapMergeStartegy(strategy) ?? config.mergeMethod;\n\n // v8 ignore else -- TODO: add test #40625\n if (mergeStrategy) {\n // This path is taken if we have auto-detected the allowed merge types from the repo or\n // automergeStrategy is configured by user\n options.body.merge_method = mergeStrategy;\n try {\n logger.debug({ options, url }, `mergePr`);\n automergeResult = await githubApi.putJson(url, options);\n automerged = true;\n } catch (err) /* v8 ignore next -- merge rejection handling (404/405 status-check bodies) is not fully mocked in specs */ {\n if (err.statusCode === 404 || err.statusCode === 405) {\n const body = err.response?.body;\n if (\n isNonEmptyString(body?.message) &&\n regEx(/^Required status check \".+\" is expected\\.$/).test(body.message)\n ) {\n logger.debug(\n { response: body },\n `GitHub blocking PR merge -- Missing required status check(s)`,\n );\n return false;\n }\n if (\n isNonEmptyString(body?.message) &&\n (body.message.includes('approving review') ||\n body.message.includes('code owner review') ||\n body.message.includes(\n 'New changes require approval from someone other than the last pusher',\n ))\n ) {\n logger.debug(\n { response: body },\n `GitHub blocking PR merge -- Needs approving review(s)`,\n );\n return false;\n }\n logger.debug(\n { response: body },\n 'GitHub blocking PR merge -- will keep trying',\n );\n } else {\n logger.warn(\n { mergeMethod: config.mergeMethod, err },\n 'Failed to merge PR',\n );\n return false;\n }\n }\n }\n if (!automerged) {\n // We need to guess the merge method and try squash -> merge -> rebase\n options.body.merge_method = 'squash';\n try {\n logger.debug({ options, url }, `mergePr`);\n automergeResult = await githubApi.putJson(url, options);\n } catch (err1) {\n logger.debug({ err: err1 }, `Failed to squash merge PR`);\n try {\n options.body.merge_method = 'merge';\n logger.debug({ options, url }, `mergePr`);\n automergeResult = await githubApi.putJson(url, options);\n } catch (err2) {\n logger.debug({ err: err2 }, `Failed to merge commit PR`);\n try {\n options.body.merge_method = 'rebase';\n logger.debug({ options, url }, `mergePr`);\n automergeResult = await githubApi.putJson(url, options);\n } catch (err3) {\n logger.debug({ err: err3 }, `Failed to rebase merge PR`);\n logger.info({ pr: prNo }, 'All merge attempts failed');\n return false;\n }\n }\n }\n }\n logger.debug(\n { automergeResult: automergeResult!.body, pr: prNo },\n 'PR merged',\n );\n const cachedPr = config.prList?.find(({ number }) => number === prNo);\n if (cachedPr) {\n cachePr({ ...cachedPr, state: 'merged' });\n }\n return true;\n}\n\nexport function massageMarkdown(input: string): string {\n if (platformConfig.host.type !== 'github') {\n return smartTruncate(input, maxBodyLength());\n }\n const massagedInput = massageMarkdownLinks(input)\n // to be safe, replace all github.com links with redirect.github.com\n .replace(\n regEx(/href=\"https?:\\/\\/github.com\\//g),\n 'href=\"https://redirect.github.com/',\n )\n .replace(\n regEx(/]\\(https:\\/\\/github\\.com\\//g),\n '](https://redirect.github.com/',\n )\n .replace(\n regEx(/]: https:\\/\\/github\\.com\\//g),\n ']: https://redirect.github.com/',\n )\n .replaceAll('> ℹ **Note**\\n> \\n', '> [!NOTE]\\n')\n .replaceAll('> ℹ️ **Note**\\n> \\n', '> [!NOTE]\\n')\n .replaceAll('> ⚠ **Warning**\\n> \\n', '> [!WARNING]\\n')\n .replaceAll('> ⚠️ **Warning**\\n> \\n', '> [!WARNING]\\n')\n .replaceAll('> ❗ **Caution**\\n> \\n', '> [!CAUTION]\\n')\n .replaceAll('> ❗ **Important**\\n> \\n', '> [!IMPORTANT]\\n');\n return smartTruncate(massagedInput, maxBodyLength());\n}\n\nexport function maxBodyLength(): number {\n return GitHubMaxPrBodyLen;\n}\n\nexport async function getVulnerabilityAlerts(): Promise<GithubVulnerabilityAlerts> {\n /* v8 ignore next -- specs initialize repos with vulnerability alerts enabled */\n if (config.hasVulnerabilityAlertsEnabled === false) {\n logger.debug('No vulnerability alerts enabled for repo');\n return [];\n }\n let vulnerabilityAlerts: GithubVulnerabilityAlerts | undefined;\n try {\n vulnerabilityAlerts = (\n await githubApi.getJson(\n `/repos/${config.repositoryOwner}/${config.repositoryName}/dependabot/alerts?state=open&direction=asc&per_page=100`,\n {\n paginate: true,\n headers: { accept: 'application/vnd.github+json' },\n cacheProvider: repoCacheProvider,\n },\n GithubVulnerabilityAlerts,\n )\n ).body;\n } catch (err) /* v8 ignore next -- alert-permission failures are logged and swallowed, not mocked in specs */ {\n logger.debug({ err }, 'Error retrieving vulnerability alerts');\n logger.warn(\n {\n url: `${GlobalConfig.get('productLinks').documentation}configuration-options/#vulnerabilityalerts`,\n },\n 'Cannot access vulnerability alerts. Please ensure permissions have been granted.',\n );\n }\n try {\n if (vulnerabilityAlerts?.length) {\n const shortAlerts: AggregatedVulnerabilities = {};\n logger.trace(\n { alerts: vulnerabilityAlerts },\n 'GitHub vulnerability details',\n );\n for (const alert of vulnerabilityAlerts) {\n // v8 ignore if -- TODO: can never happen but makes typescript happy #40625\n if (alert.security_vulnerability === null) {\n // As described in the documentation, there are cases in which\n // GitHub API responds with `\"securityVulnerability\": null`.\n // But it's may be faulty, so skip processing it here.\n continue;\n }\n const {\n package: { name, ecosystem },\n vulnerable_version_range: vulnerableVersionRange,\n first_patched_version: firstPatchedVersion,\n } = alert.security_vulnerability;\n const patch = firstPatchedVersion?.identifier;\n\n const normalizedName =\n ecosystem === 'pip' ? normalizePythonDepName(name) : name;\n alert.security_vulnerability.package.name = normalizedName;\n const key = `${ecosystem.toLowerCase()}/${normalizedName}`;\n const range = vulnerableVersionRange;\n const elem = shortAlerts[key] || {};\n elem[range] = coerceToNull(patch);\n shortAlerts[key] = elem;\n }\n logger.debug({ alerts: shortAlerts }, 'GitHub vulnerability details');\n } else {\n logger.debug('No vulnerability alerts found');\n }\n } catch (err) /* v8 ignore next -- defensive: processing already-parsed alerts does not throw in specs */ {\n logger.error({ err }, 'Error processing vulnerabity alerts');\n }\n return coerceArray(vulnerabilityAlerts);\n}\n\nasync function pushFiles(\n { branchName, message, trailers }: CommitFilesConfig,\n { parentCommitSha, commitSha }: CommitResult,\n): Promise<LongCommitSha | null> {\n try {\n // Hybrid git/REST commit strategy (see #13824, #14271):\n // 1. The git push below uploads blobs to GitHub via a custom ref\n // (refs/renovate/branches/*) which does NOT trigger CI/Actions.\n // 2. We then recreate the tree+commit via REST API so that:\n // - The commit is signed by GitHub (\"committed via GitHub\" badge)\n // - Force-push and file mode bits are supported (GraphQL can't do this)\n // - We can use base_tree to send only changed files, avoiding org\n // ruleset file-path restrictions on unchanged files (#42554)\n // Reusing the pushed commit/tree SHAs directly does not work because\n // the branch ref must point to an API-created commit for signing.\n await pushCommitToRenovateRef(commitSha, branchName);\n const baseTreeSha = await getCommitTreeSha(parentCommitSha);\n const treeItems = await diffCommitTree(parentCommitSha, commitSha);\n\n if (treeItems.length === 0) {\n logger.debug(\n { branchName },\n 'Platform-native commit: no changed files between commits',\n );\n return null;\n }\n\n const treeRes = await githubApi.postJson<{ sha: string }>(\n `/repos/${config.repository}/git/trees`,\n { body: { base_tree: baseTreeSha, tree: treeItems } },\n );\n const treeSha = treeRes.body.sha;\n\n const commitMessage = formatCommitMessage(message, trailers);\n\n // Now we recreate the commit using the tree we recreated the step before\n const commitRes = await githubApi.postJson<{ sha: string }>(\n `/repos/${config.repository}/git/commits`,\n {\n body: {\n message: commitMessage,\n tree: treeSha,\n parents: [parentCommitSha],\n },\n },\n );\n incLimitedValue('Commits');\n const remoteCommitSha = toLongCommitSha(commitRes.body.sha);\n await ensureBranchSha(branchName, remoteCommitSha);\n return remoteCommitSha;\n } catch (err) {\n logger.debug({ branchName, err }, 'Platform-native commit: unknown error');\n return null;\n }\n}\n\nexport async function commitFiles(\n config: CommitFilesConfig,\n): Promise<LongCommitSha | null> {\n const commitResult = await git.prepareCommit(config); // Commit locally and don't push\n const { branchName, files } = config;\n if (!commitResult) {\n logger.debug(\n { branchName, files: files.map(({ path }) => path) },\n `Platform-native commit: unable to prepare for commit`,\n );\n return null;\n }\n // Perform the commits using REST API\n const pushResult = await pushFiles(config, commitResult);\n if (!pushResult) {\n return null;\n }\n // Replace locally created branch with the remotely created one\n // and return the remote commit SHA\n await git.resetToCommit(commitResult.parentCommitSha);\n const commitSha = await git.fetchBranch(branchName);\n return commitSha;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["hostRules.find","Issue","git.initRepo","git.getBranchCommit","git.forcePushToRemote","checkPrInMergeQueue","git.prepareCommit","git.resetToCommit","git.fetchBranch"],"sources":["../../../../lib/modules/platform/github/index.ts"],"sourcesContent":["import { setTimeout } from 'node:timers/promises';\nimport { isArray, isNonEmptyObject, isNonEmptyString } from '@sindresorhus/is';\nimport semver from 'semver';\nimport { GlobalConfig } from '../../../config/global.ts';\nimport type { MergeStrategy } from '../../../config/types.ts';\nimport {\n PLATFORM_INTEGRATION_UNAUTHORIZED,\n PLATFORM_RATE_LIMIT_EXCEEDED,\n PLATFORM_UNKNOWN_ERROR,\n PR_ALREADY_IN_MERGE_QUEUE,\n REPOSITORY_ACCESS_FORBIDDEN,\n REPOSITORY_ARCHIVED,\n REPOSITORY_BLOCKED,\n REPOSITORY_CANNOT_FORK,\n REPOSITORY_CHANGED,\n REPOSITORY_DISABLED,\n REPOSITORY_EMPTY,\n REPOSITORY_FORKED,\n REPOSITORY_FORK_MISSING,\n REPOSITORY_FORK_MODE_FORKED,\n REPOSITORY_NOT_FOUND,\n REPOSITORY_RENAMED,\n} from '../../../constants/error-messages.ts';\nimport { instrument } from '../../../instrumentation/index.ts';\nimport { logger } from '../../../logger/index.ts';\nimport { ExternalHostError } from '../../../types/errors/external-host-error.ts';\nimport type { BranchStatus } from '../../../types/index.ts';\nimport { coerceArray } from '../../../util/array.ts';\nimport { isGithubFineGrainedPersonalAccessToken } from '../../../util/check-token.ts';\nimport { coerceToNull } from '../../../util/coerce.ts';\nimport { parseJson } from '../../../util/common.ts';\nimport { getEnv } from '../../../util/env.ts';\nimport { formatCommitMessage } from '../../../util/git/commit-trailers.ts';\nimport * as git from '../../../util/git/index.ts';\nimport {\n diffCommitTree,\n getCommitTreeSha,\n pushCommitToRenovateRef,\n} from '../../../util/git/index.ts';\nimport type {\n CommitFilesConfig,\n CommitResult,\n} from '../../../util/git/types.ts';\nimport * as hostRules from '../../../util/host-rules.ts';\nimport { memCacheProvider } from '../../../util/http/cache/memory-http-cache-provider.ts';\nimport { repoCacheProvider } from '../../../util/http/cache/repository-http-cache-provider.ts';\nimport type { GithubHttpOptions } from '../../../util/http/github.ts';\nimport * as githubHttp from '../../../util/http/github.ts';\nimport type { HttpResponse } from '../../../util/http/types.ts';\nimport { coerceObject } from '../../../util/object.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport { sanitize } from '../../../util/sanitize.ts';\nimport type { LongCommitSha } from '../../../util/schema-utils/git.ts';\nimport { toLongCommitSha } from '../../../util/schema-utils/git.ts';\nimport { looseEquals } from '../../../util/string.ts';\nimport { ensureTrailingSlash, isHttpUrl, parseUrl } from '../../../util/url.ts';\nimport { incLimitedValue } from '../../../workers/global/limits.ts';\nimport { normalizePythonDepName } from '../../datasource/pypi/common.ts';\nimport type {\n AutodiscoverConfig,\n BranchStatusConfig,\n CreatePRConfig,\n EnsureCommentConfig,\n EnsureCommentRemovalConfig,\n EnsureIssueConfig,\n EnsureIssueResult,\n FindPRConfig,\n MergePRConfig,\n PlatformParams,\n PlatformPrOptions,\n PlatformResult,\n Pr,\n ReattemptPlatformAutomergeConfig,\n RepoParams,\n RepoResult,\n UpdatePrConfig,\n} from '../types.ts';\nimport { repoFingerprint } from '../util.ts';\nimport { smartTruncate } from '../utils/pr-body.ts';\nimport { remoteBranchExists } from './branch.ts';\nimport { coerceRestPr, githubApi, mapMergeStartegy } from './common.ts';\nimport { getRepoFile } from './files.ts';\nimport {\n enableAutoMergeMutation,\n enqueuePullRequestMutation,\n getIssuesQuery,\n repoInfoQuery,\n repoMergeQueueQuery,\n} from './graphql.ts';\nimport { GithubIssueCache } from './issue.ts';\nimport { massageMarkdownLinks } from './massage-markdown-links.ts';\nimport {\n isPrInMergeQueue as checkPrInMergeQueue,\n getPrCache,\n updatePrCache,\n} from './pr.ts';\nimport {\n GithubBranchProtection,\n GithubBranchRulesets,\n GithubVulnerabilityAlerts,\n GithubIssue as Issue,\n} from './schema.ts';\nimport type {\n AggregatedVulnerabilities,\n CombinedBranchStatus,\n Comment,\n GhAutomergeResponse,\n GhBranchStatus,\n GhEnqueuePullRequestResponse,\n GhPr,\n GhRepo,\n GhRestPr,\n GhRestRepo,\n GithubHost,\n LocalRepoConfig,\n PlatformConfig,\n} from './types.ts';\nimport { getAppDetails, getUserDetails, getUserEmail } from './user.ts';\nimport {\n getRepoUrl,\n isGithubEnterpriseServer,\n warnIfDefaultGitAuthorEmail,\n} from './utils.ts';\n\nexport const id = 'github';\n\nlet config: LocalRepoConfig;\nlet platformConfig: PlatformConfig;\n\nconst defaultGithubApiUrl = 'https://api.github.com/';\n\n// GitHub's max is 60k but in the hosted app we've observed that content-length is ~1k longer\nconst GitHubMaxPrBodyLen = 58000;\n\nconst noteAlertRegex = regEx(/> ℹ️? \\*\\*Note\\*\\*\\n> ?\\n/g);\nconst warningAlertRegex = regEx(/> ⚠️? \\*\\*Warning\\*\\*\\n> ?\\n/g);\nconst cautionAlertRegex = regEx(/> 🛑 \\*\\*Caution\\*\\*\\n> ?\\n/g);\nconst importantAlertRegex = regEx(/> ❗ \\*\\*Important\\*\\*\\n> ?\\n/g);\n\nexport function resetConfigs(): void {\n config = {} as never;\n platformConfig = {\n host: {\n type: 'github',\n apiUrl: parseUrl(defaultGithubApiUrl)!,\n },\n };\n}\n\nresetConfigs();\n\nfunction escapeHash(input: string): string {\n return input?.replace(regEx(/#/g), '%23');\n}\n\nexport function isGHApp(): boolean {\n return !!platformConfig.isGHApp;\n}\n\nasync function detectGithubHost(\n apiUrl: URL,\n token: string,\n): Promise<GithubHost> {\n const { hostname } = apiUrl;\n\n if (hostname === 'api.github.com') {\n return { type: 'github', apiUrl };\n }\n\n if (hostname.endsWith('.ghe.com')) {\n logger.debug('Detected GitHub Enterprise Cloud');\n return { type: 'ghec', apiUrl };\n }\n\n const gheHeaderKey = 'x-github-enterprise-version';\n const gheQueryRes = await githubApi.headJson('/', { token });\n const gheHeaders = coerceObject(gheQueryRes?.headers);\n const gheVersionHeader = Object.entries(gheHeaders).find(\n ([k]) => k.toLowerCase() === gheHeaderKey,\n );\n\n const version = semver.valid(gheVersionHeader?.[1] as string) ?? null;\n logger.debug(`Detected GitHub Enterprise Server, version: ${version}`);\n return { type: 'ghes', apiUrl, version };\n}\n\nexport async function initPlatform({\n endpoint,\n token: originalToken,\n username,\n gitAuthor,\n}: PlatformParams): Promise<PlatformResult> {\n let token = originalToken;\n if (!token) {\n throw new Error('Init: You must configure a GitHub token');\n }\n token = token.replace(regEx(/^ghs_/), 'x-access-token:ghs_');\n platformConfig.isGHApp = token.startsWith('x-access-token:');\n\n let githubApiUrl = platformConfig.host.apiUrl;\n if (endpoint) {\n const parsedApiUrl = parseUrl(ensureTrailingSlash(endpoint));\n if (!parsedApiUrl || !isHttpUrl(parsedApiUrl)) {\n throw new Error(`Init: Invalid GitHub endpoint URL: ${endpoint}`);\n }\n githubApiUrl = parsedApiUrl;\n githubHttp.setBaseUrl(githubApiUrl.href);\n } else {\n logger.debug(`Using default github endpoint: ${githubApiUrl.href}`);\n }\n\n platformConfig.host = await detectGithubHost(githubApiUrl, token);\n /**\n * GHE requires version >=3.10 to support fine-grained access tokens\n * https://docs.github.com/en/enterprise-server@3.10/admin/release-notes#authentication\n */\n if (\n isGithubFineGrainedPersonalAccessToken(token) &&\n isGithubEnterpriseServer(platformConfig.host) &&\n (!platformConfig.host.version ||\n semver.lt(platformConfig.host.version, '3.10.0'))\n ) {\n throw new Error(\n 'Init: Fine-grained Personal Access Tokens do not support GitHub Enterprise Server API version <3.10 and cannot be used with Renovate.',\n );\n }\n\n let renovateUsername: string;\n if (username) {\n renovateUsername = username;\n } else if (platformConfig.isGHApp) {\n platformConfig.userDetails ??= await getAppDetails(token);\n renovateUsername = platformConfig.userDetails.username;\n } else {\n platformConfig.userDetails ??= await getUserDetails(\n platformConfig.host.apiUrl.href,\n token,\n );\n renovateUsername = platformConfig.userDetails.username;\n }\n\n let ghHostname: string;\n if (platformConfig.host.type === 'ghec') {\n ghHostname = 'ghe.com';\n } else if (platformConfig.host.type === 'ghes') {\n ghHostname = platformConfig.host.apiUrl.hostname;\n } else {\n ghHostname = 'github.com';\n }\n\n let discoveredGitAuthor: string | undefined;\n if (!gitAuthor) {\n if (platformConfig.isGHApp) {\n platformConfig.userDetails ??= await getAppDetails(token);\n // v8 ignore next -- TODO: coverage error #40625\n discoveredGitAuthor = `${platformConfig.userDetails.name} <${platformConfig.userDetails.id}+${platformConfig.userDetails.username}@users.noreply.${ghHostname}>`;\n } else {\n platformConfig.userDetails ??= await getUserDetails(\n platformConfig.host.apiUrl.href,\n token,\n );\n // v8 ignore next -- TODO: coverage error #40625\n platformConfig.userEmail =\n platformConfig.userDetails.email ??\n (await getUserEmail(platformConfig.host.apiUrl.href, token));\n if (platformConfig.userEmail) {\n discoveredGitAuthor = `${platformConfig.userDetails.name} <${platformConfig.userEmail}>`;\n }\n }\n }\n\n git.setPlatformIgnoredAuthors([`noreply@${ghHostname}`]);\n\n logger.debug({ platformConfig, renovateUsername }, 'Platform config');\n const platformResult: PlatformResult = {\n endpoint: platformConfig.host.apiUrl.href,\n gitAuthor: gitAuthor ?? discoveredGitAuthor,\n renovateUsername,\n token,\n };\n\n warnIfDefaultGitAuthorEmail(\n platformResult.gitAuthor,\n platformConfig.host.type !== 'github',\n );\n\n if (\n getEnv().RENOVATE_X_GITHUB_HOST_RULES &&\n platformResult.endpoint === 'https://api.github.com/'\n ) {\n logger.debug('Adding GitHub token as GHCR password');\n platformResult.hostRules = [\n {\n matchHost: 'ghcr.io',\n hostType: 'docker',\n username: 'USERNAME',\n password: token.replace(regEx(/^x-access-token:/), ''),\n },\n ];\n logger.debug('Adding GitHub token as npm.pkg.github.com Basic token');\n platformResult.hostRules.push({\n matchHost: 'npm.pkg.github.com',\n hostType: 'npm',\n token: token.replace(regEx(/^x-access-token:/), ''),\n });\n const usernamePasswordHostTypes = ['rubygems', 'maven', 'nuget'];\n for (const hostType of usernamePasswordHostTypes) {\n logger.debug(\n `Adding GitHub token as ${hostType}.pkg.github.com password`,\n );\n platformResult.hostRules.push({\n hostType,\n matchHost: `${hostType}.pkg.github.com`,\n username: renovateUsername,\n password: token.replace(regEx(/^x-access-token:/), ''),\n });\n }\n }\n return platformResult;\n}\n\nasync function fetchRepositories(): Promise<GhRestRepo[]> {\n try {\n if (isGHApp()) {\n const res = await githubApi.getJsonUnchecked<{\n repositories: GhRestRepo[];\n }>(`installation/repositories?per_page=100`, {\n paginationField: 'repositories',\n paginate: 'all',\n });\n return res.body.repositories;\n }\n const res = await githubApi.getJsonUnchecked<GhRestRepo[]>(\n `user/repos?per_page=100`,\n { paginate: 'all' },\n );\n return res.body;\n } catch (err) /* v8 ignore next -- defensive: repo listing failures are logged and rethrown, not simulated in specs */ {\n logger.error({ err }, `GitHub getRepos error`);\n throw err;\n }\n}\n\n// Get all repositories that the user has access to\nexport async function getRepos(config?: AutodiscoverConfig): Promise<string[]> {\n logger.debug('Autodiscovering GitHub repositories');\n const nonEmptyRepositories = (await fetchRepositories()).filter(\n isNonEmptyObject,\n );\n const nonArchivedRepositories = nonEmptyRepositories.filter(\n (repo) => !repo.archived,\n );\n if (nonArchivedRepositories.length < nonEmptyRepositories.length) {\n logger.debug(\n `Filtered out ${\n nonEmptyRepositories.length - nonArchivedRepositories.length\n } archived repositories`,\n );\n }\n if (!config?.topics) {\n return nonArchivedRepositories.map((repo) => repo.full_name);\n }\n\n logger.debug({ topics: config.topics }, 'Filtering by topics');\n const topicRepositories = nonArchivedRepositories.filter((repo) =>\n repo.topics?.some((topic) => config?.topics?.includes(topic)),\n );\n\n // v8 ignore else -- TODO: add test #40625\n if (topicRepositories.length < nonArchivedRepositories.length) {\n logger.debug(\n `Filtered out ${\n nonArchivedRepositories.length - topicRepositories.length\n } repositories not matching topic filters`,\n );\n }\n return topicRepositories.map((repo) => repo.full_name);\n}\n\nasync function getBranchProtection(\n branchName: string,\n): Promise<GithubBranchProtection> {\n if (config.parentRepo) {\n return {};\n }\n\n const res = await githubApi.getJson(\n `repos/${config.repository}/branches/${escapeHash(branchName)}/protection`,\n { cacheProvider: repoCacheProvider },\n GithubBranchProtection,\n );\n return res.body;\n}\n\nasync function getBranchRulesets(\n branchName: string,\n): Promise<GithubBranchRulesets> {\n if (config.parentRepo) {\n return [];\n }\n\n try {\n const res = await githubApi.getJson(\n `repos/${config.repository}/rules/branches/${escapeHash(branchName)}`,\n { cacheProvider: repoCacheProvider },\n GithubBranchRulesets,\n );\n return res.body;\n } catch (err) {\n if (err.statusCode === 404) {\n logger.debug(`No branch rulesets found for ${branchName}`);\n return [];\n }\n throw err;\n }\n}\n\nexport async function getRawFile(\n fileName: string,\n repoName?: string,\n branchOrTag?: string,\n): Promise<string | null> {\n const repo = repoName ?? config.repository;\n\n // only use cache for the same org\n const httpOptions: GithubHttpOptions = {};\n const isSameOrg = repo?.split('/')?.[0] === config.repositoryOwner;\n // v8 ignore else -- TODO: add test #40625\n if (isSameOrg) {\n httpOptions.cacheProvider = repoCacheProvider;\n }\n\n return await getRepoFile(\n githubApi,\n // TODO #22198\n repo!,\n fileName,\n branchOrTag,\n httpOptions,\n );\n}\n\nexport async function getJsonFile(\n fileName: string,\n repoName?: string,\n branchOrTag?: string,\n): Promise<any> {\n const raw = await getRawFile(fileName, repoName, branchOrTag);\n return parseJson(raw, fileName);\n}\n\nexport async function listForks(\n token: string,\n repository: string,\n): Promise<GhRestRepo[]> {\n try {\n // Get list of existing repos\n const url = `repos/${repository}/forks?per_page=100`;\n const repos = (\n await githubApi.getJsonUnchecked<GhRestRepo[]>(url, {\n token,\n paginate: true,\n pageLimit: 100,\n })\n ).body;\n logger.debug(`Found ${repos.length} forked repo(s)`);\n return repos;\n } catch (err) {\n if (err.statusCode === 404) {\n logger.debug('Cannot list repo forks - it is likely private');\n } else {\n logger.debug({ err }, 'Unknown error listing repository forks');\n }\n throw new Error(REPOSITORY_CANNOT_FORK);\n }\n}\n\nexport async function findFork(\n token: string,\n repository: string,\n forkOrg?: string,\n): Promise<GhRestRepo | null> {\n const forks = await listForks(token, repository);\n if (forkOrg) {\n logger.debug(`Searching for forked repo in forkOrg (${forkOrg})`);\n const forkedRepo = forks.find((repo) => repo.owner.login === forkOrg);\n if (forkedRepo) {\n logger.debug(`Found repo in forkOrg: ${forkedRepo.full_name}`);\n return forkedRepo;\n }\n logger.debug(`No repo found in forkOrg`);\n }\n logger.debug(`Searching for forked repo in user account`);\n try {\n const { username } = await getUserDetails(\n platformConfig.host.apiUrl.href,\n token,\n );\n const forkedRepo = forks.find((repo) => repo.owner.login === username);\n if (forkedRepo) {\n logger.debug(`Found repo in user account: ${forkedRepo.full_name}`);\n return forkedRepo;\n }\n } catch {\n throw new Error(REPOSITORY_CANNOT_FORK);\n }\n logger.debug(`No repo found in user account`);\n return null;\n}\n\nexport async function createFork(\n token: string,\n repository: string,\n forkOrg?: string,\n): Promise<GhRestRepo> {\n let forkedRepo: GhRestRepo | undefined;\n try {\n forkedRepo = (\n await githubApi.postJson<GhRestRepo>(`repos/${repository}/forks`, {\n token,\n body: {\n organization: forkOrg ?? undefined,\n name: config.parentRepo!.replace('/', '-_-'),\n default_branch_only: true, // no baseBranchPatterns support yet\n },\n })\n ).body;\n } catch (err) {\n logger.debug({ err }, 'Error creating fork');\n }\n if (!forkedRepo) {\n throw new Error(REPOSITORY_CANNOT_FORK);\n }\n logger.info({ forkedRepo: forkedRepo.full_name }, 'Created forked repo');\n logger.debug(`Sleeping 30s after creating fork`);\n await setTimeout(30000);\n return forkedRepo;\n}\n\n// Initialize GitHub by getting base branch and SHA\nexport async function initRepo({\n repository,\n forkCreation,\n forkOrg,\n forkToken,\n gitUrl,\n renovateUsername,\n cloneSubmodules,\n cloneSubmodulesFilter,\n}: RepoParams): Promise<RepoResult> {\n logger.debug(`initRepo(\"${repository}\")`);\n // config is used by the platform api itself, not necessary for the app layer to know\n config = {\n repository,\n cloneSubmodules,\n cloneSubmodulesFilter,\n ignorePrAuthor: GlobalConfig.get('ignorePrAuthor'),\n mergeQueueEnabled: {},\n } as any;\n const opts = hostRules.find({\n hostType: 'github',\n url: platformConfig.host.apiUrl.href,\n readOnly: true,\n });\n config.renovateUsername = renovateUsername;\n [config.repositoryOwner, config.repositoryName] = repository.split('/');\n let repo: GhRepo | undefined;\n let forkSshUrl: string | null = null;\n try {\n let infoQuery = repoInfoQuery;\n\n // GitHub Enterprise Server <3.3.0 doesn't support autoMergeAllowed and hasIssuesEnabled objects\n // TODO #22198\n if (\n isGithubEnterpriseServer(platformConfig.host) &&\n semver.satisfies(platformConfig.host.version ?? '', '<3.3.0')\n ) {\n infoQuery = infoQuery.replace(regEx(/\\n\\s*autoMergeAllowed\\s*\\n/), '\\n');\n infoQuery = infoQuery.replace(regEx(/\\n\\s*hasIssuesEnabled\\s*\\n/), '\\n');\n }\n\n // GitHub Enterprise Server <3.9.0 doesn't support hasVulnerabilityAlertsEnabled objects\n if (\n isGithubEnterpriseServer(platformConfig.host) &&\n semver.satisfies(platformConfig.host.version ?? '', '<3.9.0')\n ) {\n infoQuery = infoQuery.replace(\n regEx(/\\n\\s*hasVulnerabilityAlertsEnabled\\s*\\n/),\n '\\n',\n );\n }\n\n // GitHub Enterprise Server <3.12.0 doesn't support merge queues\n if (\n isGithubEnterpriseServer(platformConfig.host) &&\n semver.satisfies(platformConfig.host.version ?? '', '<3.12.0')\n ) {\n infoQuery = infoQuery.replace(\n regEx(/\\n\\s*mergeQueue\\s*\\{\\s*id\\s*\\}\\s*\\n/),\n '\\n',\n );\n }\n\n const res = await githubApi.requestGraphql<{\n repository: GhRepo;\n }>(infoQuery, {\n variables: {\n owner: config.repositoryOwner,\n name: config.repositoryName,\n ...(!config.ignorePrAuthor && { user: renovateUsername }),\n },\n readOnly: true,\n count: 1, // bypass graphql check\n });\n\n if (res?.errors) {\n logger.debug({ res }, 'Unexpected GraphQL errors');\n throw new Error(PLATFORM_UNKNOWN_ERROR);\n }\n\n repo = res?.data?.repository;\n /* v8 ignore next -- defensive: GraphQL errors are handled above, a null repository is not mocked in specs */\n if (!repo) {\n logger.debug({ res }, 'No repository returned');\n throw new Error(REPOSITORY_NOT_FOUND);\n }\n /* v8 ignore next -- empty-repo detection via missing defaultBranchRef is not mocked in specs */\n if (!repo.defaultBranchRef?.name) {\n logger.debug(\n { res },\n 'No default branch returned - treating repo as empty',\n );\n throw new Error(REPOSITORY_EMPTY);\n }\n if (\n repo.nameWithOwner &&\n repo.nameWithOwner.toUpperCase() !== repository.toUpperCase()\n ) {\n logger.debug(\n { desiredRepo: repository, foundRepo: repo.nameWithOwner },\n 'Repository has been renamed',\n );\n throw new Error(REPOSITORY_RENAMED);\n }\n if (repo.isArchived) {\n logger.debug(\n 'Repository is archived - throwing error to abort renovation',\n );\n throw new Error(REPOSITORY_ARCHIVED);\n }\n // Use default branch as PR target unless later overridden.\n config.defaultBranch = repo.defaultBranchRef.name;\n // Base branch may be configured but defaultBranch is always fixed\n logger.debug(`${repository} default branch = ${config.defaultBranch}`);\n // GitHub allows administrators to block certain types of merge, so we need to check it\n if (repo.squashMergeAllowed) {\n config.mergeMethod = 'squash';\n } else if (repo.mergeCommitAllowed) {\n config.mergeMethod = 'merge';\n } else if (repo.rebaseMergeAllowed) {\n config.mergeMethod = 'rebase';\n } else {\n // This happens if we don't have Administrator read access, it is not a critical error\n logger.debug('Could not find allowed merge methods for repo');\n }\n config.autoMergeAllowed = repo.autoMergeAllowed;\n config.hasIssuesEnabled = repo.hasIssuesEnabled;\n config.hasVulnerabilityAlertsEnabled = repo.hasVulnerabilityAlertsEnabled;\n config.mergeQueueEnabled[config.defaultBranch] = isNonEmptyObject(\n repo.mergeQueue,\n );\n\n const recentIssues = Issue.array()\n .catch([])\n .parse(res?.data?.repository?.issues?.nodes);\n GithubIssueCache.addIssuesToReconcile(recentIssues);\n } catch (err) /* v8 ignore next -- initRepo error mapping needs failure shapes not mocked in specs */ {\n logger.debug({ err }, 'Caught initRepo error');\n if (\n err.message === REPOSITORY_ARCHIVED ||\n err.message === REPOSITORY_RENAMED ||\n err.message === REPOSITORY_NOT_FOUND\n ) {\n throw err;\n }\n if (err.statusCode === 403) {\n throw new Error(REPOSITORY_ACCESS_FORBIDDEN);\n }\n if (err.statusCode === 404) {\n throw new Error(REPOSITORY_NOT_FOUND);\n }\n if (err.message.startsWith('Repository access blocked')) {\n throw new Error(REPOSITORY_BLOCKED);\n }\n if (err.message === REPOSITORY_FORK_MODE_FORKED) {\n throw err;\n }\n if (err.message === REPOSITORY_FORKED) {\n throw err;\n }\n if (err.message === REPOSITORY_DISABLED) {\n throw err;\n }\n if (err.message === 'Response code 451 (Unavailable for Legal Reasons)') {\n throw new Error(REPOSITORY_ACCESS_FORBIDDEN);\n }\n logger.debug({ err }, 'Unknown GitHub initRepo error');\n throw err;\n }\n // This shouldn't be necessary, but occasional strange errors happened until it was added\n config.prList = null;\n\n if (forkToken) {\n logger.debug('Renovate is in fork mode');\n if (repo.isFork) {\n logger.debug(\n `Forked repos cannot be processed when running with a forkToken, so this repo will be skipped`,\n );\n logger.debug(\n `Parent repo for this forked repo is ${repo.parent?.nameWithOwner}`,\n );\n throw new Error(REPOSITORY_FORKED);\n }\n config.forkOrg = forkOrg;\n config.forkToken = forkToken;\n // save parent name then delete\n config.parentRepo = config.repository;\n config.repository = null;\n let forkedRepo = await findFork(forkToken, repository, forkOrg);\n if (forkedRepo) {\n config.repository = forkedRepo.full_name;\n forkSshUrl = forkedRepo.ssh_url;\n const forkDefaultBranch = forkedRepo.default_branch;\n if (forkDefaultBranch !== config.defaultBranch) {\n const body = {\n ref: `refs/heads/${config.defaultBranch}`,\n sha: repo.defaultBranchRef.target.oid,\n };\n logger.debug(\n {\n defaultBranch: config.defaultBranch,\n forkDefaultBranch,\n body,\n },\n 'Fork has different default branch to parent, attempting to create branch',\n );\n try {\n await githubApi.postJson(`repos/${config.repository}/git/refs`, {\n body,\n token: forkToken,\n });\n logger.debug('Created new default branch in fork');\n } catch (err) /* v8 ignore next -- fork default-branch creation failures are not mocked in specs */ {\n if (err.response?.body?.message === 'Reference already exists') {\n logger.debug(\n `Branch ${config.defaultBranch} already exists in the fork`,\n );\n } else {\n logger.warn(\n { err, body: err.response?.body },\n 'Could not create parent defaultBranch in fork',\n );\n }\n }\n logger.debug(\n `Setting ${config.defaultBranch} as default branch for ${config.repository}`,\n );\n try {\n await githubApi.patchJson(`repos/${config.repository}`, {\n body: {\n name: config.repository.split('/')[1],\n default_branch: config.defaultBranch,\n },\n token: forkToken,\n });\n logger.debug('Successfully changed default branch for fork');\n } catch (err) /* v8 ignore next -- defensive: fork default-branch update failures are logged and swallowed, not simulated in specs */ {\n logger.warn({ err }, 'Could not set default branch');\n }\n }\n } else if (forkCreation) {\n logger.debug('Forked repo is not found - attempting to create it');\n forkedRepo = await createFork(forkToken, repository, forkOrg);\n config.repository = forkedRepo.full_name;\n forkSshUrl = forkedRepo.ssh_url;\n } else {\n logger.debug('Forked repo is not found and forkCreation is disabled');\n throw new Error(REPOSITORY_FORK_MISSING);\n }\n }\n\n let authToken: string | null;\n if (forkToken) {\n logger.debug('Using forkToken for git init');\n authToken = coerceToNull(config.forkToken);\n } /* v8 ignore next -- token-type detection depends on opts.token shapes not varied in specs */ else {\n const tokenType = opts.token?.startsWith('x-access-token:')\n ? 'app'\n : 'personal access';\n logger.debug(`Using ${tokenType} token for git init`);\n authToken = opts.token ?? null;\n }\n const workingSshUrl = forkToken ? forkSshUrl : repo.sshUrl;\n const url = getRepoUrl(\n config.repository!,\n gitUrl,\n workingSshUrl,\n platformConfig.host.apiUrl,\n authToken,\n );\n let upstreamUrl: string | undefined;\n if (forkCreation && config.parentRepo) {\n upstreamUrl = getRepoUrl(\n config.parentRepo,\n gitUrl,\n repo.sshUrl,\n platformConfig.host.apiUrl,\n authToken,\n );\n }\n await git.initRepo({\n ...config,\n url,\n upstreamUrl,\n });\n const repoConfig: RepoResult = {\n defaultBranch: config.defaultBranch,\n isFork: repo.isFork === true,\n repoFingerprint: repoFingerprint(repo.id, platformConfig.host.apiUrl.href),\n };\n return repoConfig;\n}\n\nasync function checkRulesetsForForceRebase(\n branchName: string,\n): Promise<boolean> {\n try {\n const rulesets = await getBranchRulesets(branchName);\n logger.trace(\n `Ruleset: Found ${rulesets.length} rulesets for branch ${branchName}`,\n );\n\n return rulesets.some((rule) => {\n if (\n rule.type === 'required_status_checks' &&\n rule.parameters?.strict_required_status_checks_policy === true\n ) {\n logger.debug(\n `Ruleset: strict required status checks found for ${branchName}`,\n );\n return true;\n }\n\n return false;\n });\n } catch (err) {\n handleBranchProtectionError('rulesets', err, branchName);\n return false;\n }\n}\n\nasync function checkBranchProtectionForForceRebase(\n branchName: string,\n): Promise<boolean> {\n try {\n const branchProtection = await getBranchProtection(branchName);\n logger.trace(`Found branch protection for branch ${branchName}`);\n\n const strictStatusChecks = branchProtection?.required_status_checks?.strict;\n if (strictStatusChecks) {\n logger.debug(\n `Branch protection: PRs must be up-to-date before merging for ${branchName}`,\n );\n return true;\n }\n return false;\n } catch (err) {\n handleBranchProtectionError('branch-protection', err, branchName);\n return false;\n }\n}\n\nexport async function getBranchForceRebase(\n branchName: string,\n): Promise<boolean> {\n config.branchForceRebase ??= {};\n\n const cachedResult = config.branchForceRebase[branchName];\n if (cachedResult !== undefined) {\n return cachedResult;\n }\n\n // Initialize to false before checking branch protection\n config.branchForceRebase[branchName] = false;\n\n // Check rulesets first (newer API)\n const hasRulesetForceRebase = await checkRulesetsForForceRebase(branchName);\n if (hasRulesetForceRebase) {\n config.branchForceRebase[branchName] = true;\n return true;\n }\n\n // Fall back to legacy branch protection\n const hasBranchProtectionForceRebase =\n await checkBranchProtectionForForceRebase(branchName);\n if (hasBranchProtectionForceRebase) {\n config.branchForceRebase[branchName] = true;\n }\n\n return config.branchForceRebase[branchName];\n}\n\nfunction handleBranchProtectionError(\n protection: 'branch-protection' | 'rulesets',\n err: any,\n branchName: string,\n): void {\n if (err.statusCode === 404) {\n logger.debug(`No ${protection} found for ${branchName}`);\n return;\n }\n\n const isUnauthorized =\n err.message === PLATFORM_INTEGRATION_UNAUTHORIZED || err.statusCode === 403;\n\n if (isUnauthorized) {\n logger.once.debug(\n `Branch protection: Do not have permissions to detect ${protection} for ${branchName}`,\n );\n return;\n }\n\n throw err;\n}\n\nfunction cachePr(pr?: GhPr | null): void {\n config.prList ??= [];\n // v8 ignore else -- TODO: add test #40625\n if (pr) {\n updatePrCache(pr);\n for (let idx = 0; idx < config.prList.length; idx += 1) {\n const cachedPr = config.prList[idx];\n if (cachedPr.number === pr.number) {\n config.prList[idx] = pr;\n return;\n }\n }\n config.prList.push(pr);\n }\n}\n\n// Fetch fresh Pull Request and cache it when possible\nasync function fetchPr(prNo: number): Promise<GhPr | null> {\n try {\n const { body: ghRestPr } = await githubApi.getJsonUnchecked<GhRestPr>(\n `repos/${config.parentRepo ?? config.repository}/pulls/${prNo}`,\n );\n const result = coerceRestPr(ghRestPr);\n cachePr(result);\n return result;\n } catch (err) {\n logger.warn({ err, prNo }, `GitHub fetchPr error`);\n return null;\n }\n}\n\n// Gets details for a PR\nexport async function getPr(prNo: number): Promise<GhPr | null> {\n if (!prNo) {\n return null;\n }\n const prList = await getPrList();\n let pr = prList.find(({ number }) => number === prNo) ?? null;\n if (pr) {\n logger.debug('Returning PR from cache');\n }\n pr ??= await fetchPr(prNo);\n return pr;\n}\n\nfunction matchesState(state: string, desiredState: string): boolean {\n if (desiredState === 'all') {\n return true;\n }\n if (desiredState.startsWith('!')) {\n return state !== desiredState.substring(1);\n }\n return state === desiredState;\n}\n\nexport async function getPrList(): Promise<GhPr[]> {\n if (!config.prList) {\n const repo = config.parentRepo ?? config.repository;\n\n let username = config.renovateUsername;\n if (config.forkToken || config.ignorePrAuthor) {\n username = undefined;\n }\n\n // TODO: check null `repo` (#22198)\n const prCache = await instrument('getPrCache', () =>\n getPrCache(githubApi, repo!, username),\n );\n config.prList = Object.values(prCache).sort(\n ({ number: a }, { number: b }) => b - a,\n );\n }\n\n return config.prList;\n}\n\nexport async function findPr({\n branchName,\n prTitle,\n state = 'all',\n includeOtherAuthors,\n}: FindPRConfig): Promise<GhPr | null> {\n logger.debug(`findPr(${branchName}, ${prTitle}, ${state})`);\n\n if (includeOtherAuthors) {\n const repo = config.parentRepo ?? config.repository;\n const org = repo?.split('/')[0];\n // PR might have been created by anyone, so don't use the cached Renovate PR list\n const { body: prList } = await githubApi.getJsonUnchecked<GhRestPr[]>(\n `repos/${repo}/pulls?head=${org}:${branchName}&state=open`,\n { cacheProvider: repoCacheProvider },\n );\n\n if (!prList.length) {\n logger.debug(`No PR found for branch ${branchName}`);\n return null;\n }\n\n return coerceRestPr(prList[0]);\n }\n\n const prList = await getPrList();\n const pr = prList.find((p) => {\n if (p.sourceBranch !== branchName) {\n return false;\n }\n\n if (prTitle && prTitle.toUpperCase() !== p.title.toUpperCase()) {\n return false;\n }\n\n if (!matchesState(p.state, state)) {\n return false;\n }\n\n if (!config.forkToken && !looseEquals(config.repository, p.sourceRepo)) {\n return false;\n }\n\n return true;\n });\n if (pr) {\n logger.debug(`Found PR #${pr.number}`);\n }\n return pr ?? null;\n}\n\nasync function ensureBranchSha(\n branchName: string,\n sha: LongCommitSha,\n): Promise<void> {\n const repository = config.repository!;\n try {\n const commitUrl = `/repos/${repository}/git/commits/${sha}`;\n await githubApi.head(commitUrl, { memCache: false });\n } catch (err) {\n logger.error({ err, sha, branchName }, 'Commit not found');\n throw err;\n }\n\n const refUrl = `/repos/${config.repository}/git/refs/heads/${branchName}`;\n const branchExists = await remoteBranchExists(repository, branchName);\n\n if (branchExists) {\n try {\n await githubApi.patchJson(refUrl, { body: { sha, force: true } });\n return;\n } catch (err) {\n if (err.err?.response?.statusCode === 422) {\n logger.debug(\n { err },\n 'Branch update failed due to reference not existing - will try to create',\n );\n } else {\n logger.warn({ refUrl, err }, 'Error updating branch');\n throw err;\n }\n }\n }\n\n await githubApi.postJson(`/repos/${repository}/git/refs`, {\n body: { sha, ref: `refs/heads/${branchName}` },\n });\n}\n\n// Returns the Pull Request for a branch. Null if not exists.\nexport async function getBranchPr(branchName: string): Promise<GhPr | null> {\n logger.debug(`getBranchPr(${branchName})`);\n\n const openPr = await findPr({\n branchName,\n state: 'open',\n });\n\n if (openPr) {\n return openPr;\n }\n\n return null;\n}\n\nexport async function tryReuseAutoclosedPr(\n autoclosedPr: Pr,\n newTitle: string,\n): Promise<Pr | null> {\n const { sha, number, sourceBranch: branchName } = autoclosedPr;\n try {\n await ensureBranchSha(branchName, sha!);\n logger.debug(`Recreated autoclosed branch ${branchName} with sha ${sha}`);\n } catch (err) {\n logger.debug(\n { err, branchName, sha, autoclosedPr },\n 'Could not recreate autoclosed branch - skipping reopen',\n );\n return null;\n }\n\n try {\n const { body: ghPr } = await githubApi.patchJson<GhRestPr>(\n `repos/${config.repository}/pulls/${number}`,\n {\n body: {\n state: 'open',\n title: newTitle,\n },\n },\n );\n logger.info(\n { branchName, oldTitle: autoclosedPr.title, newTitle, number },\n 'Successfully reopened autoclosed PR',\n );\n\n const result = coerceRestPr(ghPr);\n\n const localSha = git.getBranchCommit(branchName);\n // v8 ignore else -- TODO: add test #40625\n if (localSha && localSha !== sha) {\n await git.forcePushToRemote(branchName, 'origin');\n result.sha = localSha;\n }\n\n cachePr(result);\n return result;\n } catch {\n logger.debug('Could not reopen autoclosed PR');\n return null;\n }\n}\n\nasync function getStatus(\n branchName: string,\n useCache = true,\n): Promise<CombinedBranchStatus> {\n const branch = escapeHash(branchName);\n const url = `repos/${config.repository}/commits/${branch}/status`;\n\n const { body: status } =\n await githubApi.getJsonUnchecked<CombinedBranchStatus>(url, {\n memCache: useCache,\n cacheProvider: repoCacheProvider,\n });\n\n return status;\n}\n\n// Returns the combined status for a branch.\nexport async function getBranchStatus(\n branchName: string,\n internalChecksAsSuccess: boolean,\n): Promise<BranchStatus> {\n logger.debug(`getBranchStatus(${branchName})`);\n let commitStatus: CombinedBranchStatus;\n try {\n commitStatus = await getStatus(branchName);\n } catch (err) /* v8 ignore next -- 404-to-REPOSITORY_CHANGED mapping for deleted branches is not mocked in specs */ {\n if (err.statusCode === 404) {\n logger.debug(\n 'Received 404 when checking branch status, assuming that branch has been deleted',\n );\n throw new Error(REPOSITORY_CHANGED);\n }\n logger.debug('Unknown error when checking branch status');\n throw err;\n }\n logger.debug(\n { state: commitStatus.state, statuses: commitStatus.statuses },\n 'branch status check result',\n );\n if (commitStatus.statuses && !internalChecksAsSuccess) {\n commitStatus.statuses = commitStatus.statuses.filter(\n (status) =>\n status.state !== 'success' || !status.context?.startsWith('renovate/'),\n );\n // v8 ignore else -- TODO: add test #40625\n if (!commitStatus.statuses.length) {\n logger.debug(\n 'Successful checks are all internal renovate/ checks, so returning \"pending\" branch status',\n );\n commitStatus.state = 'pending';\n }\n }\n let checkRuns: { name: string; status: string; conclusion: string }[] = [];\n // API is supported in oldest available GHE version 2.19\n try {\n const checkRunsUrl = `repos/${config.repository}/commits/${escapeHash(\n branchName,\n )}/check-runs?per_page=100`;\n const opts = {\n headers: {\n accept: 'application/vnd.github.antiope-preview+json',\n },\n paginate: true,\n paginationField: 'check_runs',\n cacheProvider: memCacheProvider,\n };\n const checkRunsRaw = (\n await githubApi.getJsonUnchecked<{\n check_runs: { name: string; status: string; conclusion: string }[];\n }>(checkRunsUrl, opts)\n ).body;\n if (checkRunsRaw.check_runs?.length) {\n checkRuns = checkRunsRaw.check_runs.map((run) => ({\n name: run.name,\n status: run.status,\n conclusion: run.conclusion,\n }));\n logger.debug({ checkRuns }, 'check runs result');\n } /* v8 ignore next -- specs always mock a non-empty check_runs response */ else {\n logger.debug({ result: checkRunsRaw }, 'No check runs found');\n }\n } catch (err) /* v8 ignore next -- check-run permission errors (403) are mapped to empty results, not mocked in specs */ {\n if (err instanceof ExternalHostError) {\n throw err;\n }\n if (\n err.statusCode === 403 ||\n err.message === PLATFORM_INTEGRATION_UNAUTHORIZED\n ) {\n logger.debug('No permission to view check runs');\n } else {\n logger.warn({ err }, 'Error retrieving check runs');\n }\n }\n if (checkRuns.length === 0) {\n if (commitStatus.state === 'success') {\n return 'green';\n }\n if (commitStatus.state === 'failure') {\n return 'red';\n }\n return 'yellow';\n }\n if (\n commitStatus.state === 'failure' ||\n checkRuns.some((run) => run.conclusion === 'failure')\n ) {\n return 'red';\n }\n if (\n (commitStatus.state === 'success' || commitStatus.statuses.length === 0) &&\n checkRuns.every((run) =>\n ['skipped', 'neutral', 'success'].includes(run.conclusion),\n )\n ) {\n return 'green';\n }\n return 'yellow';\n}\n\nasync function getStatusCheck(\n branchName: string,\n useCache = true,\n): Promise<GhBranchStatus[]> {\n const branchCommit = git.getBranchCommit(branchName);\n\n const url = `repos/${config.repository}/commits/${branchCommit}/statuses`;\n\n const opts: GithubHttpOptions = useCache\n ? { cacheProvider: memCacheProvider }\n : { memCache: false };\n\n return (await githubApi.getJsonUnchecked<GhBranchStatus[]>(url, opts)).body;\n}\n\ntype GithubToRenovateStatusMapping = Record<string, BranchStatus>;\nconst githubToRenovateStatusMapping: GithubToRenovateStatusMapping = {\n success: 'green',\n error: 'red',\n failure: 'red',\n pending: 'yellow',\n};\n\nexport async function getBranchStatusCheck(\n branchName: string,\n context: string,\n): Promise<BranchStatus | null> {\n try {\n const res = await getStatusCheck(branchName);\n for (const check of res) {\n if (check.context === context) {\n return githubToRenovateStatusMapping[check.state] || 'yellow';\n }\n }\n return null;\n } catch (err) /* v8 ignore next -- 404-to-REPOSITORY_CHANGED mapping for missing commits is not mocked in specs */ {\n if (err.statusCode === 404) {\n logger.debug('Commit not found when checking statuses');\n throw new Error(REPOSITORY_CHANGED);\n }\n throw err;\n }\n}\n\nexport async function setBranchStatus({\n branchName,\n context,\n description,\n state,\n url: targetUrl,\n}: BranchStatusConfig): Promise<void> {\n /* v8 ignore next -- specs do not run setBranchStatus in forking mode */\n if (config.parentRepo) {\n logger.debug('Cannot set branch status when in forking mode');\n return;\n }\n const existingStatus = await getBranchStatusCheck(branchName, context);\n if (existingStatus === state) {\n return;\n }\n logger.debug({ branch: branchName, context, state }, 'Setting branch status');\n let url: string | undefined;\n try {\n const branchCommit = git.getBranchCommit(branchName);\n url = `repos/${config.repository}/statuses/${branchCommit}`;\n const renovateToGitHubStateMapping = {\n green: 'success',\n yellow: 'pending',\n red: 'failure',\n };\n const options: any = {\n state: renovateToGitHubStateMapping[state],\n description,\n context,\n };\n // v8 ignore else -- TODO: add test #40625\n if (targetUrl) {\n options.target_url = targetUrl;\n }\n await githubApi.postJson(url, { body: options });\n\n // update status cache\n await getStatus(branchName, false);\n await getStatusCheck(branchName, false);\n } catch (err) /* v8 ignore next -- defensive: status POST failures abort with REPOSITORY_CHANGED, not simulated in specs */ {\n logger.debug({ err, url }, 'Caught error setting branch status - aborting');\n throw new Error(REPOSITORY_CHANGED);\n }\n}\n\n// Issue\n\nasync function getIssues(): Promise<Issue[]> {\n const result = await githubApi.queryRepoField<unknown>(\n getIssuesQuery,\n 'issues',\n {\n variables: {\n owner: config.repositoryOwner,\n name: config.repositoryName,\n ...(!config.ignorePrAuthor && { user: config.renovateUsername }),\n },\n readOnly: true,\n },\n );\n\n logger.debug(`Retrieved ${result.length} issues`);\n return Issue.array().parse(result);\n}\n\nexport async function getIssueList(): Promise<Issue[]> {\n /* v8 ignore next -- specs initialize repos with issues enabled */\n if (config.hasIssuesEnabled === false) {\n return [];\n }\n let issueList = GithubIssueCache.getIssues();\n // v8 ignore else -- TODO: add test #40625\n if (!issueList) {\n logger.debug('Retrieving issueList');\n issueList = await getIssues();\n GithubIssueCache.setIssues(issueList);\n }\n return issueList;\n}\n\nexport async function getIssue(number: number): Promise<Issue | null> {\n if (config.hasIssuesEnabled === false) {\n return null;\n }\n try {\n const repo = config.parentRepo ?? config.repository;\n const { body: issue } = await githubApi.getJson(\n `repos/${repo}/issues/${number}`,\n {\n cacheProvider: repoCacheProvider,\n },\n Issue,\n );\n GithubIssueCache.updateIssue(issue);\n return issue;\n } catch (err) {\n logger.debug({ err, number }, 'Error getting issue');\n if (err.response?.statusCode === 410) {\n logger.debug(`Issue #${number} has been deleted`);\n GithubIssueCache.deleteIssue(number);\n }\n return null;\n }\n}\n\nexport async function findIssue(title: string): Promise<Issue | null> {\n logger.debug(`findIssue(${title})`);\n const [issue] = (await getIssueList()).filter(\n (i) => i.state === 'open' && i.title === title,\n );\n if (!issue) {\n return null;\n }\n logger.debug(`Found issue ${issue.number}`);\n return getIssue(issue.number);\n}\n\nasync function closeIssue(issueNumber: number): Promise<void> {\n logger.debug(`closeIssue(${issueNumber})`);\n const repo = config.parentRepo ?? config.repository;\n try {\n const { body: closedIssue } = await githubApi.patchJson(\n `repos/${repo}/issues/${issueNumber}`,\n { body: { state: 'closed' } },\n Issue,\n );\n GithubIssueCache.updateIssue(closedIssue);\n } catch (err) {\n const statusCode = err.response?.statusCode;\n if (statusCode === 404 || statusCode === 410) {\n logger.debug(\n `Issue #${issueNumber} no longer exists on the platform, removing from cache`,\n );\n GithubIssueCache.deleteIssue(issueNumber);\n return;\n }\n throw err;\n }\n}\n\nexport async function ensureIssue({\n title,\n reuseTitle,\n body: rawBody,\n labels,\n once = false,\n shouldReOpen = true,\n}: EnsureIssueConfig): Promise<EnsureIssueResult | null> {\n logger.debug(`ensureIssue(${title})`);\n /* v8 ignore next -- specs initialize repos with issues enabled */\n if (config.hasIssuesEnabled === false) {\n logger.info(\n 'Cannot ensure issue because issues are disabled in this repository',\n );\n return null;\n }\n const body = sanitize(rawBody);\n try {\n const issueList = await getIssueList();\n let issues = issueList.filter((i) => i.title === title);\n if (!issues.length) {\n issues = issueList.filter((i) => i.title === reuseTitle);\n if (issues.length) {\n logger.debug(`Reusing issue title: \"${reuseTitle}\"`);\n }\n }\n if (issues.length) {\n let issue = issues.find((i) => i.state === 'open');\n if (!issue) {\n if (once) {\n logger.debug('Issue already closed - skipping recreation');\n return null;\n }\n if (shouldReOpen) {\n logger.debug('Reopening previously closed issue');\n }\n issue = issues.at(-1)!;\n }\n for (const i of issues) {\n if (i.state === 'open' && i.number !== issue.number) {\n logger.warn({ issueNo: i.number }, 'Closing duplicate issue');\n await closeIssue(i.number);\n }\n }\n\n const repo = config.parentRepo ?? config.repository;\n const { body: serverIssue } = await githubApi.getJson(\n `repos/${repo}/issues/${issue.number}`,\n { cacheProvider: repoCacheProvider },\n Issue,\n );\n GithubIssueCache.updateIssue(serverIssue);\n\n if (\n issue.title === title &&\n serverIssue.body === body &&\n issue.state === 'open'\n ) {\n logger.debug('Issue is open and up to date - nothing to do');\n return null;\n }\n if (shouldReOpen || issue.state === 'open') {\n logger.debug('Patching issue');\n const data: Record<string, unknown> = { body, state: 'open', title };\n if (labels) {\n data.labels = labels;\n }\n const repo = config.parentRepo ?? config.repository;\n const { body: updatedIssue } = await githubApi.patchJson(\n `repos/${repo}/issues/${issue.number}`,\n { body: data },\n Issue,\n );\n GithubIssueCache.updateIssue(updatedIssue);\n logger.debug('Issue updated');\n return 'updated';\n }\n }\n const { body: createdIssue } = await githubApi.postJson(\n `repos/${config.parentRepo ?? config.repository}/issues`,\n {\n body: {\n title,\n body,\n labels: coerceArray(labels),\n },\n },\n Issue,\n );\n logger.info('Issue created');\n // reset issueList so that it will be fetched again as-needed\n GithubIssueCache.updateIssue(createdIssue);\n return 'created';\n } catch (err) {\n if (err instanceof Error && err.message === PLATFORM_RATE_LIMIT_EXCEEDED) {\n throw err;\n }\n if (err.body?.message?.startsWith('Issues are disabled for this repo')) {\n logger.debug(`Issues are disabled, so could not create issue: ${title}`);\n } else {\n logger.warn({ err }, 'Could not ensure issue');\n }\n }\n return null;\n}\n\nexport async function ensureIssueClosing(title: string): Promise<void> {\n logger.trace(`ensureIssueClosing(${title})`);\n /* v8 ignore next -- specs initialize repos with issues enabled */\n if (config.hasIssuesEnabled === false) {\n return;\n }\n const issueList = await getIssueList();\n for (const issue of issueList) {\n if (issue.state === 'open' && issue.title === title) {\n await closeIssue(issue.number);\n logger.debug(`Issue closed, issueNo: ${issue.number}`);\n }\n }\n}\n\nasync function tryAddMilestone(\n issueNo: number,\n milestoneNo: number | undefined,\n): Promise<void> {\n if (!milestoneNo) {\n return;\n }\n\n logger.debug(\n {\n milestone: milestoneNo,\n pr: issueNo,\n },\n 'Adding milestone to PR',\n );\n try {\n const repo = config.parentRepo ?? config.repository;\n const { body: updatedIssue } = await githubApi.patchJson(\n `repos/${repo}/issues/${issueNo}`,\n { body: { milestone: milestoneNo } },\n Issue,\n );\n GithubIssueCache.updateIssue(updatedIssue);\n } catch (err) {\n /* v8 ignore next -- defensive: the raw-error fallback is for non-HTTP failures not seen in specs */\n const actualError = err.response?.body ?? err;\n logger.warn(\n {\n milestone: milestoneNo,\n pr: issueNo,\n err: actualError,\n },\n 'Unable to add milestone to PR',\n );\n }\n}\n\nexport async function addAssignees(\n issueNo: number,\n assignees: string[],\n): Promise<void> {\n logger.debug(`Adding assignees '${assignees.join(', ')}' to #${issueNo}`);\n const repository = config.parentRepo ?? config.repository;\n const url = `repos/${repository}/issues/${issueNo}/assignees`;\n let lastErr: Error | undefined;\n for (let attempt = 0; attempt < 3; attempt += 1) {\n try {\n const { body: updatedIssue } = await githubApi.postJson(\n url,\n { body: { assignees } },\n Issue,\n );\n GithubIssueCache.updateIssue(updatedIssue);\n return;\n } catch (err) {\n if (err.statusCode !== 404) {\n throw err;\n }\n lastErr = err;\n logger.debug(\n { attempt: attempt + 1 },\n `Retrying addAssignees for #${issueNo} after 404`,\n );\n await setTimeout(1000);\n }\n }\n throw lastErr!;\n}\n\nexport async function addReviewers(\n prNo: number,\n reviewers: string[],\n): Promise<void> {\n logger.debug(`Adding reviewers '${reviewers.join(', ')}' to #${prNo}`);\n\n const userReviewers = reviewers.filter((e) => !e.startsWith('team:'));\n const teamReviewers = reviewers\n .filter((e) => e.startsWith('team:'))\n .map((e) => e.replace(regEx(/^team:/), ''));\n try {\n await githubApi.postJson(\n `repos/${\n config.parentRepo ?? config.repository\n }/pulls/${prNo}/requested_reviewers`,\n {\n body: {\n reviewers: userReviewers,\n team_reviewers: teamReviewers,\n },\n },\n );\n } catch (err) /* v8 ignore next -- defensive: reviewer assignment failures are logged and swallowed, not simulated in specs */ {\n logger.warn({ err }, 'Failed to assign reviewer');\n }\n}\n\nexport async function addLabels(\n issueNo: number,\n labels: string[] | null | undefined,\n): Promise<void> {\n logger.debug(`Adding labels '${labels?.join(', ')}' to #${issueNo}`);\n try {\n const repository = config.parentRepo ?? config.repository;\n if (isArray(labels) && labels.length) {\n await githubApi.postJson(`repos/${repository}/issues/${issueNo}/labels`, {\n body: labels,\n });\n }\n } catch (err) /* v8 ignore next -- defensive: label-adding failures are logged and swallowed, not simulated in specs */ {\n logger.warn(\n { err, issueNo, labels },\n 'Error while adding labels. Skipping',\n );\n }\n}\n\nexport async function deleteLabel(\n issueNo: number,\n label: string,\n): Promise<void> {\n logger.debug(`Deleting label ${label} from #${issueNo}`);\n const repository = config.parentRepo ?? config.repository;\n try {\n await githubApi.deleteJson(\n `repos/${repository}/issues/${issueNo}/labels/${label}`,\n );\n } catch (err) /* v8 ignore next -- defensive: label deletion failures are logged and swallowed, not simulated in specs */ {\n logger.warn({ err, issueNo, label }, 'Failed to delete label');\n }\n}\n\nasync function addComment(issueNo: number, body: string): Promise<void> {\n // POST /repos/:owner/:repo/issues/:number/comments\n await githubApi.postJson(\n `repos/${\n config.parentRepo ?? config.repository\n }/issues/${issueNo}/comments`,\n {\n body: { body },\n },\n );\n}\n\nasync function editComment(commentId: number, body: string): Promise<void> {\n // PATCH /repos/:owner/:repo/issues/comments/:id\n await githubApi.patchJson(\n `repos/${\n config.parentRepo ?? config.repository\n }/issues/comments/${commentId}`,\n {\n body: { body },\n },\n );\n}\n\nasync function deleteComment(commentId: number): Promise<void> {\n // DELETE /repos/:owner/:repo/issues/comments/:id\n await githubApi.deleteJson(\n `repos/${\n config.parentRepo ?? config.repository\n }/issues/comments/${commentId}`,\n );\n}\n\nasync function getComments(issueNo: number): Promise<Comment[]> {\n // GET /repos/:owner/:repo/issues/:number/comments\n logger.debug(`Getting comments for #${issueNo}`);\n const repo = config.parentRepo ?? config.repository;\n const url = `repos/${repo}/issues/${issueNo}/comments?per_page=100`;\n try {\n const { body: comments } = await githubApi.getJsonUnchecked<Comment[]>(\n url,\n {\n paginate: true,\n cacheProvider: repoCacheProvider,\n },\n );\n logger.debug(`Found ${comments.length} comments`);\n return comments;\n } catch (err) /* v8 ignore next -- comment-fetch 404s are wrapped as ExternalHostError, not mocked in specs */ {\n if (err.statusCode === 404) {\n logger.debug('404 response when retrieving comments');\n throw new ExternalHostError(err, 'github');\n }\n throw err;\n }\n}\n\nexport async function ensureComment({\n number,\n topic,\n content,\n}: EnsureCommentConfig): Promise<boolean> {\n const sanitizedContent = sanitize(content);\n try {\n const comments = await getComments(number);\n let body: string;\n let commentId: number | null = null;\n let commentNeedsUpdating = false;\n if (topic) {\n logger.debug(`Ensuring comment \"${topic}\" in #${number}`);\n body = `### ${topic}\\n\\n${sanitizedContent}`;\n comments.forEach((comment) => {\n if (comment.body.startsWith(`### ${topic}\\n\\n`)) {\n commentId = comment.id;\n commentNeedsUpdating = comment.body !== body;\n }\n });\n } else {\n logger.debug(`Ensuring content-only comment in #${number}`);\n body = `${sanitizedContent}`;\n comments.forEach((comment) => {\n // v8 ignore else -- TODO: add test #40625\n if (comment.body === body) {\n commentId = comment.id;\n commentNeedsUpdating = false;\n }\n });\n }\n if (!commentId) {\n await addComment(number, body);\n logger.info(\n { repository: config.repository, issueNo: number, topic },\n 'Comment added',\n );\n } else if (commentNeedsUpdating) {\n await editComment(commentId, body);\n logger.debug(\n { repository: config.repository, issueNo: number },\n 'Comment updated',\n );\n } else {\n logger.debug('Comment is already up-to-date');\n }\n return true;\n } catch (err) /* v8 ignore next -- comment API failure handling (locked issues) is not mocked in specs */ {\n if (err instanceof ExternalHostError) {\n throw err;\n }\n if (err.body?.message?.includes('is locked')) {\n logger.debug('Issue is locked - cannot add comment');\n } else {\n logger.warn({ err }, 'Error ensuring comment');\n }\n return false;\n }\n}\n\nfunction byTopic(comment: Comment, topic: string): boolean {\n return comment.body.startsWith(`### ${topic}\\n\\n`);\n}\n\nfunction byContent(comment: Comment, content: string): boolean {\n return comment.body.trim() === content;\n}\n\nexport async function ensureCommentRemoval(\n deleteConfig: EnsureCommentRemovalConfig,\n): Promise<void> {\n const { number: issueNo } = deleteConfig;\n const key =\n deleteConfig.type === 'by-topic'\n ? deleteConfig.topic\n : deleteConfig.content;\n logger.trace(`Ensuring comment \"${key}\" in #${issueNo} is removed`);\n const comments = await getComments(issueNo);\n let commentId: number | null | undefined = null;\n\n // v8 ignore else -- TODO: add test #40625\n if (deleteConfig.type === 'by-topic') {\n const topic = deleteConfig.topic;\n commentId = comments.find((comment) => byTopic(comment, topic))?.id;\n } else if (deleteConfig.type === 'by-content') {\n const content = deleteConfig.content;\n commentId = comments.find((comment) => byContent(comment, content))?.id;\n }\n\n try {\n // v8 ignore else -- TODO: add test #40625\n if (commentId) {\n logger.debug(`Removing comment from issueNo: ${issueNo}`);\n await deleteComment(commentId);\n }\n } catch (err) /* v8 ignore next -- defensive: comment deletion failures are logged and swallowed, not simulated in specs */ {\n logger.warn({ err }, 'Error deleting comment');\n }\n}\n\n// Pull Request\n\nasync function tryPrAutomerge(\n prNumber: number,\n prNodeId: string,\n platformPrOptions: PlatformPrOptions | undefined,\n): Promise<void> {\n if (!platformPrOptions?.usePlatformAutomerge) {\n return;\n }\n\n // If GitHub Enterprise Server <3.3.0 it doesn't support automerge\n // TODO #22198\n if (\n isGithubEnterpriseServer(platformConfig.host) &&\n semver.satisfies(platformConfig.host.version ?? '', '<3.3.0')\n ) {\n logger.debug(\n { prNumber },\n 'GitHub-native automerge: not supported on this version of GHE. Use 3.3.0 or newer.',\n );\n return;\n }\n\n if (!config.autoMergeAllowed) {\n logger.debug(\n { prNumber },\n 'GitHub-native automerge: not enabled in repo settings',\n );\n return;\n }\n\n try {\n const mergeMethod =\n (\n mapMergeStartegy(platformPrOptions.automergeStrategy) ??\n config.mergeMethod\n )?.toUpperCase() || 'MERGE';\n\n let commitHeadline: string | undefined;\n let commitBody: string | undefined;\n // For SQUASH and MERGE methods, pass the commit message explicitly to avoid\n // GitHub using the PR description as the commit body when \"Use PR title and\n // body as commit message\" is enabled in repository settings.\n const automergeCommitMessage = platformPrOptions?.automergeCommitMessage;\n if (mergeMethod !== 'REBASE' && automergeCommitMessage) {\n const newlineIndex = automergeCommitMessage.indexOf('\\n');\n if (newlineIndex === -1) {\n commitHeadline = automergeCommitMessage;\n } else {\n commitHeadline = automergeCommitMessage.slice(0, newlineIndex);\n commitBody = automergeCommitMessage.slice(newlineIndex + 1).trim();\n }\n\n // Add PR number to the commit headline to match the default GitHub behavior\n commitHeadline = `${commitHeadline} (#${prNumber})`;\n }\n\n const variables = {\n pullRequestId: prNodeId,\n mergeMethod,\n commitHeadline,\n commitBody,\n };\n // set count to one bypass graphql check\n const queryOptions = { variables, count: 1 };\n\n const res = await githubApi.requestGraphql<GhAutomergeResponse>(\n enableAutoMergeMutation,\n queryOptions,\n );\n\n if (res?.errors) {\n logger.debug(\n { prNumber, errors: res.errors },\n 'GitHub-native automerge: fail',\n );\n return;\n }\n\n logger.debug(`GitHub-native automerge: success...PrNo: ${prNumber}`);\n } catch (err) {\n if (err instanceof Error && err.message === PLATFORM_RATE_LIMIT_EXCEEDED) {\n throw err;\n }\n logger.warn({ prNumber, err }, 'GitHub-native automerge: REST API error');\n }\n}\n\n// Creates PR and returns PR number\nexport async function createPr({\n sourceBranch,\n targetBranch,\n prTitle: title,\n prBody: rawBody,\n labels,\n draftPR = false,\n platformPrOptions,\n milestone,\n}: CreatePRConfig): Promise<GhPr | null> {\n const body = sanitize(rawBody);\n const base = targetBranch;\n // Include the repository owner to handle forkToken and regular mode\n // TODO: can `repository` be null? (#22198)\n\n const head = `${config.repository!.split('/')[0]}:${sourceBranch}`;\n const options: any = {\n body: {\n title,\n head,\n base,\n body,\n draft: draftPR,\n },\n };\n /* v8 ignore next -- fork mode is not exercised in createPr specs */\n if (config.forkToken) {\n options.token = config.forkToken;\n options.body.maintainer_can_modify =\n !config.forkOrg &&\n platformPrOptions?.forkModeDisallowMaintainerEdits !== true;\n }\n logger.debug({ title, head, base, draft: draftPR }, 'Creating PR');\n const ghPr = (\n await githubApi.postJson<GhRestPr>(\n `repos/${config.parentRepo ?? config.repository}/pulls`,\n options,\n )\n ).body;\n logger.debug(\n { branch: sourceBranch, pr: ghPr.number, draft: draftPR },\n 'PR created',\n );\n\n const result = coerceRestPr(ghPr);\n const { number, node_id } = result;\n\n await addLabels(number, labels);\n await tryAddMilestone(number, milestone);\n await tryPrAutomerge(number, node_id, platformPrOptions);\n\n cachePr(result);\n return result;\n}\n\nexport async function isBranchMergeQueueEnabled(\n baseBranch: string,\n): Promise<boolean> {\n const cachedResult = config.mergeQueueEnabled[baseBranch];\n if (cachedResult !== undefined) {\n return cachedResult;\n }\n\n // TODO #22198\n if (\n isGithubEnterpriseServer(platformConfig.host) &&\n semver.satisfies(platformConfig.host.version ?? '', '<3.12.0')\n ) {\n // Merge queues are only supported on GHES >=3.12.0\n config.mergeQueueEnabled[baseBranch] = false;\n return false;\n }\n\n // Assume enabled unless proven otherwise, so the merge queue check is not\n // skipped by mistake\n let result = true;\n try {\n const res = await githubApi.requestGraphql<{\n repository: { mergeQueue: { id: string } | null };\n }>(repoMergeQueueQuery, {\n variables: {\n owner: config.repositoryOwner,\n name: config.repositoryName,\n branch: baseBranch,\n },\n readOnly: true,\n count: 1, // bypass graphql check\n });\n if (res?.errors) {\n logger.debug(\n { baseBranch, errors: res.errors },\n 'Failed to fetch merge queue status - assuming merge queue is enabled',\n );\n } else {\n result = isNonEmptyObject(res?.data?.repository?.mergeQueue);\n }\n } catch (err) {\n if (err instanceof Error && err.message === PLATFORM_RATE_LIMIT_EXCEEDED) {\n throw err;\n }\n logger.debug(\n { baseBranch, err },\n 'Error fetching merge queue status - assuming merge queue is enabled',\n );\n }\n\n config.mergeQueueEnabled[baseBranch] = result;\n return result;\n}\n\nexport function isPrInMergeQueue(prNo: number): Promise<boolean> {\n return checkPrInMergeQueue(\n githubApi,\n config.repositoryOwner,\n config.repositoryName,\n prNo,\n );\n}\n\nexport async function assertPrNotInMergeQueue(\n branchName: string,\n baseBranch?: string,\n): Promise<void> {\n if (!(await isBranchMergeQueueEnabled(baseBranch ?? config.defaultBranch))) {\n return;\n }\n\n const pr = await findPr({ branchName, state: 'open' });\n if (!pr) {\n return;\n }\n\n if (await isPrInMergeQueue(pr.number)) {\n logger.debug(`PR #${pr.number} is in the merge queue - aborting push`);\n throw new Error(PR_ALREADY_IN_MERGE_QUEUE);\n }\n}\n\nexport async function updatePr({\n number: prNo,\n prTitle: title,\n prBody: rawBody,\n addLabels: labelsToAdd,\n removeLabels,\n state,\n targetBranch,\n}: UpdatePrConfig): Promise<void> {\n logger.debug(`updatePr(${prNo}, ${title}, body)`);\n const body = sanitize(rawBody);\n const patchBody: any = { title };\n // v8 ignore else -- TODO: add test #40625\n if (body) {\n patchBody.body = body;\n }\n if (targetBranch) {\n patchBody.base = targetBranch;\n }\n if (state) {\n patchBody.state = state;\n }\n const options: any = {\n body: patchBody,\n };\n /* v8 ignore next -- fork mode is not exercised in updatePr specs */\n if (config.forkToken) {\n options.token = config.forkToken;\n }\n\n // Update PR labels\n try {\n if (labelsToAdd) {\n await addLabels(prNo, labelsToAdd);\n }\n\n if (removeLabels) {\n for (const label of removeLabels) {\n await deleteLabel(prNo, label);\n }\n }\n\n const { body: ghPr } = await githubApi.patchJson<GhRestPr>(\n `repos/${config.parentRepo ?? config.repository}/pulls/${prNo}`,\n options,\n );\n const result = coerceRestPr(ghPr);\n cachePr(result);\n logger.debug(`PR updated...prNo: ${prNo}`);\n } catch (err) /* v8 ignore next -- non-host update failures are logged and swallowed, not mocked in specs */ {\n if (err instanceof ExternalHostError) {\n throw err;\n }\n logger.warn({ err }, 'Error updating PR');\n }\n}\n\nexport async function reattemptPlatformAutomerge({\n number,\n platformPrOptions,\n}: ReattemptPlatformAutomergeConfig): Promise<void> {\n try {\n const result = (await getPr(number))!;\n const { node_id } = result;\n\n await tryPrAutomerge(number, node_id, platformPrOptions);\n\n logger.debug(`PR platform automerge re-attempted...prNo: ${number}`);\n } catch (err) {\n if (err instanceof Error && err.message === PLATFORM_RATE_LIMIT_EXCEEDED) {\n throw err;\n }\n logger.warn({ err }, 'Error re-attempting PR platform automerge');\n }\n}\n\nasync function tryEnqueuePr(pr: GhPr): Promise<boolean> {\n const prNo = pr.number;\n try {\n const res = await githubApi.requestGraphql<GhEnqueuePullRequestResponse>(\n enqueuePullRequestMutation,\n {\n variables: { pullRequestId: pr.node_id },\n count: 1, // set count to one to bypass graphql check\n },\n );\n\n if (res?.errors) {\n // GitHub does not document the exact message, so match loosely.\n // \"enqueue\" contains \"queue\", so both wordings are covered.\n if (\n res.errors.some((error) => regEx(/already.*queue/i).test(error.message))\n ) {\n logger.debug(`PR #${prNo} is already in the merge queue`);\n return true;\n }\n logger.debug(\n { prNumber: prNo, errors: res.errors },\n 'Failed to add PR to the merge queue',\n );\n return false;\n }\n\n logger.debug(`PR #${prNo} added to the merge queue`);\n return true;\n } catch (err) {\n logger.warn({ prNumber: prNo, err }, 'Failed to add PR to the merge queue');\n return false;\n }\n}\n\nexport async function mergePr({\n branchName,\n id: prNo,\n strategy,\n}: MergePRConfig): Promise<boolean> {\n logger.debug(`mergePr(${prNo}, ${branchName})`);\n\n const pr = await getPr(prNo);\n if (await directMergePr(prNo, strategy)) {\n return true;\n }\n if (pr?.targetBranch && (await isBranchMergeQueueEnabled(pr.targetBranch))) {\n // The direct merge was refused - fall back to adding the PR to the merge\n // queue, so it must not be cached as merged nor may its branch be deleted\n return tryEnqueuePr(pr);\n }\n return false;\n}\n\nasync function directMergePr(\n prNo: number,\n strategy?: MergeStrategy,\n): Promise<boolean> {\n const url = `repos/${\n config.parentRepo ?? config.repository\n }/pulls/${prNo}/merge`;\n const options: GithubHttpOptions = {\n body: {},\n };\n /* v8 ignore next -- fork mode is not exercised in mergePr specs */\n if (config.forkToken) {\n options.token = config.forkToken;\n }\n let automerged = false;\n let automergeResult: HttpResponse<unknown>;\n const mergeStrategy = mapMergeStartegy(strategy) ?? config.mergeMethod;\n\n // v8 ignore else -- TODO: add test #40625\n if (mergeStrategy) {\n // This path is taken if we have auto-detected the allowed merge types from the repo or\n // automergeStrategy is configured by user\n options.body.merge_method = mergeStrategy;\n try {\n logger.debug({ options, url }, `mergePr`);\n automergeResult = await githubApi.putJson(url, options);\n automerged = true;\n } catch (err) /* v8 ignore next -- merge rejection handling (404/405 status-check bodies) is not fully mocked in specs */ {\n if (err.statusCode === 404 || err.statusCode === 405) {\n const body = err.response?.body;\n if (\n isNonEmptyString(body?.message) &&\n regEx(/^Required status check \".+\" is expected\\.$/).test(body.message)\n ) {\n logger.debug(\n { response: body },\n `GitHub blocking PR merge -- Missing required status check(s)`,\n );\n return false;\n }\n if (\n isNonEmptyString(body?.message) &&\n (body.message.includes('approving review') ||\n body.message.includes('code owner review') ||\n body.message.includes(\n 'New changes require approval from someone other than the last pusher',\n ))\n ) {\n logger.debug(\n { response: body },\n `GitHub blocking PR merge -- Needs approving review(s)`,\n );\n return false;\n }\n logger.debug(\n { response: body },\n 'GitHub blocking PR merge -- will keep trying',\n );\n } else {\n logger.warn(\n { mergeMethod: config.mergeMethod, err },\n 'Failed to merge PR',\n );\n return false;\n }\n }\n }\n if (!automerged) {\n // We need to guess the merge method and try squash -> merge -> rebase\n options.body.merge_method = 'squash';\n try {\n logger.debug({ options, url }, `mergePr`);\n automergeResult = await githubApi.putJson(url, options);\n } catch (err1) {\n logger.debug({ err: err1 }, `Failed to squash merge PR`);\n try {\n options.body.merge_method = 'merge';\n logger.debug({ options, url }, `mergePr`);\n automergeResult = await githubApi.putJson(url, options);\n } catch (err2) {\n logger.debug({ err: err2 }, `Failed to merge commit PR`);\n try {\n options.body.merge_method = 'rebase';\n logger.debug({ options, url }, `mergePr`);\n automergeResult = await githubApi.putJson(url, options);\n } catch (err3) {\n logger.debug({ err: err3 }, `Failed to rebase merge PR`);\n logger.info({ pr: prNo }, 'All merge attempts failed');\n return false;\n }\n }\n }\n }\n logger.debug(\n { automergeResult: automergeResult!.body, pr: prNo },\n 'PR merged',\n );\n const cachedPr = config.prList?.find(({ number }) => number === prNo);\n if (cachedPr) {\n cachePr({ ...cachedPr, state: 'merged' });\n }\n return true;\n}\n\nexport function massageMarkdown(input: string): string {\n if (platformConfig.host.type !== 'github') {\n return smartTruncate(input, maxBodyLength());\n }\n const linkifiedInput = massageMarkdownLinks(input)\n // to be safe, replace all github.com links with redirect.github.com\n .replace(\n regEx(/href=\"https?:\\/\\/github.com\\//g),\n 'href=\"https://redirect.github.com/',\n )\n .replace(\n regEx(/]\\(https:\\/\\/github\\.com\\//g),\n '](https://redirect.github.com/',\n )\n .replace(\n regEx(/]: https:\\/\\/github\\.com\\//g),\n ']: https://redirect.github.com/',\n );\n // Run after truncation so any Note added by smartTruncate() is also converted\n return smartTruncate(linkifiedInput, maxBodyLength())\n .replaceAll(noteAlertRegex, '> [!NOTE]\\n')\n .replaceAll(warningAlertRegex, '> [!WARNING]\\n')\n .replaceAll(cautionAlertRegex, '> [!CAUTION]\\n')\n .replaceAll(importantAlertRegex, '> [!IMPORTANT]\\n');\n}\n\nexport function maxBodyLength(): number {\n return GitHubMaxPrBodyLen;\n}\n\nexport async function getVulnerabilityAlerts(): Promise<GithubVulnerabilityAlerts> {\n /* v8 ignore next -- specs initialize repos with vulnerability alerts enabled */\n if (config.hasVulnerabilityAlertsEnabled === false) {\n logger.debug('No vulnerability alerts enabled for repo');\n return [];\n }\n let vulnerabilityAlerts: GithubVulnerabilityAlerts | undefined;\n try {\n vulnerabilityAlerts = (\n await githubApi.getJson(\n `/repos/${config.repositoryOwner}/${config.repositoryName}/dependabot/alerts?state=open&direction=asc&per_page=100`,\n {\n paginate: true,\n headers: { accept: 'application/vnd.github+json' },\n cacheProvider: repoCacheProvider,\n },\n GithubVulnerabilityAlerts,\n )\n ).body;\n } catch (err) /* v8 ignore next -- alert-permission failures are logged and swallowed, not mocked in specs */ {\n logger.debug({ err }, 'Error retrieving vulnerability alerts');\n logger.warn(\n {\n url: `${GlobalConfig.get('productLinks').documentation}configuration-options/#vulnerabilityalerts`,\n },\n 'Cannot access vulnerability alerts. Please ensure permissions have been granted.',\n );\n }\n try {\n if (vulnerabilityAlerts?.length) {\n const shortAlerts: AggregatedVulnerabilities = {};\n logger.trace(\n { alerts: vulnerabilityAlerts },\n 'GitHub vulnerability details',\n );\n for (const alert of vulnerabilityAlerts) {\n // v8 ignore if -- TODO: can never happen but makes typescript happy #40625\n if (alert.security_vulnerability === null) {\n // As described in the documentation, there are cases in which\n // GitHub API responds with `\"securityVulnerability\": null`.\n // But it's may be faulty, so skip processing it here.\n continue;\n }\n const {\n package: { name, ecosystem },\n vulnerable_version_range: vulnerableVersionRange,\n first_patched_version: firstPatchedVersion,\n } = alert.security_vulnerability;\n const patch = firstPatchedVersion?.identifier;\n\n const normalizedName =\n ecosystem === 'pip' ? normalizePythonDepName(name) : name;\n alert.security_vulnerability.package.name = normalizedName;\n const key = `${ecosystem.toLowerCase()}/${normalizedName}`;\n const range = vulnerableVersionRange;\n const elem = shortAlerts[key] || {};\n elem[range] = coerceToNull(patch);\n shortAlerts[key] = elem;\n }\n logger.debug({ alerts: shortAlerts }, 'GitHub vulnerability details');\n } else {\n logger.debug('No vulnerability alerts found');\n }\n } catch (err) /* v8 ignore next -- defensive: processing already-parsed alerts does not throw in specs */ {\n logger.error({ err }, 'Error processing vulnerabity alerts');\n }\n return coerceArray(vulnerabilityAlerts);\n}\n\nasync function pushFiles(\n { branchName, message, trailers }: CommitFilesConfig,\n { parentCommitSha, commitSha }: CommitResult,\n): Promise<LongCommitSha | null> {\n try {\n // Hybrid git/REST commit strategy (see #13824, #14271):\n // 1. The git push below uploads blobs to GitHub via a custom ref\n // (refs/renovate/branches/*) which does NOT trigger CI/Actions.\n // 2. We then recreate the tree+commit via REST API so that:\n // - The commit is signed by GitHub (\"committed via GitHub\" badge)\n // - Force-push and file mode bits are supported (GraphQL can't do this)\n // - We can use base_tree to send only changed files, avoiding org\n // ruleset file-path restrictions on unchanged files (#42554)\n // Reusing the pushed commit/tree SHAs directly does not work because\n // the branch ref must point to an API-created commit for signing.\n await pushCommitToRenovateRef(commitSha, branchName);\n const baseTreeSha = await getCommitTreeSha(parentCommitSha);\n const treeItems = await diffCommitTree(parentCommitSha, commitSha);\n\n if (treeItems.length === 0) {\n logger.debug(\n { branchName },\n 'Platform-native commit: no changed files between commits',\n );\n return null;\n }\n\n const treeRes = await githubApi.postJson<{ sha: string }>(\n `/repos/${config.repository}/git/trees`,\n { body: { base_tree: baseTreeSha, tree: treeItems } },\n );\n const treeSha = treeRes.body.sha;\n\n const commitMessage = formatCommitMessage(message, trailers);\n\n // Now we recreate the commit using the tree we recreated the step before\n const commitRes = await githubApi.postJson<{ sha: string }>(\n `/repos/${config.repository}/git/commits`,\n {\n body: {\n message: commitMessage,\n tree: treeSha,\n parents: [parentCommitSha],\n },\n },\n );\n incLimitedValue('Commits');\n const remoteCommitSha = toLongCommitSha(commitRes.body.sha);\n await ensureBranchSha(branchName, remoteCommitSha);\n return remoteCommitSha;\n } catch (err) {\n logger.debug({ branchName, err }, 'Platform-native commit: unknown error');\n return null;\n }\n}\n\nexport async function commitFiles(\n config: CommitFilesConfig,\n): Promise<LongCommitSha | null> {\n const commitResult = await git.prepareCommit(config); // Commit locally and don't push\n const { branchName, files } = config;\n if (!commitResult) {\n logger.debug(\n { branchName, files: files.map(({ path }) => path) },\n `Platform-native commit: unable to prepare for commit`,\n );\n return null;\n }\n // Perform the commits using REST API\n const pushResult = await pushFiles(config, commitResult);\n if (!pushResult) {\n return null;\n }\n // Replace locally created branch with the remotely created one\n // and return the remote commit SHA\n await git.resetToCommit(commitResult.parentCommitSha);\n const commitSha = await git.fetchBranch(branchName);\n return commitSha;\n}\n"],"mappings":"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"}
@@ -251,7 +251,7 @@ async function ensureDependencyDashboard(config, allBranches, packageFiles = {},
251
251
  if (hasDeprecationsOrReplacements) {
252
252
  issueBody += "## Deprecations / Replacements\n";
253
253
  issueBody += emojify("> :warning: **Warning**\n> \n");
254
- issueBody += "The following dependencies are either deprecated or have replacements available.\n\n";
254
+ issueBody += "> The following dependencies are either deprecated or have replacements available.\n\n";
255
255
  issueBody += "| Datasource | Package | Replacement PR? |\n";
256
256
  issueBody += "|------------|------|--------------|\n";
257
257
  for (const manager of Object.keys(deprecatedPackages).sort()) {
@@ -342,7 +342,7 @@ function getAbandonedPackagesMd(config, packageFiles) {
342
342
  let abandonedMd = "## Abandoned Dependencies\n\n";
343
343
  abandonedMd += "The following dependencies have not received updates for an extended period and may be unmaintained.\n\n";
344
344
  abandonedMd += emojify("> :information_source: **Note**\n> \n");
345
- abandonedMd += `Packages are marked as abandoned when they exceed the [\`abandonmentThreshold\`](${GlobalConfig.get("productLinks").documentation}configuration-options/#abandonmentthreshold) since their last release. `;
345
+ abandonedMd += `> Packages are marked as abandoned when they exceed the [\`abandonmentThreshold\`](${GlobalConfig.get("productLinks").documentation}configuration-options/#abandonmentthreshold) since their last release. `;
346
346
  abandonedMd += "Unlike deprecated packages with official notices, abandonment is detected by release inactivity.\n> \n";
347
347
  abandonedMd += "<details>\n";
348
348
  abandonedMd += `<summary>View abandoned dependencies (${abandonedCount})</summary>\n\n`;
@@ -1 +1 @@
1
- {"version":3,"file":"dependency-dashboard.js","names":["template.compile"],"sources":["../../../lib/workers/repository/dependency-dashboard.ts"],"sourcesContent":["import {\n isNonEmptyArray,\n isNonEmptyObject,\n isNonEmptyString,\n isNullOrUndefined,\n isTruthy,\n} from '@sindresorhus/is';\nimport { DateTime } from 'luxon';\nimport { GlobalConfig } from '../../config/global.ts';\nimport type { RenovateConfig } from '../../config/types.ts';\nimport { logger } from '../../logger/index.ts';\nimport type { PackageFile } from '../../modules/manager/types.ts';\nimport { platform } from '../../modules/platform/index.ts';\nimport { coerceArray } from '../../util/array.ts';\nimport { emojify } from '../../util/emoji.ts';\nimport { regEx } from '../../util/regex.ts';\nimport { coerceString } from '../../util/string.ts';\nimport * as template from '../../util/template/index.ts';\nimport type { BranchConfig, SelectAllConfig } from '../types.ts';\nimport { extractRepoProblems, replacementAlreadyExists } from './common.ts';\nimport type { ConfigMigrationResult } from './config-migration/index.ts';\nimport { getDepWarningsDashboard } from './errors-warnings.ts';\nimport { PackageFiles } from './package-files.ts';\nimport type { Vulnerability } from './process/types.ts';\nimport { Vulnerabilities } from './process/vulnerabilities.ts';\nimport type {\n DependencyDashboardCheck,\n DependencyDashboardListItemType,\n} from './types.ts';\n\ninterface DependencyDashboard {\n dependencyDashboardChecks: Record<string, string>;\n dependencyDashboardRebaseAllOpen: boolean;\n dependencyDashboardAllPending: boolean;\n dependencyDashboardAllRateLimited: boolean;\n dependencyDashboardAllAwaitingSchedule: boolean;\n}\n\nconst rateLimitedRe = regEx(\n ` - \\\\[ \\\\] ${getMarkdownComment('unlimit-branch=([^\\\\s]+)')}`,\n 'g',\n);\nconst pendingApprovalRe = regEx(\n ` - \\\\[ \\\\] ${getMarkdownComment('approve-branch=([^\\\\s]+)')}`,\n 'g',\n);\nconst awaitingScheduleRe = regEx(\n ` - \\\\[ \\\\] ${getMarkdownComment('unschedule-branch=([^\\\\s]+)')}`,\n 'g',\n);\nconst generalBranchRe = regEx(\n ` ${getMarkdownComment('([a-zA-Z]+)-branch=([^\\\\s]+)')}`,\n);\nconst markedBranchesRe = regEx(\n ` - \\\\[x\\\\] ${getMarkdownComment('([a-zA-Z]+)-branch=([^\\\\s]+)')}`,\n 'g',\n);\n\nconst approveAllPendingPrs = 'approve-all-pending-prs';\nconst createAllRateLimitedPrs = 'create-all-rate-limited-prs';\nconst createAllAwaitingSchedulePrs = 'create-all-awaiting-schedule-prs';\nconst createConfigMigrationPr = 'create-config-migration-pr';\nconst configMigrationPrInfo = 'config-migration-pr-info';\nconst rebaseAllOpenPrs = 'rebase-all-open-prs';\n\nfunction getMarkdownComment(comment: string): string {\n return `<!-- ${comment} -->`;\n}\n\nfunction isBoxChecked(issueBody: string, type: string): boolean {\n return issueBody.includes(getCheckbox(type, true));\n}\n\nfunction isBoxUnchecked(issueBody: string, type: string): boolean {\n return issueBody.includes(getCheckbox(type));\n}\n\nfunction getCheckbox(type: string, checked = false): string {\n return ` - [${checked ? 'x' : ' '}] ${getMarkdownComment(type)}`;\n}\n\nfunction checkOpenAllRateLimitedPR(issueBody: string): boolean {\n return isBoxChecked(issueBody, createAllRateLimitedPrs);\n}\n\nfunction checkOpenAllAwaitingSchedulePR(issueBody: string): boolean {\n return isBoxChecked(issueBody, createAllAwaitingSchedulePrs);\n}\n\nfunction checkApproveAllPendingPR(issueBody: string): boolean {\n return isBoxChecked(issueBody, approveAllPendingPrs);\n}\n\nfunction checkRebaseAll(issueBody: string): boolean {\n return isBoxChecked(issueBody, rebaseAllOpenPrs);\n}\n\nfunction getConfigMigrationCheckboxState(\n issueBody: string,\n): 'no-checkbox' | 'checked' | 'unchecked' | 'migration-pr-exists' {\n if (issueBody.includes(getMarkdownComment(configMigrationPrInfo))) {\n return 'migration-pr-exists';\n }\n\n if (isBoxChecked(issueBody, createConfigMigrationPr)) {\n return 'checked';\n }\n\n if (isBoxUnchecked(issueBody, createConfigMigrationPr)) {\n return 'unchecked';\n }\n\n return 'no-checkbox';\n}\n\nfunction selectAllRelevantBranches(issueBody: string): string[] {\n const checkedBranches = [];\n if (checkOpenAllRateLimitedPR(issueBody)) {\n for (const match of issueBody.matchAll(rateLimitedRe)) {\n checkedBranches.push(match[0]);\n }\n }\n if (checkOpenAllAwaitingSchedulePR(issueBody)) {\n for (const match of issueBody.matchAll(awaitingScheduleRe)) {\n checkedBranches.push(match[0]);\n }\n }\n if (checkApproveAllPendingPR(issueBody)) {\n for (const match of issueBody.matchAll(pendingApprovalRe)) {\n checkedBranches.push(match[0]);\n }\n }\n return checkedBranches;\n}\n\nfunction getAllSelectedBranches(\n issueBody: string,\n dependencyDashboardChecks: Record<string, string>,\n): Record<string, string> {\n const allRelevantBranches = selectAllRelevantBranches(issueBody);\n for (const branch of allRelevantBranches) {\n const [, type, branchName] = generalBranchRe.exec(branch)!;\n dependencyDashboardChecks[branchName] = type;\n }\n return dependencyDashboardChecks;\n}\n\nfunction getCheckedBranches(issueBody: string): Record<string, string> {\n let dependencyDashboardChecks: Record<string, string> = {};\n for (const [, type, branchName] of issueBody.matchAll(markedBranchesRe)) {\n dependencyDashboardChecks[branchName] = type;\n }\n dependencyDashboardChecks = getAllSelectedBranches(\n issueBody,\n dependencyDashboardChecks,\n );\n return dependencyDashboardChecks;\n}\n\nfunction parseDashboardIssue(issueBody: string): DependencyDashboard {\n const dependencyDashboardChecks = getCheckedBranches(issueBody);\n const dependencyDashboardRebaseAllOpen = checkRebaseAll(issueBody);\n const dependencyDashboardAllAwaitingSchedule =\n checkOpenAllAwaitingSchedulePR(issueBody);\n const dependencyDashboardAllPending = checkApproveAllPendingPR(issueBody);\n const dependencyDashboardAllRateLimited =\n checkOpenAllRateLimitedPR(issueBody);\n dependencyDashboardChecks.configMigrationCheckboxState =\n getConfigMigrationCheckboxState(issueBody);\n return {\n dependencyDashboardChecks,\n dependencyDashboardRebaseAllOpen,\n dependencyDashboardAllAwaitingSchedule,\n dependencyDashboardAllPending,\n dependencyDashboardAllRateLimited,\n };\n}\n\nexport async function readDashboardBody(\n config: SelectAllConfig,\n): Promise<void> {\n let dashboardChecks: DependencyDashboard = {\n dependencyDashboardChecks: {},\n dependencyDashboardRebaseAllOpen: false,\n dependencyDashboardAllAwaitingSchedule: false,\n dependencyDashboardAllPending: false,\n dependencyDashboardAllRateLimited: false,\n };\n const stringifiedConfig = JSON.stringify(config);\n if (\n config.dependencyDashboard === true ||\n stringifiedConfig.includes('\"dependencyDashboardApproval\":true') ||\n stringifiedConfig.includes('\"prCreation\":\"approval\"')\n ) {\n config.dependencyDashboardTitle =\n config.dependencyDashboardTitle ?? `Dependency Dashboard`;\n const issue = await platform.findIssue(config.dependencyDashboardTitle);\n if (issue) {\n config.dependencyDashboardIssue = issue.number;\n dashboardChecks = parseDashboardIssue(issue.body ?? '');\n }\n }\n\n const checkedBranches = GlobalConfig.get('checkedBranches');\n if (isNonEmptyArray(checkedBranches)) {\n const checkedBranchesRec: Record<string, DependencyDashboardCheck> =\n Object.fromEntries(\n checkedBranches.map((branchName) => [branchName, 'global-config']),\n );\n dashboardChecks.dependencyDashboardChecks = {\n ...dashboardChecks.dependencyDashboardChecks,\n ...checkedBranchesRec,\n };\n }\n\n if (GlobalConfig.get('rebaseAllOpenBranches')) {\n dashboardChecks.dependencyDashboardRebaseAllOpen = true;\n }\n\n Object.assign(config, dashboardChecks);\n}\n\nfunction formatAsMarkdownLink(name: string, url?: string | null): string {\n return url ? `[${name}](${url})` : `\\`${name}\\``;\n}\n\nfunction getListItem(\n branch: BranchConfig,\n type: DependencyDashboardListItemType,\n): string {\n let item = getCheckbox(`${type}-branch=${branch.branchName}`);\n if (branch.prNo) {\n // TODO: types (#22198)\n item += `[${branch.prTitle!}](../pull/${branch.prNo})`;\n } else {\n item += branch.prTitle;\n }\n const uniquePackages = [\n // TODO: types (#22198)\n ...new Set(branch.upgrades.map((upgrade) => `\\`${upgrade.depName!}\\``)),\n ];\n if (uniquePackages.length < 2) {\n return `${item}\\n`;\n }\n return `${item} (${uniquePackages.join(', ')})\\n`;\n}\n\nfunction splitBranchesByCategory(filteredBranches: BranchConfig[]): {\n categories: Record<string, BranchConfig[]>;\n uncategorized: BranchConfig[];\n hasCategorized: boolean;\n hasUncategorized: boolean;\n} {\n const categories: Record<string, BranchConfig[]> = {};\n const uncategorized: BranchConfig[] = [];\n let hasCategorized = false;\n let hasUncategorized = false;\n for (const branch of filteredBranches) {\n if (branch.dependencyDashboardCategory) {\n categories[branch.dependencyDashboardCategory] ??= [];\n categories[branch.dependencyDashboardCategory].push(branch);\n hasCategorized = true;\n continue;\n }\n uncategorized.push(branch);\n hasUncategorized = true;\n }\n return { categories, uncategorized, hasCategorized, hasUncategorized };\n}\n\nfunction getBranchList(\n branches: BranchConfig[],\n listItemType: DependencyDashboardListItemType,\n): string {\n return branches\n .map((branch: BranchConfig): string => getListItem(branch, listItemType))\n .join('');\n}\n\nfunction getBranchesListMd(\n branches: BranchConfig[],\n predicate: (\n value: BranchConfig,\n index: number,\n array: BranchConfig[],\n ) => unknown,\n title: string,\n description: string,\n listItemType: DependencyDashboardListItemType = 'approvePr',\n bulkComment?: string,\n bulkMessage?: string,\n bulkIcon?: '🔐',\n): string {\n const filteredBranches = branches.filter(predicate);\n if (filteredBranches.length === 0) {\n return '';\n }\n let result = `## ${title}\\n\\n${description}\\n\\n`;\n const { categories, uncategorized, hasCategorized, hasUncategorized } =\n splitBranchesByCategory(filteredBranches);\n if (hasCategorized) {\n for (const [category, branches] of Object.entries(categories).sort(\n ([keyA], [keyB]) =>\n keyA.localeCompare(keyB, undefined, { numeric: true }),\n )) {\n result = `${result.trimEnd()}\\n\\n`;\n result += `### ${category}\\n\\n`;\n result += getBranchList(branches, listItemType);\n }\n if (hasUncategorized) {\n result = `${result.trimEnd()}\\n\\n`;\n result += `### Others`;\n }\n }\n result = `${result.trimEnd()}\\n\\n`;\n result += getBranchList(uncategorized, listItemType);\n\n if (bulkComment && bulkMessage && filteredBranches.length > 1) {\n if (hasCategorized) {\n result = `${result.trimEnd()}\\n\\n`;\n result += '### All\\n\\n';\n }\n result += getCheckbox(bulkComment);\n result += `${bulkIcon ? `${bulkIcon} ` : ''}**${bulkMessage}**${bulkIcon ? ` ${bulkIcon}` : ''}`;\n }\n return `${result.trimEnd()}\\n\\n`;\n}\n\nfunction appendRepoProblems(config: RenovateConfig, issueBody: string): string {\n let newIssueBody = issueBody;\n const repoProblems = extractRepoProblems(config.repository);\n if (repoProblems.size) {\n newIssueBody += '## Repository Problems\\n\\n';\n const repoProblemsHeader =\n config.customizeDashboard?.repoProblemsHeader ??\n 'Renovate tried to run on this repository, but found these problems.';\n newIssueBody += `${template.compile(repoProblemsHeader, config)}\\n\\n`;\n\n for (const repoProblem of repoProblems) {\n newIssueBody += ` - ${repoProblem}\\n`;\n }\n newIssueBody += '\\n';\n }\n return newIssueBody;\n}\n\nexport async function ensureDependencyDashboard(\n config: SelectAllConfig,\n allBranches: BranchConfig[],\n packageFiles: Record<string, PackageFile[]> = {},\n configMigrationRes: ConfigMigrationResult,\n): Promise<void> {\n logger.debug('ensureDependencyDashboard()');\n if (config.mode === 'silent') {\n logger.debug(\n 'Dependency Dashboard issue is not created, updated or closed when mode=silent',\n );\n return;\n }\n // legacy/migrated issue\n const reuseTitle = 'Update Dependencies (Renovate Bot)';\n const branches = allBranches.filter(\n (branch) =>\n branch.result !== 'automerged' &&\n !branch.upgrades?.every((upgrade) => upgrade.remediationNotPossible),\n );\n if (!(\n config.dependencyDashboard === true ||\n config.dependencyDashboardApproval === true ||\n config.packageRules?.some((rule) => rule.dependencyDashboardApproval) ===\n true ||\n branches.some(\n (branch) =>\n !!branch.dependencyDashboardApproval ||\n !!branch.dependencyDashboardPrApproval,\n )\n )) {\n if (GlobalConfig.get('dryRun')) {\n logger.info(\n { title: config.dependencyDashboardTitle },\n 'DRY-RUN: Would close Dependency Dashboard',\n );\n } else {\n logger.debug('Closing Dependency Dashboard');\n await platform.ensureIssueClosing(config.dependencyDashboardTitle!);\n }\n return;\n }\n // istanbul ignore if\n if (config.repoIsOnboarded === false) {\n logger.debug('Repo is onboarding - skipping dependency dashboard');\n return;\n }\n logger.debug('Ensuring Dependency Dashboard');\n\n // Check packageFiles for any deprecations or replacements\n let hasDeprecationsOrReplacements = false;\n const deprecatedPackages: Record<\n string,\n Record<\n string,\n { hasActionableReplacement: boolean; sourceUrl?: string | null }\n >\n > = {};\n logger.debug('Checking packageFiles for deprecated or replacement packages');\n if (isNonEmptyObject(packageFiles)) {\n for (const [manager, fileNames] of Object.entries(packageFiles)) {\n for (const fileName of fileNames) {\n for (const dep of fileName.deps) {\n const name = dep.packageName;\n const replacementUpdate = dep.updates?.find(\n (update) => update.updateType === 'replacement',\n );\n const hasAnyReplacement = !!replacementUpdate;\n const hasActionableReplacement =\n hasAnyReplacement &&\n !(\n replacementUpdate.newName &&\n replacementAlreadyExists(\n fileName.deps,\n dep,\n replacementUpdate.newName,\n )\n );\n if (name && (dep.deprecationMessage ?? hasAnyReplacement)) {\n hasDeprecationsOrReplacements = true;\n deprecatedPackages[manager] ??= {};\n deprecatedPackages[manager][name] ??= {\n hasActionableReplacement,\n sourceUrl: dep.sourceUrl,\n };\n }\n }\n }\n }\n }\n\n const hasBranches = isNonEmptyArray(branches);\n if (\n config.dependencyDashboardAutoclose &&\n !hasBranches &&\n !hasDeprecationsOrReplacements\n ) {\n if (GlobalConfig.get('dryRun')) {\n logger.info(\n { title: config.dependencyDashboardTitle },\n 'DRY-RUN: Would close Dependency Dashboard',\n );\n } else {\n logger.debug('Closing Dependency Dashboard');\n await platform.ensureIssueClosing(config.dependencyDashboardTitle!);\n }\n return;\n }\n let issueBody = '';\n\n if (config.dependencyDashboardHeader?.length) {\n issueBody += `${template.compile(config.dependencyDashboardHeader, config)}\\n\\n`;\n }\n\n if (configMigrationRes.result === 'pr-exists') {\n issueBody += `## Config Migration Needed\\n\\n${getMarkdownComment(configMigrationPrInfo)} See Config Migration PR: #${configMigrationRes.prNumber}.\\n\\n`;\n } else if (configMigrationRes?.result === 'pr-modified') {\n issueBody += `## Config Migration Needed (Blocked)\\n\\n${getMarkdownComment(configMigrationPrInfo)} The Config Migration branch exists but has been modified by another user. Renovate will not push to this branch unless it is first deleted. \\n\\n See Config Migration PR: #${configMigrationRes.prNumber}.\\n\\n`;\n } else if (configMigrationRes?.result === 'add-checkbox') {\n issueBody += `## Config Migration Needed\\n\\n${getCheckbox(createConfigMigrationPr)} Select this checkbox to let Renovate create an automated Config Migration PR.\\n\\n`;\n }\n\n issueBody = appendRepoProblems(config, issueBody);\n\n if (hasDeprecationsOrReplacements) {\n issueBody += '## Deprecations / Replacements\\n';\n issueBody += emojify('> :warning: **Warning**\\n> \\n');\n issueBody +=\n 'The following dependencies are either deprecated or have replacements available.\\n\\n';\n issueBody += '| Datasource | Package | Replacement PR? |\\n';\n issueBody += '|------------|------|--------------|\\n';\n for (const manager of Object.keys(deprecatedPackages).sort()) {\n const deps = deprecatedPackages[manager];\n for (const depName of Object.keys(deps).sort()) {\n const { hasActionableReplacement, sourceUrl } = deps[depName];\n const packageName = formatAsMarkdownLink(depName, sourceUrl);\n\n issueBody += `| ${manager} | ${packageName} | ${\n hasActionableReplacement\n ? '![Available](https://img.shields.io/badge/available-green?style=flat-square)'\n : '![Unavailable](https://img.shields.io/badge/unavailable-orange?style=flat-square)'\n } |\\n`;\n }\n }\n issueBody += '\\n';\n }\n\n if (config.dependencyDashboardReportAbandonment) {\n issueBody += getAbandonedPackagesMd(config, packageFiles);\n }\n\n issueBody += getBranchesListMd(\n branches,\n (branch) => branch.result === 'needs-approval',\n 'Pending Approval',\n 'The following branches are pending approval. To create them, click on a checkbox below.',\n 'approve',\n approveAllPendingPrs,\n 'Create all pending approval PRs at once',\n '🔐',\n );\n issueBody += getBranchesListMd(\n branches,\n (branch) => branch.result === 'minimum-group-size-not-met',\n 'Group Size Not Met',\n 'The following branches have not met their minimum group size. To create them, click on a checkbox below.',\n 'approveGroup',\n );\n issueBody += getBranchesListMd(\n branches,\n (branch) => branch.result === 'not-scheduled',\n 'Awaiting Schedule',\n 'The following updates are awaiting their schedule. To get an update now, click on a checkbox below.',\n 'unschedule',\n createAllAwaitingSchedulePrs,\n 'Create all awaiting schedule PRs at once',\n '🔐',\n );\n issueBody += getBranchesListMd(\n branches,\n (branch) =>\n branch.result === 'branch-limit-reached' ||\n branch.result === 'pr-limit-reached' ||\n branch.result === 'commit-per-run-limit-reached' ||\n branch.result === 'commit-hourly-limit-reached',\n 'Rate-Limited',\n 'The following updates are currently rate-limited. To force their creation now, click on a checkbox below.',\n 'unlimit',\n createAllRateLimitedPrs,\n 'Create all rate-limited PRs at once',\n '🔐',\n );\n issueBody += getBranchesListMd(\n branches,\n (branch) => branch.result === 'error',\n 'Errored',\n 'The following updates encountered an error and will be retried. To force a retry now, click on a checkbox below.',\n 'retry',\n );\n issueBody += getBranchesListMd(\n branches,\n (branch) => branch.result === 'needs-pr-approval',\n 'PR Creation Approval Required',\n 'The following branches exist but PR creation requires approval. To approve PR creation, click on a checkbox below.',\n );\n issueBody += getBranchesListMd(\n branches,\n (branch) => branch.result === 'pr-edited',\n 'PR Edited (Blocked)',\n 'The following updates have been manually edited so Renovate will no longer make changes. To discard all commits and start over, click on a checkbox below.',\n 'rebase',\n );\n issueBody += getBranchesListMd(\n branches,\n (branch) => branch.result === 'pending',\n 'Pending Status Checks',\n 'The following updates await pending status checks. To force their creation now, click on a checkbox below.',\n 'unpend',\n );\n issueBody += getBranchesListMd(\n branches,\n (branch) => branch.prBlockedBy === 'BranchAutomerge',\n 'Pending Branch Automerge',\n 'The following updates await pending status checks before automerging. To abort the branch automerge and create a PR instead, click on a checkbox below.',\n );\n\n const warn = getDepWarningsDashboard(packageFiles, config);\n if (warn) {\n issueBody += warn;\n issueBody += '\\n';\n }\n\n const otherRes = [\n 'pending',\n 'needs-approval',\n 'needs-pr-approval',\n 'not-scheduled',\n 'pr-limit-reached',\n 'commit-per-run-limit-reached',\n 'commit-hourly-limit-reached',\n 'branch-limit-reached',\n 'already-existed',\n 'error',\n 'automerged',\n 'pr-edited',\n 'minimum-group-size-not-met',\n ];\n const inProgress = branches.filter(\n (branch) =>\n !otherRes.includes(branch.result!) &&\n branch.prBlockedBy !== 'BranchAutomerge',\n );\n issueBody += getBranchesListMd(\n inProgress,\n (branch) => !!branch.prBlockedBy || !branch.prNo,\n 'Other Branches',\n 'The following updates are pending. To force the creation of a PR, click on a checkbox below.',\n 'other',\n );\n issueBody += getBranchesListMd(\n inProgress,\n (branch) => branch.prNo && !branch.prBlockedBy,\n 'Open',\n 'The following updates have all been created. To force a retry/rebase of any, click on a checkbox below.',\n 'rebase',\n rebaseAllOpenPrs,\n 'Click on this checkbox to rebase all open PRs at once',\n );\n\n issueBody += getBranchesListMd(\n branches,\n (branch) => branch.result === 'already-existed',\n 'PR Closed (Blocked)',\n 'The following updates are blocked by an existing closed PR. To recreate the PR, click on a checkbox below.',\n 'recreate',\n );\n\n if (!hasBranches) {\n issueBody +=\n 'This repository currently has no open or pending branches.\\n\\n';\n }\n\n // add CVE section\n issueBody += await getDashboardMarkdownVulnerabilities(config, packageFiles);\n\n // fit the detected dependencies section\n const footer = getFooter(config);\n issueBody += PackageFiles.getDashboardMarkdown(\n platform.maxBodyLength() - issueBody.length - footer.length,\n );\n\n issueBody += footer;\n\n if (config.dependencyDashboardIssue) {\n // If we're not changing the dashboard issue, then we can skip checking if the user changed it.\n // The cached issue we get back here will reflect its state at the _start_ of our run\n const cachedIssue = await platform.getIssue?.(\n config.dependencyDashboardIssue,\n );\n if (cachedIssue?.body === issueBody) {\n logger.debug('No changes to dependency dashboard issue needed');\n return;\n }\n\n // Skip cache when getting the issue to ensure we get the latest body,\n // including any updates the user made after we started the run\n const updatedIssue = await platform.getIssue?.(\n config.dependencyDashboardIssue,\n false,\n );\n if (updatedIssue) {\n const { dependencyDashboardChecks } = parseDashboardIssue(\n coerceString(updatedIssue.body),\n );\n for (const branchName of Object.keys(config.dependencyDashboardChecks!)) {\n delete dependencyDashboardChecks[branchName];\n }\n for (const branchName of Object.keys(dependencyDashboardChecks)) {\n const checkText = getCheckbox(\n `${dependencyDashboardChecks[branchName]}-branch=${branchName}`,\n );\n issueBody = issueBody.replace(\n checkText,\n checkText.replace('[ ]', '[x]'),\n );\n }\n }\n }\n\n if (GlobalConfig.get('dryRun')) {\n logger.info(\n { title: config.dependencyDashboardTitle },\n 'DRY-RUN: Would ensure Dependency Dashboard',\n );\n } else {\n await platform.ensureIssue({\n title: config.dependencyDashboardTitle!,\n reuseTitle,\n body: platform.massageMarkdown(issueBody, config.rebaseLabel),\n labels: config.dependencyDashboardLabels,\n confidential: config.confidential,\n });\n }\n}\n\nexport function getAbandonedPackagesMd(\n config: RenovateConfig,\n packageFiles: Record<string, PackageFile[]>,\n): string {\n const abandonedPackages: Record<\n string,\n Record<\n string,\n { mostRecentTimestamp?: string | null; sourceUrl?: string | null }\n >\n > = {};\n let abandonedCount = 0;\n\n for (const [manager, managerPackageFiles] of Object.entries(packageFiles)) {\n for (const packageFile of managerPackageFiles) {\n for (const dep of coerceArray(packageFile.deps)) {\n if (dep.depName && dep.isAbandoned) {\n abandonedCount++;\n abandonedPackages[manager] = abandonedPackages[manager] || {};\n abandonedPackages[manager][dep.depName] = {\n mostRecentTimestamp: dep.mostRecentTimestamp,\n sourceUrl: dep.sourceUrl,\n };\n }\n }\n }\n }\n\n if (abandonedCount === 0) {\n return '';\n }\n\n let abandonedMd = '## Abandoned Dependencies\\n\\n';\n abandonedMd +=\n 'The following dependencies have not received updates for an extended period and may be unmaintained.\\n\\n';\n\n // Keep the note outside the `<details>` block: GitHub only renders alert\n // callouts at the top level of a body, not inside collapsible sections.\n abandonedMd += emojify('> :information_source: **Note**\\n> \\n');\n abandonedMd += `Packages are marked as abandoned when they exceed the [\\`abandonmentThreshold\\`](${GlobalConfig.get('productLinks').documentation}configuration-options/#abandonmentthreshold) since their last release. `;\n abandonedMd +=\n 'Unlike deprecated packages with official notices, abandonment is detected by release inactivity.\\n> \\n';\n\n abandonedMd += '<details>\\n';\n abandonedMd += `<summary>View abandoned dependencies (${abandonedCount})</summary>\\n\\n`;\n\n abandonedMd += '| Datasource | Package | Last Updated |\\n';\n abandonedMd += '|------------|------|-------------|\\n';\n\n for (const manager of Object.keys(abandonedPackages).sort()) {\n const deps = abandonedPackages[manager];\n for (const depName of Object.keys(deps).sort()) {\n const { mostRecentTimestamp, sourceUrl } = deps[depName];\n const formattedDate = mostRecentTimestamp\n ? DateTime.fromISO(mostRecentTimestamp).toFormat('yyyy-MM-dd')\n : 'unknown';\n const packageName = formatAsMarkdownLink(depName, sourceUrl);\n abandonedMd += `| ${manager} | ${packageName} | \\`${formattedDate}\\` |\\n`;\n }\n }\n\n abandonedMd += '\\n</details>\\n\\n\\n';\n\n return abandonedMd;\n}\n\nfunction getFooter(config: RenovateConfig): string {\n let footer = '';\n if (config.dependencyDashboardFooter?.length) {\n footer += `---\\n${template.compile(config.dependencyDashboardFooter, config)}\\n`;\n }\n\n return footer;\n}\n\nexport async function getDashboardMarkdownVulnerabilities(\n config: RenovateConfig,\n packageFiles: Record<string, PackageFile[]>,\n): Promise<string> {\n let result = '';\n\n if (\n isNullOrUndefined(config.dependencyDashboardOSVVulnerabilitySummary) ||\n config.dependencyDashboardOSVVulnerabilitySummary === 'none'\n ) {\n return result;\n }\n\n result += '## Vulnerabilities\\n\\n';\n\n let vulnerabilities: Vulnerability[];\n try {\n const vulnerabilityFetcher = await Vulnerabilities.create();\n vulnerabilities = await vulnerabilityFetcher.fetchVulnerabilities(\n config,\n packageFiles,\n );\n } catch (err) {\n logger.warn({ err }, 'Unable to read vulnerability information');\n result +=\n 'Renovate was unable to fetch CVE information from [osv.dev](https://osv.dev) this run.\\n\\n';\n return result;\n }\n\n if (vulnerabilities.length === 0) {\n result +=\n 'Renovate has not found any CVEs on [osv.dev](https://osv.dev).\\n\\n';\n return result;\n }\n\n const unresolvedVulnerabilities = vulnerabilities.filter((value) =>\n isNullOrUndefined(value.fixedVersion),\n );\n const resolvedVulnerabilitiesLength =\n vulnerabilities.length - unresolvedVulnerabilities.length;\n\n result += emojify('> :exclamation: **Important**\\n> \\n');\n result += `> \\`${resolvedVulnerabilitiesLength}\\`/\\`${vulnerabilities.length}\\``;\n if (isTruthy(config.osvVulnerabilityAlerts)) {\n result += ' CVEs have Renovate fixes.\\n\\n';\n } else {\n result += ` CVEs have possible Renovate fixes.\\n> See [\\`osvVulnerabilityAlerts\\`](${GlobalConfig.get('productLinks').documentation}configuration-options/#osvvulnerabilityalerts) to allow Renovate to supply fixes.\\n\\n`;\n }\n\n let renderedVulnerabilities: Vulnerability[];\n switch (config.dependencyDashboardOSVVulnerabilitySummary) {\n // filter vulnerabilities to display based on configuration\n case 'unresolved':\n renderedVulnerabilities = unresolvedVulnerabilities;\n break;\n default:\n renderedVulnerabilities = vulnerabilities;\n }\n\n const managerRecords: Record<\n string,\n Record<string, Record<string, Vulnerability[]>>\n > = {};\n for (const vulnerability of renderedVulnerabilities) {\n const { manager, packageFile } = vulnerability.packageFileConfig;\n if (isNullOrUndefined(managerRecords[manager!])) {\n managerRecords[manager!] = {};\n }\n if (isNullOrUndefined(managerRecords[manager!][packageFile])) {\n managerRecords[manager!][packageFile] = {};\n }\n if (\n isNullOrUndefined(\n managerRecords[manager!][packageFile][vulnerability.packageName],\n )\n ) {\n managerRecords[manager!][packageFile][vulnerability.packageName] = [];\n }\n managerRecords[manager!][packageFile][vulnerability.packageName].push(\n vulnerability,\n );\n }\n\n for (const [manager, packageFileRecords] of Object.entries(managerRecords)) {\n result += `<details><summary>${manager}</summary>\\n<blockquote>\\n\\n`;\n for (const [packageFile, packageNameRecords] of Object.entries(\n packageFileRecords,\n )) {\n result += `<details><summary>${packageFile}</summary>\\n<blockquote>\\n\\n`;\n for (const [packageName, cves] of Object.entries(packageNameRecords)) {\n result += `<details><summary>${packageName}</summary>\\n<blockquote>\\n\\n`;\n for (const vul of cves) {\n const id = vul.vulnerability.id;\n const suffix = isNonEmptyString(vul.fixedVersion)\n ? ` (fixed in ${vul.fixedVersion})`\n : '';\n result += `- [${id}](https://osv.dev/vulnerability/${id})${suffix}\\n`;\n }\n result += `</blockquote>\\n</details>\\n\\n`;\n }\n result += `</blockquote>\\n</details>\\n\\n`;\n }\n result += `</blockquote>\\n</details>\\n\\n`;\n }\n\n return result;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"dependency-dashboard.js","names":["template.compile"],"sources":["../../../lib/workers/repository/dependency-dashboard.ts"],"sourcesContent":["import {\n isNonEmptyArray,\n isNonEmptyObject,\n isNonEmptyString,\n isNullOrUndefined,\n isTruthy,\n} from '@sindresorhus/is';\nimport { DateTime } from 'luxon';\nimport { GlobalConfig } from '../../config/global.ts';\nimport type { RenovateConfig } from '../../config/types.ts';\nimport { logger } from '../../logger/index.ts';\nimport type { PackageFile } from '../../modules/manager/types.ts';\nimport { platform } from '../../modules/platform/index.ts';\nimport { coerceArray } from '../../util/array.ts';\nimport { emojify } from '../../util/emoji.ts';\nimport { regEx } from '../../util/regex.ts';\nimport { coerceString } from '../../util/string.ts';\nimport * as template from '../../util/template/index.ts';\nimport type { BranchConfig, SelectAllConfig } from '../types.ts';\nimport { extractRepoProblems, replacementAlreadyExists } from './common.ts';\nimport type { ConfigMigrationResult } from './config-migration/index.ts';\nimport { getDepWarningsDashboard } from './errors-warnings.ts';\nimport { PackageFiles } from './package-files.ts';\nimport type { Vulnerability } from './process/types.ts';\nimport { Vulnerabilities } from './process/vulnerabilities.ts';\nimport type {\n DependencyDashboardCheck,\n DependencyDashboardListItemType,\n} from './types.ts';\n\ninterface DependencyDashboard {\n dependencyDashboardChecks: Record<string, string>;\n dependencyDashboardRebaseAllOpen: boolean;\n dependencyDashboardAllPending: boolean;\n dependencyDashboardAllRateLimited: boolean;\n dependencyDashboardAllAwaitingSchedule: boolean;\n}\n\nconst rateLimitedRe = regEx(\n ` - \\\\[ \\\\] ${getMarkdownComment('unlimit-branch=([^\\\\s]+)')}`,\n 'g',\n);\nconst pendingApprovalRe = regEx(\n ` - \\\\[ \\\\] ${getMarkdownComment('approve-branch=([^\\\\s]+)')}`,\n 'g',\n);\nconst awaitingScheduleRe = regEx(\n ` - \\\\[ \\\\] ${getMarkdownComment('unschedule-branch=([^\\\\s]+)')}`,\n 'g',\n);\nconst generalBranchRe = regEx(\n ` ${getMarkdownComment('([a-zA-Z]+)-branch=([^\\\\s]+)')}`,\n);\nconst markedBranchesRe = regEx(\n ` - \\\\[x\\\\] ${getMarkdownComment('([a-zA-Z]+)-branch=([^\\\\s]+)')}`,\n 'g',\n);\n\nconst approveAllPendingPrs = 'approve-all-pending-prs';\nconst createAllRateLimitedPrs = 'create-all-rate-limited-prs';\nconst createAllAwaitingSchedulePrs = 'create-all-awaiting-schedule-prs';\nconst createConfigMigrationPr = 'create-config-migration-pr';\nconst configMigrationPrInfo = 'config-migration-pr-info';\nconst rebaseAllOpenPrs = 'rebase-all-open-prs';\n\nfunction getMarkdownComment(comment: string): string {\n return `<!-- ${comment} -->`;\n}\n\nfunction isBoxChecked(issueBody: string, type: string): boolean {\n return issueBody.includes(getCheckbox(type, true));\n}\n\nfunction isBoxUnchecked(issueBody: string, type: string): boolean {\n return issueBody.includes(getCheckbox(type));\n}\n\nfunction getCheckbox(type: string, checked = false): string {\n return ` - [${checked ? 'x' : ' '}] ${getMarkdownComment(type)}`;\n}\n\nfunction checkOpenAllRateLimitedPR(issueBody: string): boolean {\n return isBoxChecked(issueBody, createAllRateLimitedPrs);\n}\n\nfunction checkOpenAllAwaitingSchedulePR(issueBody: string): boolean {\n return isBoxChecked(issueBody, createAllAwaitingSchedulePrs);\n}\n\nfunction checkApproveAllPendingPR(issueBody: string): boolean {\n return isBoxChecked(issueBody, approveAllPendingPrs);\n}\n\nfunction checkRebaseAll(issueBody: string): boolean {\n return isBoxChecked(issueBody, rebaseAllOpenPrs);\n}\n\nfunction getConfigMigrationCheckboxState(\n issueBody: string,\n): 'no-checkbox' | 'checked' | 'unchecked' | 'migration-pr-exists' {\n if (issueBody.includes(getMarkdownComment(configMigrationPrInfo))) {\n return 'migration-pr-exists';\n }\n\n if (isBoxChecked(issueBody, createConfigMigrationPr)) {\n return 'checked';\n }\n\n if (isBoxUnchecked(issueBody, createConfigMigrationPr)) {\n return 'unchecked';\n }\n\n return 'no-checkbox';\n}\n\nfunction selectAllRelevantBranches(issueBody: string): string[] {\n const checkedBranches = [];\n if (checkOpenAllRateLimitedPR(issueBody)) {\n for (const match of issueBody.matchAll(rateLimitedRe)) {\n checkedBranches.push(match[0]);\n }\n }\n if (checkOpenAllAwaitingSchedulePR(issueBody)) {\n for (const match of issueBody.matchAll(awaitingScheduleRe)) {\n checkedBranches.push(match[0]);\n }\n }\n if (checkApproveAllPendingPR(issueBody)) {\n for (const match of issueBody.matchAll(pendingApprovalRe)) {\n checkedBranches.push(match[0]);\n }\n }\n return checkedBranches;\n}\n\nfunction getAllSelectedBranches(\n issueBody: string,\n dependencyDashboardChecks: Record<string, string>,\n): Record<string, string> {\n const allRelevantBranches = selectAllRelevantBranches(issueBody);\n for (const branch of allRelevantBranches) {\n const [, type, branchName] = generalBranchRe.exec(branch)!;\n dependencyDashboardChecks[branchName] = type;\n }\n return dependencyDashboardChecks;\n}\n\nfunction getCheckedBranches(issueBody: string): Record<string, string> {\n let dependencyDashboardChecks: Record<string, string> = {};\n for (const [, type, branchName] of issueBody.matchAll(markedBranchesRe)) {\n dependencyDashboardChecks[branchName] = type;\n }\n dependencyDashboardChecks = getAllSelectedBranches(\n issueBody,\n dependencyDashboardChecks,\n );\n return dependencyDashboardChecks;\n}\n\nfunction parseDashboardIssue(issueBody: string): DependencyDashboard {\n const dependencyDashboardChecks = getCheckedBranches(issueBody);\n const dependencyDashboardRebaseAllOpen = checkRebaseAll(issueBody);\n const dependencyDashboardAllAwaitingSchedule =\n checkOpenAllAwaitingSchedulePR(issueBody);\n const dependencyDashboardAllPending = checkApproveAllPendingPR(issueBody);\n const dependencyDashboardAllRateLimited =\n checkOpenAllRateLimitedPR(issueBody);\n dependencyDashboardChecks.configMigrationCheckboxState =\n getConfigMigrationCheckboxState(issueBody);\n return {\n dependencyDashboardChecks,\n dependencyDashboardRebaseAllOpen,\n dependencyDashboardAllAwaitingSchedule,\n dependencyDashboardAllPending,\n dependencyDashboardAllRateLimited,\n };\n}\n\nexport async function readDashboardBody(\n config: SelectAllConfig,\n): Promise<void> {\n let dashboardChecks: DependencyDashboard = {\n dependencyDashboardChecks: {},\n dependencyDashboardRebaseAllOpen: false,\n dependencyDashboardAllAwaitingSchedule: false,\n dependencyDashboardAllPending: false,\n dependencyDashboardAllRateLimited: false,\n };\n const stringifiedConfig = JSON.stringify(config);\n if (\n config.dependencyDashboard === true ||\n stringifiedConfig.includes('\"dependencyDashboardApproval\":true') ||\n stringifiedConfig.includes('\"prCreation\":\"approval\"')\n ) {\n config.dependencyDashboardTitle =\n config.dependencyDashboardTitle ?? `Dependency Dashboard`;\n const issue = await platform.findIssue(config.dependencyDashboardTitle);\n if (issue) {\n config.dependencyDashboardIssue = issue.number;\n dashboardChecks = parseDashboardIssue(issue.body ?? '');\n }\n }\n\n const checkedBranches = GlobalConfig.get('checkedBranches');\n if (isNonEmptyArray(checkedBranches)) {\n const checkedBranchesRec: Record<string, DependencyDashboardCheck> =\n Object.fromEntries(\n checkedBranches.map((branchName) => [branchName, 'global-config']),\n );\n dashboardChecks.dependencyDashboardChecks = {\n ...dashboardChecks.dependencyDashboardChecks,\n ...checkedBranchesRec,\n };\n }\n\n if (GlobalConfig.get('rebaseAllOpenBranches')) {\n dashboardChecks.dependencyDashboardRebaseAllOpen = true;\n }\n\n Object.assign(config, dashboardChecks);\n}\n\nfunction formatAsMarkdownLink(name: string, url?: string | null): string {\n return url ? `[${name}](${url})` : `\\`${name}\\``;\n}\n\nfunction getListItem(\n branch: BranchConfig,\n type: DependencyDashboardListItemType,\n): string {\n let item = getCheckbox(`${type}-branch=${branch.branchName}`);\n if (branch.prNo) {\n // TODO: types (#22198)\n item += `[${branch.prTitle!}](../pull/${branch.prNo})`;\n } else {\n item += branch.prTitle;\n }\n const uniquePackages = [\n // TODO: types (#22198)\n ...new Set(branch.upgrades.map((upgrade) => `\\`${upgrade.depName!}\\``)),\n ];\n if (uniquePackages.length < 2) {\n return `${item}\\n`;\n }\n return `${item} (${uniquePackages.join(', ')})\\n`;\n}\n\nfunction splitBranchesByCategory(filteredBranches: BranchConfig[]): {\n categories: Record<string, BranchConfig[]>;\n uncategorized: BranchConfig[];\n hasCategorized: boolean;\n hasUncategorized: boolean;\n} {\n const categories: Record<string, BranchConfig[]> = {};\n const uncategorized: BranchConfig[] = [];\n let hasCategorized = false;\n let hasUncategorized = false;\n for (const branch of filteredBranches) {\n if (branch.dependencyDashboardCategory) {\n categories[branch.dependencyDashboardCategory] ??= [];\n categories[branch.dependencyDashboardCategory].push(branch);\n hasCategorized = true;\n continue;\n }\n uncategorized.push(branch);\n hasUncategorized = true;\n }\n return { categories, uncategorized, hasCategorized, hasUncategorized };\n}\n\nfunction getBranchList(\n branches: BranchConfig[],\n listItemType: DependencyDashboardListItemType,\n): string {\n return branches\n .map((branch: BranchConfig): string => getListItem(branch, listItemType))\n .join('');\n}\n\nfunction getBranchesListMd(\n branches: BranchConfig[],\n predicate: (\n value: BranchConfig,\n index: number,\n array: BranchConfig[],\n ) => unknown,\n title: string,\n description: string,\n listItemType: DependencyDashboardListItemType = 'approvePr',\n bulkComment?: string,\n bulkMessage?: string,\n bulkIcon?: '🔐',\n): string {\n const filteredBranches = branches.filter(predicate);\n if (filteredBranches.length === 0) {\n return '';\n }\n let result = `## ${title}\\n\\n${description}\\n\\n`;\n const { categories, uncategorized, hasCategorized, hasUncategorized } =\n splitBranchesByCategory(filteredBranches);\n if (hasCategorized) {\n for (const [category, branches] of Object.entries(categories).sort(\n ([keyA], [keyB]) =>\n keyA.localeCompare(keyB, undefined, { numeric: true }),\n )) {\n result = `${result.trimEnd()}\\n\\n`;\n result += `### ${category}\\n\\n`;\n result += getBranchList(branches, listItemType);\n }\n if (hasUncategorized) {\n result = `${result.trimEnd()}\\n\\n`;\n result += `### Others`;\n }\n }\n result = `${result.trimEnd()}\\n\\n`;\n result += getBranchList(uncategorized, listItemType);\n\n if (bulkComment && bulkMessage && filteredBranches.length > 1) {\n if (hasCategorized) {\n result = `${result.trimEnd()}\\n\\n`;\n result += '### All\\n\\n';\n }\n result += getCheckbox(bulkComment);\n result += `${bulkIcon ? `${bulkIcon} ` : ''}**${bulkMessage}**${bulkIcon ? ` ${bulkIcon}` : ''}`;\n }\n return `${result.trimEnd()}\\n\\n`;\n}\n\nfunction appendRepoProblems(config: RenovateConfig, issueBody: string): string {\n let newIssueBody = issueBody;\n const repoProblems = extractRepoProblems(config.repository);\n if (repoProblems.size) {\n newIssueBody += '## Repository Problems\\n\\n';\n const repoProblemsHeader =\n config.customizeDashboard?.repoProblemsHeader ??\n 'Renovate tried to run on this repository, but found these problems.';\n newIssueBody += `${template.compile(repoProblemsHeader, config)}\\n\\n`;\n\n for (const repoProblem of repoProblems) {\n newIssueBody += ` - ${repoProblem}\\n`;\n }\n newIssueBody += '\\n';\n }\n return newIssueBody;\n}\n\nexport async function ensureDependencyDashboard(\n config: SelectAllConfig,\n allBranches: BranchConfig[],\n packageFiles: Record<string, PackageFile[]> = {},\n configMigrationRes: ConfigMigrationResult,\n): Promise<void> {\n logger.debug('ensureDependencyDashboard()');\n if (config.mode === 'silent') {\n logger.debug(\n 'Dependency Dashboard issue is not created, updated or closed when mode=silent',\n );\n return;\n }\n // legacy/migrated issue\n const reuseTitle = 'Update Dependencies (Renovate Bot)';\n const branches = allBranches.filter(\n (branch) =>\n branch.result !== 'automerged' &&\n !branch.upgrades?.every((upgrade) => upgrade.remediationNotPossible),\n );\n if (!(\n config.dependencyDashboard === true ||\n config.dependencyDashboardApproval === true ||\n config.packageRules?.some((rule) => rule.dependencyDashboardApproval) ===\n true ||\n branches.some(\n (branch) =>\n !!branch.dependencyDashboardApproval ||\n !!branch.dependencyDashboardPrApproval,\n )\n )) {\n if (GlobalConfig.get('dryRun')) {\n logger.info(\n { title: config.dependencyDashboardTitle },\n 'DRY-RUN: Would close Dependency Dashboard',\n );\n } else {\n logger.debug('Closing Dependency Dashboard');\n await platform.ensureIssueClosing(config.dependencyDashboardTitle!);\n }\n return;\n }\n // istanbul ignore if\n if (config.repoIsOnboarded === false) {\n logger.debug('Repo is onboarding - skipping dependency dashboard');\n return;\n }\n logger.debug('Ensuring Dependency Dashboard');\n\n // Check packageFiles for any deprecations or replacements\n let hasDeprecationsOrReplacements = false;\n const deprecatedPackages: Record<\n string,\n Record<\n string,\n { hasActionableReplacement: boolean; sourceUrl?: string | null }\n >\n > = {};\n logger.debug('Checking packageFiles for deprecated or replacement packages');\n if (isNonEmptyObject(packageFiles)) {\n for (const [manager, fileNames] of Object.entries(packageFiles)) {\n for (const fileName of fileNames) {\n for (const dep of fileName.deps) {\n const name = dep.packageName;\n const replacementUpdate = dep.updates?.find(\n (update) => update.updateType === 'replacement',\n );\n const hasAnyReplacement = !!replacementUpdate;\n const hasActionableReplacement =\n hasAnyReplacement &&\n !(\n replacementUpdate.newName &&\n replacementAlreadyExists(\n fileName.deps,\n dep,\n replacementUpdate.newName,\n )\n );\n if (name && (dep.deprecationMessage ?? hasAnyReplacement)) {\n hasDeprecationsOrReplacements = true;\n deprecatedPackages[manager] ??= {};\n deprecatedPackages[manager][name] ??= {\n hasActionableReplacement,\n sourceUrl: dep.sourceUrl,\n };\n }\n }\n }\n }\n }\n\n const hasBranches = isNonEmptyArray(branches);\n if (\n config.dependencyDashboardAutoclose &&\n !hasBranches &&\n !hasDeprecationsOrReplacements\n ) {\n if (GlobalConfig.get('dryRun')) {\n logger.info(\n { title: config.dependencyDashboardTitle },\n 'DRY-RUN: Would close Dependency Dashboard',\n );\n } else {\n logger.debug('Closing Dependency Dashboard');\n await platform.ensureIssueClosing(config.dependencyDashboardTitle!);\n }\n return;\n }\n let issueBody = '';\n\n if (config.dependencyDashboardHeader?.length) {\n issueBody += `${template.compile(config.dependencyDashboardHeader, config)}\\n\\n`;\n }\n\n if (configMigrationRes.result === 'pr-exists') {\n issueBody += `## Config Migration Needed\\n\\n${getMarkdownComment(configMigrationPrInfo)} See Config Migration PR: #${configMigrationRes.prNumber}.\\n\\n`;\n } else if (configMigrationRes?.result === 'pr-modified') {\n issueBody += `## Config Migration Needed (Blocked)\\n\\n${getMarkdownComment(configMigrationPrInfo)} The Config Migration branch exists but has been modified by another user. Renovate will not push to this branch unless it is first deleted. \\n\\n See Config Migration PR: #${configMigrationRes.prNumber}.\\n\\n`;\n } else if (configMigrationRes?.result === 'add-checkbox') {\n issueBody += `## Config Migration Needed\\n\\n${getCheckbox(createConfigMigrationPr)} Select this checkbox to let Renovate create an automated Config Migration PR.\\n\\n`;\n }\n\n issueBody = appendRepoProblems(config, issueBody);\n\n if (hasDeprecationsOrReplacements) {\n issueBody += '## Deprecations / Replacements\\n';\n issueBody += emojify('> :warning: **Warning**\\n> \\n');\n issueBody +=\n '> The following dependencies are either deprecated or have replacements available.\\n\\n';\n issueBody += '| Datasource | Package | Replacement PR? |\\n';\n issueBody += '|------------|------|--------------|\\n';\n for (const manager of Object.keys(deprecatedPackages).sort()) {\n const deps = deprecatedPackages[manager];\n for (const depName of Object.keys(deps).sort()) {\n const { hasActionableReplacement, sourceUrl } = deps[depName];\n const packageName = formatAsMarkdownLink(depName, sourceUrl);\n\n issueBody += `| ${manager} | ${packageName} | ${\n hasActionableReplacement\n ? '![Available](https://img.shields.io/badge/available-green?style=flat-square)'\n : '![Unavailable](https://img.shields.io/badge/unavailable-orange?style=flat-square)'\n } |\\n`;\n }\n }\n issueBody += '\\n';\n }\n\n if (config.dependencyDashboardReportAbandonment) {\n issueBody += getAbandonedPackagesMd(config, packageFiles);\n }\n\n issueBody += getBranchesListMd(\n branches,\n (branch) => branch.result === 'needs-approval',\n 'Pending Approval',\n 'The following branches are pending approval. To create them, click on a checkbox below.',\n 'approve',\n approveAllPendingPrs,\n 'Create all pending approval PRs at once',\n '🔐',\n );\n issueBody += getBranchesListMd(\n branches,\n (branch) => branch.result === 'minimum-group-size-not-met',\n 'Group Size Not Met',\n 'The following branches have not met their minimum group size. To create them, click on a checkbox below.',\n 'approveGroup',\n );\n issueBody += getBranchesListMd(\n branches,\n (branch) => branch.result === 'not-scheduled',\n 'Awaiting Schedule',\n 'The following updates are awaiting their schedule. To get an update now, click on a checkbox below.',\n 'unschedule',\n createAllAwaitingSchedulePrs,\n 'Create all awaiting schedule PRs at once',\n '🔐',\n );\n issueBody += getBranchesListMd(\n branches,\n (branch) =>\n branch.result === 'branch-limit-reached' ||\n branch.result === 'pr-limit-reached' ||\n branch.result === 'commit-per-run-limit-reached' ||\n branch.result === 'commit-hourly-limit-reached',\n 'Rate-Limited',\n 'The following updates are currently rate-limited. To force their creation now, click on a checkbox below.',\n 'unlimit',\n createAllRateLimitedPrs,\n 'Create all rate-limited PRs at once',\n '🔐',\n );\n issueBody += getBranchesListMd(\n branches,\n (branch) => branch.result === 'error',\n 'Errored',\n 'The following updates encountered an error and will be retried. To force a retry now, click on a checkbox below.',\n 'retry',\n );\n issueBody += getBranchesListMd(\n branches,\n (branch) => branch.result === 'needs-pr-approval',\n 'PR Creation Approval Required',\n 'The following branches exist but PR creation requires approval. To approve PR creation, click on a checkbox below.',\n );\n issueBody += getBranchesListMd(\n branches,\n (branch) => branch.result === 'pr-edited',\n 'PR Edited (Blocked)',\n 'The following updates have been manually edited so Renovate will no longer make changes. To discard all commits and start over, click on a checkbox below.',\n 'rebase',\n );\n issueBody += getBranchesListMd(\n branches,\n (branch) => branch.result === 'pending',\n 'Pending Status Checks',\n 'The following updates await pending status checks. To force their creation now, click on a checkbox below.',\n 'unpend',\n );\n issueBody += getBranchesListMd(\n branches,\n (branch) => branch.prBlockedBy === 'BranchAutomerge',\n 'Pending Branch Automerge',\n 'The following updates await pending status checks before automerging. To abort the branch automerge and create a PR instead, click on a checkbox below.',\n );\n\n const warn = getDepWarningsDashboard(packageFiles, config);\n if (warn) {\n issueBody += warn;\n issueBody += '\\n';\n }\n\n const otherRes = [\n 'pending',\n 'needs-approval',\n 'needs-pr-approval',\n 'not-scheduled',\n 'pr-limit-reached',\n 'commit-per-run-limit-reached',\n 'commit-hourly-limit-reached',\n 'branch-limit-reached',\n 'already-existed',\n 'error',\n 'automerged',\n 'pr-edited',\n 'minimum-group-size-not-met',\n ];\n const inProgress = branches.filter(\n (branch) =>\n !otherRes.includes(branch.result!) &&\n branch.prBlockedBy !== 'BranchAutomerge',\n );\n issueBody += getBranchesListMd(\n inProgress,\n (branch) => !!branch.prBlockedBy || !branch.prNo,\n 'Other Branches',\n 'The following updates are pending. To force the creation of a PR, click on a checkbox below.',\n 'other',\n );\n issueBody += getBranchesListMd(\n inProgress,\n (branch) => branch.prNo && !branch.prBlockedBy,\n 'Open',\n 'The following updates have all been created. To force a retry/rebase of any, click on a checkbox below.',\n 'rebase',\n rebaseAllOpenPrs,\n 'Click on this checkbox to rebase all open PRs at once',\n );\n\n issueBody += getBranchesListMd(\n branches,\n (branch) => branch.result === 'already-existed',\n 'PR Closed (Blocked)',\n 'The following updates are blocked by an existing closed PR. To recreate the PR, click on a checkbox below.',\n 'recreate',\n );\n\n if (!hasBranches) {\n issueBody +=\n 'This repository currently has no open or pending branches.\\n\\n';\n }\n\n // add CVE section\n issueBody += await getDashboardMarkdownVulnerabilities(config, packageFiles);\n\n // fit the detected dependencies section\n const footer = getFooter(config);\n issueBody += PackageFiles.getDashboardMarkdown(\n platform.maxBodyLength() - issueBody.length - footer.length,\n );\n\n issueBody += footer;\n\n if (config.dependencyDashboardIssue) {\n // If we're not changing the dashboard issue, then we can skip checking if the user changed it.\n // The cached issue we get back here will reflect its state at the _start_ of our run\n const cachedIssue = await platform.getIssue?.(\n config.dependencyDashboardIssue,\n );\n if (cachedIssue?.body === issueBody) {\n logger.debug('No changes to dependency dashboard issue needed');\n return;\n }\n\n // Skip cache when getting the issue to ensure we get the latest body,\n // including any updates the user made after we started the run\n const updatedIssue = await platform.getIssue?.(\n config.dependencyDashboardIssue,\n false,\n );\n if (updatedIssue) {\n const { dependencyDashboardChecks } = parseDashboardIssue(\n coerceString(updatedIssue.body),\n );\n for (const branchName of Object.keys(config.dependencyDashboardChecks!)) {\n delete dependencyDashboardChecks[branchName];\n }\n for (const branchName of Object.keys(dependencyDashboardChecks)) {\n const checkText = getCheckbox(\n `${dependencyDashboardChecks[branchName]}-branch=${branchName}`,\n );\n issueBody = issueBody.replace(\n checkText,\n checkText.replace('[ ]', '[x]'),\n );\n }\n }\n }\n\n if (GlobalConfig.get('dryRun')) {\n logger.info(\n { title: config.dependencyDashboardTitle },\n 'DRY-RUN: Would ensure Dependency Dashboard',\n );\n } else {\n await platform.ensureIssue({\n title: config.dependencyDashboardTitle!,\n reuseTitle,\n body: platform.massageMarkdown(issueBody, config.rebaseLabel),\n labels: config.dependencyDashboardLabels,\n confidential: config.confidential,\n });\n }\n}\n\nexport function getAbandonedPackagesMd(\n config: RenovateConfig,\n packageFiles: Record<string, PackageFile[]>,\n): string {\n const abandonedPackages: Record<\n string,\n Record<\n string,\n { mostRecentTimestamp?: string | null; sourceUrl?: string | null }\n >\n > = {};\n let abandonedCount = 0;\n\n for (const [manager, managerPackageFiles] of Object.entries(packageFiles)) {\n for (const packageFile of managerPackageFiles) {\n for (const dep of coerceArray(packageFile.deps)) {\n if (dep.depName && dep.isAbandoned) {\n abandonedCount++;\n abandonedPackages[manager] = abandonedPackages[manager] || {};\n abandonedPackages[manager][dep.depName] = {\n mostRecentTimestamp: dep.mostRecentTimestamp,\n sourceUrl: dep.sourceUrl,\n };\n }\n }\n }\n }\n\n if (abandonedCount === 0) {\n return '';\n }\n\n let abandonedMd = '## Abandoned Dependencies\\n\\n';\n abandonedMd +=\n 'The following dependencies have not received updates for an extended period and may be unmaintained.\\n\\n';\n\n // Keep the note outside the `<details>` block: GitHub only renders alert\n // callouts at the top level of a body, not inside collapsible sections.\n abandonedMd += emojify('> :information_source: **Note**\\n> \\n');\n abandonedMd += `> Packages are marked as abandoned when they exceed the [\\`abandonmentThreshold\\`](${GlobalConfig.get('productLinks').documentation}configuration-options/#abandonmentthreshold) since their last release. `;\n abandonedMd +=\n 'Unlike deprecated packages with official notices, abandonment is detected by release inactivity.\\n> \\n';\n\n abandonedMd += '<details>\\n';\n abandonedMd += `<summary>View abandoned dependencies (${abandonedCount})</summary>\\n\\n`;\n\n abandonedMd += '| Datasource | Package | Last Updated |\\n';\n abandonedMd += '|------------|------|-------------|\\n';\n\n for (const manager of Object.keys(abandonedPackages).sort()) {\n const deps = abandonedPackages[manager];\n for (const depName of Object.keys(deps).sort()) {\n const { mostRecentTimestamp, sourceUrl } = deps[depName];\n const formattedDate = mostRecentTimestamp\n ? DateTime.fromISO(mostRecentTimestamp).toFormat('yyyy-MM-dd')\n : 'unknown';\n const packageName = formatAsMarkdownLink(depName, sourceUrl);\n abandonedMd += `| ${manager} | ${packageName} | \\`${formattedDate}\\` |\\n`;\n }\n }\n\n abandonedMd += '\\n</details>\\n\\n\\n';\n\n return abandonedMd;\n}\n\nfunction getFooter(config: RenovateConfig): string {\n let footer = '';\n if (config.dependencyDashboardFooter?.length) {\n footer += `---\\n${template.compile(config.dependencyDashboardFooter, config)}\\n`;\n }\n\n return footer;\n}\n\nexport async function getDashboardMarkdownVulnerabilities(\n config: RenovateConfig,\n packageFiles: Record<string, PackageFile[]>,\n): Promise<string> {\n let result = '';\n\n if (\n isNullOrUndefined(config.dependencyDashboardOSVVulnerabilitySummary) ||\n config.dependencyDashboardOSVVulnerabilitySummary === 'none'\n ) {\n return result;\n }\n\n result += '## Vulnerabilities\\n\\n';\n\n let vulnerabilities: Vulnerability[];\n try {\n const vulnerabilityFetcher = await Vulnerabilities.create();\n vulnerabilities = await vulnerabilityFetcher.fetchVulnerabilities(\n config,\n packageFiles,\n );\n } catch (err) {\n logger.warn({ err }, 'Unable to read vulnerability information');\n result +=\n 'Renovate was unable to fetch CVE information from [osv.dev](https://osv.dev) this run.\\n\\n';\n return result;\n }\n\n if (vulnerabilities.length === 0) {\n result +=\n 'Renovate has not found any CVEs on [osv.dev](https://osv.dev).\\n\\n';\n return result;\n }\n\n const unresolvedVulnerabilities = vulnerabilities.filter((value) =>\n isNullOrUndefined(value.fixedVersion),\n );\n const resolvedVulnerabilitiesLength =\n vulnerabilities.length - unresolvedVulnerabilities.length;\n\n result += emojify('> :exclamation: **Important**\\n> \\n');\n result += `> \\`${resolvedVulnerabilitiesLength}\\`/\\`${vulnerabilities.length}\\``;\n if (isTruthy(config.osvVulnerabilityAlerts)) {\n result += ' CVEs have Renovate fixes.\\n\\n';\n } else {\n result += ` CVEs have possible Renovate fixes.\\n> See [\\`osvVulnerabilityAlerts\\`](${GlobalConfig.get('productLinks').documentation}configuration-options/#osvvulnerabilityalerts) to allow Renovate to supply fixes.\\n\\n`;\n }\n\n let renderedVulnerabilities: Vulnerability[];\n switch (config.dependencyDashboardOSVVulnerabilitySummary) {\n // filter vulnerabilities to display based on configuration\n case 'unresolved':\n renderedVulnerabilities = unresolvedVulnerabilities;\n break;\n default:\n renderedVulnerabilities = vulnerabilities;\n }\n\n const managerRecords: Record<\n string,\n Record<string, Record<string, Vulnerability[]>>\n > = {};\n for (const vulnerability of renderedVulnerabilities) {\n const { manager, packageFile } = vulnerability.packageFileConfig;\n if (isNullOrUndefined(managerRecords[manager!])) {\n managerRecords[manager!] = {};\n }\n if (isNullOrUndefined(managerRecords[manager!][packageFile])) {\n managerRecords[manager!][packageFile] = {};\n }\n if (\n isNullOrUndefined(\n managerRecords[manager!][packageFile][vulnerability.packageName],\n )\n ) {\n managerRecords[manager!][packageFile][vulnerability.packageName] = [];\n }\n managerRecords[manager!][packageFile][vulnerability.packageName].push(\n vulnerability,\n );\n }\n\n for (const [manager, packageFileRecords] of Object.entries(managerRecords)) {\n result += `<details><summary>${manager}</summary>\\n<blockquote>\\n\\n`;\n for (const [packageFile, packageNameRecords] of Object.entries(\n packageFileRecords,\n )) {\n result += `<details><summary>${packageFile}</summary>\\n<blockquote>\\n\\n`;\n for (const [packageName, cves] of Object.entries(packageNameRecords)) {\n result += `<details><summary>${packageName}</summary>\\n<blockquote>\\n\\n`;\n for (const vul of cves) {\n const id = vul.vulnerability.id;\n const suffix = isNonEmptyString(vul.fixedVersion)\n ? ` (fixed in ${vul.fixedVersion})`\n : '';\n result += `- [${id}](https://osv.dev/vulnerability/${id})${suffix}\\n`;\n }\n result += `</blockquote>\\n</details>\\n\\n`;\n }\n result += `</blockquote>\\n</details>\\n\\n`;\n }\n result += `</blockquote>\\n</details>\\n\\n`;\n }\n\n return result;\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.152.0",
4
+ "version": "44.153.1",
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.152.0 config files (https://renovatebot.com/)",
3
+ "title": "JSON schema for Renovate 44.153.1 config files (https://renovatebot.com/)",
4
4
  "$schema": "http://json-schema.org/draft-07/schema#",
5
- "x-renovate-version": "44.152.0",
5
+ "x-renovate-version": "44.153.1",
6
6
  "allowComments": true,
7
7
  "type": "object",
8
8
  "definitions": {