renovate 44.71.2 → 44.72.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/dist/config/global.js.map +1 -1
  2. package/dist/config/options/index.js +2 -0
  3. package/dist/config/options/index.js.map +1 -1
  4. package/dist/config/presets/internal/security.preset.js.map +1 -1
  5. package/dist/config/types.js.map +1 -1
  6. package/dist/config/validation.js.map +1 -1
  7. package/dist/logger/config-serializer.js +7 -7
  8. package/dist/logger/config-serializer.js.map +1 -1
  9. package/dist/modules/datasource/conan/schema.js.map +1 -1
  10. package/dist/modules/datasource/deb/index.js +1 -1
  11. package/dist/modules/datasource/deb/index.js.map +1 -1
  12. package/dist/modules/datasource/deb/packages.js +1 -1
  13. package/dist/modules/datasource/deb/packages.js.map +1 -1
  14. package/dist/modules/datasource/docker/schema.js +1 -1
  15. package/dist/modules/datasource/docker/schema.js.map +1 -1
  16. package/dist/modules/datasource/orb/schema.js.map +1 -1
  17. package/dist/modules/datasource/terraform-module/schema.js.map +1 -1
  18. package/dist/modules/datasource/terraform-provider/schema.js.map +1 -1
  19. package/dist/modules/manager/argocd/extract.js +17 -15
  20. package/dist/modules/manager/argocd/extract.js.map +1 -1
  21. package/dist/modules/manager/bazel-module/rules.js.map +1 -1
  22. package/dist/modules/manager/cargo/schema.js.map +1 -1
  23. package/dist/modules/manager/dockerfile/extract.js.map +1 -1
  24. package/dist/modules/manager/fingerprint.generated.js +10 -10
  25. package/dist/modules/manager/fingerprint.generated.js.map +1 -1
  26. package/dist/modules/manager/fleet/extract.js +16 -7
  27. package/dist/modules/manager/fleet/extract.js.map +1 -1
  28. package/dist/modules/manager/flux/extract.js +4 -8
  29. package/dist/modules/manager/flux/extract.js.map +1 -1
  30. package/dist/modules/manager/gradle/extract/catalog.js.map +1 -1
  31. package/dist/modules/manager/helmfile/extract.js +12 -12
  32. package/dist/modules/manager/helmfile/extract.js.map +1 -1
  33. package/dist/modules/manager/helmsman/extract.js +8 -10
  34. package/dist/modules/manager/helmsman/extract.js.map +1 -1
  35. package/dist/modules/manager/helmv3/oci.js +22 -1
  36. package/dist/modules/manager/helmv3/oci.js.map +1 -1
  37. package/dist/modules/manager/helmv3/utils.js +2 -7
  38. package/dist/modules/manager/helmv3/utils.js.map +1 -1
  39. package/dist/modules/manager/kustomize/extract.js +6 -10
  40. package/dist/modules/manager/kustomize/extract.js.map +1 -1
  41. package/dist/modules/manager/mise/extract.js +1 -1
  42. package/dist/modules/manager/mise/extract.js.map +1 -1
  43. package/dist/modules/manager/nix/extract.js +2 -2
  44. package/dist/modules/manager/nix/extract.js.map +1 -1
  45. package/dist/modules/manager/npm/extract/index.js.map +1 -1
  46. package/dist/modules/manager/npm/post-update/index.js.map +1 -1
  47. package/dist/modules/manager/npm/post-update/npm.js.map +1 -1
  48. package/dist/modules/manager/npm/update/dependency/index.js.map +1 -1
  49. package/dist/modules/manager/ocb/extract.js +2 -2
  50. package/dist/modules/manager/ocb/extract.js.map +1 -1
  51. package/dist/modules/manager/pep723/utils.js +1 -1
  52. package/dist/modules/manager/pep723/utils.js.map +1 -1
  53. package/dist/modules/manager/pipenv/extract.js.map +1 -1
  54. package/dist/modules/manager/poetry/schema.js.map +1 -1
  55. package/dist/modules/manager/poetry/update-locked.js.map +1 -1
  56. package/dist/modules/manager/sveltos/extract.js +13 -19
  57. package/dist/modules/manager/sveltos/extract.js.map +1 -1
  58. package/dist/modules/manager/swift/artifacts.js +1 -1
  59. package/dist/modules/manager/swift/artifacts.js.map +1 -1
  60. package/dist/modules/manager/terraform/extractors/resources/helm-release.js +3 -10
  61. package/dist/modules/manager/terraform/extractors/resources/helm-release.js.map +1 -1
  62. package/dist/modules/manager/vendir/extract.js +3 -4
  63. package/dist/modules/manager/vendir/extract.js.map +1 -1
  64. package/dist/modules/platform/bitbucket/pr-cache.js.map +1 -1
  65. package/dist/modules/platform/forgejo/pr-cache.js.map +1 -1
  66. package/dist/modules/platform/gerrit/index.js.map +1 -1
  67. package/dist/modules/platform/gitea/pr-cache.js.map +1 -1
  68. package/dist/modules/platform/github/schema.js +1 -1
  69. package/dist/modules/platform/github/schema.js.map +1 -1
  70. package/dist/modules/platform/scm-manager/index.js.map +1 -1
  71. package/dist/modules/versioning/ruby/range.js.map +1 -1
  72. package/dist/util/cache/package/impl/redis.js.map +1 -1
  73. package/dist/util/cache/package/impl/sqlite.js.map +1 -1
  74. package/dist/util/cache/package/namespaces.js.map +1 -1
  75. package/dist/util/exec/index.js.map +1 -1
  76. package/dist/util/package-rules/merge-confidence.js +5 -0
  77. package/dist/util/package-rules/merge-confidence.js.map +1 -1
  78. package/dist/util/result.js.map +1 -1
  79. package/dist/util/yaml.js +1 -1
  80. package/dist/util/yaml.js.map +1 -1
  81. package/dist/workers/global/config/parse/additional-config-file.js +1 -1
  82. package/dist/workers/global/config/parse/additional-config-file.js.map +1 -1
  83. package/dist/workers/global/config/parse/file.js +1 -1
  84. package/dist/workers/global/config/parse/file.js.map +1 -1
  85. package/dist/workers/global/config/parse/host-rules-from-env.js.map +1 -1
  86. package/dist/workers/repository/dependency-dashboard.js.map +1 -1
  87. package/dist/workers/repository/error.js +1 -1
  88. package/dist/workers/repository/error.js.map +1 -1
  89. package/dist/workers/repository/index.js +1 -1
  90. package/dist/workers/repository/index.js.map +1 -1
  91. package/dist/workers/repository/onboarding/branch/onboarding-branch-cache.js.map +1 -1
  92. package/dist/workers/repository/onboarding/pr/pr-list.js.map +1 -1
  93. package/dist/workers/repository/update/branch/index.js.map +1 -1
  94. package/package.json +7 -7
  95. package/renovate-schema.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"update-locked.js","names":[],"sources":["../../../../lib/modules/manager/poetry/update-locked.ts"],"sourcesContent":["import { logger } from '../../../logger/index.ts';\nimport { Result } from '../../../util/result.ts';\nimport type { UpdateLockedConfig, UpdateLockedResult } from '../types.ts';\nimport { Lockfile } from './schema.ts';\n\nexport function updateLockedDependency(\n config: UpdateLockedConfig,\n): UpdateLockedResult {\n const { depName, currentVersion, newVersion, lockFile, lockFileContent } =\n config;\n logger.debug(\n `poetry.updateLockedDependency: ${depName}@${currentVersion} -> ${newVersion} [${lockFile}]`,\n );\n\n const LockedVersion = Lockfile.transform(({ lock }) => lock[depName]);\n return Result.parse(lockFileContent, LockedVersion)\n .transform(\n (lockedVersion): UpdateLockedResult =>\n lockedVersion === newVersion\n ? { status: 'already-updated' }\n : { status: 'unsupported' },\n )\n .unwrapOr({ status: 'unsupported' });\n}\n"],"mappings":";;;;AAKA,SAAgB,uBACd,QACoB;CACpB,MAAM,EAAE,SAAS,gBAAgB,YAAY,UAAU,oBACrD;CACF,OAAO,MACL,kCAAkC,QAAQ,GAAG,eAAe,MAAM,WAAW,IAAI,SAAS,EAC5F;CAEA,MAAM,gBAAgB,SAAS,WAAW,EAAE,WAAW,KAAK,QAAQ;CACpE,OAAO,OAAO,MAAM,iBAAiB,aAAa,CAAC,CAChD,WACE,kBACC,kBAAkB,aACd,EAAE,QAAQ,kBAAkB,IAC5B,EAAE,QAAQ,cAAc,CAChC,CAAC,CACA,SAAS,EAAE,QAAQ,cAAc,CAAC;AACvC"}
1
+ {"version":3,"file":"update-locked.js","names":[],"sources":["../../../../lib/modules/manager/poetry/update-locked.ts"],"sourcesContent":["import { logger } from '../../../logger/index.ts';\nimport { Result } from '../../../util/result.ts';\nimport type { UpdateLockedConfig, UpdateLockedResult } from '../types.ts';\nimport { Lockfile } from './schema.ts';\n\nexport function updateLockedDependency(\n config: UpdateLockedConfig,\n): UpdateLockedResult {\n const { depName, currentVersion, newVersion, lockFile, lockFileContent } =\n config;\n logger.debug(\n `poetry.updateLockedDependency: ${depName}@${currentVersion} -> ${newVersion} [${lockFile}]`,\n );\n\n const LockedVersion = Lockfile.transform(({ lock }) => lock[depName]);\n return Result.parse(lockFileContent, LockedVersion)\n .transform((lockedVersion): UpdateLockedResult =>\n lockedVersion === newVersion\n ? { status: 'already-updated' }\n : { status: 'unsupported' },\n )\n .unwrapOr({ status: 'unsupported' });\n}\n"],"mappings":";;;;AAKA,SAAgB,uBACd,QACoB;CACpB,MAAM,EAAE,SAAS,gBAAgB,YAAY,UAAU,oBACrD;CACF,OAAO,MACL,kCAAkC,QAAQ,GAAG,eAAe,MAAM,WAAW,IAAI,SAAS,EAC5F;CAEA,MAAM,gBAAgB,SAAS,WAAW,EAAE,WAAW,KAAK,QAAQ;CACpE,OAAO,OAAO,MAAM,iBAAiB,aAAa,CAAC,CAChD,WAAW,kBACV,kBAAkB,aACd,EAAE,QAAQ,kBAAkB,IAC5B,EAAE,QAAQ,cAAc,CAC9B,CAAC,CACA,SAAS,EAAE,QAAQ,cAAc,CAAC;AACvC"}
@@ -1,10 +1,7 @@
1
1
  import { coerceArray } from "../../../util/array.js";
2
- import { trimTrailingSlash } from "../../../util/url.js";
3
2
  import { parseYaml } from "../../../util/yaml.js";
4
- import { DockerDatasource } from "../../datasource/docker/index.js";
5
3
  import { HelmDatasource } from "../../datasource/helm/index.js";
6
- import { getDep } from "../dockerfile/extract.js";
7
- import { isOCIRegistry, removeOCIPrefix } from "../helmv3/oci.js";
4
+ import { getOciChartDep, isOCIRegistry } from "../helmv3/oci.js";
8
5
  import { ProfileDefinition } from "./schema.js";
9
6
  import { removeRepositoryName } from "./util.js";
10
7
  //#region lib/modules/manager/sveltos/extract.ts
@@ -26,19 +23,18 @@ function extractDefinition(definition, config) {
26
23
  function processHelmCharts(source, registryAliases) {
27
24
  const dep = {
28
25
  depName: source.chartName,
29
- currentValue: source.chartVersion,
26
+ currentValue: source.chartVersion
27
+ };
28
+ if (isOCIRegistry(source.repositoryURL)) return {
29
+ ...dep,
30
+ ...getOciChartDep(source.repositoryURL, source.chartName, registryAliases)
31
+ };
32
+ return {
33
+ ...dep,
34
+ packageName: removeRepositoryName(source.repositoryName, source.chartName),
35
+ registryUrls: [source.repositoryURL],
30
36
  datasource: HelmDatasource.id
31
37
  };
32
- if (isOCIRegistry(source.repositoryURL)) {
33
- const image = trimTrailingSlash(removeOCIPrefix(source.repositoryURL));
34
- dep.datasource = DockerDatasource.id;
35
- dep.packageName = getDep(`${image}/${source.chartName}`, false, registryAliases).packageName;
36
- } else {
37
- dep.packageName = removeRepositoryName(source.repositoryName, source.chartName);
38
- dep.registryUrls = [source.repositoryURL];
39
- dep.datasource = HelmDatasource.id;
40
- }
41
- return dep;
42
38
  }
43
39
  function processAppSpec(definition, config) {
44
40
  const deps = [];
@@ -46,10 +42,8 @@ function processAppSpec(definition, config) {
46
42
  const helmCharts = definition.kind === "ClusterPromotion" ? definition.spec?.profileSpec?.helmCharts : definition.spec?.helmCharts;
47
43
  for (const source of coerceArray(helmCharts)) {
48
44
  const dep = processHelmCharts(source, config?.registryAliases);
49
- if (dep) {
50
- dep.depType = depType;
51
- deps.push(dep);
52
- }
45
+ dep.depType = depType;
46
+ deps.push(dep);
53
47
  }
54
48
  return deps;
55
49
  }
@@ -1 +1 @@
1
- {"version":3,"file":"extract.js","names":[],"sources":["../../../../lib/modules/manager/sveltos/extract.ts"],"sourcesContent":["import { coerceArray } from '../../../util/array.ts';\nimport { trimTrailingSlash } from '../../../util/url.ts';\nimport { parseYaml } from '../../../util/yaml.ts';\nimport { DockerDatasource } from '../../datasource/docker/index.ts';\nimport { HelmDatasource } from '../../datasource/helm/index.ts';\nimport { getDep } from '../dockerfile/extract.ts';\nimport { isOCIRegistry, removeOCIPrefix } from '../helmv3/oci.ts';\nimport type {\n ExtractConfig,\n PackageDependency,\n PackageFileContent,\n} from '../types.ts';\nimport { ProfileDefinition, type SveltosHelmSource } from './schema.ts';\nimport { removeRepositoryName } from './util.ts';\n\nexport function extractPackageFile(\n content: string,\n packageFile: string,\n config?: ExtractConfig,\n): PackageFileContent | null {\n const definitions = parseYaml(content, {\n customSchema: ProfileDefinition,\n failureBehaviour: 'filter',\n });\n\n const deps: PackageDependency[] = [];\n\n for (const definition of definitions) {\n const extractedDeps = extractDefinition(definition, config);\n deps.push(...extractedDeps);\n }\n\n return deps.length ? { deps } : null;\n}\n\nexport function extractDefinition(\n definition: ProfileDefinition,\n config?: ExtractConfig,\n): PackageDependency[] {\n return processAppSpec(definition, config);\n}\n\nfunction processHelmCharts(\n source: SveltosHelmSource,\n registryAliases: Record<string, string> | undefined,\n): PackageDependency | null {\n const dep: PackageDependency = {\n depName: source.chartName,\n currentValue: source.chartVersion,\n datasource: HelmDatasource.id,\n };\n\n if (isOCIRegistry(source.repositoryURL)) {\n const image = trimTrailingSlash(removeOCIPrefix(source.repositoryURL));\n\n dep.datasource = DockerDatasource.id;\n dep.packageName = getDep(\n `${image}/${source.chartName}`,\n false,\n registryAliases,\n ).packageName;\n } else {\n dep.packageName = removeRepositoryName(\n source.repositoryName,\n source.chartName,\n );\n dep.registryUrls = [source.repositoryURL];\n dep.datasource = HelmDatasource.id;\n }\n\n return dep;\n}\n\nfunction processAppSpec(\n definition: ProfileDefinition,\n config?: ExtractConfig,\n): PackageDependency[] {\n const deps: PackageDependency[] = [];\n\n const depType = definition.kind;\n\n const helmCharts =\n definition.kind === 'ClusterPromotion'\n ? definition.spec?.profileSpec?.helmCharts\n : definition.spec?.helmCharts;\n\n for (const source of coerceArray(helmCharts)) {\n const dep = processHelmCharts(source, config?.registryAliases);\n if (dep) {\n dep.depType = depType;\n deps.push(dep);\n }\n }\n\n return deps;\n}\n"],"mappings":";;;;;;;;;;AAeA,SAAgB,mBACd,SACA,aACA,QAC2B;CAC3B,MAAM,cAAc,UAAU,SAAS;EACrC,cAAc;EACd,kBAAkB;CACpB,CAAC;CAED,MAAM,OAA4B,CAAC;CAEnC,KAAK,MAAM,cAAc,aAAa;EACpC,MAAM,gBAAgB,kBAAkB,YAAY,MAAM;EAC1D,KAAK,KAAK,GAAG,aAAa;CAC5B;CAEA,OAAO,KAAK,SAAS,EAAE,KAAK,IAAI;AAClC;AAEA,SAAgB,kBACd,YACA,QACqB;CACrB,OAAO,eAAe,YAAY,MAAM;AAC1C;AAEA,SAAS,kBACP,QACA,iBAC0B;CAC1B,MAAM,MAAyB;EAC7B,SAAS,OAAO;EAChB,cAAc,OAAO;EACrB,YAAY,eAAe;CAC7B;CAEA,IAAI,cAAc,OAAO,aAAa,GAAG;EACvC,MAAM,QAAQ,kBAAkB,gBAAgB,OAAO,aAAa,CAAC;EAErE,IAAI,aAAa,iBAAiB;EAClC,IAAI,cAAc,OAChB,GAAG,MAAM,GAAG,OAAO,aACnB,OACA,eACF,CAAC,CAAC;CACJ,OAAO;EACL,IAAI,cAAc,qBAChB,OAAO,gBACP,OAAO,SACT;EACA,IAAI,eAAe,CAAC,OAAO,aAAa;EACxC,IAAI,aAAa,eAAe;CAClC;CAEA,OAAO;AACT;AAEA,SAAS,eACP,YACA,QACqB;CACrB,MAAM,OAA4B,CAAC;CAEnC,MAAM,UAAU,WAAW;CAE3B,MAAM,aACJ,WAAW,SAAS,qBAChB,WAAW,MAAM,aAAa,aAC9B,WAAW,MAAM;CAEvB,KAAK,MAAM,UAAU,YAAY,UAAU,GAAG;EAC5C,MAAM,MAAM,kBAAkB,QAAQ,QAAQ,eAAe;EAC7D,IAAI,KAAK;GACP,IAAI,UAAU;GACd,KAAK,KAAK,GAAG;EACf;CACF;CAEA,OAAO;AACT"}
1
+ {"version":3,"file":"extract.js","names":[],"sources":["../../../../lib/modules/manager/sveltos/extract.ts"],"sourcesContent":["import { coerceArray } from '../../../util/array.ts';\nimport { parseYaml } from '../../../util/yaml.ts';\nimport { HelmDatasource } from '../../datasource/helm/index.ts';\nimport { getOciChartDep, isOCIRegistry } from '../helmv3/oci.ts';\nimport type {\n ExtractConfig,\n PackageDependency,\n PackageFileContent,\n} from '../types.ts';\nimport { ProfileDefinition, type SveltosHelmSource } from './schema.ts';\nimport { removeRepositoryName } from './util.ts';\n\nexport function extractPackageFile(\n content: string,\n packageFile: string,\n config?: ExtractConfig,\n): PackageFileContent | null {\n const definitions = parseYaml(content, {\n customSchema: ProfileDefinition,\n failureBehaviour: 'filter',\n });\n\n const deps: PackageDependency[] = [];\n\n for (const definition of definitions) {\n const extractedDeps = extractDefinition(definition, config);\n deps.push(...extractedDeps);\n }\n\n return deps.length ? { deps } : null;\n}\n\nexport function extractDefinition(\n definition: ProfileDefinition,\n config?: ExtractConfig,\n): PackageDependency[] {\n return processAppSpec(definition, config);\n}\n\nfunction processHelmCharts(\n source: SveltosHelmSource,\n registryAliases: Record<string, string> | undefined,\n): PackageDependency {\n const dep: PackageDependency = {\n depName: source.chartName,\n currentValue: source.chartVersion,\n };\n\n if (isOCIRegistry(source.repositoryURL)) {\n return {\n ...dep,\n ...getOciChartDep(\n source.repositoryURL,\n source.chartName,\n registryAliases,\n ),\n };\n }\n\n return {\n ...dep,\n packageName: removeRepositoryName(source.repositoryName, source.chartName),\n registryUrls: [source.repositoryURL],\n datasource: HelmDatasource.id,\n };\n}\n\nfunction processAppSpec(\n definition: ProfileDefinition,\n config?: ExtractConfig,\n): PackageDependency[] {\n const deps: PackageDependency[] = [];\n\n const depType = definition.kind;\n\n const helmCharts =\n definition.kind === 'ClusterPromotion'\n ? definition.spec?.profileSpec?.helmCharts\n : definition.spec?.helmCharts;\n\n for (const source of coerceArray(helmCharts)) {\n const dep = processHelmCharts(source, config?.registryAliases);\n dep.depType = depType;\n deps.push(dep);\n }\n\n return deps;\n}\n"],"mappings":";;;;;;;AAYA,SAAgB,mBACd,SACA,aACA,QAC2B;CAC3B,MAAM,cAAc,UAAU,SAAS;EACrC,cAAc;EACd,kBAAkB;CACpB,CAAC;CAED,MAAM,OAA4B,CAAC;CAEnC,KAAK,MAAM,cAAc,aAAa;EACpC,MAAM,gBAAgB,kBAAkB,YAAY,MAAM;EAC1D,KAAK,KAAK,GAAG,aAAa;CAC5B;CAEA,OAAO,KAAK,SAAS,EAAE,KAAK,IAAI;AAClC;AAEA,SAAgB,kBACd,YACA,QACqB;CACrB,OAAO,eAAe,YAAY,MAAM;AAC1C;AAEA,SAAS,kBACP,QACA,iBACmB;CACnB,MAAM,MAAyB;EAC7B,SAAS,OAAO;EAChB,cAAc,OAAO;CACvB;CAEA,IAAI,cAAc,OAAO,aAAa,GACpC,OAAO;EACL,GAAG;EACH,GAAG,eACD,OAAO,eACP,OAAO,WACP,eACF;CACF;CAGF,OAAO;EACL,GAAG;EACH,aAAa,qBAAqB,OAAO,gBAAgB,OAAO,SAAS;EACzE,cAAc,CAAC,OAAO,aAAa;EACnC,YAAY,eAAe;CAC7B;AACF;AAEA,SAAS,eACP,YACA,QACqB;CACrB,MAAM,OAA4B,CAAC;CAEnC,MAAM,UAAU,WAAW;CAE3B,MAAM,aACJ,WAAW,SAAS,qBAChB,WAAW,MAAM,aAAa,aAC9B,WAAW,MAAM;CAEvB,KAAK,MAAM,UAAU,YAAY,UAAU,GAAG;EAC5C,MAAM,MAAM,kBAAkB,QAAQ,QAAQ,eAAe;EAC7D,IAAI,UAAU;EACd,KAAK,KAAK,GAAG;CACf;CAEA,OAAO;AACT"}
@@ -100,7 +100,7 @@ async function updateArtifacts({ updatedDeps, config }) {
100
100
  if (!parseResult.success) {
101
101
  logger.debug({
102
102
  resolvedFile,
103
- error: parseResult.error
103
+ err: parseResult.error
104
104
  }, "swift: could not parse Package.resolved");
105
105
  continue;
106
106
  }
@@ -1 +1 @@
1
- {"version":3,"file":"artifacts.js","names":[],"sources":["../../../../lib/modules/manager/swift/artifacts.ts"],"sourcesContent":["import { logger } from '../../../logger/index.ts';\nimport { readLocalFile } from '../../../util/fs/index.ts';\nimport { parseGitUrl } from '../../../util/git/url.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport { trimTrailingSlash } from '../../../util/url.ts';\nimport { GitTagsDatasource } from '../../datasource/git-tags/index.ts';\nimport { getDigest } from '../../datasource/index.ts';\nimport { scm } from '../../platform/scm.ts';\nimport type {\n PackageDependency,\n UpdateArtifact,\n UpdateArtifactsResult,\n Upgrade,\n} from '../types.ts';\nimport type { PackageResolvedPin } from './schema.ts';\nimport { PackageResolvedJson } from './schema.ts';\n\nasync function findPackageResolvedFiles(): Promise<string[]> {\n const fileList = await scm.getFileList();\n return fileList.filter((f) => f.endsWith('Package.resolved'));\n}\n\nfunction normalizeUrl(url: string): string {\n try {\n const parsed = parseGitUrl(url);\n // Only use parsed result when both resource and full_name are present,\n // otherwise fall through to basic normalization\n if (parsed.resource && parsed.full_name) {\n // Normalize to host/full_name form to allow cross-protocol matching\n // e.g. https://github.com/owner/repo, git@github.com:owner/repo.git\n // -> github.com/owner/repo\n return `${parsed.resource}/${trimTrailingSlash(parsed.full_name)}`.toLowerCase();\n }\n } catch {\n // Fall through to basic normalization\n }\n return url\n .replace(regEx(/\\.git$/), '')\n .replace(regEx(/\\/$/), '')\n .toLowerCase();\n}\n\nfunction matchPinForDep(\n dep: PackageDependency,\n pins: PackageResolvedPin[],\n): PackageResolvedPin | null {\n let depUrl: string;\n\n if (dep.datasource === GitTagsDatasource.id) {\n depUrl = dep.depName ?? '';\n } else {\n const registryUrl = dep.registryUrls?.[0] ?? 'https://github.com';\n depUrl = `${registryUrl}/${dep.depName}`;\n }\n\n const normalizedDepUrl = normalizeUrl(depUrl);\n\n return (\n pins.find((pin) => normalizeUrl(pin.location) === normalizedDepUrl) ?? null\n );\n}\n\nasync function resolveCommitSha(\n dep: Upgrade,\n newVersion: string,\n): Promise<string | null> {\n if (dep.newDigest) {\n return dep.newDigest;\n }\n\n const datasource = dep.datasource;\n const packageName = dep.packageName ?? dep.depName;\n if (!datasource || !packageName) {\n return null;\n }\n\n try {\n const digest = await getDigest(\n {\n datasource,\n packageName,\n registryUrls: dep.registryUrls,\n },\n newVersion,\n );\n return digest;\n } catch (err) {\n logger.debug(\n { err, packageName, newVersion },\n 'swift: failed to resolve commit SHA',\n );\n return null;\n }\n}\n\nfunction updatePinInJson(\n content: string,\n pin: PackageResolvedPin,\n newVersion: string,\n newRevision: string | null,\n): string {\n let updated = content;\n\n // Find the pin block by its unique identity value\n const identityPattern = regEx(\n `\"identity\"\\\\s*:\\\\s*\"${RegExp.escape(pin.identity)}\"`,\n );\n const identityMatch = identityPattern.exec(updated);\n /* istanbul ignore if: identity always exists after JSON parse + matchPinForDep */\n if (!identityMatch) {\n return content;\n }\n\n // Find the enclosing object block (search for the opening brace before identity)\n const beforeIdentity = updated.slice(0, identityMatch.index);\n const blockStart = beforeIdentity.lastIndexOf('{');\n /* istanbul ignore if: valid JSON always has enclosing braces */\n if (blockStart === -1) {\n return content;\n }\n\n // Find the closing brace of this pin block (handle nested braces)\n let braceDepth = 0;\n let blockEnd = -1;\n for (let i = blockStart; i < updated.length; i++) {\n if (updated[i] === '{') {\n braceDepth++;\n } else if (updated[i] === '}') {\n braceDepth--;\n if (braceDepth === 0) {\n blockEnd = i + 1;\n break;\n }\n }\n }\n /* istanbul ignore if: valid JSON always has matching braces */\n if (blockEnd === -1) {\n return content;\n }\n\n let pinBlock = updated.slice(blockStart, blockEnd);\n\n // Replace version within the pin block\n const versionPattern = regEx(/(?<prefix>\"version\"\\s*:\\s*)\"[^\"]*\"/);\n pinBlock = pinBlock.replace(versionPattern, `$<prefix>\"${newVersion}\"`);\n\n // Replace revision within the pin block if we have a new one\n if (newRevision) {\n const revisionPattern = regEx(/(?<prefix>\"revision\"\\s*:\\s*)\"[^\"]*\"/);\n pinBlock = pinBlock.replace(revisionPattern, `$<prefix>\"${newRevision}\"`);\n }\n\n updated = updated.slice(0, blockStart) + pinBlock + updated.slice(blockEnd);\n return updated;\n}\n\nexport async function updateArtifacts({\n updatedDeps,\n config,\n}: UpdateArtifact): Promise<UpdateArtifactsResult[] | null> {\n if (config.isLockFileMaintenance) {\n logger.debug('swift: lockFileMaintenance is not supported');\n return null;\n }\n\n if (!updatedDeps.length) {\n logger.debug('swift: no updatedDeps, nothing to do');\n return null;\n }\n\n const resolvedFiles = await findPackageResolvedFiles();\n if (!resolvedFiles.length) {\n logger.debug('swift: no Package.resolved files found');\n return null;\n }\n\n const results: UpdateArtifactsResult[] = [];\n\n for (const resolvedFile of resolvedFiles) {\n const content = await readLocalFile(resolvedFile, 'utf8');\n if (!content) {\n logger.debug({ resolvedFile }, 'swift: could not read Package.resolved');\n continue;\n }\n\n const parseResult = PackageResolvedJson.safeParse(content);\n if (!parseResult.success) {\n logger.debug(\n { resolvedFile, error: parseResult.error },\n 'swift: could not parse Package.resolved',\n );\n continue;\n }\n\n const parsed = parseResult.data;\n let updated = content;\n\n for (const dep of updatedDeps) {\n const newValue = dep.newValue;\n if (!newValue) {\n continue;\n }\n\n // shouldn't happen\n if (!dep.newVersion) {\n logger.debug(\n {\n depName: dep.depName,\n newVersion: dep.newVersion,\n newValue: dep.newValue,\n },\n 'swift: found a newValue but not a newVersion',\n );\n continue;\n }\n\n const pin = matchPinForDep(dep, parsed.pins);\n if (!pin) {\n logger.debug(\n { depName: dep.depName },\n 'swift: no matching pin found in Package.resolved',\n );\n continue;\n }\n\n const resolvedVersion = dep.newVersion.replace(regEx(/^v/), '');\n\n // Skip if already up-to-date\n if (pin.state.version === resolvedVersion) {\n logger.debug(\n { depName: dep.depName, resolvedVersion },\n 'swift: pin already at target version',\n );\n continue;\n }\n\n const newRevision = await resolveCommitSha(dep, dep.newVersion);\n updated = updatePinInJson(updated, pin, resolvedVersion, newRevision);\n }\n\n if (updated !== content) {\n results.push({\n file: {\n type: 'addition',\n path: resolvedFile,\n contents: updated,\n },\n });\n }\n }\n\n return results.length ? results : null;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"artifacts.js","names":[],"sources":["../../../../lib/modules/manager/swift/artifacts.ts"],"sourcesContent":["import { logger } from '../../../logger/index.ts';\nimport { readLocalFile } from '../../../util/fs/index.ts';\nimport { parseGitUrl } from '../../../util/git/url.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport { trimTrailingSlash } from '../../../util/url.ts';\nimport { GitTagsDatasource } from '../../datasource/git-tags/index.ts';\nimport { getDigest } from '../../datasource/index.ts';\nimport { scm } from '../../platform/scm.ts';\nimport type {\n PackageDependency,\n UpdateArtifact,\n UpdateArtifactsResult,\n Upgrade,\n} from '../types.ts';\nimport type { PackageResolvedPin } from './schema.ts';\nimport { PackageResolvedJson } from './schema.ts';\n\nasync function findPackageResolvedFiles(): Promise<string[]> {\n const fileList = await scm.getFileList();\n return fileList.filter((f) => f.endsWith('Package.resolved'));\n}\n\nfunction normalizeUrl(url: string): string {\n try {\n const parsed = parseGitUrl(url);\n // Only use parsed result when both resource and full_name are present,\n // otherwise fall through to basic normalization\n if (parsed.resource && parsed.full_name) {\n // Normalize to host/full_name form to allow cross-protocol matching\n // e.g. https://github.com/owner/repo, git@github.com:owner/repo.git\n // -> github.com/owner/repo\n return `${parsed.resource}/${trimTrailingSlash(parsed.full_name)}`.toLowerCase();\n }\n } catch {\n // Fall through to basic normalization\n }\n return url\n .replace(regEx(/\\.git$/), '')\n .replace(regEx(/\\/$/), '')\n .toLowerCase();\n}\n\nfunction matchPinForDep(\n dep: PackageDependency,\n pins: PackageResolvedPin[],\n): PackageResolvedPin | null {\n let depUrl: string;\n\n if (dep.datasource === GitTagsDatasource.id) {\n depUrl = dep.depName ?? '';\n } else {\n const registryUrl = dep.registryUrls?.[0] ?? 'https://github.com';\n depUrl = `${registryUrl}/${dep.depName}`;\n }\n\n const normalizedDepUrl = normalizeUrl(depUrl);\n\n return (\n pins.find((pin) => normalizeUrl(pin.location) === normalizedDepUrl) ?? null\n );\n}\n\nasync function resolveCommitSha(\n dep: Upgrade,\n newVersion: string,\n): Promise<string | null> {\n if (dep.newDigest) {\n return dep.newDigest;\n }\n\n const datasource = dep.datasource;\n const packageName = dep.packageName ?? dep.depName;\n if (!datasource || !packageName) {\n return null;\n }\n\n try {\n const digest = await getDigest(\n {\n datasource,\n packageName,\n registryUrls: dep.registryUrls,\n },\n newVersion,\n );\n return digest;\n } catch (err) {\n logger.debug(\n { err, packageName, newVersion },\n 'swift: failed to resolve commit SHA',\n );\n return null;\n }\n}\n\nfunction updatePinInJson(\n content: string,\n pin: PackageResolvedPin,\n newVersion: string,\n newRevision: string | null,\n): string {\n let updated = content;\n\n // Find the pin block by its unique identity value\n const identityPattern = regEx(\n `\"identity\"\\\\s*:\\\\s*\"${RegExp.escape(pin.identity)}\"`,\n );\n const identityMatch = identityPattern.exec(updated);\n /* istanbul ignore if: identity always exists after JSON parse + matchPinForDep */\n if (!identityMatch) {\n return content;\n }\n\n // Find the enclosing object block (search for the opening brace before identity)\n const beforeIdentity = updated.slice(0, identityMatch.index);\n const blockStart = beforeIdentity.lastIndexOf('{');\n /* istanbul ignore if: valid JSON always has enclosing braces */\n if (blockStart === -1) {\n return content;\n }\n\n // Find the closing brace of this pin block (handle nested braces)\n let braceDepth = 0;\n let blockEnd = -1;\n for (let i = blockStart; i < updated.length; i++) {\n if (updated[i] === '{') {\n braceDepth++;\n } else if (updated[i] === '}') {\n braceDepth--;\n if (braceDepth === 0) {\n blockEnd = i + 1;\n break;\n }\n }\n }\n /* istanbul ignore if: valid JSON always has matching braces */\n if (blockEnd === -1) {\n return content;\n }\n\n let pinBlock = updated.slice(blockStart, blockEnd);\n\n // Replace version within the pin block\n const versionPattern = regEx(/(?<prefix>\"version\"\\s*:\\s*)\"[^\"]*\"/);\n pinBlock = pinBlock.replace(versionPattern, `$<prefix>\"${newVersion}\"`);\n\n // Replace revision within the pin block if we have a new one\n if (newRevision) {\n const revisionPattern = regEx(/(?<prefix>\"revision\"\\s*:\\s*)\"[^\"]*\"/);\n pinBlock = pinBlock.replace(revisionPattern, `$<prefix>\"${newRevision}\"`);\n }\n\n updated = updated.slice(0, blockStart) + pinBlock + updated.slice(blockEnd);\n return updated;\n}\n\nexport async function updateArtifacts({\n updatedDeps,\n config,\n}: UpdateArtifact): Promise<UpdateArtifactsResult[] | null> {\n if (config.isLockFileMaintenance) {\n logger.debug('swift: lockFileMaintenance is not supported');\n return null;\n }\n\n if (!updatedDeps.length) {\n logger.debug('swift: no updatedDeps, nothing to do');\n return null;\n }\n\n const resolvedFiles = await findPackageResolvedFiles();\n if (!resolvedFiles.length) {\n logger.debug('swift: no Package.resolved files found');\n return null;\n }\n\n const results: UpdateArtifactsResult[] = [];\n\n for (const resolvedFile of resolvedFiles) {\n const content = await readLocalFile(resolvedFile, 'utf8');\n if (!content) {\n logger.debug({ resolvedFile }, 'swift: could not read Package.resolved');\n continue;\n }\n\n const parseResult = PackageResolvedJson.safeParse(content);\n if (!parseResult.success) {\n logger.debug(\n { resolvedFile, err: parseResult.error },\n 'swift: could not parse Package.resolved',\n );\n continue;\n }\n\n const parsed = parseResult.data;\n let updated = content;\n\n for (const dep of updatedDeps) {\n const newValue = dep.newValue;\n if (!newValue) {\n continue;\n }\n\n // shouldn't happen\n if (!dep.newVersion) {\n logger.debug(\n {\n depName: dep.depName,\n newVersion: dep.newVersion,\n newValue: dep.newValue,\n },\n 'swift: found a newValue but not a newVersion',\n );\n continue;\n }\n\n const pin = matchPinForDep(dep, parsed.pins);\n if (!pin) {\n logger.debug(\n { depName: dep.depName },\n 'swift: no matching pin found in Package.resolved',\n );\n continue;\n }\n\n const resolvedVersion = dep.newVersion.replace(regEx(/^v/), '');\n\n // Skip if already up-to-date\n if (pin.state.version === resolvedVersion) {\n logger.debug(\n { depName: dep.depName, resolvedVersion },\n 'swift: pin already at target version',\n );\n continue;\n }\n\n const newRevision = await resolveCommitSha(dep, dep.newVersion);\n updated = updatePinInJson(updated, pin, resolvedVersion, newRevision);\n }\n\n if (updated !== content) {\n results.push({\n file: {\n type: 'addition',\n path: resolvedFile,\n contents: updated,\n },\n });\n }\n }\n\n return results.length ? results : null;\n}\n"],"mappings":"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"}
@@ -1,8 +1,6 @@
1
1
  import { logger } from "../../../../../logger/index.js";
2
- import { joinUrlParts } from "../../../../../util/url.js";
3
2
  import { HelmDatasource } from "../../../../datasource/helm/index.js";
4
- import { getDep } from "../../../dockerfile/extract.js";
5
- import { isOCIRegistry, removeOCIPrefix } from "../../../helmv3/oci.js";
3
+ import { getOciChartDep, isOCIRegistry, removeOCIPrefix } from "../../../helmv3/oci.js";
6
4
  import { checkIfStringIsPath } from "../../util.js";
7
5
  import { DependencyExtractor } from "../../base.js";
8
6
  import { isNonEmptyString, isNullOrUndefined, isPlainObject } from "@sindresorhus/is";
@@ -31,20 +29,15 @@ var HelmReleaseExtractor = class extends DependencyExtractor {
31
29
  if (!isNonEmptyString(helmRelease.chart)) dep.skipReason = "invalid-name";
32
30
  else if (isOCIRegistry(helmRelease.chart)) {
33
31
  dep.depName = removeOCIPrefix(helmRelease.chart);
34
- this.processOCI(dep.depName, config, dep);
32
+ Object.assign(dep, getOciChartDep(helmRelease.chart, void 0, config.registryAliases));
35
33
  } else if (checkIfStringIsPath(helmRelease.chart)) dep.skipReason = "local-chart";
36
34
  else if (isNonEmptyString(helmRelease.repository)) {
37
- if (isOCIRegistry(helmRelease.repository)) this.processOCI(joinUrlParts(removeOCIPrefix(helmRelease.repository), helmRelease.chart), config, dep);
35
+ if (isOCIRegistry(helmRelease.repository)) Object.assign(dep, getOciChartDep(helmRelease.repository, helmRelease.chart, config.registryAliases));
38
36
  else dep.registryUrls = [helmRelease.repository];
39
37
  }
40
38
  }
41
39
  return dependencies;
42
40
  }
43
- processOCI(depName, config, dep) {
44
- const { packageName, datasource } = getDep(depName, false, config.registryAliases);
45
- dep.packageName = packageName;
46
- dep.datasource = datasource;
47
- }
48
41
  };
49
42
  //#endregion
50
43
  export { HelmReleaseExtractor };
@@ -1 +1 @@
1
- {"version":3,"file":"helm-release.js","names":[],"sources":["../../../../../../lib/modules/manager/terraform/extractors/resources/helm-release.ts"],"sourcesContent":["import {\n isNonEmptyString,\n isNullOrUndefined,\n isPlainObject,\n} from '@sindresorhus/is';\nimport { logger } from '../../../../../logger/index.ts';\nimport { joinUrlParts } from '../../../../../util/url.ts';\nimport { HelmDatasource } from '../../../../datasource/helm/index.ts';\nimport { getDep } from '../../../dockerfile/extract.ts';\nimport { isOCIRegistry, removeOCIPrefix } from '../../../helmv3/oci.ts';\nimport type { ExtractConfig, PackageDependency } from '../../../types.ts';\nimport { DependencyExtractor } from '../../base.ts';\nimport type { TerraformDefinitionFile } from '../../hcl/types.ts';\nimport type { ProviderLock } from '../../lockfile/types.ts';\nimport { checkIfStringIsPath } from '../../util.ts';\n\nexport class HelmReleaseExtractor extends DependencyExtractor {\n getCheckList(): string[] {\n return [`\"helm_release\"`];\n }\n\n override extract(\n hclMap: TerraformDefinitionFile,\n _locks: ProviderLock[],\n config: ExtractConfig,\n ): PackageDependency[] {\n const dependencies = [];\n\n const helmReleases = hclMap?.resource?.helm_release;\n if (isNullOrUndefined(helmReleases)) {\n return [];\n }\n\n /* v8 ignore next -- needs test */\n if (!isPlainObject(helmReleases)) {\n logger.debug(\n { helmReleases },\n 'Terraform: unexpected `helmReleases` value',\n );\n return [];\n }\n\n for (const helmRelease of Object.values(helmReleases).flat()) {\n const dep: PackageDependency = {\n currentValue: helmRelease.version,\n depType: 'helm_release',\n depName: helmRelease.chart,\n datasource: HelmDatasource.id,\n };\n\n dependencies.push(dep);\n\n if (!isNonEmptyString(helmRelease.chart)) {\n dep.skipReason = 'invalid-name';\n } else if (isOCIRegistry(helmRelease.chart)) {\n // For oci charts, we remove the oci:// and use the docker datasource\n dep.depName = removeOCIPrefix(helmRelease.chart);\n this.processOCI(dep.depName, config, dep);\n } else if (checkIfStringIsPath(helmRelease.chart)) {\n dep.skipReason = 'local-chart';\n } else if (isNonEmptyString(helmRelease.repository)) {\n if (isOCIRegistry(helmRelease.repository)) {\n // For oci charts, we remove the oci:// and use the docker datasource\n this.processOCI(\n joinUrlParts(\n removeOCIPrefix(helmRelease.repository),\n helmRelease.chart,\n ),\n config,\n dep,\n );\n } else {\n dep.registryUrls = [helmRelease.repository];\n }\n }\n }\n\n return dependencies;\n }\n\n private processOCI(\n depName: string,\n config: ExtractConfig,\n dep: PackageDependency,\n ): void {\n const { packageName, datasource } = getDep(\n depName,\n false,\n config.registryAliases,\n );\n dep.packageName = packageName;\n dep.datasource = datasource;\n }\n}\n"],"mappings":";;;;;;;;;AAgBA,IAAa,uBAAb,cAA0C,oBAAoB;CAC5D,eAAyB;EACvB,OAAO,CAAC,gBAAgB;CAC1B;CAEA,QACE,QACA,QACA,QACqB;EACrB,MAAM,eAAe,CAAC;EAEtB,MAAM,eAAe,QAAQ,UAAU;EACvC,IAAI,kBAAkB,YAAY,GAChC,OAAO,CAAC;;EAIV,IAAI,CAAC,cAAc,YAAY,GAAG;GAChC,OAAO,MACL,EAAE,aAAa,GACf,4CACF;GACA,OAAO,CAAC;EACV;EAEA,KAAK,MAAM,eAAe,OAAO,OAAO,YAAY,CAAC,CAAC,KAAK,GAAG;GAC5D,MAAM,MAAyB;IAC7B,cAAc,YAAY;IAC1B,SAAS;IACT,SAAS,YAAY;IACrB,YAAY,eAAe;GAC7B;GAEA,aAAa,KAAK,GAAG;GAErB,IAAI,CAAC,iBAAiB,YAAY,KAAK,GACrC,IAAI,aAAa;QACZ,IAAI,cAAc,YAAY,KAAK,GAAG;IAE3C,IAAI,UAAU,gBAAgB,YAAY,KAAK;IAC/C,KAAK,WAAW,IAAI,SAAS,QAAQ,GAAG;GAC1C,OAAO,IAAI,oBAAoB,YAAY,KAAK,GAC9C,IAAI,aAAa;QACZ,IAAI,iBAAiB,YAAY,UAAU,GAAG;IACnD,IAAI,cAAc,YAAY,UAAU,GAEtC,KAAK,WACH,aACE,gBAAgB,YAAY,UAAU,GACtC,YAAY,KACd,GACA,QACA,GACF;SAEA,IAAI,eAAe,CAAC,YAAY,UAAU;GAE9C;EACF;EAEA,OAAO;CACT;CAEA,WACE,SACA,QACA,KACM;EACN,MAAM,EAAE,aAAa,eAAe,OAClC,SACA,OACA,OAAO,eACT;EACA,IAAI,cAAc;EAClB,IAAI,aAAa;CACnB;AACF"}
1
+ {"version":3,"file":"helm-release.js","names":[],"sources":["../../../../../../lib/modules/manager/terraform/extractors/resources/helm-release.ts"],"sourcesContent":["import {\n isNonEmptyString,\n isNullOrUndefined,\n isPlainObject,\n} from '@sindresorhus/is';\nimport { logger } from '../../../../../logger/index.ts';\nimport { HelmDatasource } from '../../../../datasource/helm/index.ts';\nimport {\n getOciChartDep,\n isOCIRegistry,\n removeOCIPrefix,\n} from '../../../helmv3/oci.ts';\nimport type { ExtractConfig, PackageDependency } from '../../../types.ts';\nimport { DependencyExtractor } from '../../base.ts';\nimport type { TerraformDefinitionFile } from '../../hcl/types.ts';\nimport type { ProviderLock } from '../../lockfile/types.ts';\nimport { checkIfStringIsPath } from '../../util.ts';\n\nexport class HelmReleaseExtractor extends DependencyExtractor {\n getCheckList(): string[] {\n return [`\"helm_release\"`];\n }\n\n override extract(\n hclMap: TerraformDefinitionFile,\n _locks: ProviderLock[],\n config: ExtractConfig,\n ): PackageDependency[] {\n const dependencies = [];\n\n const helmReleases = hclMap?.resource?.helm_release;\n if (isNullOrUndefined(helmReleases)) {\n return [];\n }\n\n /* v8 ignore next -- needs test */\n if (!isPlainObject(helmReleases)) {\n logger.debug(\n { helmReleases },\n 'Terraform: unexpected `helmReleases` value',\n );\n return [];\n }\n\n for (const helmRelease of Object.values(helmReleases).flat()) {\n const dep: PackageDependency = {\n currentValue: helmRelease.version,\n depType: 'helm_release',\n depName: helmRelease.chart,\n datasource: HelmDatasource.id,\n };\n\n dependencies.push(dep);\n\n if (!isNonEmptyString(helmRelease.chart)) {\n dep.skipReason = 'invalid-name';\n } else if (isOCIRegistry(helmRelease.chart)) {\n // For oci charts, we remove the oci:// and use the docker datasource\n dep.depName = removeOCIPrefix(helmRelease.chart);\n Object.assign(\n dep,\n getOciChartDep(helmRelease.chart, undefined, config.registryAliases),\n );\n } else if (checkIfStringIsPath(helmRelease.chart)) {\n dep.skipReason = 'local-chart';\n } else if (isNonEmptyString(helmRelease.repository)) {\n if (isOCIRegistry(helmRelease.repository)) {\n // For oci charts, we remove the oci:// and use the docker datasource\n Object.assign(\n dep,\n getOciChartDep(\n helmRelease.repository,\n helmRelease.chart,\n config.registryAliases,\n ),\n );\n } else {\n dep.registryUrls = [helmRelease.repository];\n }\n }\n }\n\n return dependencies;\n }\n}\n"],"mappings":";;;;;;;AAkBA,IAAa,uBAAb,cAA0C,oBAAoB;CAC5D,eAAyB;EACvB,OAAO,CAAC,gBAAgB;CAC1B;CAEA,QACE,QACA,QACA,QACqB;EACrB,MAAM,eAAe,CAAC;EAEtB,MAAM,eAAe,QAAQ,UAAU;EACvC,IAAI,kBAAkB,YAAY,GAChC,OAAO,CAAC;;EAIV,IAAI,CAAC,cAAc,YAAY,GAAG;GAChC,OAAO,MACL,EAAE,aAAa,GACf,4CACF;GACA,OAAO,CAAC;EACV;EAEA,KAAK,MAAM,eAAe,OAAO,OAAO,YAAY,CAAC,CAAC,KAAK,GAAG;GAC5D,MAAM,MAAyB;IAC7B,cAAc,YAAY;IAC1B,SAAS;IACT,SAAS,YAAY;IACrB,YAAY,eAAe;GAC7B;GAEA,aAAa,KAAK,GAAG;GAErB,IAAI,CAAC,iBAAiB,YAAY,KAAK,GACrC,IAAI,aAAa;QACZ,IAAI,cAAc,YAAY,KAAK,GAAG;IAE3C,IAAI,UAAU,gBAAgB,YAAY,KAAK;IAC/C,OAAO,OACL,KACA,eAAe,YAAY,OAAO,KAAA,GAAW,OAAO,eAAe,CACrE;GACF,OAAO,IAAI,oBAAoB,YAAY,KAAK,GAC9C,IAAI,aAAa;QACZ,IAAI,iBAAiB,YAAY,UAAU,GAAG;IACnD,IAAI,cAAc,YAAY,UAAU,GAEtC,OAAO,OACL,KACA,eACE,YAAY,YACZ,YAAY,OACZ,OAAO,eACT,CACF;SAEA,IAAI,eAAe,CAAC,YAAY,UAAU;GAE9C;EACF;EAEA,OAAO;CACT;AACF"}
@@ -4,16 +4,15 @@ import { getHttpUrl } from "../../../util/git/url.js";
4
4
  import { GitRefsDatasource } from "../../datasource/git-refs/index.js";
5
5
  import { GithubReleasesDatasource } from "../../datasource/github-releases/index.js";
6
6
  import { HelmDatasource } from "../../datasource/helm/index.js";
7
- import { getDep } from "../dockerfile/extract.js";
8
- import { isOCIRegistry, removeOCIPrefix } from "../helmv3/oci.js";
7
+ import { getOciChartDep, isOCIRegistry } from "../helmv3/oci.js";
9
8
  import { Vendir } from "./schema.js";
10
9
  //#region lib/modules/manager/vendir/extract.ts
11
10
  function extractHelmChart(helmChart, aliases) {
12
11
  if (isOCIRegistry(helmChart.repository.url)) return {
13
- ...getDep(`${removeOCIPrefix(helmChart.repository.url)}/${helmChart.name}:${helmChart.version}`, false, aliases),
12
+ ...getOciChartDep(helmChart.repository.url, helmChart.name, aliases),
14
13
  depName: helmChart.name,
15
14
  depType: "HelmChart",
16
- pinDigests: false
15
+ currentValue: helmChart.version
17
16
  };
18
17
  return {
19
18
  depName: helmChart.name,
@@ -1 +1 @@
1
- {"version":3,"file":"extract.js","names":[],"sources":["../../../../lib/modules/manager/vendir/extract.ts"],"sourcesContent":["import { logger } from '../../../logger/index.ts';\nimport { getHttpUrl } from '../../../util/git/url.ts';\nimport { parseSingleYaml } from '../../../util/yaml.ts';\nimport { GitRefsDatasource } from '../../datasource/git-refs/index.ts';\nimport { GithubReleasesDatasource } from '../../datasource/github-releases/index.ts';\nimport { HelmDatasource } from '../../datasource/helm/index.ts';\nimport { getDep } from '../dockerfile/extract.ts';\nimport { isOCIRegistry, removeOCIPrefix } from '../helmv3/oci.ts';\nimport type {\n ExtractConfig,\n PackageDependency,\n PackageFileContent,\n} from '../types.ts';\nimport type {\n GitRef,\n GithubRelease,\n HelmChart,\n HttpRelease,\n} from './schema.ts';\nimport { Vendir } from './schema.ts';\n\nexport function extractHelmChart(\n helmChart: HelmChart,\n aliases?: Record<string, string>,\n): PackageDependency {\n if (isOCIRegistry(helmChart.repository.url)) {\n const dep = getDep(\n `${removeOCIPrefix(helmChart.repository.url)}/${helmChart.name}:${helmChart.version}`,\n false,\n aliases,\n );\n return {\n ...dep,\n depName: helmChart.name,\n depType: 'HelmChart',\n // https://github.com/helm/helm/issues/10312\n // https://github.com/helm/helm/issues/10678\n pinDigests: false,\n };\n }\n return {\n depName: helmChart.name,\n currentValue: helmChart.version,\n depType: 'HelmChart',\n registryUrls: [helmChart.repository.url],\n datasource: HelmDatasource.id,\n };\n}\n\nexport function extractGitSource(gitSource: GitRef): PackageDependency {\n const httpUrl = getHttpUrl(gitSource.url);\n return {\n depName: httpUrl,\n depType: 'GitSource',\n currentValue: gitSource.ref,\n datasource: GitRefsDatasource.id,\n };\n}\n\nexport function extractGithubReleaseSource(\n githubRelease: GithubRelease,\n): PackageDependency {\n return {\n depName: githubRelease.slug,\n packageName: githubRelease.slug,\n depType: 'GithubRelease',\n currentValue: githubRelease.tag,\n datasource: GithubReleasesDatasource.id,\n };\n}\n\nexport function extractHttpReleaseSource(\n httpRelease: HttpRelease,\n): PackageDependency {\n return {\n packageName: httpRelease.url,\n currentValue: 'latest',\n depType: 'HttpSource',\n skipReason: 'unsupported-datasource',\n };\n}\n\nexport function parseVendir(\n content: string,\n packageFile?: string,\n): Vendir | null {\n try {\n return parseSingleYaml(content, {\n customSchema: Vendir,\n removeTemplates: true,\n });\n } catch {\n logger.debug({ packageFile }, 'Error parsing vendir.yml file');\n return null;\n }\n}\n\nexport function extractPackageFile(\n content: string,\n packageFile: string,\n config: ExtractConfig,\n): PackageFileContent | null {\n logger.trace(`vendir.extractPackageFile(${packageFile})`);\n const deps: PackageDependency[] = [];\n\n const pkg = parseVendir(content, packageFile);\n if (!pkg) {\n return null;\n }\n\n // grab the helm charts\n const contents = pkg.directories.flatMap((directory) => directory.contents);\n for (const content of contents) {\n // v8 ignore else -- hard to test\n if ('helmChart' in content && content.helmChart) {\n const dep = extractHelmChart(content.helmChart, config.registryAliases);\n deps.push(dep);\n } else if ('git' in content && content.git) {\n const dep = extractGitSource(content.git);\n deps.push(dep);\n } else if ('githubRelease' in content && content.githubRelease) {\n const dep = extractGithubReleaseSource(content.githubRelease);\n deps.push(dep);\n }\n // v8 ignore else -- hard to test\n else if ('http' in content && content.http) {\n const dep = extractHttpReleaseSource(content.http);\n deps.push(dep);\n }\n }\n\n if (!deps.length) {\n return null;\n }\n return { deps };\n}\n"],"mappings":";;;;;;;;;;AAqBA,SAAgB,iBACd,WACA,SACmB;CACnB,IAAI,cAAc,UAAU,WAAW,GAAG,GAMxC,OAAO;EACL,GANU,OACV,GAAG,gBAAgB,UAAU,WAAW,GAAG,EAAE,GAAG,UAAU,KAAK,GAAG,UAAU,WAC5E,OACA,OAGK;EACL,SAAS,UAAU;EACnB,SAAS;EAGT,YAAY;CACd;CAEF,OAAO;EACL,SAAS,UAAU;EACnB,cAAc,UAAU;EACxB,SAAS;EACT,cAAc,CAAC,UAAU,WAAW,GAAG;EACvC,YAAY,eAAe;CAC7B;AACF;AAEA,SAAgB,iBAAiB,WAAsC;CAErE,OAAO;EACL,SAFc,WAAW,UAAU,GAEpB;EACf,SAAS;EACT,cAAc,UAAU;EACxB,YAAY,kBAAkB;CAChC;AACF;AAEA,SAAgB,2BACd,eACmB;CACnB,OAAO;EACL,SAAS,cAAc;EACvB,aAAa,cAAc;EAC3B,SAAS;EACT,cAAc,cAAc;EAC5B,YAAY,yBAAyB;CACvC;AACF;AAEA,SAAgB,yBACd,aACmB;CACnB,OAAO;EACL,aAAa,YAAY;EACzB,cAAc;EACd,SAAS;EACT,YAAY;CACd;AACF;AAEA,SAAgB,YACd,SACA,aACe;CACf,IAAI;EACF,OAAO,gBAAgB,SAAS;GAC9B,cAAc;GACd,iBAAiB;EACnB,CAAC;CACH,QAAQ;EACN,OAAO,MAAM,EAAE,YAAY,GAAG,+BAA+B;EAC7D,OAAO;CACT;AACF;AAEA,SAAgB,mBACd,SACA,aACA,QAC2B;CAC3B,OAAO,MAAM,6BAA6B,YAAY,EAAE;CACxD,MAAM,OAA4B,CAAC;CAEnC,MAAM,MAAM,YAAY,SAAS,WAAW;CAC5C,IAAI,CAAC,KACH,OAAO;CAIT,MAAM,WAAW,IAAI,YAAY,SAAS,cAAc,UAAU,QAAQ;CAC1E,KAAK,MAAM,WAAW;;CAEpB,IAAI,eAAe,WAAW,QAAQ,WAAW;EAC/C,MAAM,MAAM,iBAAiB,QAAQ,WAAW,OAAO,eAAe;EACtE,KAAK,KAAK,GAAG;CACf,OAAO,IAAI,SAAS,WAAW,QAAQ,KAAK;EAC1C,MAAM,MAAM,iBAAiB,QAAQ,GAAG;EACxC,KAAK,KAAK,GAAG;CACf,OAAO,IAAI,mBAAmB,WAAW,QAAQ,eAAe;EAC9D,MAAM,MAAM,2BAA2B,QAAQ,aAAa;EAC5D,KAAK,KAAK,GAAG;CACf,OAEK,IAAI,UAAU,WAAW,QAAQ,MAAM;EAC1C,MAAM,MAAM,yBAAyB,QAAQ,IAAI;EACjD,KAAK,KAAK,GAAG;CACf;CAGF,IAAI,CAAC,KAAK,QACR,OAAO;CAET,OAAO,EAAE,KAAK;AAChB"}
1
+ {"version":3,"file":"extract.js","names":[],"sources":["../../../../lib/modules/manager/vendir/extract.ts"],"sourcesContent":["import { logger } from '../../../logger/index.ts';\nimport { getHttpUrl } from '../../../util/git/url.ts';\nimport { parseSingleYaml } from '../../../util/yaml.ts';\nimport { GitRefsDatasource } from '../../datasource/git-refs/index.ts';\nimport { GithubReleasesDatasource } from '../../datasource/github-releases/index.ts';\nimport { HelmDatasource } from '../../datasource/helm/index.ts';\nimport { getOciChartDep, isOCIRegistry } from '../helmv3/oci.ts';\nimport type {\n ExtractConfig,\n PackageDependency,\n PackageFileContent,\n} from '../types.ts';\nimport type {\n GitRef,\n GithubRelease,\n HelmChart,\n HttpRelease,\n} from './schema.ts';\nimport { Vendir } from './schema.ts';\n\nexport function extractHelmChart(\n helmChart: HelmChart,\n aliases?: Record<string, string>,\n): PackageDependency {\n if (isOCIRegistry(helmChart.repository.url)) {\n return {\n ...getOciChartDep(helmChart.repository.url, helmChart.name, aliases),\n depName: helmChart.name,\n depType: 'HelmChart',\n currentValue: helmChart.version,\n };\n }\n return {\n depName: helmChart.name,\n currentValue: helmChart.version,\n depType: 'HelmChart',\n registryUrls: [helmChart.repository.url],\n datasource: HelmDatasource.id,\n };\n}\n\nexport function extractGitSource(gitSource: GitRef): PackageDependency {\n const httpUrl = getHttpUrl(gitSource.url);\n return {\n depName: httpUrl,\n depType: 'GitSource',\n currentValue: gitSource.ref,\n datasource: GitRefsDatasource.id,\n };\n}\n\nexport function extractGithubReleaseSource(\n githubRelease: GithubRelease,\n): PackageDependency {\n return {\n depName: githubRelease.slug,\n packageName: githubRelease.slug,\n depType: 'GithubRelease',\n currentValue: githubRelease.tag,\n datasource: GithubReleasesDatasource.id,\n };\n}\n\nexport function extractHttpReleaseSource(\n httpRelease: HttpRelease,\n): PackageDependency {\n return {\n packageName: httpRelease.url,\n currentValue: 'latest',\n depType: 'HttpSource',\n skipReason: 'unsupported-datasource',\n };\n}\n\nexport function parseVendir(\n content: string,\n packageFile?: string,\n): Vendir | null {\n try {\n return parseSingleYaml(content, {\n customSchema: Vendir,\n removeTemplates: true,\n });\n } catch {\n logger.debug({ packageFile }, 'Error parsing vendir.yml file');\n return null;\n }\n}\n\nexport function extractPackageFile(\n content: string,\n packageFile: string,\n config: ExtractConfig,\n): PackageFileContent | null {\n logger.trace(`vendir.extractPackageFile(${packageFile})`);\n const deps: PackageDependency[] = [];\n\n const pkg = parseVendir(content, packageFile);\n if (!pkg) {\n return null;\n }\n\n // grab the helm charts\n const contents = pkg.directories.flatMap((directory) => directory.contents);\n for (const content of contents) {\n // v8 ignore else -- hard to test\n if ('helmChart' in content && content.helmChart) {\n const dep = extractHelmChart(content.helmChart, config.registryAliases);\n deps.push(dep);\n } else if ('git' in content && content.git) {\n const dep = extractGitSource(content.git);\n deps.push(dep);\n } else if ('githubRelease' in content && content.githubRelease) {\n const dep = extractGithubReleaseSource(content.githubRelease);\n deps.push(dep);\n }\n // v8 ignore else -- hard to test\n else if ('http' in content && content.http) {\n const dep = extractHttpReleaseSource(content.http);\n deps.push(dep);\n }\n }\n\n if (!deps.length) {\n return null;\n }\n return { deps };\n}\n"],"mappings":";;;;;;;;;AAoBA,SAAgB,iBACd,WACA,SACmB;CACnB,IAAI,cAAc,UAAU,WAAW,GAAG,GACxC,OAAO;EACL,GAAG,eAAe,UAAU,WAAW,KAAK,UAAU,MAAM,OAAO;EACnE,SAAS,UAAU;EACnB,SAAS;EACT,cAAc,UAAU;CAC1B;CAEF,OAAO;EACL,SAAS,UAAU;EACnB,cAAc,UAAU;EACxB,SAAS;EACT,cAAc,CAAC,UAAU,WAAW,GAAG;EACvC,YAAY,eAAe;CAC7B;AACF;AAEA,SAAgB,iBAAiB,WAAsC;CAErE,OAAO;EACL,SAFc,WAAW,UAAU,GAEpB;EACf,SAAS;EACT,cAAc,UAAU;EACxB,YAAY,kBAAkB;CAChC;AACF;AAEA,SAAgB,2BACd,eACmB;CACnB,OAAO;EACL,SAAS,cAAc;EACvB,aAAa,cAAc;EAC3B,SAAS;EACT,cAAc,cAAc;EAC5B,YAAY,yBAAyB;CACvC;AACF;AAEA,SAAgB,yBACd,aACmB;CACnB,OAAO;EACL,aAAa,YAAY;EACzB,cAAc;EACd,SAAS;EACT,YAAY;CACd;AACF;AAEA,SAAgB,YACd,SACA,aACe;CACf,IAAI;EACF,OAAO,gBAAgB,SAAS;GAC9B,cAAc;GACd,iBAAiB;EACnB,CAAC;CACH,QAAQ;EACN,OAAO,MAAM,EAAE,YAAY,GAAG,+BAA+B;EAC7D,OAAO;CACT;AACF;AAEA,SAAgB,mBACd,SACA,aACA,QAC2B;CAC3B,OAAO,MAAM,6BAA6B,YAAY,EAAE;CACxD,MAAM,OAA4B,CAAC;CAEnC,MAAM,MAAM,YAAY,SAAS,WAAW;CAC5C,IAAI,CAAC,KACH,OAAO;CAIT,MAAM,WAAW,IAAI,YAAY,SAAS,cAAc,UAAU,QAAQ;CAC1E,KAAK,MAAM,WAAW;;CAEpB,IAAI,eAAe,WAAW,QAAQ,WAAW;EAC/C,MAAM,MAAM,iBAAiB,QAAQ,WAAW,OAAO,eAAe;EACtE,KAAK,KAAK,GAAG;CACf,OAAO,IAAI,SAAS,WAAW,QAAQ,KAAK;EAC1C,MAAM,MAAM,iBAAiB,QAAQ,GAAG;EACxC,KAAK,KAAK,GAAG;CACf,OAAO,IAAI,mBAAmB,WAAW,QAAQ,eAAe;EAC9D,MAAM,MAAM,2BAA2B,QAAQ,aAAa;EAC5D,KAAK,KAAK,GAAG;CACf,OAEK,IAAI,UAAU,WAAW,QAAQ,MAAM;EAC1C,MAAM,MAAM,yBAAyB,QAAQ,IAAI;EACjD,KAAK,KAAK,GAAG;CACf;CAGF,IAAI,CAAC,KAAK,QACR,OAAO;CAET,OAAO,EAAE,KAAK;AAChB"}
@@ -1 +1 @@
1
- {"version":3,"file":"pr-cache.js","names":["memCache.get"],"sources":["../../../../lib/modules/platform/bitbucket/pr-cache.ts"],"sourcesContent":["import { dequal } from 'dequal';\nimport { DateTime } from 'luxon';\nimport { logger } from '../../../logger/index.ts';\nimport * as memCache from '../../../util/cache/memory/index.ts';\nimport { getCache } from '../../../util/cache/repository/index.ts';\nimport { clone } from '../../../util/clone.ts';\nimport type { BitbucketHttp } from '../../../util/http/bitbucket.ts';\nimport { repoCacheProvider } from '../../../util/http/cache/repository-http-cache-provider.ts';\nimport type { Pr } from '../types.ts';\nimport type { BitbucketPrCacheData, PagedResult, PrResponse } from './types.ts';\nimport { prFieldsFilter, prInfo, prStates } from './utils.ts';\n\nexport class BitbucketPrCache {\n private items: Pr[] = [];\n private cache: BitbucketPrCacheData;\n private repo: string;\n private author: string | null;\n\n private constructor(repo: string, author: string | null) {\n this.repo = repo;\n this.author = author;\n const repoCache = getCache();\n repoCache.platform ??= {};\n repoCache.platform.bitbucket ??= {};\n\n let pullRequestCache = repoCache.platform.bitbucket.pullRequestsCache as\n | BitbucketPrCacheData\n | undefined;\n if (!pullRequestCache) {\n logger.debug('Initializing new PR cache at repository cache');\n pullRequestCache = {\n items: {},\n updated_on: null,\n author,\n };\n } else if (pullRequestCache.author !== author) {\n logger.debug('Resetting PR cache because authors do not match');\n pullRequestCache = {\n items: {},\n updated_on: null,\n author,\n };\n }\n repoCache.platform.bitbucket.pullRequestsCache = pullRequestCache;\n this.cache = pullRequestCache;\n this.updateItems();\n }\n\n private static async init(\n http: BitbucketHttp,\n repo: string,\n author: string | null,\n ): Promise<BitbucketPrCache> {\n const res = new BitbucketPrCache(repo, author);\n const isSynced = memCache.get<true | undefined>(\n 'bitbucket-pr-cache-synced',\n );\n\n if (!isSynced) {\n await res.sync(http);\n memCache.set('bitbucket-pr-cache-synced', true);\n }\n\n return res;\n }\n\n private getPrs(): Pr[] {\n return this.items;\n }\n\n static async getPrs(\n http: BitbucketHttp,\n repo: string,\n author: string | null,\n ): Promise<Pr[]> {\n const prCache = await BitbucketPrCache.init(http, repo, author);\n return prCache.getPrs();\n }\n\n private setPr(pr: Pr): void {\n logger.debug(`Adding PR #${pr.number} to the PR cache`);\n this.cache.items[pr.number] = pr;\n this.updateItems();\n }\n\n static async setPr(\n http: BitbucketHttp,\n repo: string,\n author: string | null,\n item: Pr,\n ): Promise<void> {\n const prCache = await BitbucketPrCache.init(http, repo, author);\n prCache.setPr(item);\n }\n\n private reconcile(rawItems: PrResponse[]): void {\n const { items: oldItems } = this.cache;\n let { updated_on } = this.cache;\n\n for (const rawItem of rawItems) {\n const id = rawItem.id;\n\n const oldItem = oldItems[id];\n const newItem = prInfo(rawItem);\n\n const itemNewTime = DateTime.fromISO(rawItem.updated_on);\n\n if (!dequal(oldItem, newItem)) {\n oldItems[id] = newItem;\n }\n\n const cacheOldTime = updated_on ? DateTime.fromISO(updated_on) : null;\n // v8 ignore else -- TODO: add test #40625\n if (!cacheOldTime || itemNewTime > cacheOldTime) {\n updated_on = rawItem.updated_on;\n }\n }\n\n this.cache.updated_on = updated_on;\n }\n\n private getUrl(): string {\n const params = new URLSearchParams();\n\n for (const state of prStates.all) {\n params.append('state', state);\n }\n\n params.append('fields', prFieldsFilter);\n\n const q: string[] = [];\n if (this.author) {\n q.push(`author.uuid = \"${this.author}\"`);\n }\n if (this.cache.updated_on) {\n q.push(`updated_on > \"${this.cache.updated_on}\"`);\n }\n params.append('q', q.join(' AND '));\n\n const query = params.toString();\n return `/2.0/repositories/${this.repo}/pullrequests?${query}`;\n }\n\n private async sync(http: BitbucketHttp): Promise<BitbucketPrCache> {\n logger.debug('Syncing PR list');\n const url = this.getUrl();\n const opts = {\n paginate: true,\n pagelen: 50,\n cacheProvider: repoCacheProvider,\n };\n const res = await http.getJsonUnchecked<PagedResult<PrResponse>>(url, opts);\n\n const items = res.body.values;\n logger.debug(`Fetched ${items.length} PRs to sync with cache`);\n const oldCache = clone(this.cache.items);\n\n this.reconcile(items);\n\n logger.debug(`Total PRs cached: ${Object.values(this.cache.items).length}`);\n logger.trace(\n {\n items,\n oldCache,\n newCache: this.cache.items,\n },\n `PR cache sync finished`,\n );\n\n this.updateItems();\n return this;\n }\n\n /**\n * Ensure the pr cache starts with the most recent PRs.\n * JavaScript ensures that the cache is sorted by PR number.\n */\n private updateItems(): void {\n this.items = Object.values(this.cache.items).reverse();\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"pr-cache.js","names":["memCache.get"],"sources":["../../../../lib/modules/platform/bitbucket/pr-cache.ts"],"sourcesContent":["import { dequal } from 'dequal';\nimport { DateTime } from 'luxon';\nimport { logger } from '../../../logger/index.ts';\nimport * as memCache from '../../../util/cache/memory/index.ts';\nimport { getCache } from '../../../util/cache/repository/index.ts';\nimport { clone } from '../../../util/clone.ts';\nimport type { BitbucketHttp } from '../../../util/http/bitbucket.ts';\nimport { repoCacheProvider } from '../../../util/http/cache/repository-http-cache-provider.ts';\nimport type { Pr } from '../types.ts';\nimport type { BitbucketPrCacheData, PagedResult, PrResponse } from './types.ts';\nimport { prFieldsFilter, prInfo, prStates } from './utils.ts';\n\nexport class BitbucketPrCache {\n private items: Pr[] = [];\n private cache: BitbucketPrCacheData;\n private repo: string;\n private author: string | null;\n\n private constructor(repo: string, author: string | null) {\n this.repo = repo;\n this.author = author;\n const repoCache = getCache();\n repoCache.platform ??= {};\n repoCache.platform.bitbucket ??= {};\n\n let pullRequestCache = repoCache.platform.bitbucket.pullRequestsCache as\n BitbucketPrCacheData | undefined;\n if (!pullRequestCache) {\n logger.debug('Initializing new PR cache at repository cache');\n pullRequestCache = {\n items: {},\n updated_on: null,\n author,\n };\n } else if (pullRequestCache.author !== author) {\n logger.debug('Resetting PR cache because authors do not match');\n pullRequestCache = {\n items: {},\n updated_on: null,\n author,\n };\n }\n repoCache.platform.bitbucket.pullRequestsCache = pullRequestCache;\n this.cache = pullRequestCache;\n this.updateItems();\n }\n\n private static async init(\n http: BitbucketHttp,\n repo: string,\n author: string | null,\n ): Promise<BitbucketPrCache> {\n const res = new BitbucketPrCache(repo, author);\n const isSynced = memCache.get<true | undefined>(\n 'bitbucket-pr-cache-synced',\n );\n\n if (!isSynced) {\n await res.sync(http);\n memCache.set('bitbucket-pr-cache-synced', true);\n }\n\n return res;\n }\n\n private getPrs(): Pr[] {\n return this.items;\n }\n\n static async getPrs(\n http: BitbucketHttp,\n repo: string,\n author: string | null,\n ): Promise<Pr[]> {\n const prCache = await BitbucketPrCache.init(http, repo, author);\n return prCache.getPrs();\n }\n\n private setPr(pr: Pr): void {\n logger.debug(`Adding PR #${pr.number} to the PR cache`);\n this.cache.items[pr.number] = pr;\n this.updateItems();\n }\n\n static async setPr(\n http: BitbucketHttp,\n repo: string,\n author: string | null,\n item: Pr,\n ): Promise<void> {\n const prCache = await BitbucketPrCache.init(http, repo, author);\n prCache.setPr(item);\n }\n\n private reconcile(rawItems: PrResponse[]): void {\n const { items: oldItems } = this.cache;\n let { updated_on } = this.cache;\n\n for (const rawItem of rawItems) {\n const id = rawItem.id;\n\n const oldItem = oldItems[id];\n const newItem = prInfo(rawItem);\n\n const itemNewTime = DateTime.fromISO(rawItem.updated_on);\n\n if (!dequal(oldItem, newItem)) {\n oldItems[id] = newItem;\n }\n\n const cacheOldTime = updated_on ? DateTime.fromISO(updated_on) : null;\n // v8 ignore else -- TODO: add test #40625\n if (!cacheOldTime || itemNewTime > cacheOldTime) {\n updated_on = rawItem.updated_on;\n }\n }\n\n this.cache.updated_on = updated_on;\n }\n\n private getUrl(): string {\n const params = new URLSearchParams();\n\n for (const state of prStates.all) {\n params.append('state', state);\n }\n\n params.append('fields', prFieldsFilter);\n\n const q: string[] = [];\n if (this.author) {\n q.push(`author.uuid = \"${this.author}\"`);\n }\n if (this.cache.updated_on) {\n q.push(`updated_on > \"${this.cache.updated_on}\"`);\n }\n params.append('q', q.join(' AND '));\n\n const query = params.toString();\n return `/2.0/repositories/${this.repo}/pullrequests?${query}`;\n }\n\n private async sync(http: BitbucketHttp): Promise<BitbucketPrCache> {\n logger.debug('Syncing PR list');\n const url = this.getUrl();\n const opts = {\n paginate: true,\n pagelen: 50,\n cacheProvider: repoCacheProvider,\n };\n const res = await http.getJsonUnchecked<PagedResult<PrResponse>>(url, opts);\n\n const items = res.body.values;\n logger.debug(`Fetched ${items.length} PRs to sync with cache`);\n const oldCache = clone(this.cache.items);\n\n this.reconcile(items);\n\n logger.debug(`Total PRs cached: ${Object.values(this.cache.items).length}`);\n logger.trace(\n {\n items,\n oldCache,\n newCache: this.cache.items,\n },\n `PR cache sync finished`,\n );\n\n this.updateItems();\n return this;\n }\n\n /**\n * Ensure the pr cache starts with the most recent PRs.\n * JavaScript ensures that the cache is sorted by PR number.\n */\n private updateItems(): void {\n this.items = Object.values(this.cache.items).reverse();\n }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"pr-cache.js","names":["memCache.get"],"sources":["../../../../lib/modules/platform/forgejo/pr-cache.ts"],"sourcesContent":["import { isNullOrUndefined } from '@sindresorhus/is';\nimport { dequal } from 'dequal';\nimport { DateTime } from 'luxon';\nimport { TEMPORARY_ERROR } from '../../../constants/error-messages.ts';\nimport { logger } from '../../../logger/index.ts';\nimport * as memCache from '../../../util/cache/memory/index.ts';\nimport { getCache } from '../../../util/cache/repository/index.ts';\nimport type { ForgejoHttp } from '../../../util/http/forgejo.ts';\nimport {\n getQueryString,\n parseLinkHeader,\n parseUrl,\n} from '../../../util/url.ts';\nimport type { Pr } from '../types.ts';\nimport type { PR } from './schema.ts';\nimport { PRList } from './schema.ts';\nimport type { ForgejoPrCacheData } from './types.ts';\nimport { API_PATH, toRenovatePR } from './utils.ts';\n\nexport class ForgejoPrCache {\n private cache: ForgejoPrCacheData;\n private items: Pr[] = [];\n private repo: string;\n private readonly ignorePrAuthor: boolean;\n private author: string | null;\n\n private constructor(\n repo: string,\n ignorePrAuthor: boolean,\n author: string | null,\n ) {\n this.repo = repo;\n this.ignorePrAuthor = ignorePrAuthor;\n this.author = author;\n const repoCache = getCache();\n repoCache.platform ??= {};\n repoCache.platform.forgejo ??= {};\n let pullRequestCache = repoCache.platform.forgejo.pullRequestsCache as\n | ForgejoPrCacheData\n | undefined;\n if (\n isNullOrUndefined(pullRequestCache) ||\n pullRequestCache.author !== author\n ) {\n pullRequestCache = {\n items: {},\n updated_at: null,\n author,\n };\n }\n repoCache.platform.forgejo.pullRequestsCache = pullRequestCache;\n this.cache = pullRequestCache;\n this.updateItems();\n }\n\n static forceSync(): void {\n memCache.set('forgejo-pr-cache-synced', false);\n }\n\n private static async init(\n http: ForgejoHttp,\n repo: string,\n ignorePrAuthor: boolean,\n author: string | null,\n ): Promise<ForgejoPrCache> {\n const res = new ForgejoPrCache(repo, ignorePrAuthor, author);\n const isSynced = memCache.get<true | undefined>('forgejo-pr-cache-synced');\n\n if (!isSynced) {\n await res.sync(http);\n memCache.set('forgejo-pr-cache-synced', true);\n }\n\n return res;\n }\n\n private getPrs(): Pr[] {\n return this.items;\n }\n\n static async getPrs(\n http: ForgejoHttp,\n repo: string,\n ignorePrAuthor: boolean,\n author: string,\n ): Promise<Pr[]> {\n const prCache = await ForgejoPrCache.init(\n http,\n repo,\n ignorePrAuthor,\n author,\n );\n return prCache.getPrs();\n }\n\n private setPr(item: Pr): void {\n this.cache.items[item.number] = item;\n this.updateItems();\n }\n\n static async setPr(\n http: ForgejoHttp,\n repo: string,\n ignorePrAuthor: boolean,\n author: string,\n item: Pr,\n ): Promise<void> {\n const prCache = await ForgejoPrCache.init(\n http,\n repo,\n ignorePrAuthor,\n author,\n );\n prCache.setPr(item);\n }\n\n private reconcile(rawItems: (PR | null)[]): boolean {\n const { items } = this.cache;\n let { updated_at } = this.cache;\n const cacheTime = updated_at ? DateTime.fromISO(updated_at) : null;\n\n let needNextPage = true;\n\n for (const rawItem of rawItems) {\n if (!rawItem) {\n logger.warn('Forgejo PR is empty, throwing temporary error');\n // Forgejo API sometimes returns empty PRs, so we throw a temporary error\n // https://github.com/go-forgejo/forgejo/blob/fcd096231ac2deaefbca10a7db1b9b01f1da93d7/services/convert/pull.go#L34-L52\n throw new Error(TEMPORARY_ERROR);\n }\n const id = rawItem.number;\n\n const newItem = toRenovatePR(rawItem, this.author);\n if (!newItem) {\n continue;\n }\n\n const oldItem = items[id];\n if (dequal(oldItem, newItem)) {\n needNextPage = false;\n continue;\n }\n\n items[id] = newItem;\n\n const itemTime = DateTime.fromISO(rawItem.updated_at);\n if (!cacheTime || itemTime > cacheTime) {\n updated_at = rawItem.updated_at;\n }\n }\n\n this.cache.updated_at = updated_at;\n\n return needNextPage;\n }\n\n private async sync(http: ForgejoHttp): Promise<ForgejoPrCache> {\n let query: string | null = getQueryString({\n state: 'all',\n sort: 'recentupdate',\n // Fetch 100 PRs on the first run to ensure we have the most recent PRs.\n // Forgejo will cap appropriate (50 by default, see `MAX_RESPONSE_ITEMS`).\n // https://docs.forgejo.com/administration/config-cheat-sheet#api-api\n // https://forgejo.org/docs/latest/admin/config-cheat-sheet/#api-api\n limit: this.items.length ? 20 : 100,\n // Supported since Forgejo v10.0.0.\n // Will be ignored by older instances.\n ...(this.ignorePrAuthor ? {} : { poster: this.author }),\n });\n\n while (query) {\n const res = await http.getJson(\n `${API_PATH}/repos/${this.repo}/pulls?${query}`,\n {\n memCache: false,\n paginate: false,\n },\n PRList,\n );\n\n const needNextPage = this.reconcile(res.body);\n if (!needNextPage) {\n break;\n }\n\n const uri = parseUrl(parseLinkHeader(res.headers.link)?.next?.url);\n query = uri ? uri.search : null;\n }\n\n this.updateItems();\n\n return this;\n }\n\n /**\n * Ensure the pr cache starts with the most recent PRs.\n * JavaScript ensures that the cache is sorted by PR number.\n */\n private updateItems(): void {\n this.items = Object.values(this.cache.items).reverse();\n }\n}\n"],"mappings":";;;;;;;;;;;AAmBA,IAAa,iBAAb,MAAa,eAAe;CAC1B;CACA,QAAsB,CAAC;CACvB;CACA;CACA;CAEA,YACE,MACA,gBACA,QACA;EACA,KAAK,OAAO;EACZ,KAAK,iBAAiB;EACtB,KAAK,SAAS;EACd,MAAM,YAAY,SAAS;EAC3B,UAAU,aAAa,CAAC;EACxB,UAAU,SAAS,YAAY,CAAC;EAChC,IAAI,mBAAmB,UAAU,SAAS,QAAQ;EAGlD,IACE,kBAAkB,gBAAgB,KAClC,iBAAiB,WAAW,QAE5B,mBAAmB;GACjB,OAAO,CAAC;GACR,YAAY;GACZ;EACF;EAEF,UAAU,SAAS,QAAQ,oBAAoB;EAC/C,KAAK,QAAQ;EACb,KAAK,YAAY;CACnB;CAEA,OAAO,YAAkB;EACvB,IAAa,2BAA2B,KAAK;CAC/C;CAEA,aAAqB,KACnB,MACA,MACA,gBACA,QACyB;EACzB,MAAM,MAAM,IAAI,eAAe,MAAM,gBAAgB,MAAM;EAG3D,IAAI,CAFaA,IAA+B,yBAEpC,GAAG;GACb,MAAM,IAAI,KAAK,IAAI;GACnB,IAAa,2BAA2B,IAAI;EAC9C;EAEA,OAAO;CACT;CAEA,SAAuB;EACrB,OAAO,KAAK;CACd;CAEA,aAAa,OACX,MACA,MACA,gBACA,QACe;EAOf,QAAO,MANe,eAAe,KACnC,MACA,MACA,gBACA,MACF,EAAA,CACe,OAAO;CACxB;CAEA,MAAc,MAAgB;EAC5B,KAAK,MAAM,MAAM,KAAK,UAAU;EAChC,KAAK,YAAY;CACnB;CAEA,aAAa,MACX,MACA,MACA,gBACA,QACA,MACe;EAOf,CAAA,MANsB,eAAe,KACnC,MACA,MACA,gBACA,MACF,EAAA,CACQ,MAAM,IAAI;CACpB;CAEA,UAAkB,UAAkC;EAClD,MAAM,EAAE,UAAU,KAAK;EACvB,IAAI,EAAE,eAAe,KAAK;EAC1B,MAAM,YAAY,aAAa,SAAS,QAAQ,UAAU,IAAI;EAE9D,IAAI,eAAe;EAEnB,KAAK,MAAM,WAAW,UAAU;GAC9B,IAAI,CAAC,SAAS;IACZ,OAAO,KAAK,+CAA+C;IAG3D,MAAM,IAAI,MAAM,eAAe;GACjC;GACA,MAAM,KAAK,QAAQ;GAEnB,MAAM,UAAU,aAAa,SAAS,KAAK,MAAM;GACjD,IAAI,CAAC,SACH;GAGF,MAAM,UAAU,MAAM;GACtB,IAAI,OAAO,SAAS,OAAO,GAAG;IAC5B,eAAe;IACf;GACF;GAEA,MAAM,MAAM;GAEZ,MAAM,WAAW,SAAS,QAAQ,QAAQ,UAAU;GACpD,IAAI,CAAC,aAAa,WAAW,WAC3B,aAAa,QAAQ;EAEzB;EAEA,KAAK,MAAM,aAAa;EAExB,OAAO;CACT;CAEA,MAAc,KAAK,MAA4C;EAC7D,IAAI,QAAuB,eAAe;GACxC,OAAO;GACP,MAAM;GAKN,OAAO,KAAK,MAAM,SAAS,KAAK;GAGhC,GAAI,KAAK,iBAAiB,CAAC,IAAI,EAAE,QAAQ,KAAK,OAAO;EACvD,CAAC;EAED,OAAO,OAAO;GACZ,MAAM,MAAM,MAAM,KAAK,QACrB,GAAG,SAAS,SAAS,KAAK,KAAK,SAAS,SACxC;IACE,UAAU;IACV,UAAU;GACZ,GACA,MACF;GAGA,IAAI,CADiB,KAAK,UAAU,IAAI,IACxB,GACd;GAGF,MAAM,MAAM,SAAS,gBAAgB,IAAI,QAAQ,IAAI,CAAC,EAAE,MAAM,GAAG;GACjE,QAAQ,MAAM,IAAI,SAAS;EAC7B;EAEA,KAAK,YAAY;EAEjB,OAAO;CACT;;;;;CAMA,cAA4B;EAC1B,KAAK,QAAQ,OAAO,OAAO,KAAK,MAAM,KAAK,CAAC,CAAC,QAAQ;CACvD;AACF"}
1
+ {"version":3,"file":"pr-cache.js","names":["memCache.get"],"sources":["../../../../lib/modules/platform/forgejo/pr-cache.ts"],"sourcesContent":["import { isNullOrUndefined } from '@sindresorhus/is';\nimport { dequal } from 'dequal';\nimport { DateTime } from 'luxon';\nimport { TEMPORARY_ERROR } from '../../../constants/error-messages.ts';\nimport { logger } from '../../../logger/index.ts';\nimport * as memCache from '../../../util/cache/memory/index.ts';\nimport { getCache } from '../../../util/cache/repository/index.ts';\nimport type { ForgejoHttp } from '../../../util/http/forgejo.ts';\nimport {\n getQueryString,\n parseLinkHeader,\n parseUrl,\n} from '../../../util/url.ts';\nimport type { Pr } from '../types.ts';\nimport type { PR } from './schema.ts';\nimport { PRList } from './schema.ts';\nimport type { ForgejoPrCacheData } from './types.ts';\nimport { API_PATH, toRenovatePR } from './utils.ts';\n\nexport class ForgejoPrCache {\n private cache: ForgejoPrCacheData;\n private items: Pr[] = [];\n private repo: string;\n private readonly ignorePrAuthor: boolean;\n private author: string | null;\n\n private constructor(\n repo: string,\n ignorePrAuthor: boolean,\n author: string | null,\n ) {\n this.repo = repo;\n this.ignorePrAuthor = ignorePrAuthor;\n this.author = author;\n const repoCache = getCache();\n repoCache.platform ??= {};\n repoCache.platform.forgejo ??= {};\n let pullRequestCache = repoCache.platform.forgejo.pullRequestsCache as\n ForgejoPrCacheData | undefined;\n if (\n isNullOrUndefined(pullRequestCache) ||\n pullRequestCache.author !== author\n ) {\n pullRequestCache = {\n items: {},\n updated_at: null,\n author,\n };\n }\n repoCache.platform.forgejo.pullRequestsCache = pullRequestCache;\n this.cache = pullRequestCache;\n this.updateItems();\n }\n\n static forceSync(): void {\n memCache.set('forgejo-pr-cache-synced', false);\n }\n\n private static async init(\n http: ForgejoHttp,\n repo: string,\n ignorePrAuthor: boolean,\n author: string | null,\n ): Promise<ForgejoPrCache> {\n const res = new ForgejoPrCache(repo, ignorePrAuthor, author);\n const isSynced = memCache.get<true | undefined>('forgejo-pr-cache-synced');\n\n if (!isSynced) {\n await res.sync(http);\n memCache.set('forgejo-pr-cache-synced', true);\n }\n\n return res;\n }\n\n private getPrs(): Pr[] {\n return this.items;\n }\n\n static async getPrs(\n http: ForgejoHttp,\n repo: string,\n ignorePrAuthor: boolean,\n author: string,\n ): Promise<Pr[]> {\n const prCache = await ForgejoPrCache.init(\n http,\n repo,\n ignorePrAuthor,\n author,\n );\n return prCache.getPrs();\n }\n\n private setPr(item: Pr): void {\n this.cache.items[item.number] = item;\n this.updateItems();\n }\n\n static async setPr(\n http: ForgejoHttp,\n repo: string,\n ignorePrAuthor: boolean,\n author: string,\n item: Pr,\n ): Promise<void> {\n const prCache = await ForgejoPrCache.init(\n http,\n repo,\n ignorePrAuthor,\n author,\n );\n prCache.setPr(item);\n }\n\n private reconcile(rawItems: (PR | null)[]): boolean {\n const { items } = this.cache;\n let { updated_at } = this.cache;\n const cacheTime = updated_at ? DateTime.fromISO(updated_at) : null;\n\n let needNextPage = true;\n\n for (const rawItem of rawItems) {\n if (!rawItem) {\n logger.warn('Forgejo PR is empty, throwing temporary error');\n // Forgejo API sometimes returns empty PRs, so we throw a temporary error\n // https://github.com/go-forgejo/forgejo/blob/fcd096231ac2deaefbca10a7db1b9b01f1da93d7/services/convert/pull.go#L34-L52\n throw new Error(TEMPORARY_ERROR);\n }\n const id = rawItem.number;\n\n const newItem = toRenovatePR(rawItem, this.author);\n if (!newItem) {\n continue;\n }\n\n const oldItem = items[id];\n if (dequal(oldItem, newItem)) {\n needNextPage = false;\n continue;\n }\n\n items[id] = newItem;\n\n const itemTime = DateTime.fromISO(rawItem.updated_at);\n if (!cacheTime || itemTime > cacheTime) {\n updated_at = rawItem.updated_at;\n }\n }\n\n this.cache.updated_at = updated_at;\n\n return needNextPage;\n }\n\n private async sync(http: ForgejoHttp): Promise<ForgejoPrCache> {\n let query: string | null = getQueryString({\n state: 'all',\n sort: 'recentupdate',\n // Fetch 100 PRs on the first run to ensure we have the most recent PRs.\n // Forgejo will cap appropriate (50 by default, see `MAX_RESPONSE_ITEMS`).\n // https://docs.forgejo.com/administration/config-cheat-sheet#api-api\n // https://forgejo.org/docs/latest/admin/config-cheat-sheet/#api-api\n limit: this.items.length ? 20 : 100,\n // Supported since Forgejo v10.0.0.\n // Will be ignored by older instances.\n ...(this.ignorePrAuthor ? {} : { poster: this.author }),\n });\n\n while (query) {\n const res = await http.getJson(\n `${API_PATH}/repos/${this.repo}/pulls?${query}`,\n {\n memCache: false,\n paginate: false,\n },\n PRList,\n );\n\n const needNextPage = this.reconcile(res.body);\n if (!needNextPage) {\n break;\n }\n\n const uri = parseUrl(parseLinkHeader(res.headers.link)?.next?.url);\n query = uri ? uri.search : null;\n }\n\n this.updateItems();\n\n return this;\n }\n\n /**\n * Ensure the pr cache starts with the most recent PRs.\n * JavaScript ensures that the cache is sorted by PR number.\n */\n private updateItems(): void {\n this.items = Object.values(this.cache.items).reverse();\n }\n}\n"],"mappings":";;;;;;;;;;;AAmBA,IAAa,iBAAb,MAAa,eAAe;CAC1B;CACA,QAAsB,CAAC;CACvB;CACA;CACA;CAEA,YACE,MACA,gBACA,QACA;EACA,KAAK,OAAO;EACZ,KAAK,iBAAiB;EACtB,KAAK,SAAS;EACd,MAAM,YAAY,SAAS;EAC3B,UAAU,aAAa,CAAC;EACxB,UAAU,SAAS,YAAY,CAAC;EAChC,IAAI,mBAAmB,UAAU,SAAS,QAAQ;EAElD,IACE,kBAAkB,gBAAgB,KAClC,iBAAiB,WAAW,QAE5B,mBAAmB;GACjB,OAAO,CAAC;GACR,YAAY;GACZ;EACF;EAEF,UAAU,SAAS,QAAQ,oBAAoB;EAC/C,KAAK,QAAQ;EACb,KAAK,YAAY;CACnB;CAEA,OAAO,YAAkB;EACvB,IAAa,2BAA2B,KAAK;CAC/C;CAEA,aAAqB,KACnB,MACA,MACA,gBACA,QACyB;EACzB,MAAM,MAAM,IAAI,eAAe,MAAM,gBAAgB,MAAM;EAG3D,IAAI,CAFaA,IAA+B,yBAEpC,GAAG;GACb,MAAM,IAAI,KAAK,IAAI;GACnB,IAAa,2BAA2B,IAAI;EAC9C;EAEA,OAAO;CACT;CAEA,SAAuB;EACrB,OAAO,KAAK;CACd;CAEA,aAAa,OACX,MACA,MACA,gBACA,QACe;EAOf,QAAO,MANe,eAAe,KACnC,MACA,MACA,gBACA,MACF,EAAA,CACe,OAAO;CACxB;CAEA,MAAc,MAAgB;EAC5B,KAAK,MAAM,MAAM,KAAK,UAAU;EAChC,KAAK,YAAY;CACnB;CAEA,aAAa,MACX,MACA,MACA,gBACA,QACA,MACe;EAOf,CAAA,MANsB,eAAe,KACnC,MACA,MACA,gBACA,MACF,EAAA,CACQ,MAAM,IAAI;CACpB;CAEA,UAAkB,UAAkC;EAClD,MAAM,EAAE,UAAU,KAAK;EACvB,IAAI,EAAE,eAAe,KAAK;EAC1B,MAAM,YAAY,aAAa,SAAS,QAAQ,UAAU,IAAI;EAE9D,IAAI,eAAe;EAEnB,KAAK,MAAM,WAAW,UAAU;GAC9B,IAAI,CAAC,SAAS;IACZ,OAAO,KAAK,+CAA+C;IAG3D,MAAM,IAAI,MAAM,eAAe;GACjC;GACA,MAAM,KAAK,QAAQ;GAEnB,MAAM,UAAU,aAAa,SAAS,KAAK,MAAM;GACjD,IAAI,CAAC,SACH;GAGF,MAAM,UAAU,MAAM;GACtB,IAAI,OAAO,SAAS,OAAO,GAAG;IAC5B,eAAe;IACf;GACF;GAEA,MAAM,MAAM;GAEZ,MAAM,WAAW,SAAS,QAAQ,QAAQ,UAAU;GACpD,IAAI,CAAC,aAAa,WAAW,WAC3B,aAAa,QAAQ;EAEzB;EAEA,KAAK,MAAM,aAAa;EAExB,OAAO;CACT;CAEA,MAAc,KAAK,MAA4C;EAC7D,IAAI,QAAuB,eAAe;GACxC,OAAO;GACP,MAAM;GAKN,OAAO,KAAK,MAAM,SAAS,KAAK;GAGhC,GAAI,KAAK,iBAAiB,CAAC,IAAI,EAAE,QAAQ,KAAK,OAAO;EACvD,CAAC;EAED,OAAO,OAAO;GACZ,MAAM,MAAM,MAAM,KAAK,QACrB,GAAG,SAAS,SAAS,KAAK,KAAK,SAAS,SACxC;IACE,UAAU;IACV,UAAU;GACZ,GACA,MACF;GAGA,IAAI,CADiB,KAAK,UAAU,IAAI,IACxB,GACd;GAGF,MAAM,MAAM,SAAS,gBAAgB,IAAI,QAAQ,IAAI,CAAC,EAAE,MAAM,GAAG;GACjE,QAAQ,MAAM,IAAI,SAAS;EAC7B;EAEA,KAAK,YAAY;EAEjB,OAAO;CACT;;;;;CAMA,cAA4B;EAC1B,KAAK,QAAQ,OAAO,OAAO,KAAK,MAAM,KAAK,CAAC,CAAC,QAAQ;CACvD;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["git.initRepo","git.setVirtualBranch"],"sources":["../../../../lib/modules/platform/gerrit/index.ts"],"sourcesContent":["import { isTruthy, isUndefined } from '@sindresorhus/is';\nimport semver from 'semver';\nimport { logger } from '../../../logger/index.ts';\nimport type { BranchStatus } from '../../../types/index.ts';\nimport { parseJson } from '../../../util/common.ts';\nimport { getEnv } from '../../../util/env.ts';\nimport * as git from '../../../util/git/index.ts';\nimport type { VirtualBranch } from '../../../util/git/types.ts';\nimport { setBaseUrl } from '../../../util/http/gerrit.ts';\nimport { coerceObject } from '../../../util/object.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport { toLongCommitSha } from '../../../util/schema-utils/git.ts';\nimport { ensureTrailingSlash } from '../../../util/url.ts';\nimport type {\n BranchStatusConfig,\n CreatePRConfig,\n EnsureCommentConfig,\n EnsureCommentRemovalConfigByContent,\n EnsureCommentRemovalConfigByTopic,\n EnsureIssueConfig,\n EnsureIssueResult,\n FindPRConfig,\n Issue,\n MergePRConfig,\n PlatformParams,\n PlatformResult,\n Pr,\n RepoParams,\n RepoResult,\n UpdatePrConfig,\n} from '../types.ts';\nimport { repoFingerprint } from '../util.ts';\nimport { smartTruncate } from '../utils/pr-body.ts';\nimport { readOnlyIssueBody } from '../utils/read-only-issue-body.ts';\nimport { client } from './client.ts';\nimport type { GerritLabels, GerritProjectInfo } from './schema.ts';\nimport { configureScm, pushForReview } from './scm.ts';\nimport {\n MAX_GERRIT_COMMENT_SIZE,\n REQUEST_DETAILS_FOR_PRS,\n TAG_PULL_REQUEST_BODY,\n extractSourceBranch,\n getGerritRepoUrl,\n mapBranchStatusToLabel,\n mapGerritChangeToPr,\n} from './utils.ts';\n\nexport const id = 'gerrit';\nexport const experimental = true;\n\nconst defaults: {\n endpoint?: string;\n} = {};\n\nlet config: {\n repository?: string;\n head?: string;\n config?: GerritProjectInfo;\n labels: GerritLabels;\n gerritUsername?: string;\n} = {\n labels: {},\n};\n\nexport function writeToConfig(newConfig: typeof config): void {\n config = { ...config, ...newConfig };\n}\n\nexport async function initPlatform({\n endpoint,\n username,\n password,\n}: PlatformParams): Promise<PlatformResult> {\n logger.debug(`initPlatform(${endpoint!}, ${username!})`);\n if (!endpoint) {\n throw new Error('Init: You must configure a Gerrit Server endpoint');\n }\n if (!(username && password)) {\n throw new Error(\n 'Init: You must configure a Gerrit Server username/password',\n );\n }\n config.gerritUsername = username;\n defaults.endpoint = ensureTrailingSlash(endpoint);\n setBaseUrl(defaults.endpoint);\n\n let gerritVersion: string;\n try {\n const env = getEnv();\n /* v8 ignore if: experimental feature */\n if (env.RENOVATE_X_PLATFORM_VERSION) {\n gerritVersion = env.RENOVATE_X_PLATFORM_VERSION;\n } else {\n gerritVersion = await client.getGerritVersion({\n username,\n password,\n });\n }\n } catch (err) {\n logger.debug(\n { err },\n 'Error authenticating with Gerrit. Check your credentials',\n );\n throw new Error('Init: Authentication failure');\n }\n\n logger.debug(`Gerrit version is: ${gerritVersion}`);\n // Example: 3.13.0-rc3-148-gb478dbbb57\n const parsed = semver.parse(gerritVersion);\n if (!parsed) {\n throw new Error(`Unable to parse Gerrit version: ${gerritVersion}`);\n }\n gerritVersion = `${parsed.major}.${parsed.minor}.${parsed.patch}`;\n client.setGerritVersion(gerritVersion);\n\n const platformConfig: PlatformResult = {\n endpoint: defaults.endpoint,\n };\n return platformConfig;\n}\n\n/**\n * Get all state=\"ACTIVE\" and type=\"CODE\" repositories from gerrit\n */\nexport async function getRepos(): Promise<string[]> {\n logger.debug(`getRepos()`);\n return await client.getRepos();\n}\n\n/**\n * Clone repository to local directory\n * @param config\n */\nexport async function initRepo({\n repository,\n cloneSubmodules,\n cloneSubmodulesFilter,\n gitUrl,\n}: RepoParams): Promise<RepoResult> {\n logger.debug(`initRepo(${repository}, ${gitUrl})`);\n const projectInfo = await client.getProjectInfo(repository);\n const branchInfo = await client.getBranchInfo(repository);\n\n config = {\n ...config,\n repository,\n head: branchInfo.revision,\n config: projectInfo,\n labels: coerceObject(projectInfo.labels),\n };\n\n //abandon \"open\" and \"rejected\" changes at startup\n const rejectedChanges = await client.findChanges(repository, {\n branchName: '',\n state: 'open',\n label: '-2',\n });\n for (const change of rejectedChanges) {\n await client.abandonChange(\n change._number,\n 'This change has been abandoned as it was voted with Code-Review -2.',\n );\n logger.info(\n `Abandoned change ${change._number} with Code-Review -2 in repository ${repository}`,\n );\n }\n\n // Collect open Gerrit changes to initialize as virtual branches.\n // This allows DefaultGitScm to treat them as regular Git branches.\n const openChanges = await client.findChanges(repository, {\n branchName: '',\n state: 'open',\n requestDetails: ['CURRENT_REVISION', 'COMMIT_FOOTERS'],\n });\n const virtualBranches: Record<string, VirtualBranch> = {};\n for (const change of openChanges) {\n const branchName = extractSourceBranch(change);\n if (!branchName) {\n continue;\n }\n const sha = toLongCommitSha(change.current_revision);\n const ref = change.revisions![sha].ref;\n virtualBranches[branchName] = { ref, sha };\n }\n\n const virtualBranchCount = Object.keys(virtualBranches).length;\n if (virtualBranchCount > 0) {\n logger.debug(\n `Will fetch ${virtualBranchCount} Gerrit changes as virtual branches`,\n );\n }\n\n const baseUrl = defaults.endpoint!;\n const url = getGerritRepoUrl(\n repository,\n baseUrl,\n gitUrl,\n config.gerritUsername!,\n );\n configureScm(repository, config.labels);\n await git.initRepo({\n url,\n cloneSubmodules,\n cloneSubmodulesFilter,\n virtualBranches,\n });\n\n const repoConfig: RepoResult = {\n defaultBranch: config.head!,\n isFork: false,\n repoFingerprint: repoFingerprint(repository, baseUrl),\n };\n return repoConfig;\n}\n\nexport async function findPr(findPRConfig: FindPRConfig): Promise<Pr | null> {\n const change = (\n await client.findChanges(config.repository!, {\n ...findPRConfig,\n singleChange: true,\n requestDetails: REQUEST_DETAILS_FOR_PRS,\n })\n ).pop();\n return change\n ? mapGerritChangeToPr(change, {\n sourceBranch: findPRConfig.branchName,\n })\n : null;\n}\n\nexport async function getPr(number: number): Promise<Pr | null> {\n try {\n const change = await client.getChange(number, REQUEST_DETAILS_FOR_PRS);\n return mapGerritChangeToPr(change);\n } catch (err) {\n if (err.statusCode === 404) {\n return null;\n }\n throw err;\n }\n}\n\nexport async function updatePr(prConfig: UpdatePrConfig): Promise<void> {\n logger.debug(`updatePr(${prConfig.number}, ${prConfig.prTitle})`);\n if (prConfig.prBody) {\n await client.addMessageIfNotAlreadyExists(\n prConfig.number,\n prConfig.prBody,\n TAG_PULL_REQUEST_BODY,\n );\n }\n await client.setHashtags(prConfig.number, {\n add: prConfig.addLabels,\n remove: prConfig.removeLabels,\n });\n if (prConfig.targetBranch) {\n await client.moveChange(prConfig.number, prConfig.targetBranch);\n }\n if (prConfig.state && prConfig.state === 'closed') {\n await client.abandonChange(prConfig.number);\n }\n}\n\nexport async function createPr(prConfig: CreatePRConfig): Promise<Pr | null> {\n logger.debug(\n `createPr(${prConfig.sourceBranch}, ${prConfig.prTitle}, ${\n prConfig.labels?.toString() ?? ''\n })`,\n );\n\n logger.debug(\n `Pushing commit to refs/for/${prConfig.targetBranch} to create Gerrit change`,\n );\n const pushResult = await pushForReview({\n sourceRef: prConfig.sourceBranch,\n targetBranch: prConfig.targetBranch,\n files: [],\n autoApprove: prConfig.platformPrOptions?.autoApprove,\n labels: prConfig.labels ?? undefined,\n });\n\n if (!pushResult) {\n throw new Error(\n `Failed to push commit to refs/for/${prConfig.targetBranch} to create Gerrit change`,\n );\n }\n\n const change = (\n await client.findChanges(config.repository!, {\n branchName: prConfig.sourceBranch,\n targetBranch: prConfig.targetBranch,\n state: 'open',\n singleChange: true,\n requestDetails: REQUEST_DETAILS_FOR_PRS,\n })\n ).pop();\n if (isUndefined(change)) {\n throw new Error(\n `Could not find the Gerrit change after pushing to refs/for/${prConfig.targetBranch}`,\n );\n }\n\n // Register the virtual branch now that the change exists and we have the ref.\n const sha = toLongCommitSha(change.current_revision);\n const ref = change.revisions![sha].ref;\n await git.setVirtualBranch(prConfig.sourceBranch, ref, sha);\n\n await client.addMessage(\n change._number,\n prConfig.prBody,\n TAG_PULL_REQUEST_BODY,\n );\n return mapGerritChangeToPr(change, {\n sourceBranch: prConfig.sourceBranch,\n prBody: prConfig.prBody,\n });\n}\n\nexport async function getBranchPr(\n branchName: string,\n targetBranch?: string,\n): Promise<Pr | null> {\n const change = await client.getBranchChange(config.repository!, {\n branchName,\n state: 'open',\n targetBranch,\n requestDetails: REQUEST_DETAILS_FOR_PRS,\n });\n\n return change\n ? mapGerritChangeToPr(change, {\n sourceBranch: branchName,\n })\n : null;\n}\n\nexport async function getPrList(): Promise<Pr[]> {\n const changes = await client.findChanges(config.repository!, {\n branchName: '',\n requestDetails: REQUEST_DETAILS_FOR_PRS,\n });\n return changes.map((change) => mapGerritChangeToPr(change)).filter(isTruthy);\n}\n\nexport async function mergePr(config: MergePRConfig): Promise<boolean> {\n logger.debug(\n `mergePr(${config.id}, ${config.branchName!}, ${config.strategy!})`,\n );\n try {\n const change = await client.submitChange(config.id);\n return change.status === 'MERGED';\n } catch (err) {\n if (err.statusCode === 409) {\n logger.warn(\n { err },\n \"Can't submit the change, because the submit rule doesn't allow it.\",\n );\n return false;\n }\n throw err;\n }\n}\n\n/**\n * BranchStatus for Gerrit assumes that the branchName refers to a change.\n * @param branchName\n */\nexport async function getBranchStatus(\n branchName: string,\n): Promise<BranchStatus> {\n logger.debug(`getBranchStatus(${branchName})`);\n const change = (\n await client.findChanges(config.repository!, {\n state: 'open',\n branchName,\n singleChange: true,\n requestDetails: ['LABELS', 'SUBMITTABLE', 'CHECK'],\n })\n ).pop();\n if (change) {\n const hasProblems = change.problems && change.problems.length > 0;\n if (hasProblems) {\n return 'red';\n }\n const hasBlockingLabels = Object.values(coerceObject(change.labels)).some(\n (label) => label.blocking,\n );\n if (hasBlockingLabels) {\n return 'red';\n }\n // v8 ignore else -- TODO: add test #40625\n if (change.submittable) {\n return 'green';\n }\n }\n return 'yellow';\n}\n\n/**\n * check the gerrit-change for the presence of the corresponding \"$context\" Gerrit label if configured,\n * return 'yellow' if not configured or not set\n * @param branchName\n * @param context renovate/stability-days || ...\n */\nexport async function getBranchStatusCheck(\n branchName: string,\n context: string,\n): Promise<BranchStatus | null> {\n const labelConfig = config.labels[context];\n if (labelConfig) {\n const change = (\n await client.findChanges(config.repository!, {\n branchName,\n state: 'open',\n singleChange: true,\n requestDetails: ['LABELS'],\n })\n ).pop();\n // v8 ignore else -- TODO: add test #40625\n if (change) {\n const label = change.labels![context];\n // v8 ignore else -- TODO: add test #40625\n if (label) {\n // Check for rejected or blocking first, as a label could have both rejected and approved\n if (label.rejected || label.blocking) {\n return 'red';\n }\n // v8 ignore else -- TODO: add test #40625\n if (label.approved) {\n return 'green';\n }\n }\n }\n }\n return 'yellow';\n}\n\n/**\n * Apply the branch state $context to the corresponding gerrit label (if available)\n * context === \"renovate/stability-days\" / \"renovate/merge-confidence\" and state === \"green\"/...\n * @param branchStatusConfig\n */\nexport async function setBranchStatus(\n branchStatusConfig: BranchStatusConfig,\n): Promise<void> {\n const label = config.labels[branchStatusConfig.context];\n const labelValue =\n label && mapBranchStatusToLabel(branchStatusConfig.state, label);\n if (branchStatusConfig.context && labelValue) {\n const change = (\n await client.findChanges(config.repository!, {\n branchName: branchStatusConfig.branchName,\n state: 'open',\n singleChange: true,\n requestDetails: ['LABELS'],\n })\n ).pop();\n\n const labelKey = branchStatusConfig.context;\n if (!change?.labels || !Object.hasOwn(change.labels, labelKey)) {\n return;\n }\n\n await client.setLabel(change._number, labelKey, labelValue);\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 if (!repo) {\n logger.debug('No repo so cannot getRawFile');\n return null;\n }\n // v8 ignore next -- TODO: add test #40625\n const branch =\n branchOrTag ??\n (repo === config.repository ? (config.head ?? 'HEAD') : 'HEAD');\n const result = await client.getFile(repo, branch, fileName);\n return result;\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 addReviewers(\n number: number,\n reviewers: string[],\n): Promise<void> {\n await client.addReviewers(number, reviewers);\n}\n\n/**\n * add \"CC\" (only one possible)\n */\nexport async function addAssignees(\n number: number,\n assignees: string[],\n): Promise<void> {\n // v8 ignore else -- TODO: add test #40625\n if (assignees.length) {\n // v8 ignore else -- TODO: add test #40625\n if (assignees.length > 1) {\n logger.debug(\n `addAssignees(${number}, ${assignees.toString()}) called with more then one assignee! Gerrit only supports one assignee! Using the first from list.`,\n );\n }\n await client.addAssignee(number, assignees[0]);\n }\n}\n\nexport async function ensureComment(\n ensureComment: EnsureCommentConfig,\n): Promise<boolean> {\n logger.debug(\n `ensureComment(${ensureComment.number}, ${ensureComment.topic!}, ${\n ensureComment.content\n })`,\n );\n await client.addMessageIfNotAlreadyExists(\n ensureComment.number,\n ensureComment.content,\n ensureComment.topic ?? undefined,\n );\n return true;\n}\n\nexport function massageMarkdown(prBody: string, rebaseLabel: string): string {\n return (\n smartTruncate(readOnlyIssueBody(prBody), maxBodyLength())\n .replace('Branch creation', 'Change creation')\n .replace(\n 'close this Pull Request unmerged',\n 'abandon or vote this change with Code-Review -2',\n )\n .replace(\n 'Close this PR',\n 'Abandon or vote this change with Code-Review -2',\n )\n .replace(\n 'you tick the rebase/retry checkbox',\n `you add the _${rebaseLabel}_ hashtag to this change`,\n )\n .replace(\n 'checking the rebase/retry box above',\n `adding the _${rebaseLabel}_ hashtag to this change`,\n )\n .replace(regEx(/\\b(?:Pull Request|PR)/g), 'change')\n // Remove HTML tags not supported in Gerrit markdown\n .replace(regEx(/<\\/?summary>/g), '**')\n .replace(regEx(/<\\/?(?:details|blockquote)>/g), '')\n .replace(regEx(`\\n---\\n\\n.*?<!-- rebase-check -->.*?\\n`), '')\n .replace(regEx(/<!--renovate-(?:debug|config-hash):.*?-->/g), '')\n // Remove zero-width-space not supported in Gerrit markdown\n .replace(regEx(/&#8203;/g), '')\n );\n}\n\nexport function maxBodyLength(): number {\n return MAX_GERRIT_COMMENT_SIZE;\n}\n\nexport async function deleteLabel(\n number: number,\n label: string,\n): Promise<void> {\n await client.setHashtags(number, { remove: [label] });\n}\n\nexport function ensureCommentRemoval(\n _ensureCommentRemoval:\n | EnsureCommentRemovalConfigByTopic\n | EnsureCommentRemovalConfigByContent,\n): Promise<void> {\n return Promise.resolve();\n}\n\nexport function ensureIssueClosing(_title: string): Promise<void> {\n return Promise.resolve();\n}\n\nexport function ensureIssue(\n _issueConfig: EnsureIssueConfig,\n): Promise<EnsureIssueResult | null> {\n return Promise.resolve(null);\n}\n\nexport function findIssue(_title: string): Promise<Issue | null> {\n return Promise.resolve(null);\n}\n\nexport function getIssueList(): Promise<Issue[]> {\n return Promise.resolve([]);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["git.initRepo","git.setVirtualBranch"],"sources":["../../../../lib/modules/platform/gerrit/index.ts"],"sourcesContent":["import { isTruthy, isUndefined } from '@sindresorhus/is';\nimport semver from 'semver';\nimport { logger } from '../../../logger/index.ts';\nimport type { BranchStatus } from '../../../types/index.ts';\nimport { parseJson } from '../../../util/common.ts';\nimport { getEnv } from '../../../util/env.ts';\nimport * as git from '../../../util/git/index.ts';\nimport type { VirtualBranch } from '../../../util/git/types.ts';\nimport { setBaseUrl } from '../../../util/http/gerrit.ts';\nimport { coerceObject } from '../../../util/object.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport { toLongCommitSha } from '../../../util/schema-utils/git.ts';\nimport { ensureTrailingSlash } from '../../../util/url.ts';\nimport type {\n BranchStatusConfig,\n CreatePRConfig,\n EnsureCommentConfig,\n EnsureCommentRemovalConfigByContent,\n EnsureCommentRemovalConfigByTopic,\n EnsureIssueConfig,\n EnsureIssueResult,\n FindPRConfig,\n Issue,\n MergePRConfig,\n PlatformParams,\n PlatformResult,\n Pr,\n RepoParams,\n RepoResult,\n UpdatePrConfig,\n} from '../types.ts';\nimport { repoFingerprint } from '../util.ts';\nimport { smartTruncate } from '../utils/pr-body.ts';\nimport { readOnlyIssueBody } from '../utils/read-only-issue-body.ts';\nimport { client } from './client.ts';\nimport type { GerritLabels, GerritProjectInfo } from './schema.ts';\nimport { configureScm, pushForReview } from './scm.ts';\nimport {\n MAX_GERRIT_COMMENT_SIZE,\n REQUEST_DETAILS_FOR_PRS,\n TAG_PULL_REQUEST_BODY,\n extractSourceBranch,\n getGerritRepoUrl,\n mapBranchStatusToLabel,\n mapGerritChangeToPr,\n} from './utils.ts';\n\nexport const id = 'gerrit';\nexport const experimental = true;\n\nconst defaults: {\n endpoint?: string;\n} = {};\n\nlet config: {\n repository?: string;\n head?: string;\n config?: GerritProjectInfo;\n labels: GerritLabels;\n gerritUsername?: string;\n} = {\n labels: {},\n};\n\nexport function writeToConfig(newConfig: typeof config): void {\n config = { ...config, ...newConfig };\n}\n\nexport async function initPlatform({\n endpoint,\n username,\n password,\n}: PlatformParams): Promise<PlatformResult> {\n logger.debug(`initPlatform(${endpoint!}, ${username!})`);\n if (!endpoint) {\n throw new Error('Init: You must configure a Gerrit Server endpoint');\n }\n if (!(username && password)) {\n throw new Error(\n 'Init: You must configure a Gerrit Server username/password',\n );\n }\n config.gerritUsername = username;\n defaults.endpoint = ensureTrailingSlash(endpoint);\n setBaseUrl(defaults.endpoint);\n\n let gerritVersion: string;\n try {\n const env = getEnv();\n /* v8 ignore if: experimental feature */\n if (env.RENOVATE_X_PLATFORM_VERSION) {\n gerritVersion = env.RENOVATE_X_PLATFORM_VERSION;\n } else {\n gerritVersion = await client.getGerritVersion({\n username,\n password,\n });\n }\n } catch (err) {\n logger.debug(\n { err },\n 'Error authenticating with Gerrit. Check your credentials',\n );\n throw new Error('Init: Authentication failure');\n }\n\n logger.debug(`Gerrit version is: ${gerritVersion}`);\n // Example: 3.13.0-rc3-148-gb478dbbb57\n const parsed = semver.parse(gerritVersion);\n if (!parsed) {\n throw new Error(`Unable to parse Gerrit version: ${gerritVersion}`);\n }\n gerritVersion = `${parsed.major}.${parsed.minor}.${parsed.patch}`;\n client.setGerritVersion(gerritVersion);\n\n const platformConfig: PlatformResult = {\n endpoint: defaults.endpoint,\n };\n return platformConfig;\n}\n\n/**\n * Get all state=\"ACTIVE\" and type=\"CODE\" repositories from gerrit\n */\nexport async function getRepos(): Promise<string[]> {\n logger.debug(`getRepos()`);\n return await client.getRepos();\n}\n\n/**\n * Clone repository to local directory\n * @param config\n */\nexport async function initRepo({\n repository,\n cloneSubmodules,\n cloneSubmodulesFilter,\n gitUrl,\n}: RepoParams): Promise<RepoResult> {\n logger.debug(`initRepo(${repository}, ${gitUrl})`);\n const projectInfo = await client.getProjectInfo(repository);\n const branchInfo = await client.getBranchInfo(repository);\n\n config = {\n ...config,\n repository,\n head: branchInfo.revision,\n config: projectInfo,\n labels: coerceObject(projectInfo.labels),\n };\n\n //abandon \"open\" and \"rejected\" changes at startup\n const rejectedChanges = await client.findChanges(repository, {\n branchName: '',\n state: 'open',\n label: '-2',\n });\n for (const change of rejectedChanges) {\n await client.abandonChange(\n change._number,\n 'This change has been abandoned as it was voted with Code-Review -2.',\n );\n logger.info(\n `Abandoned change ${change._number} with Code-Review -2 in repository ${repository}`,\n );\n }\n\n // Collect open Gerrit changes to initialize as virtual branches.\n // This allows DefaultGitScm to treat them as regular Git branches.\n const openChanges = await client.findChanges(repository, {\n branchName: '',\n state: 'open',\n requestDetails: ['CURRENT_REVISION', 'COMMIT_FOOTERS'],\n });\n const virtualBranches: Record<string, VirtualBranch> = {};\n for (const change of openChanges) {\n const branchName = extractSourceBranch(change);\n if (!branchName) {\n continue;\n }\n const sha = toLongCommitSha(change.current_revision);\n const ref = change.revisions![sha].ref;\n virtualBranches[branchName] = { ref, sha };\n }\n\n const virtualBranchCount = Object.keys(virtualBranches).length;\n if (virtualBranchCount > 0) {\n logger.debug(\n `Will fetch ${virtualBranchCount} Gerrit changes as virtual branches`,\n );\n }\n\n const baseUrl = defaults.endpoint!;\n const url = getGerritRepoUrl(\n repository,\n baseUrl,\n gitUrl,\n config.gerritUsername!,\n );\n configureScm(repository, config.labels);\n await git.initRepo({\n url,\n cloneSubmodules,\n cloneSubmodulesFilter,\n virtualBranches,\n });\n\n const repoConfig: RepoResult = {\n defaultBranch: config.head!,\n isFork: false,\n repoFingerprint: repoFingerprint(repository, baseUrl),\n };\n return repoConfig;\n}\n\nexport async function findPr(findPRConfig: FindPRConfig): Promise<Pr | null> {\n const change = (\n await client.findChanges(config.repository!, {\n ...findPRConfig,\n singleChange: true,\n requestDetails: REQUEST_DETAILS_FOR_PRS,\n })\n ).pop();\n return change\n ? mapGerritChangeToPr(change, {\n sourceBranch: findPRConfig.branchName,\n })\n : null;\n}\n\nexport async function getPr(number: number): Promise<Pr | null> {\n try {\n const change = await client.getChange(number, REQUEST_DETAILS_FOR_PRS);\n return mapGerritChangeToPr(change);\n } catch (err) {\n if (err.statusCode === 404) {\n return null;\n }\n throw err;\n }\n}\n\nexport async function updatePr(prConfig: UpdatePrConfig): Promise<void> {\n logger.debug(`updatePr(${prConfig.number}, ${prConfig.prTitle})`);\n if (prConfig.prBody) {\n await client.addMessageIfNotAlreadyExists(\n prConfig.number,\n prConfig.prBody,\n TAG_PULL_REQUEST_BODY,\n );\n }\n await client.setHashtags(prConfig.number, {\n add: prConfig.addLabels,\n remove: prConfig.removeLabels,\n });\n if (prConfig.targetBranch) {\n await client.moveChange(prConfig.number, prConfig.targetBranch);\n }\n if (prConfig.state && prConfig.state === 'closed') {\n await client.abandonChange(prConfig.number);\n }\n}\n\nexport async function createPr(prConfig: CreatePRConfig): Promise<Pr | null> {\n logger.debug(\n `createPr(${prConfig.sourceBranch}, ${prConfig.prTitle}, ${\n prConfig.labels?.toString() ?? ''\n })`,\n );\n\n logger.debug(\n `Pushing commit to refs/for/${prConfig.targetBranch} to create Gerrit change`,\n );\n const pushResult = await pushForReview({\n sourceRef: prConfig.sourceBranch,\n targetBranch: prConfig.targetBranch,\n files: [],\n autoApprove: prConfig.platformPrOptions?.autoApprove,\n labels: prConfig.labels ?? undefined,\n });\n\n if (!pushResult) {\n throw new Error(\n `Failed to push commit to refs/for/${prConfig.targetBranch} to create Gerrit change`,\n );\n }\n\n const change = (\n await client.findChanges(config.repository!, {\n branchName: prConfig.sourceBranch,\n targetBranch: prConfig.targetBranch,\n state: 'open',\n singleChange: true,\n requestDetails: REQUEST_DETAILS_FOR_PRS,\n })\n ).pop();\n if (isUndefined(change)) {\n throw new Error(\n `Could not find the Gerrit change after pushing to refs/for/${prConfig.targetBranch}`,\n );\n }\n\n // Register the virtual branch now that the change exists and we have the ref.\n const sha = toLongCommitSha(change.current_revision);\n const ref = change.revisions![sha].ref;\n await git.setVirtualBranch(prConfig.sourceBranch, ref, sha);\n\n await client.addMessage(\n change._number,\n prConfig.prBody,\n TAG_PULL_REQUEST_BODY,\n );\n return mapGerritChangeToPr(change, {\n sourceBranch: prConfig.sourceBranch,\n prBody: prConfig.prBody,\n });\n}\n\nexport async function getBranchPr(\n branchName: string,\n targetBranch?: string,\n): Promise<Pr | null> {\n const change = await client.getBranchChange(config.repository!, {\n branchName,\n state: 'open',\n targetBranch,\n requestDetails: REQUEST_DETAILS_FOR_PRS,\n });\n\n return change\n ? mapGerritChangeToPr(change, {\n sourceBranch: branchName,\n })\n : null;\n}\n\nexport async function getPrList(): Promise<Pr[]> {\n const changes = await client.findChanges(config.repository!, {\n branchName: '',\n requestDetails: REQUEST_DETAILS_FOR_PRS,\n });\n return changes.map((change) => mapGerritChangeToPr(change)).filter(isTruthy);\n}\n\nexport async function mergePr(config: MergePRConfig): Promise<boolean> {\n logger.debug(\n `mergePr(${config.id}, ${config.branchName!}, ${config.strategy!})`,\n );\n try {\n const change = await client.submitChange(config.id);\n return change.status === 'MERGED';\n } catch (err) {\n if (err.statusCode === 409) {\n logger.warn(\n { err },\n \"Can't submit the change, because the submit rule doesn't allow it.\",\n );\n return false;\n }\n throw err;\n }\n}\n\n/**\n * BranchStatus for Gerrit assumes that the branchName refers to a change.\n * @param branchName\n */\nexport async function getBranchStatus(\n branchName: string,\n): Promise<BranchStatus> {\n logger.debug(`getBranchStatus(${branchName})`);\n const change = (\n await client.findChanges(config.repository!, {\n state: 'open',\n branchName,\n singleChange: true,\n requestDetails: ['LABELS', 'SUBMITTABLE', 'CHECK'],\n })\n ).pop();\n if (change) {\n const hasProblems = change.problems && change.problems.length > 0;\n if (hasProblems) {\n return 'red';\n }\n const hasBlockingLabels = Object.values(coerceObject(change.labels)).some(\n (label) => label.blocking,\n );\n if (hasBlockingLabels) {\n return 'red';\n }\n // v8 ignore else -- TODO: add test #40625\n if (change.submittable) {\n return 'green';\n }\n }\n return 'yellow';\n}\n\n/**\n * check the gerrit-change for the presence of the corresponding \"$context\" Gerrit label if configured,\n * return 'yellow' if not configured or not set\n * @param branchName\n * @param context renovate/stability-days || ...\n */\nexport async function getBranchStatusCheck(\n branchName: string,\n context: string,\n): Promise<BranchStatus | null> {\n const labelConfig = config.labels[context];\n if (labelConfig) {\n const change = (\n await client.findChanges(config.repository!, {\n branchName,\n state: 'open',\n singleChange: true,\n requestDetails: ['LABELS'],\n })\n ).pop();\n // v8 ignore else -- TODO: add test #40625\n if (change) {\n const label = change.labels![context];\n // v8 ignore else -- TODO: add test #40625\n if (label) {\n // Check for rejected or blocking first, as a label could have both rejected and approved\n if (label.rejected || label.blocking) {\n return 'red';\n }\n // v8 ignore else -- TODO: add test #40625\n if (label.approved) {\n return 'green';\n }\n }\n }\n }\n return 'yellow';\n}\n\n/**\n * Apply the branch state $context to the corresponding gerrit label (if available)\n * context === \"renovate/stability-days\" / \"renovate/merge-confidence\" and state === \"green\"/...\n * @param branchStatusConfig\n */\nexport async function setBranchStatus(\n branchStatusConfig: BranchStatusConfig,\n): Promise<void> {\n const label = config.labels[branchStatusConfig.context];\n const labelValue =\n label && mapBranchStatusToLabel(branchStatusConfig.state, label);\n if (branchStatusConfig.context && labelValue) {\n const change = (\n await client.findChanges(config.repository!, {\n branchName: branchStatusConfig.branchName,\n state: 'open',\n singleChange: true,\n requestDetails: ['LABELS'],\n })\n ).pop();\n\n const labelKey = branchStatusConfig.context;\n if (!change?.labels || !Object.hasOwn(change.labels, labelKey)) {\n return;\n }\n\n await client.setLabel(change._number, labelKey, labelValue);\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 if (!repo) {\n logger.debug('No repo so cannot getRawFile');\n return null;\n }\n // v8 ignore next -- TODO: add test #40625\n const branch =\n branchOrTag ??\n (repo === config.repository ? (config.head ?? 'HEAD') : 'HEAD');\n const result = await client.getFile(repo, branch, fileName);\n return result;\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 addReviewers(\n number: number,\n reviewers: string[],\n): Promise<void> {\n await client.addReviewers(number, reviewers);\n}\n\n/**\n * add \"CC\" (only one possible)\n */\nexport async function addAssignees(\n number: number,\n assignees: string[],\n): Promise<void> {\n // v8 ignore else -- TODO: add test #40625\n if (assignees.length) {\n // v8 ignore else -- TODO: add test #40625\n if (assignees.length > 1) {\n logger.debug(\n `addAssignees(${number}, ${assignees.toString()}) called with more then one assignee! Gerrit only supports one assignee! Using the first from list.`,\n );\n }\n await client.addAssignee(number, assignees[0]);\n }\n}\n\nexport async function ensureComment(\n ensureComment: EnsureCommentConfig,\n): Promise<boolean> {\n logger.debug(\n `ensureComment(${ensureComment.number}, ${ensureComment.topic!}, ${\n ensureComment.content\n })`,\n );\n await client.addMessageIfNotAlreadyExists(\n ensureComment.number,\n ensureComment.content,\n ensureComment.topic ?? undefined,\n );\n return true;\n}\n\nexport function massageMarkdown(prBody: string, rebaseLabel: string): string {\n return (\n smartTruncate(readOnlyIssueBody(prBody), maxBodyLength())\n .replace('Branch creation', 'Change creation')\n .replace(\n 'close this Pull Request unmerged',\n 'abandon or vote this change with Code-Review -2',\n )\n .replace(\n 'Close this PR',\n 'Abandon or vote this change with Code-Review -2',\n )\n .replace(\n 'you tick the rebase/retry checkbox',\n `you add the _${rebaseLabel}_ hashtag to this change`,\n )\n .replace(\n 'checking the rebase/retry box above',\n `adding the _${rebaseLabel}_ hashtag to this change`,\n )\n .replace(regEx(/\\b(?:Pull Request|PR)/g), 'change')\n // Remove HTML tags not supported in Gerrit markdown\n .replace(regEx(/<\\/?summary>/g), '**')\n .replace(regEx(/<\\/?(?:details|blockquote)>/g), '')\n .replace(regEx(`\\n---\\n\\n.*?<!-- rebase-check -->.*?\\n`), '')\n .replace(regEx(/<!--renovate-(?:debug|config-hash):.*?-->/g), '')\n // Remove zero-width-space not supported in Gerrit markdown\n .replace(regEx(/&#8203;/g), '')\n );\n}\n\nexport function maxBodyLength(): number {\n return MAX_GERRIT_COMMENT_SIZE;\n}\n\nexport async function deleteLabel(\n number: number,\n label: string,\n): Promise<void> {\n await client.setHashtags(number, { remove: [label] });\n}\n\nexport function ensureCommentRemoval(\n _ensureCommentRemoval:\n EnsureCommentRemovalConfigByTopic | EnsureCommentRemovalConfigByContent,\n): Promise<void> {\n return Promise.resolve();\n}\n\nexport function ensureIssueClosing(_title: string): Promise<void> {\n return Promise.resolve();\n}\n\nexport function ensureIssue(\n _issueConfig: EnsureIssueConfig,\n): Promise<EnsureIssueResult | null> {\n return Promise.resolve(null);\n}\n\nexport function findIssue(_title: string): Promise<Issue | null> {\n return Promise.resolve(null);\n}\n\nexport function getIssueList(): Promise<Issue[]> {\n return Promise.resolve([]);\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"pr-cache.js","names":["memCache.get"],"sources":["../../../../lib/modules/platform/gitea/pr-cache.ts"],"sourcesContent":["import { isNullOrUndefined } from '@sindresorhus/is';\nimport { dequal } from 'dequal';\nimport { DateTime } from 'luxon';\nimport { TEMPORARY_ERROR } from '../../../constants/error-messages.ts';\nimport { logger } from '../../../logger/index.ts';\nimport * as memCache from '../../../util/cache/memory/index.ts';\nimport { getCache } from '../../../util/cache/repository/index.ts';\nimport type { GiteaHttp } from '../../../util/http/gitea.ts';\nimport type { HttpResponse } from '../../../util/http/types.ts';\nimport {\n getQueryString,\n parseLinkHeader,\n parseUrl,\n} from '../../../util/url.ts';\nimport type { Pr } from '../types.ts';\nimport type { GiteaPrCacheData, PR } from './types.ts';\nimport { API_PATH, toRenovatePR } from './utils.ts';\n\nexport class GiteaPrCache {\n private cache: GiteaPrCacheData;\n private items: Pr[] = [];\n private repo: string;\n private readonly ignorePrAuthor: boolean;\n private author: string | null;\n\n private constructor(\n repo: string,\n ignorePrAuthor: boolean,\n author: string | null,\n ) {\n this.repo = repo;\n this.ignorePrAuthor = ignorePrAuthor;\n this.author = author;\n const repoCache = getCache();\n repoCache.platform ??= {};\n repoCache.platform.gitea ??= {};\n let pullRequestCache = repoCache.platform.gitea.pullRequestsCache as\n | GiteaPrCacheData\n | undefined;\n if (\n isNullOrUndefined(pullRequestCache) ||\n pullRequestCache.author !== author\n ) {\n pullRequestCache = {\n items: {},\n updated_at: null,\n author,\n };\n }\n repoCache.platform.gitea.pullRequestsCache = pullRequestCache;\n this.cache = pullRequestCache;\n this.updateItems();\n }\n\n static forceSync(): void {\n memCache.set('gitea-pr-cache-synced', false);\n }\n\n private static async init(\n http: GiteaHttp,\n repo: string,\n ignorePrAuthor: boolean,\n author: string | null,\n ): Promise<GiteaPrCache> {\n const res = new GiteaPrCache(repo, ignorePrAuthor, author);\n const isSynced = memCache.get<true | undefined>('gitea-pr-cache-synced');\n\n if (!isSynced) {\n await res.sync(http);\n memCache.set('gitea-pr-cache-synced', true);\n }\n\n return res;\n }\n\n private getPrs(): Pr[] {\n return this.items;\n }\n\n static async getPrs(\n http: GiteaHttp,\n repo: string,\n ignorePrAuthor: boolean,\n author: string,\n ): Promise<Pr[]> {\n const prCache = await GiteaPrCache.init(http, repo, ignorePrAuthor, author);\n return prCache.getPrs();\n }\n\n private setPr(item: Pr): void {\n this.cache.items[item.number] = item;\n this.updateItems();\n }\n\n static async setPr(\n http: GiteaHttp,\n repo: string,\n ignorePrAuthor: boolean,\n author: string,\n item: Pr,\n ): Promise<void> {\n const prCache = await GiteaPrCache.init(http, repo, ignorePrAuthor, author);\n prCache.setPr(item);\n }\n\n private reconcile(rawItems: (PR | null)[]): boolean {\n const { items } = this.cache;\n let { updated_at } = this.cache;\n const cacheTime = updated_at ? DateTime.fromISO(updated_at) : null;\n\n let needNextPage = true;\n\n for (const rawItem of rawItems) {\n if (!rawItem) {\n logger.warn('Gitea PR is empty, throwing temporary error');\n // Gitea API sometimes returns empty PRs, so we throw a temporary error\n // https://github.com/go-gitea/gitea/blob/fcd096231ac2deaefbca10a7db1b9b01f1da93d7/services/convert/pull.go#L34-L52\n throw new Error(TEMPORARY_ERROR);\n }\n const id = rawItem.number;\n\n const newItem = toRenovatePR(rawItem, this.author);\n if (!newItem) {\n continue;\n }\n\n const oldItem = items[id];\n if (dequal(oldItem, newItem)) {\n needNextPage = false;\n continue;\n }\n\n items[id] = newItem;\n\n const itemTime = DateTime.fromISO(rawItem.updated_at);\n if (!cacheTime || itemTime > cacheTime) {\n updated_at = rawItem.updated_at;\n }\n }\n\n this.cache.updated_at = updated_at;\n\n return needNextPage;\n }\n\n private async sync(http: GiteaHttp): Promise<GiteaPrCache> {\n let query: string | null = getQueryString({\n state: 'all',\n sort: 'recentupdate',\n // Fetch 100 PRs on the first run to ensure we have the most recent PRs.\n // Gitea / Forgejo will cap appropriate (50 by default, see `MAX_RESPONSE_ITEMS`).\n // https://docs.gitea.com/administration/config-cheat-sheet#api-api\n // https://forgejo.org/docs/latest/admin/config-cheat-sheet/#api-api\n limit: this.items.length ? 20 : 100,\n // Supported since Gitea 1.23.0 and Forgejo v10.0.0.\n // Will be ignoded by older instances.\n ...(this.ignorePrAuthor ? {} : { poster: this.author }),\n });\n\n while (query) {\n // TODO: use zod, typescript can't infer the type of the response #22198\n const res: HttpResponse<(PR | null)[]> = await http.getJsonUnchecked(\n `${API_PATH}/repos/${this.repo}/pulls?${query}`,\n {\n memCache: false,\n paginate: false,\n },\n );\n\n const needNextPage = this.reconcile(res.body);\n if (!needNextPage) {\n break;\n }\n\n const uri = parseUrl(parseLinkHeader(res.headers.link)?.next?.url);\n query = uri ? uri.search : null;\n }\n\n this.updateItems();\n\n return this;\n }\n\n /**\n * Ensure the pr cache starts with the most recent PRs.\n * JavaScript ensures that the cache is sorted by PR number.\n */\n private updateItems(): void {\n this.items = Object.values(this.cache.items).reverse();\n }\n}\n"],"mappings":";;;;;;;;;;AAkBA,IAAa,eAAb,MAAa,aAAa;CACxB;CACA,QAAsB,CAAC;CACvB;CACA;CACA;CAEA,YACE,MACA,gBACA,QACA;EACA,KAAK,OAAO;EACZ,KAAK,iBAAiB;EACtB,KAAK,SAAS;EACd,MAAM,YAAY,SAAS;EAC3B,UAAU,aAAa,CAAC;EACxB,UAAU,SAAS,UAAU,CAAC;EAC9B,IAAI,mBAAmB,UAAU,SAAS,MAAM;EAGhD,IACE,kBAAkB,gBAAgB,KAClC,iBAAiB,WAAW,QAE5B,mBAAmB;GACjB,OAAO,CAAC;GACR,YAAY;GACZ;EACF;EAEF,UAAU,SAAS,MAAM,oBAAoB;EAC7C,KAAK,QAAQ;EACb,KAAK,YAAY;CACnB;CAEA,OAAO,YAAkB;EACvB,IAAa,yBAAyB,KAAK;CAC7C;CAEA,aAAqB,KACnB,MACA,MACA,gBACA,QACuB;EACvB,MAAM,MAAM,IAAI,aAAa,MAAM,gBAAgB,MAAM;EAGzD,IAAI,CAFaA,IAA+B,uBAEpC,GAAG;GACb,MAAM,IAAI,KAAK,IAAI;GACnB,IAAa,yBAAyB,IAAI;EAC5C;EAEA,OAAO;CACT;CAEA,SAAuB;EACrB,OAAO,KAAK;CACd;CAEA,aAAa,OACX,MACA,MACA,gBACA,QACe;EAEf,QAAO,MADe,aAAa,KAAK,MAAM,MAAM,gBAAgB,MAAM,EAAA,CAC3D,OAAO;CACxB;CAEA,MAAc,MAAgB;EAC5B,KAAK,MAAM,MAAM,KAAK,UAAU;EAChC,KAAK,YAAY;CACnB;CAEA,aAAa,MACX,MACA,MACA,gBACA,QACA,MACe;EAEf,CAAA,MADsB,aAAa,KAAK,MAAM,MAAM,gBAAgB,MAAM,EAAA,CAClE,MAAM,IAAI;CACpB;CAEA,UAAkB,UAAkC;EAClD,MAAM,EAAE,UAAU,KAAK;EACvB,IAAI,EAAE,eAAe,KAAK;EAC1B,MAAM,YAAY,aAAa,SAAS,QAAQ,UAAU,IAAI;EAE9D,IAAI,eAAe;EAEnB,KAAK,MAAM,WAAW,UAAU;GAC9B,IAAI,CAAC,SAAS;IACZ,OAAO,KAAK,6CAA6C;IAGzD,MAAM,IAAI,MAAM,eAAe;GACjC;GACA,MAAM,KAAK,QAAQ;GAEnB,MAAM,UAAU,aAAa,SAAS,KAAK,MAAM;GACjD,IAAI,CAAC,SACH;GAGF,MAAM,UAAU,MAAM;GACtB,IAAI,OAAO,SAAS,OAAO,GAAG;IAC5B,eAAe;IACf;GACF;GAEA,MAAM,MAAM;GAEZ,MAAM,WAAW,SAAS,QAAQ,QAAQ,UAAU;GACpD,IAAI,CAAC,aAAa,WAAW,WAC3B,aAAa,QAAQ;EAEzB;EAEA,KAAK,MAAM,aAAa;EAExB,OAAO;CACT;CAEA,MAAc,KAAK,MAAwC;EACzD,IAAI,QAAuB,eAAe;GACxC,OAAO;GACP,MAAM;GAKN,OAAO,KAAK,MAAM,SAAS,KAAK;GAGhC,GAAI,KAAK,iBAAiB,CAAC,IAAI,EAAE,QAAQ,KAAK,OAAO;EACvD,CAAC;EAED,OAAO,OAAO;GAEZ,MAAM,MAAmC,MAAM,KAAK,iBAClD,GAAG,SAAS,SAAS,KAAK,KAAK,SAAS,SACxC;IACE,UAAU;IACV,UAAU;GACZ,CACF;GAGA,IAAI,CADiB,KAAK,UAAU,IAAI,IACxB,GACd;GAGF,MAAM,MAAM,SAAS,gBAAgB,IAAI,QAAQ,IAAI,CAAC,EAAE,MAAM,GAAG;GACjE,QAAQ,MAAM,IAAI,SAAS;EAC7B;EAEA,KAAK,YAAY;EAEjB,OAAO;CACT;;;;;CAMA,cAA4B;EAC1B,KAAK,QAAQ,OAAO,OAAO,KAAK,MAAM,KAAK,CAAC,CAAC,QAAQ;CACvD;AACF"}
1
+ {"version":3,"file":"pr-cache.js","names":["memCache.get"],"sources":["../../../../lib/modules/platform/gitea/pr-cache.ts"],"sourcesContent":["import { isNullOrUndefined } from '@sindresorhus/is';\nimport { dequal } from 'dequal';\nimport { DateTime } from 'luxon';\nimport { TEMPORARY_ERROR } from '../../../constants/error-messages.ts';\nimport { logger } from '../../../logger/index.ts';\nimport * as memCache from '../../../util/cache/memory/index.ts';\nimport { getCache } from '../../../util/cache/repository/index.ts';\nimport type { GiteaHttp } from '../../../util/http/gitea.ts';\nimport type { HttpResponse } from '../../../util/http/types.ts';\nimport {\n getQueryString,\n parseLinkHeader,\n parseUrl,\n} from '../../../util/url.ts';\nimport type { Pr } from '../types.ts';\nimport type { GiteaPrCacheData, PR } from './types.ts';\nimport { API_PATH, toRenovatePR } from './utils.ts';\n\nexport class GiteaPrCache {\n private cache: GiteaPrCacheData;\n private items: Pr[] = [];\n private repo: string;\n private readonly ignorePrAuthor: boolean;\n private author: string | null;\n\n private constructor(\n repo: string,\n ignorePrAuthor: boolean,\n author: string | null,\n ) {\n this.repo = repo;\n this.ignorePrAuthor = ignorePrAuthor;\n this.author = author;\n const repoCache = getCache();\n repoCache.platform ??= {};\n repoCache.platform.gitea ??= {};\n let pullRequestCache = repoCache.platform.gitea.pullRequestsCache as\n GiteaPrCacheData | undefined;\n if (\n isNullOrUndefined(pullRequestCache) ||\n pullRequestCache.author !== author\n ) {\n pullRequestCache = {\n items: {},\n updated_at: null,\n author,\n };\n }\n repoCache.platform.gitea.pullRequestsCache = pullRequestCache;\n this.cache = pullRequestCache;\n this.updateItems();\n }\n\n static forceSync(): void {\n memCache.set('gitea-pr-cache-synced', false);\n }\n\n private static async init(\n http: GiteaHttp,\n repo: string,\n ignorePrAuthor: boolean,\n author: string | null,\n ): Promise<GiteaPrCache> {\n const res = new GiteaPrCache(repo, ignorePrAuthor, author);\n const isSynced = memCache.get<true | undefined>('gitea-pr-cache-synced');\n\n if (!isSynced) {\n await res.sync(http);\n memCache.set('gitea-pr-cache-synced', true);\n }\n\n return res;\n }\n\n private getPrs(): Pr[] {\n return this.items;\n }\n\n static async getPrs(\n http: GiteaHttp,\n repo: string,\n ignorePrAuthor: boolean,\n author: string,\n ): Promise<Pr[]> {\n const prCache = await GiteaPrCache.init(http, repo, ignorePrAuthor, author);\n return prCache.getPrs();\n }\n\n private setPr(item: Pr): void {\n this.cache.items[item.number] = item;\n this.updateItems();\n }\n\n static async setPr(\n http: GiteaHttp,\n repo: string,\n ignorePrAuthor: boolean,\n author: string,\n item: Pr,\n ): Promise<void> {\n const prCache = await GiteaPrCache.init(http, repo, ignorePrAuthor, author);\n prCache.setPr(item);\n }\n\n private reconcile(rawItems: (PR | null)[]): boolean {\n const { items } = this.cache;\n let { updated_at } = this.cache;\n const cacheTime = updated_at ? DateTime.fromISO(updated_at) : null;\n\n let needNextPage = true;\n\n for (const rawItem of rawItems) {\n if (!rawItem) {\n logger.warn('Gitea PR is empty, throwing temporary error');\n // Gitea API sometimes returns empty PRs, so we throw a temporary error\n // https://github.com/go-gitea/gitea/blob/fcd096231ac2deaefbca10a7db1b9b01f1da93d7/services/convert/pull.go#L34-L52\n throw new Error(TEMPORARY_ERROR);\n }\n const id = rawItem.number;\n\n const newItem = toRenovatePR(rawItem, this.author);\n if (!newItem) {\n continue;\n }\n\n const oldItem = items[id];\n if (dequal(oldItem, newItem)) {\n needNextPage = false;\n continue;\n }\n\n items[id] = newItem;\n\n const itemTime = DateTime.fromISO(rawItem.updated_at);\n if (!cacheTime || itemTime > cacheTime) {\n updated_at = rawItem.updated_at;\n }\n }\n\n this.cache.updated_at = updated_at;\n\n return needNextPage;\n }\n\n private async sync(http: GiteaHttp): Promise<GiteaPrCache> {\n let query: string | null = getQueryString({\n state: 'all',\n sort: 'recentupdate',\n // Fetch 100 PRs on the first run to ensure we have the most recent PRs.\n // Gitea / Forgejo will cap appropriate (50 by default, see `MAX_RESPONSE_ITEMS`).\n // https://docs.gitea.com/administration/config-cheat-sheet#api-api\n // https://forgejo.org/docs/latest/admin/config-cheat-sheet/#api-api\n limit: this.items.length ? 20 : 100,\n // Supported since Gitea 1.23.0 and Forgejo v10.0.0.\n // Will be ignoded by older instances.\n ...(this.ignorePrAuthor ? {} : { poster: this.author }),\n });\n\n while (query) {\n // TODO: use zod, typescript can't infer the type of the response #22198\n const res: HttpResponse<(PR | null)[]> = await http.getJsonUnchecked(\n `${API_PATH}/repos/${this.repo}/pulls?${query}`,\n {\n memCache: false,\n paginate: false,\n },\n );\n\n const needNextPage = this.reconcile(res.body);\n if (!needNextPage) {\n break;\n }\n\n const uri = parseUrl(parseLinkHeader(res.headers.link)?.next?.url);\n query = uri ? uri.search : null;\n }\n\n this.updateItems();\n\n return this;\n }\n\n /**\n * Ensure the pr cache starts with the most recent PRs.\n * JavaScript ensures that the cache is sorted by PR number.\n */\n private updateItems(): void {\n this.items = Object.values(this.cache.items).reverse();\n }\n}\n"],"mappings":";;;;;;;;;;AAkBA,IAAa,eAAb,MAAa,aAAa;CACxB;CACA,QAAsB,CAAC;CACvB;CACA;CACA;CAEA,YACE,MACA,gBACA,QACA;EACA,KAAK,OAAO;EACZ,KAAK,iBAAiB;EACtB,KAAK,SAAS;EACd,MAAM,YAAY,SAAS;EAC3B,UAAU,aAAa,CAAC;EACxB,UAAU,SAAS,UAAU,CAAC;EAC9B,IAAI,mBAAmB,UAAU,SAAS,MAAM;EAEhD,IACE,kBAAkB,gBAAgB,KAClC,iBAAiB,WAAW,QAE5B,mBAAmB;GACjB,OAAO,CAAC;GACR,YAAY;GACZ;EACF;EAEF,UAAU,SAAS,MAAM,oBAAoB;EAC7C,KAAK,QAAQ;EACb,KAAK,YAAY;CACnB;CAEA,OAAO,YAAkB;EACvB,IAAa,yBAAyB,KAAK;CAC7C;CAEA,aAAqB,KACnB,MACA,MACA,gBACA,QACuB;EACvB,MAAM,MAAM,IAAI,aAAa,MAAM,gBAAgB,MAAM;EAGzD,IAAI,CAFaA,IAA+B,uBAEpC,GAAG;GACb,MAAM,IAAI,KAAK,IAAI;GACnB,IAAa,yBAAyB,IAAI;EAC5C;EAEA,OAAO;CACT;CAEA,SAAuB;EACrB,OAAO,KAAK;CACd;CAEA,aAAa,OACX,MACA,MACA,gBACA,QACe;EAEf,QAAO,MADe,aAAa,KAAK,MAAM,MAAM,gBAAgB,MAAM,EAAA,CAC3D,OAAO;CACxB;CAEA,MAAc,MAAgB;EAC5B,KAAK,MAAM,MAAM,KAAK,UAAU;EAChC,KAAK,YAAY;CACnB;CAEA,aAAa,MACX,MACA,MACA,gBACA,QACA,MACe;EAEf,CAAA,MADsB,aAAa,KAAK,MAAM,MAAM,gBAAgB,MAAM,EAAA,CAClE,MAAM,IAAI;CACpB;CAEA,UAAkB,UAAkC;EAClD,MAAM,EAAE,UAAU,KAAK;EACvB,IAAI,EAAE,eAAe,KAAK;EAC1B,MAAM,YAAY,aAAa,SAAS,QAAQ,UAAU,IAAI;EAE9D,IAAI,eAAe;EAEnB,KAAK,MAAM,WAAW,UAAU;GAC9B,IAAI,CAAC,SAAS;IACZ,OAAO,KAAK,6CAA6C;IAGzD,MAAM,IAAI,MAAM,eAAe;GACjC;GACA,MAAM,KAAK,QAAQ;GAEnB,MAAM,UAAU,aAAa,SAAS,KAAK,MAAM;GACjD,IAAI,CAAC,SACH;GAGF,MAAM,UAAU,MAAM;GACtB,IAAI,OAAO,SAAS,OAAO,GAAG;IAC5B,eAAe;IACf;GACF;GAEA,MAAM,MAAM;GAEZ,MAAM,WAAW,SAAS,QAAQ,QAAQ,UAAU;GACpD,IAAI,CAAC,aAAa,WAAW,WAC3B,aAAa,QAAQ;EAEzB;EAEA,KAAK,MAAM,aAAa;EAExB,OAAO;CACT;CAEA,MAAc,KAAK,MAAwC;EACzD,IAAI,QAAuB,eAAe;GACxC,OAAO;GACP,MAAM;GAKN,OAAO,KAAK,MAAM,SAAS,KAAK;GAGhC,GAAI,KAAK,iBAAiB,CAAC,IAAI,EAAE,QAAQ,KAAK,OAAO;EACvD,CAAC;EAED,OAAO,OAAO;GAEZ,MAAM,MAAmC,MAAM,KAAK,iBAClD,GAAG,SAAS,SAAS,KAAK,KAAK,SAAS,SACxC;IACE,UAAU;IACV,UAAU;GACZ,CACF;GAGA,IAAI,CADiB,KAAK,UAAU,IAAI,IACxB,GACd;GAGF,MAAM,MAAM,SAAS,gBAAgB,IAAI,QAAQ,IAAI,CAAC,EAAE,MAAM,GAAG;GACjE,QAAQ,MAAM,IAAI,SAAS;EAC7B;EAEA,KAAK,YAAY;EAEjB,OAAO;CACT;;;;;CAMA,cAA4B;EAC1B,KAAK,QAAQ,OAAO,OAAO,KAAK,MAAM,KAAK,CAAC,CAAC,QAAQ;CACvD;AACF"}
@@ -56,7 +56,7 @@ const GithubVulnerabilityAlerts = LooseArray(z.object({
56
56
  security_vulnerability: SecurityVulnerability,
57
57
  dependency: z.object({ manifest_path: z.string() })
58
58
  }), { onError: ({ error }) => {
59
- logger.debug({ error }, "Vulnerability Alert: Failed to parse some alerts");
59
+ logger.debug({ err: error }, "Vulnerability Alert: Failed to parse some alerts");
60
60
  } }).transform((alerts) => alerts.filter((alert) => alert.security_vulnerability?.package?.ecosystem));
61
61
  const GithubResponseMetadata = z.object({
62
62
  name: z.string(),
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","names":[],"sources":["../../../../lib/modules/platform/github/schema.ts"],"sourcesContent":["import { z } from 'zod/v4';\nimport { logger } from '../../../logger/index.ts';\nimport {\n DeepNullish,\n LooseArray,\n Nullish,\n} from '../../../util/schema-utils/index.ts';\n\nconst Ecosystem = z.enum([\n 'actions',\n 'composer',\n 'go',\n 'maven',\n 'npm',\n 'nuget',\n 'pip',\n 'rubygems',\n 'rust',\n]);\nexport type Ecosystem = z.infer<typeof Ecosystem>;\n\nconst Package = z.object({\n ecosystem: Ecosystem.catch((ctx) => {\n logger.debug(\n { ecosystem: ctx.input },\n 'Skipping vulnerability alert with unsupported ecosystem',\n );\n return undefined as any;\n }),\n name: z.string(),\n});\n\nconst Severity = z.enum(['low', 'medium', 'high', 'critical']);\n\nconst SecurityVulnerability = z\n .object({\n first_patched_version: Nullish(z.object({ identifier: z.string() })),\n package: Package,\n severity: Severity,\n vulnerable_version_range: z.string(),\n })\n .nullable();\n\nconst CvssSeverity = z.object({\n vector_string: z.string().nullable(),\n score: z.number().nullable(),\n});\n\nconst SecurityAdvisory = z.object({\n ghsa_id: z.string(),\n summary: z.string(),\n description: z.string(),\n identifiers: z.array(\n z.object({\n type: z.string(),\n value: z.string(),\n }),\n ),\n references: z.array(z.object({ url: z.string() })).optional(),\n severity: Severity,\n cvss_severities: Nullish(\n DeepNullish(\n z.object({\n cvss_v3: CvssSeverity.optional(),\n cvss_v4: CvssSeverity.optional(),\n }),\n ),\n ),\n});\nexport type SecurityAdvisory = z.infer<typeof SecurityAdvisory>;\n\nexport const GithubVulnerabilityAlerts = LooseArray(\n z.object({\n dismissed_reason: Nullish(z.string()),\n security_advisory: SecurityAdvisory,\n security_vulnerability: SecurityVulnerability,\n dependency: z.object({\n manifest_path: z.string(),\n }),\n }),\n {\n onError: ({ error }) => {\n logger.debug(\n { error },\n 'Vulnerability Alert: Failed to parse some alerts',\n );\n },\n },\n).transform((alerts) =>\n alerts.filter((alert) => alert.security_vulnerability?.package?.ecosystem),\n);\nexport type GithubVulnerabilityAlerts = z.infer<\n typeof GithubVulnerabilityAlerts\n>;\nexport type GithubVulnerabilityAlert = GithubVulnerabilityAlerts[number];\n\n// https://docs.github.com/en/rest/repos/contents?apiVersion=2022-11-28#get-repository-content\nconst GithubResponseMetadata = z.object({\n name: z.string(),\n path: z.string(),\n});\n\nexport const GithubFileMeta = GithubResponseMetadata.extend({\n type: z.literal('file'),\n});\nexport type GithubFileMeta = z.infer<typeof GithubFileMeta>;\n\nexport const GithubFile = GithubFileMeta.extend({\n content: z.string(),\n encoding: z.string(),\n});\nexport type GithubFile = z.infer<typeof GithubFile>;\n\nexport const GithubDirectory = GithubResponseMetadata.extend({\n type: z.literal('dir'),\n});\n\nexport type GithubDirectory = z.infer<typeof GithubDirectory>;\n\nexport const GithubOtherContent = GithubResponseMetadata.extend({\n type: z.literal('symlink').or(z.literal('submodule')),\n});\n\nexport type GithubOtherContent = z.infer<typeof GithubOtherContent>;\n\nexport const GithubElement = GithubFile.or(GithubFileMeta)\n .or(GithubDirectory)\n .or(GithubOtherContent);\nexport type GithubElement = z.infer<typeof GithubElement>;\n\nexport const GithubContentResponse = z.array(GithubElement).or(GithubElement);\n\nexport const GithubBranchProtection = z.object({\n required_status_checks: Nullish(\n z.object({\n strict: z.boolean(),\n }),\n ),\n});\nexport type GithubBranchProtection = z.infer<typeof GithubBranchProtection>;\n\nconst GithubRulesetRule = z.discriminatedUnion('type', [\n z.object({\n type: z.literal('non_fast_forward'),\n }),\n z.object({\n type: z.literal('required_status_checks'),\n parameters: z.object({\n strict_required_status_checks_policy: z.boolean().optional(),\n }),\n }),\n // prevents deletion\n z.object({\n type: z.literal('deletion'),\n }),\n]);\n\nexport const GithubBranchRulesets = LooseArray(GithubRulesetRule);\nexport type GithubBranchRulesets = z.infer<typeof GithubBranchRulesets>;\n\nconst GithubIssueBase = z.object({\n number: z.number(),\n state: z.string().transform((val) => val.toLowerCase()),\n title: z.string(),\n body: z.string(),\n});\n\nconst GithubGraphqlIssue = GithubIssueBase.extend({\n updatedAt: z.string(),\n}).transform((issue) => {\n const lastModified = issue.updatedAt;\n const { number, state, title, body } = issue;\n return { number, state, title, body, lastModified };\n});\n\nconst GithubRestIssue = GithubIssueBase.extend({\n updated_at: z.string(),\n}).transform((issue) => {\n const lastModified = issue.updated_at;\n const { number, state, title, body } = issue;\n return { number, state, title, body, lastModified };\n});\n\nexport const GithubIssue = z.union([GithubGraphqlIssue, GithubRestIssue]);\nexport type GithubIssue = z.infer<typeof GithubIssue>;\n"],"mappings":"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"}
1
+ {"version":3,"file":"schema.js","names":[],"sources":["../../../../lib/modules/platform/github/schema.ts"],"sourcesContent":["import { z } from 'zod/v4';\nimport { logger } from '../../../logger/index.ts';\nimport {\n DeepNullish,\n LooseArray,\n Nullish,\n} from '../../../util/schema-utils/index.ts';\n\nconst Ecosystem = z.enum([\n 'actions',\n 'composer',\n 'go',\n 'maven',\n 'npm',\n 'nuget',\n 'pip',\n 'rubygems',\n 'rust',\n]);\nexport type Ecosystem = z.infer<typeof Ecosystem>;\n\nconst Package = z.object({\n ecosystem: Ecosystem.catch((ctx) => {\n logger.debug(\n { ecosystem: ctx.input },\n 'Skipping vulnerability alert with unsupported ecosystem',\n );\n return undefined as any;\n }),\n name: z.string(),\n});\n\nconst Severity = z.enum(['low', 'medium', 'high', 'critical']);\n\nconst SecurityVulnerability = z\n .object({\n first_patched_version: Nullish(z.object({ identifier: z.string() })),\n package: Package,\n severity: Severity,\n vulnerable_version_range: z.string(),\n })\n .nullable();\n\nconst CvssSeverity = z.object({\n vector_string: z.string().nullable(),\n score: z.number().nullable(),\n});\n\nconst SecurityAdvisory = z.object({\n ghsa_id: z.string(),\n summary: z.string(),\n description: z.string(),\n identifiers: z.array(\n z.object({\n type: z.string(),\n value: z.string(),\n }),\n ),\n references: z.array(z.object({ url: z.string() })).optional(),\n severity: Severity,\n cvss_severities: Nullish(\n DeepNullish(\n z.object({\n cvss_v3: CvssSeverity.optional(),\n cvss_v4: CvssSeverity.optional(),\n }),\n ),\n ),\n});\nexport type SecurityAdvisory = z.infer<typeof SecurityAdvisory>;\n\nexport const GithubVulnerabilityAlerts = LooseArray(\n z.object({\n dismissed_reason: Nullish(z.string()),\n security_advisory: SecurityAdvisory,\n security_vulnerability: SecurityVulnerability,\n dependency: z.object({\n manifest_path: z.string(),\n }),\n }),\n {\n onError: ({ error }) => {\n logger.debug(\n { err: error },\n 'Vulnerability Alert: Failed to parse some alerts',\n );\n },\n },\n).transform((alerts) =>\n alerts.filter((alert) => alert.security_vulnerability?.package?.ecosystem),\n);\nexport type GithubVulnerabilityAlerts = z.infer<\n typeof GithubVulnerabilityAlerts\n>;\nexport type GithubVulnerabilityAlert = GithubVulnerabilityAlerts[number];\n\n// https://docs.github.com/en/rest/repos/contents?apiVersion=2022-11-28#get-repository-content\nconst GithubResponseMetadata = z.object({\n name: z.string(),\n path: z.string(),\n});\n\nexport const GithubFileMeta = GithubResponseMetadata.extend({\n type: z.literal('file'),\n});\nexport type GithubFileMeta = z.infer<typeof GithubFileMeta>;\n\nexport const GithubFile = GithubFileMeta.extend({\n content: z.string(),\n encoding: z.string(),\n});\nexport type GithubFile = z.infer<typeof GithubFile>;\n\nexport const GithubDirectory = GithubResponseMetadata.extend({\n type: z.literal('dir'),\n});\n\nexport type GithubDirectory = z.infer<typeof GithubDirectory>;\n\nexport const GithubOtherContent = GithubResponseMetadata.extend({\n type: z.literal('symlink').or(z.literal('submodule')),\n});\n\nexport type GithubOtherContent = z.infer<typeof GithubOtherContent>;\n\nexport const GithubElement = GithubFile.or(GithubFileMeta)\n .or(GithubDirectory)\n .or(GithubOtherContent);\nexport type GithubElement = z.infer<typeof GithubElement>;\n\nexport const GithubContentResponse = z.array(GithubElement).or(GithubElement);\n\nexport const GithubBranchProtection = z.object({\n required_status_checks: Nullish(\n z.object({\n strict: z.boolean(),\n }),\n ),\n});\nexport type GithubBranchProtection = z.infer<typeof GithubBranchProtection>;\n\nconst GithubRulesetRule = z.discriminatedUnion('type', [\n z.object({\n type: z.literal('non_fast_forward'),\n }),\n z.object({\n type: z.literal('required_status_checks'),\n parameters: z.object({\n strict_required_status_checks_policy: z.boolean().optional(),\n }),\n }),\n // prevents deletion\n z.object({\n type: z.literal('deletion'),\n }),\n]);\n\nexport const GithubBranchRulesets = LooseArray(GithubRulesetRule);\nexport type GithubBranchRulesets = z.infer<typeof GithubBranchRulesets>;\n\nconst GithubIssueBase = z.object({\n number: z.number(),\n state: z.string().transform((val) => val.toLowerCase()),\n title: z.string(),\n body: z.string(),\n});\n\nconst GithubGraphqlIssue = GithubIssueBase.extend({\n updatedAt: z.string(),\n}).transform((issue) => {\n const lastModified = issue.updatedAt;\n const { number, state, title, body } = issue;\n return { number, state, title, body, lastModified };\n});\n\nconst GithubRestIssue = GithubIssueBase.extend({\n updated_at: z.string(),\n}).transform((issue) => {\n const lastModified = issue.updated_at;\n const { number, state, title, body } = issue;\n return { number, state, title, body, lastModified };\n});\n\nexport const GithubIssue = z.union([GithubGraphqlIssue, GithubRestIssue]);\nexport type GithubIssue = z.infer<typeof GithubIssue>;\n"],"mappings":"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"}