renovate 44.210.2 → 44.211.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 (307) hide show
  1. package/dist/config/options/index.js +1 -1
  2. package/dist/config/options/index.js.map +1 -1
  3. package/dist/config/utils.js +2 -1
  4. package/dist/config/utils.js.map +1 -1
  5. package/dist/config/validation-helpers/regex-glob-matchers.js.map +1 -1
  6. package/dist/config/validation-helpers/utils.js +5 -1
  7. package/dist/config/validation-helpers/utils.js.map +1 -1
  8. package/dist/config/validation.js +8 -2
  9. package/dist/config/validation.js.map +1 -1
  10. package/dist/config-validator.js +1 -1
  11. package/dist/config-validator.js.map +1 -1
  12. package/dist/global-config-option-defaults.generated.js +1 -1
  13. package/dist/global-config-option-defaults.generated.js.map +1 -1
  14. package/dist/instrumentation/index.js +3 -2
  15. package/dist/instrumentation/index.js.map +1 -1
  16. package/dist/logger/bunyan.js +3 -2
  17. package/dist/logger/bunyan.js.map +1 -1
  18. package/dist/logger/pretty-stdout.js +2 -1
  19. package/dist/logger/pretty-stdout.js.map +1 -1
  20. package/dist/modules/datasource/apk/index.js +2 -2
  21. package/dist/modules/datasource/apk/index.js.map +1 -1
  22. package/dist/modules/datasource/artifactory/index.js +2 -3
  23. package/dist/modules/datasource/artifactory/index.js.map +1 -1
  24. package/dist/modules/datasource/bazel/index.js +2 -1
  25. package/dist/modules/datasource/bazel/index.js.map +1 -1
  26. package/dist/modules/datasource/cdnjs/index.js +2 -1
  27. package/dist/modules/datasource/cdnjs/index.js.map +1 -1
  28. package/dist/modules/datasource/conda/index.js +2 -1
  29. package/dist/modules/datasource/conda/index.js.map +1 -1
  30. package/dist/modules/datasource/crate/index.js +2 -1
  31. package/dist/modules/datasource/crate/index.js.map +1 -1
  32. package/dist/modules/datasource/dart-version/index.js +2 -1
  33. package/dist/modules/datasource/dart-version/index.js.map +1 -1
  34. package/dist/modules/datasource/datasource.js +2 -2
  35. package/dist/modules/datasource/datasource.js.map +1 -1
  36. package/dist/modules/datasource/deb/url.js +3 -1
  37. package/dist/modules/datasource/deb/url.js.map +1 -1
  38. package/dist/modules/datasource/devbox/index.js +2 -1
  39. package/dist/modules/datasource/devbox/index.js.map +1 -1
  40. package/dist/modules/datasource/docker/common.js +10 -8
  41. package/dist/modules/datasource/docker/common.js.map +1 -1
  42. package/dist/modules/datasource/docker/ecr.js +2 -1
  43. package/dist/modules/datasource/docker/ecr.js.map +1 -1
  44. package/dist/modules/datasource/docker/index.js +20 -17
  45. package/dist/modules/datasource/docker/index.js.map +1 -1
  46. package/dist/modules/datasource/gitea-tags/base.js +2 -3
  47. package/dist/modules/datasource/gitea-tags/base.js.map +1 -1
  48. package/dist/modules/datasource/github-tags/index.js +2 -1
  49. package/dist/modules/datasource/github-tags/index.js.map +1 -1
  50. package/dist/modules/datasource/gitlab-tags/index.js +2 -3
  51. package/dist/modules/datasource/gitlab-tags/index.js.map +1 -1
  52. package/dist/modules/datasource/go/base.js +1 -1
  53. package/dist/modules/datasource/go/base.js.map +1 -1
  54. package/dist/modules/datasource/go/common.js +8 -2
  55. package/dist/modules/datasource/go/common.js.map +1 -1
  56. package/dist/modules/datasource/go/env.js +2 -1
  57. package/dist/modules/datasource/go/env.js.map +1 -1
  58. package/dist/modules/datasource/go/releases-goproxy.js +7 -5
  59. package/dist/modules/datasource/go/releases-goproxy.js.map +1 -1
  60. package/dist/modules/datasource/helm/index.js +2 -1
  61. package/dist/modules/datasource/helm/index.js.map +1 -1
  62. package/dist/modules/datasource/hexpm-bob/index.js +2 -1
  63. package/dist/modules/datasource/hexpm-bob/index.js.map +1 -1
  64. package/dist/modules/datasource/index.js +4 -3
  65. package/dist/modules/datasource/index.js.map +1 -1
  66. package/dist/modules/datasource/java-version/adoptium.js +3 -2
  67. package/dist/modules/datasource/java-version/adoptium.js.map +1 -1
  68. package/dist/modules/datasource/java-version/graalvm.js +2 -1
  69. package/dist/modules/datasource/java-version/graalvm.js.map +1 -1
  70. package/dist/modules/datasource/maven/index.js.map +1 -1
  71. package/dist/modules/datasource/maven/util.js +7 -10
  72. package/dist/modules/datasource/maven/util.js.map +1 -1
  73. package/dist/modules/datasource/npm/npmrc.js +2 -2
  74. package/dist/modules/datasource/npm/npmrc.js.map +1 -1
  75. package/dist/modules/datasource/nuget/v3.js +3 -5
  76. package/dist/modules/datasource/nuget/v3.js.map +1 -1
  77. package/dist/modules/datasource/packagist/index.js +4 -5
  78. package/dist/modules/datasource/packagist/index.js.map +1 -1
  79. package/dist/modules/datasource/pod/index.js +4 -4
  80. package/dist/modules/datasource/pod/index.js.map +1 -1
  81. package/dist/modules/datasource/pypi/index.js +19 -11
  82. package/dist/modules/datasource/pypi/index.js.map +1 -1
  83. package/dist/modules/datasource/python-version/index.js +2 -3
  84. package/dist/modules/datasource/python-version/index.js.map +1 -1
  85. package/dist/modules/datasource/repology/index.js +4 -3
  86. package/dist/modules/datasource/repology/index.js.map +1 -1
  87. package/dist/modules/datasource/rpm/providers/common.js +3 -1
  88. package/dist/modules/datasource/rpm/providers/common.js.map +1 -1
  89. package/dist/modules/datasource/rubygems/index.js +2 -5
  90. package/dist/modules/datasource/rubygems/index.js.map +1 -1
  91. package/dist/modules/datasource/rubygems/versions-endpoint-cache.js +13 -18
  92. package/dist/modules/datasource/rubygems/versions-endpoint-cache.js.map +1 -1
  93. package/dist/modules/datasource/terraform-module/base.js +2 -1
  94. package/dist/modules/datasource/terraform-module/base.js.map +1 -1
  95. package/dist/modules/datasource/terraform-provider/index.js +2 -3
  96. package/dist/modules/datasource/terraform-provider/index.js.map +1 -1
  97. package/dist/modules/manager/bazel-module/parser/context.js +0 -1
  98. package/dist/modules/manager/bazel-module/parser/context.js.map +1 -1
  99. package/dist/modules/manager/bundler/host-rules.js +4 -1
  100. package/dist/modules/manager/bundler/host-rules.js.map +1 -1
  101. package/dist/modules/manager/composer/range.js +1 -1
  102. package/dist/modules/manager/composer/range.js.map +1 -1
  103. package/dist/modules/manager/custom/utils.js +3 -1
  104. package/dist/modules/manager/custom/utils.js.map +1 -1
  105. package/dist/modules/manager/devbox/schema.js +2 -1
  106. package/dist/modules/manager/devbox/schema.js.map +1 -1
  107. package/dist/modules/manager/dockerfile/extract.js +10 -2
  108. package/dist/modules/manager/dockerfile/extract.js.map +1 -1
  109. package/dist/modules/manager/fingerprint.generated.js +1 -1
  110. package/dist/modules/manager/fingerprint.generated.js.map +1 -1
  111. package/dist/modules/manager/github-actions/parse.js +2 -1
  112. package/dist/modules/manager/github-actions/parse.js.map +1 -1
  113. package/dist/modules/manager/gomod/artifacts.js +5 -2
  114. package/dist/modules/manager/gomod/artifacts.js.map +1 -1
  115. package/dist/modules/manager/gradle/artifacts.js +5 -2
  116. package/dist/modules/manager/gradle/artifacts.js.map +1 -1
  117. package/dist/modules/manager/gradle/utils.js +2 -1
  118. package/dist/modules/manager/gradle/utils.js.map +1 -1
  119. package/dist/modules/manager/gradle-wrapper/utils.js +9 -5
  120. package/dist/modules/manager/gradle-wrapper/utils.js.map +1 -1
  121. package/dist/modules/manager/helm-values/util.js +1 -1
  122. package/dist/modules/manager/helm-values/util.js.map +1 -1
  123. package/dist/modules/manager/helmfile/artifacts.js +1 -1
  124. package/dist/modules/manager/helmfile/artifacts.js.map +1 -1
  125. package/dist/modules/manager/helmv3/artifacts.js +1 -1
  126. package/dist/modules/manager/helmv3/artifacts.js.map +1 -1
  127. package/dist/modules/manager/maven/extract.js +5 -2
  128. package/dist/modules/manager/maven/extract.js.map +1 -1
  129. package/dist/modules/manager/maven-wrapper/artifacts.js +3 -2
  130. package/dist/modules/manager/maven-wrapper/artifacts.js.map +1 -1
  131. package/dist/modules/manager/mise/artifacts.js +2 -1
  132. package/dist/modules/manager/mise/artifacts.js.map +1 -1
  133. package/dist/modules/manager/mise/extract.js.map +1 -1
  134. package/dist/modules/manager/npm/artifacts.js +3 -1
  135. package/dist/modules/manager/npm/artifacts.js.map +1 -1
  136. package/dist/modules/manager/npm/extract/common/dependency.js +4 -1
  137. package/dist/modules/manager/npm/extract/common/dependency.js.map +1 -1
  138. package/dist/modules/manager/npm/extract/common/package-file.js +2 -1
  139. package/dist/modules/manager/npm/extract/common/package-file.js.map +1 -1
  140. package/dist/modules/manager/npm/extract/index.js.map +1 -1
  141. package/dist/modules/manager/npm/extract/post/locked-versions.js.map +1 -1
  142. package/dist/modules/manager/npm/npmrc.js +2 -1
  143. package/dist/modules/manager/npm/npmrc.js.map +1 -1
  144. package/dist/modules/manager/npm/post-update/index.js +2 -1
  145. package/dist/modules/manager/npm/post-update/index.js.map +1 -1
  146. package/dist/modules/manager/npm/post-update/npm.js +2 -3
  147. package/dist/modules/manager/npm/post-update/npm.js.map +1 -1
  148. package/dist/modules/manager/npm/post-update/yarn.js.map +1 -1
  149. package/dist/modules/manager/npm/schema.js +6 -2
  150. package/dist/modules/manager/npm/schema.js.map +1 -1
  151. package/dist/modules/manager/npm/update/dependency/index.js +3 -2
  152. package/dist/modules/manager/npm/update/dependency/index.js.map +1 -1
  153. package/dist/modules/manager/npm/update/locked-dependency/common/parent-version.js +6 -2
  154. package/dist/modules/manager/npm/update/locked-dependency/common/parent-version.js.map +1 -1
  155. package/dist/modules/manager/npm/update/locked-dependency/package-lock/get-locked.js +2 -1
  156. package/dist/modules/manager/npm/update/locked-dependency/package-lock/get-locked.js.map +1 -1
  157. package/dist/modules/manager/nuget/package-tree.js +2 -1
  158. package/dist/modules/manager/nuget/package-tree.js.map +1 -1
  159. package/dist/modules/manager/paket/update-locked.js +4 -1
  160. package/dist/modules/manager/paket/update-locked.js.map +1 -1
  161. package/dist/modules/manager/pipenv/extract.js +4 -1
  162. package/dist/modules/manager/pipenv/extract.js.map +1 -1
  163. package/dist/modules/platform/azure/azure-helper.js +2 -1
  164. package/dist/modules/platform/azure/azure-helper.js.map +1 -1
  165. package/dist/modules/platform/azure/index.js +7 -3
  166. package/dist/modules/platform/azure/index.js.map +1 -1
  167. package/dist/modules/platform/bitbucket/index.js +13 -6
  168. package/dist/modules/platform/bitbucket/index.js.map +1 -1
  169. package/dist/modules/platform/bitbucket-server/index.js +13 -9
  170. package/dist/modules/platform/bitbucket-server/index.js.map +1 -1
  171. package/dist/modules/platform/codecommit/index.js +2 -2
  172. package/dist/modules/platform/codecommit/index.js.map +1 -1
  173. package/dist/modules/platform/gerrit/client.js +4 -1
  174. package/dist/modules/platform/gerrit/client.js.map +1 -1
  175. package/dist/modules/platform/gerrit/index.js +3 -2
  176. package/dist/modules/platform/gerrit/index.js.map +1 -1
  177. package/dist/modules/platform/gitea/gitea-helper.js +5 -4
  178. package/dist/modules/platform/gitea/gitea-helper.js.map +1 -1
  179. package/dist/modules/platform/gitea/index.js +11 -4
  180. package/dist/modules/platform/gitea/index.js.map +1 -1
  181. package/dist/modules/platform/github/index.js +36 -23
  182. package/dist/modules/platform/github/index.js.map +1 -1
  183. package/dist/modules/platform/gitlab/index.js +16 -9
  184. package/dist/modules/platform/gitlab/index.js.map +1 -1
  185. package/dist/modules/platform/scm-manager/index.js +4 -1
  186. package/dist/modules/platform/scm-manager/index.js.map +1 -1
  187. package/dist/modules/platform/scm-manager/utils.js +2 -1
  188. package/dist/modules/platform/scm-manager/utils.js.map +1 -1
  189. package/dist/modules/versioning/cargo/index.js.map +1 -1
  190. package/dist/modules/versioning/composer/index.js +2 -1
  191. package/dist/modules/versioning/composer/index.js.map +1 -1
  192. package/dist/modules/versioning/conan/common.js +4 -1
  193. package/dist/modules/versioning/conan/common.js.map +1 -1
  194. package/dist/modules/versioning/debian/index.js +2 -1
  195. package/dist/modules/versioning/debian/index.js.map +1 -1
  196. package/dist/modules/versioning/gradle/compare.js +2 -1
  197. package/dist/modules/versioning/gradle/compare.js.map +1 -1
  198. package/dist/modules/versioning/hex/index.js +2 -1
  199. package/dist/modules/versioning/hex/index.js.map +1 -1
  200. package/dist/modules/versioning/julia/index.js.map +1 -1
  201. package/dist/modules/versioning/maven/compare.js +17 -7
  202. package/dist/modules/versioning/maven/compare.js.map +1 -1
  203. package/dist/modules/versioning/npm/index.js +2 -1
  204. package/dist/modules/versioning/npm/index.js.map +1 -1
  205. package/dist/modules/versioning/npm/range.js.map +1 -1
  206. package/dist/modules/versioning/paket/index.js +2 -1
  207. package/dist/modules/versioning/paket/index.js.map +1 -1
  208. package/dist/modules/versioning/paket/range.js +7 -3
  209. package/dist/modules/versioning/paket/range.js.map +1 -1
  210. package/dist/modules/versioning/pep440/index.js +2 -1
  211. package/dist/modules/versioning/pep440/index.js.map +1 -1
  212. package/dist/modules/versioning/poetry/index.js +2 -1
  213. package/dist/modules/versioning/poetry/index.js.map +1 -1
  214. package/dist/modules/versioning/regex/index.js +1 -1
  215. package/dist/modules/versioning/regex/index.js.map +1 -1
  216. package/dist/modules/versioning/rez/index.js +2 -1
  217. package/dist/modules/versioning/rez/index.js.map +1 -1
  218. package/dist/modules/versioning/vcpkg/index.js +2 -1
  219. package/dist/modules/versioning/vcpkg/index.js.map +1 -1
  220. package/dist/util/cache/package/impl/base.js +2 -1
  221. package/dist/util/cache/package/impl/base.js.map +1 -1
  222. package/dist/util/cache/package/with-cache.js +2 -1
  223. package/dist/util/cache/package/with-cache.js.map +1 -1
  224. package/dist/util/check-token.js +7 -4
  225. package/dist/util/check-token.js.map +1 -1
  226. package/dist/util/exec/utils.js +4 -1
  227. package/dist/util/exec/utils.js.map +1 -1
  228. package/dist/util/git/auth.js +5 -1
  229. package/dist/util/git/auth.js.map +1 -1
  230. package/dist/util/git/error.js.map +1 -1
  231. package/dist/util/host-rules.js +5 -3
  232. package/dist/util/host-rules.js.map +1 -1
  233. package/dist/util/http/cache/abstract-http-cache-provider.js +3 -2
  234. package/dist/util/http/cache/abstract-http-cache-provider.js.map +1 -1
  235. package/dist/util/http/cache/package-http-cache-provider.js +2 -1
  236. package/dist/util/http/cache/package-http-cache-provider.js.map +1 -1
  237. package/dist/util/http/github.js +15 -11
  238. package/dist/util/http/github.js.map +1 -1
  239. package/dist/util/http/gitlab.js +5 -4
  240. package/dist/util/http/gitlab.js.map +1 -1
  241. package/dist/util/http/http.js +2 -1
  242. package/dist/util/http/http.js.map +1 -1
  243. package/dist/util/http/jwt.js +2 -1
  244. package/dist/util/http/jwt.js.map +1 -1
  245. package/dist/util/http/retry-after.js +2 -1
  246. package/dist/util/http/retry-after.js.map +1 -1
  247. package/dist/util/http/status.js +95 -0
  248. package/dist/util/http/status.js.map +1 -0
  249. package/dist/util/merge-confidence/index.js +3 -2
  250. package/dist/util/merge-confidence/index.js.map +1 -1
  251. package/dist/util/package-rules/current-version.js +4 -1
  252. package/dist/util/package-rules/current-version.js.map +1 -1
  253. package/dist/util/package-rules/index.js +7 -3
  254. package/dist/util/package-rules/index.js.map +1 -1
  255. package/dist/util/schema-utils/index.js +5 -0
  256. package/dist/util/schema-utils/index.js.map +1 -1
  257. package/dist/workers/global/config/parse/host-rules-from-env.js +2 -1
  258. package/dist/workers/global/config/parse/host-rules-from-env.js.map +1 -1
  259. package/dist/workers/repository/common.js +4 -1
  260. package/dist/workers/repository/common.js.map +1 -1
  261. package/dist/workers/repository/config-migration/branch/index.js +2 -1
  262. package/dist/workers/repository/config-migration/branch/index.js.map +1 -1
  263. package/dist/workers/repository/dependency-dashboard.js +6 -2
  264. package/dist/workers/repository/dependency-dashboard.js.map +1 -1
  265. package/dist/workers/repository/finalize/repository-statistics.js +4 -1
  266. package/dist/workers/repository/finalize/repository-statistics.js.map +1 -1
  267. package/dist/workers/repository/init/merge.js +13 -3
  268. package/dist/workers/repository/init/merge.js.map +1 -1
  269. package/dist/workers/repository/onboarding/branch/check.js +2 -1
  270. package/dist/workers/repository/onboarding/branch/check.js.map +1 -1
  271. package/dist/workers/repository/onboarding/pr/pr-list.js +4 -2
  272. package/dist/workers/repository/onboarding/pr/pr-list.js.map +1 -1
  273. package/dist/workers/repository/process/extract-update.js +4 -1
  274. package/dist/workers/repository/process/extract-update.js.map +1 -1
  275. package/dist/workers/repository/process/lookup/digest.js +2 -1
  276. package/dist/workers/repository/process/lookup/digest.js.map +1 -1
  277. package/dist/workers/repository/process/lookup/generate.js +1 -1
  278. package/dist/workers/repository/process/lookup/generate.js.map +1 -1
  279. package/dist/workers/repository/process/lookup/index.js +4 -1
  280. package/dist/workers/repository/process/lookup/index.js.map +1 -1
  281. package/dist/workers/repository/process/lookup/utils.js +7 -1
  282. package/dist/workers/repository/process/lookup/utils.js.map +1 -1
  283. package/dist/workers/repository/process/vulnerabilities.js +10 -3
  284. package/dist/workers/repository/process/vulnerabilities.js.map +1 -1
  285. package/dist/workers/repository/reconfigure/index.js +2 -1
  286. package/dist/workers/repository/reconfigure/index.js.map +1 -1
  287. package/dist/workers/repository/update/branch/auto-replace.js +6 -2
  288. package/dist/workers/repository/update/branch/auto-replace.js.map +1 -1
  289. package/dist/workers/repository/update/branch/errors.js +2 -1
  290. package/dist/workers/repository/update/branch/errors.js.map +1 -1
  291. package/dist/workers/repository/update/branch/execute-post-upgrade-commands.js +2 -2
  292. package/dist/workers/repository/update/branch/execute-post-upgrade-commands.js.map +1 -1
  293. package/dist/workers/repository/update/branch/get-updated.js +1 -2
  294. package/dist/workers/repository/update/branch/get-updated.js.map +1 -1
  295. package/dist/workers/repository/update/branch/index.js +2 -1
  296. package/dist/workers/repository/update/branch/index.js.map +1 -1
  297. package/dist/workers/repository/update/branch/status-checks.js +2 -1
  298. package/dist/workers/repository/update/branch/status-checks.js.map +1 -1
  299. package/dist/workers/repository/update/pr/body/index.js.map +1 -1
  300. package/dist/workers/repository/update/pr/changelog/release-notes.js +3 -2
  301. package/dist/workers/repository/update/pr/changelog/release-notes.js.map +1 -1
  302. package/dist/workers/repository/update/pr/index.js +7 -3
  303. package/dist/workers/repository/update/pr/index.js.map +1 -1
  304. package/dist/workers/repository/updates/generate.js +6 -3
  305. package/dist/workers/repository/updates/generate.js.map +1 -1
  306. package/package.json +2 -2
  307. package/renovate-schema.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["helper.searchIssues","helper.searchRepos","helper.getCurrentUser","helper.getVersion","helper.getRepo","helper.isOrg","git.initRepo","helper.orgListRepos","git.getBranchCommit","helper.createCommitStatus","helper.toPlatformStatusMapping","helper.getCombinedCommitStatus","helper.toRenovateStatusMapping","helper.getPR","helper.getPRByBranch","helper.createPR","helper.mergePR","helper.updatePR","helper.getIssue","helper.closeIssue","helper.updateIssue","helper.updateIssueLabels","helper.createIssue","helper.unassignLabel","helper.getComments","helper.createComment","helper.updateComment","helper.deleteComment","helper.requestPrReviewers"],"sources":["../../../../lib/modules/platform/gitea/index.ts"],"sourcesContent":["import { isNumber, isString } from '@sindresorhus/is';\nimport semver from 'semver';\nimport { GlobalConfig } from '../../../config/global.ts';\nimport {\n REPOSITORY_ACCESS_FORBIDDEN,\n REPOSITORY_ARCHIVED,\n REPOSITORY_BLOCKED,\n REPOSITORY_CHANGED,\n REPOSITORY_EMPTY,\n REPOSITORY_MIRRORED,\n} from '../../../constants/error-messages.ts';\nimport { logger } from '../../../logger/index.ts';\nimport type { BranchStatus } from '../../../types/index.ts';\nimport { coerceArray, deduplicateArray } from '../../../util/array.ts';\nimport { parseJson } from '../../../util/common.ts';\nimport { getEnv } from '../../../util/env.ts';\nimport * as git from '../../../util/git/index.ts';\nimport { GiteaHttp, setBaseUrl } from '../../../util/http/gitea.ts';\nimport { map } from '../../../util/promises.ts';\nimport { sanitize } from '../../../util/sanitize.ts';\nimport { ensureTrailingSlash, joinUrlParts } from '../../../util/url.ts';\nimport { getPrBodyStruct, hashBody } from '../pr-body.ts';\nimport type {\n AutodiscoverConfig,\n BranchStatusConfig,\n CreatePRConfig,\n EnsureCommentConfig,\n EnsureCommentRemovalConfig,\n EnsureIssueConfig,\n FindPRConfig,\n Issue,\n MergePRConfig,\n Platform,\n PlatformParams,\n PlatformResult,\n Pr,\n RepoParams,\n RepoResult,\n RepoSortMethod,\n SortMethod,\n UpdatePrConfig,\n} from '../types.ts';\nimport { repoFingerprint } from '../util.ts';\nimport { smartTruncate } from '../utils/pr-body.ts';\nimport { getRepoFile } from './files.ts';\nimport * as helper from './gitea-helper.ts';\nimport { lookupLabelByName } from './labels.ts';\nimport { GiteaPrCache } from './pr-cache.ts';\nimport type { Comment, Label, Repo } from './schema.ts';\nimport { PRMergeMethod } from './schema.ts';\nimport type {\n AllowedMergeMethods,\n CombinedCommitStatus,\n GiteaPlatform,\n GiteaPlatformOptions,\n PRUpdateParams,\n} from './types.ts';\nimport {\n API_PATH,\n DRAFT_PREFIX,\n getMergeMethod,\n getRepoUrl,\n isAllowed,\n platformDisplayName,\n smartLinks,\n toRenovatePR,\n trimTrailingApiPath,\n usableRepo,\n} from './utils.ts';\n\ninterface GiteaRepoConfig {\n ignorePrAuthor: boolean;\n repository: string;\n mergeMethod: PRMergeMethod;\n /** The set of merge styles allowed by the repository, used to pick the\n * best matching Gitea/Forgejo merge style for a given `MergeStrategy`. */\n allowedMergeMethods: AllowedMergeMethods;\n\n issueList: Promise<Issue[]> | null;\n labelList: Promise<Label[]> | null;\n defaultBranch: string;\n cloneSubmodules: boolean;\n cloneSubmodulesFilter: string[] | undefined;\n hasIssuesEnabled: boolean;\n isOrgRepo: boolean;\n orgName: string;\n}\n\nexport const id = 'gitea';\n\nexport const giteaHttp = new GiteaHttp();\n\nfunction toRenovateIssue(data: Issue): Issue {\n return {\n number: data.number,\n state: data.state,\n title: data.title,\n body: data.body,\n };\n}\n\nfunction matchesState(actual: string, expected: string): boolean {\n if (expected === 'all') {\n return true;\n }\n if (expected.startsWith('!')) {\n return actual !== expected.substring(1);\n }\n\n return actual === expected;\n}\n\nfunction findCommentByTopic(\n comments: Comment[],\n topic: string,\n): Comment | null {\n return comments.find((c) => c.body.startsWith(`### ${topic}\\n\\n`)) ?? null;\n}\n\nfunction findCommentByContent(\n comments: Comment[],\n content: string,\n): Comment | null {\n return comments.find((c) => c.body.trim() === content) ?? null;\n}\n\ninterface FetchRepositoriesArgs {\n topic?: string;\n sort?: RepoSortMethod;\n order?: SortMethod;\n}\n\n/**\n * Builds the platform implementation shared by every platform which speaks the\n * Gitea API. Each call owns its own module state, so `gitea` and `forgejo` do\n * not share caches or configuration.\n */\nexport function createPlatform(options: GiteaPlatformOptions): GiteaPlatform {\n const {\n id,\n http,\n setBaseUrl,\n logDetectedVersion,\n checkNativeAutomerge,\n minReviewerVersion,\n } = options;\n const name = platformDisplayName[id];\n\n const defaults = {\n endpoint: options.defaultEndpoint,\n version: '0.0.0',\n };\n\n let config: GiteaRepoConfig = {} as any;\n let botUserID: number;\n let botUserName: string;\n const prCache = new GiteaPrCache(http, id);\n\n function resetPlatform(): void {\n config = {} as any;\n prCache.reset();\n botUserID = undefined as never;\n botUserName = undefined as never;\n defaults.endpoint = options.defaultEndpoint;\n defaults.version = '0.0.0';\n setBaseUrl(defaults.endpoint);\n }\n\n async function fetchIssueList(): Promise<Issue[]> {\n const issues = await helper.searchIssues(\n http,\n config.repository,\n { state: 'all' },\n { memCache: false },\n );\n const issueList = issues.map(toRenovateIssue);\n logger.debug(`Retrieved ${issueList.length} Issues`);\n return issueList;\n }\n\n async function fetchRepositories({\n topic,\n sort,\n order,\n }: FetchRepositoriesArgs): Promise<string[]> {\n const repos = await helper.searchRepos(http, {\n uid: botUserID,\n archived: false,\n ...(topic && {\n topic: true,\n q: topic,\n }),\n ...(sort && {\n sort,\n }),\n ...(order && {\n order,\n }),\n });\n return repos.filter(usableRepo).map((r) => r.full_name);\n }\n\n const platform: Platform = {\n async initPlatform({\n endpoint,\n token,\n }: PlatformParams): Promise<PlatformResult> {\n if (!token) {\n throw new Error(\n `Init: You must configure a ${name} personal access token`,\n );\n }\n\n if (endpoint) {\n let baseEndpoint = trimTrailingApiPath(endpoint);\n baseEndpoint = ensureTrailingSlash(baseEndpoint);\n defaults.endpoint = baseEndpoint;\n } else {\n logger.debug(`Using default ${name} endpoint: ${defaults.endpoint}`);\n }\n setBaseUrl(defaults.endpoint);\n\n let gitAuthor: string;\n try {\n const user = await helper.getCurrentUser(http, { token });\n // oxlint-disable-next-line typescript/prefer-nullish-coalescing -- `full_name` can be emtpy string\n gitAuthor = `${user.full_name || user.login} <${user.email}>`;\n botUserID = user.id;\n botUserName = user.login;\n const env = getEnv();\n /* v8 ignore if: experimental feature */\n if (semver.valid(env.RENOVATE_X_PLATFORM_VERSION)) {\n defaults.version = env.RENOVATE_X_PLATFORM_VERSION!;\n } else {\n defaults.version = await helper.getVersion(http, { token });\n }\n\n logDetectedVersion(defaults.version);\n } catch (err) {\n logger.debug(\n { err },\n `Error authenticating with ${name}. Check your token`,\n );\n throw new Error('Init: Authentication failure');\n }\n\n return {\n endpoint: defaults.endpoint,\n gitAuthor,\n };\n },\n\n async getRawFile(\n fileName: string,\n repoName?: string,\n branchOrTag?: string,\n ): Promise<string | null> {\n const repo = repoName ?? config.repository;\n const contents = await getRepoFile(http, repo, fileName, branchOrTag, {\n baseUrl: joinUrlParts(defaults.endpoint, API_PATH),\n });\n if (contents.type !== 'file') {\n return null;\n }\n return contents.contentString;\n },\n\n async getJsonFile(\n fileName: string,\n repoName?: string,\n branchOrTag?: string,\n ): Promise<any> {\n // TODO #22198\n const raw = await platform.getRawFile(fileName, repoName, branchOrTag);\n return parseJson(raw, fileName);\n },\n\n async initRepo({\n repository,\n cloneSubmodules,\n cloneSubmodulesFilter,\n gitUrl,\n }: RepoParams): Promise<RepoResult> {\n let repo: Repo;\n\n config = {} as any;\n config.repository = repository;\n config.cloneSubmodules = !!cloneSubmodules;\n config.cloneSubmodulesFilter = cloneSubmodulesFilter;\n config.ignorePrAuthor = GlobalConfig.get('ignorePrAuthor');\n\n // Try to fetch information about repository\n try {\n repo = await helper.getRepo(http, repository);\n } catch (err) {\n logger.debug({ err }, `Unknown ${name} initRepo error`);\n throw err;\n }\n\n // Ensure appropriate repository state and permissions\n if (repo.archived) {\n logger.debug('Repository is archived - aborting renovation');\n throw new Error(REPOSITORY_ARCHIVED);\n }\n if (repo.mirror) {\n logger.debug('Repository is a mirror - aborting renovation');\n throw new Error(REPOSITORY_MIRRORED);\n }\n if (!repo.permissions.pull || !repo.permissions.push) {\n logger.debug(\n 'Repository does not permit pull or push - aborting renovation',\n );\n throw new Error(REPOSITORY_ACCESS_FORBIDDEN);\n }\n if (repo.empty) {\n logger.debug('Repository is empty - aborting renovation');\n throw new Error(REPOSITORY_EMPTY);\n }\n\n if (repo.has_pull_requests === false) {\n logger.debug('Repo has disabled pull requests - aborting renovation');\n throw new Error(REPOSITORY_BLOCKED);\n }\n\n // if default merge style is allowed, use this; else fall back to\n // predefined order. Order chosen to minimize commits - see\n // https://github.com/renovatebot/renovate/pull/37768 for discussion.\n const preferredOrder: PRMergeMethod[] = [\n ...(repo.default_merge_style ? [repo.default_merge_style] : []),\n 'fast-forward-only',\n 'squash',\n 'merge',\n 'rebase',\n 'rebase-merge',\n ];\n\n const mergeStyle = preferredOrder.find((style) => isAllowed(style, repo));\n\n if (mergeStyle) {\n config.mergeMethod = mergeStyle;\n config.allowedMergeMethods = new Set(\n PRMergeMethod.options.filter((style) => isAllowed(style, repo)),\n );\n } else {\n logger.debug(\n 'Repository has no allowed merge methods - aborting renovation',\n );\n throw new Error(REPOSITORY_BLOCKED);\n }\n\n try {\n config.isOrgRepo = await helper.isOrg(http, id, repo.owner.login);\n } catch (err) {\n logger.debug({ err }, `${name} initRepo() error`);\n throw err;\n }\n\n // Determine author email and branches\n config.defaultBranch = repo.default_branch;\n logger.debug(`${repository} default branch = ${config.defaultBranch}`);\n\n const url = getRepoUrl(repo, gitUrl, defaults.endpoint, id);\n\n // Initialize Git storage\n await git.initRepo({\n ...config,\n url,\n });\n\n // Reset cached resources\n config.issueList = null;\n config.labelList = null;\n prCache.initRepo(config.repository, config.ignorePrAuthor, botUserName);\n config.hasIssuesEnabled = !repo.external_tracker && repo.has_issues;\n config.orgName = repo.owner.login;\n\n return {\n defaultBranch: config.defaultBranch,\n isFork: !!repo.fork,\n repoFingerprint: repoFingerprint(repo.id, defaults.endpoint),\n };\n },\n\n async getRepos(config?: AutodiscoverConfig): Promise<string[]> {\n logger.debug(`Auto-discovering ${name} repositories`);\n try {\n if (config?.topics) {\n logger.debug({ topics: config.topics }, 'Auto-discovering by topics');\n const fetchRepoArgs: FetchRepositoriesArgs[] = config.topics.map(\n (topic) => {\n return {\n topic,\n sort: config.sort,\n order: config.order,\n };\n },\n );\n const repos = await map(fetchRepoArgs, fetchRepositories);\n return deduplicateArray(repos.flat());\n }\n if (config?.namespaces) {\n logger.debug(\n { namespaces: config.namespaces },\n 'Auto-discovering by organization',\n );\n const repos = await map(\n config.namespaces,\n async (organization: string) => {\n const orgRepos = await helper.orgListRepos(http, organization);\n return orgRepos\n .filter((r) => !r.mirror && !r.archived)\n .map((r) => r.full_name);\n },\n );\n return deduplicateArray(repos.flat());\n }\n return await fetchRepositories({\n sort: config?.sort,\n order: config?.order,\n });\n } catch (err) {\n logger.error(\n { err, platform: id },\n 'Error auto-discovering repositories',\n );\n throw err;\n }\n },\n\n async setBranchStatus({\n branchName,\n context,\n description,\n state,\n url: target_url,\n }: BranchStatusConfig): Promise<void> {\n try {\n // Create new status for branch commit\n const branchCommit = git.getBranchCommit(branchName);\n // TODO: check branchCommit\n\n await helper.createCommitStatus(\n http,\n config.repository,\n branchCommit!,\n {\n state: helper.toPlatformStatusMapping[state] || 'pending',\n context,\n description,\n ...(target_url && { target_url }),\n },\n );\n\n // Refresh caches by re-fetching commit status for branch\n await helper.getCombinedCommitStatus(\n http,\n config.repository,\n branchName,\n {\n memCache: false,\n },\n );\n } catch (err) {\n logger.warn({ err }, 'Failed to set branch status');\n }\n },\n\n async getBranchStatus(\n branchName: string,\n internalChecksAsSuccess: boolean,\n ): Promise<BranchStatus> {\n let ccs: CombinedCommitStatus;\n try {\n ccs = await helper.getCombinedCommitStatus(\n http,\n config.repository,\n branchName,\n );\n } catch (err) {\n if (err.statusCode === 404) {\n logger.debug(\n 'Received 404 when checking branch status, assuming branch deletion',\n );\n throw new Error(REPOSITORY_CHANGED);\n }\n\n logger.debug('Unknown error when checking branch status');\n throw err;\n }\n\n logger.debug({ ccs }, 'Branch status check result');\n if (\n !internalChecksAsSuccess &&\n ccs.worstStatus === 'success' &&\n ccs.statuses.every((status) => status.context?.startsWith('renovate/'))\n ) {\n logger.debug(\n 'Successful checks are all internal renovate/ checks, so returning \"pending\" branch status',\n );\n return 'yellow';\n }\n\n return helper.toRenovateStatusMapping[ccs.worstStatus];\n },\n\n async getBranchStatusCheck(\n branchName: string,\n context: string,\n ): Promise<BranchStatus | null> {\n const ccs = await helper.getCombinedCommitStatus(\n http,\n config.repository,\n branchName,\n );\n const cs = ccs.statuses.find((s) => s.context === context);\n if (!cs) {\n return null;\n } // no status check exists\n return helper.toRenovateStatusMapping[cs.status];\n },\n\n getPrList(): Promise<Pr[]> {\n return prCache.getPrs();\n },\n\n async getPr(number: number): Promise<Pr | null> {\n // Search for pull request in cached list or attempt to query directly\n const prList = await platform.getPrList();\n let pr = prList.find((p) => p.number === number) ?? null;\n if (pr) {\n logger.debug('Returning from cached PRs');\n } else {\n logger.debug('PR not found in cached PRs - trying to fetch directly');\n const gpr = await helper.getPR(http, config.repository, number);\n pr = toRenovatePR(gpr, botUserName);\n\n // Add pull request to cache for further lookups / queries\n if (pr) {\n await prCache.setPr(pr);\n }\n }\n\n // Abort and return null if no match was found\n if (!pr) {\n return null;\n }\n\n return pr;\n },\n\n async findPr({\n branchName,\n prTitle: title,\n state = 'all',\n includeOtherAuthors,\n targetBranch,\n }: FindPRConfig): Promise<Pr | null> {\n logger.debug(`findPr(${branchName}, ${title!}, ${state})`);\n if (includeOtherAuthors && isString(targetBranch)) {\n // do not use pr cache as it only fetches prs created by the Renovate account\n const pr = await helper.getPRByBranch(\n http,\n config.repository,\n targetBranch,\n branchName,\n );\n if (!pr) {\n return null;\n }\n\n return toRenovatePR(pr, null);\n }\n const prList = await platform.getPrList();\n const pr = prList.find(\n (p) =>\n p.sourceRepo === config.repository &&\n p.sourceBranch === branchName &&\n matchesState(p.state, state) &&\n (!title || p.title === title),\n );\n\n if (pr) {\n logger.debug(`Found PR #${pr.number}`);\n }\n return pr ?? null;\n },\n\n async createPr({\n sourceBranch,\n targetBranch,\n prTitle,\n prBody: rawBody,\n labels: labelNames,\n platformPrOptions,\n draftPR,\n }: CreatePRConfig): Promise<Pr> {\n let title = prTitle;\n const base = targetBranch;\n const head = sourceBranch;\n const body = sanitize(rawBody);\n if (draftPR) {\n title = DRAFT_PREFIX + title;\n }\n\n logger.debug(`Creating pull request: ${title} (${head} => ${base})`);\n try {\n const labels = Array.isArray(labelNames)\n ? await map(labelNames, (name) =>\n lookupLabelByName(http, config, name),\n )\n : [];\n const gpr = await helper.createPR(http, config.repository, {\n base,\n head,\n title,\n body,\n labels: labels.filter(isNumber),\n });\n\n if (platformPrOptions?.usePlatformAutomerge) {\n // `delete_branch_after_merge` is required to not have undesired\n // behavior when renovate finds existing branches on next run.\n const unsupportedReason = checkNativeAutomerge(defaults.version);\n if (unsupportedReason === null) {\n try {\n await helper.mergePR(http, config.repository, gpr.number, {\n Do:\n getMergeMethod(\n platformPrOptions?.automergeStrategy,\n config.allowedMergeMethods,\n ) ?? config.mergeMethod,\n merge_when_checks_succeed: true,\n delete_branch_after_merge: true,\n });\n\n logger.debug(\n { prNumber: gpr.number },\n `${name}-native automerge: success`,\n );\n } catch (err) {\n logger.warn(\n { err, prNumber: gpr.number, platform: id },\n 'Platform-native automerge: fail',\n );\n }\n } else {\n logger.debug({ prNumber: gpr.number }, unsupportedReason);\n }\n }\n\n const pr = toRenovatePR(gpr, botUserName);\n if (!pr) {\n throw new Error('Can not parse newly created Pull Request');\n }\n\n await prCache.setPr(pr);\n return pr;\n } catch (err) {\n // When the user manually deletes a branch from Renovate, the PR remains but is no longer linked to any branch. In\n // the most recent versions of the platform, the PR gets automatically closed when that happens, but older versions\n // do not handle this properly and keep the PR open. As pushing a branch with the same name resurrects the PR, this\n // would cause a HTTP 409 conflict error, which we hereby gracefully handle.\n if (err.statusCode === 409) {\n logger.warn(\n { prTitle: title, sourceBranch },\n 'Attempting to gracefully recover from 409 Conflict response in createPr()',\n );\n\n // Refresh cached PR list and search for pull request with matching information\n prCache.forceSync();\n const pr = await platform.findPr({\n branchName: sourceBranch,\n state: 'open',\n });\n\n // If a valid PR was found, return and gracefully recover from the error. Otherwise, abort and throw error.\n // v8 ignore else -- TODO: add test #40625\n if (pr?.bodyStruct) {\n if (pr.title !== title || pr.bodyStruct.hash !== hashBody(body)) {\n logger.debug(\n `Recovered from 409 Conflict, but PR for ${sourceBranch} is outdated. Updating...`,\n );\n await platform.updatePr({\n number: pr.number,\n prTitle: title,\n prBody: body,\n });\n pr.title = title;\n pr.bodyStruct = getPrBodyStruct(body);\n } else {\n logger.debug(\n `Recovered from 409 Conflict and PR for ${sourceBranch} is up-to-date`,\n );\n }\n\n return pr;\n }\n }\n\n throw err;\n }\n },\n\n async updatePr({\n number,\n prTitle,\n prBody: body,\n labels,\n state,\n targetBranch,\n }: UpdatePrConfig): Promise<void> {\n let title = prTitle;\n if (\n (await platform.getPrList()).find((pr) => pr.number === number)?.isDraft\n ) {\n title = DRAFT_PREFIX + title;\n }\n\n const prUpdateParams: PRUpdateParams = {\n title,\n ...(body && { body }),\n ...(state && { state }),\n };\n if (targetBranch) {\n prUpdateParams.base = targetBranch;\n }\n\n /**\n * Update PR labels.\n * In the Gitea API, labels are replaced on each update if the field is present.\n * If the field is not present (i.e., undefined), labels aren't updated.\n * However, the labels array must contain label IDs instead of names,\n * so a lookup is performed to fetch the details (including the ID) of each label.\n */\n if (Array.isArray(labels)) {\n prUpdateParams.labels = (\n await map(labels, (name) => lookupLabelByName(http, config, name))\n ).filter(isNumber);\n if (labels.length !== prUpdateParams.labels.length) {\n logger.warn(\n 'Some labels could not be looked up. Renovate may halt label updates assuming changes by others.',\n );\n }\n }\n\n const gpr = await helper.updatePR(\n http,\n config.repository,\n number,\n prUpdateParams,\n );\n const pr = toRenovatePR(gpr, botUserName);\n if (pr) {\n await prCache.setPr(pr);\n }\n },\n\n async mergePr({ id: prNumber, strategy }: MergePRConfig): Promise<boolean> {\n try {\n await helper.mergePR(http, config.repository, prNumber, {\n Do:\n getMergeMethod(strategy, config.allowedMergeMethods) ??\n config.mergeMethod,\n });\n return true;\n } catch (err) {\n logger.warn({ err, id: prNumber }, 'Merging of PR failed');\n return false;\n }\n },\n\n getIssueList(): Promise<Issue[]> {\n if (config.hasIssuesEnabled === false) {\n return Promise.resolve([]);\n }\n config.issueList ??= fetchIssueList();\n\n return config.issueList;\n },\n\n async getIssue(number: number, memCache = true): Promise<Issue | null> {\n if (config.hasIssuesEnabled === false) {\n return null;\n }\n try {\n const body = (\n await helper.getIssue(http, config.repository, number, { memCache })\n ).body;\n return {\n number,\n body,\n };\n } catch (err) {\n logger.debug({ err, number }, 'Error getting issue');\n return null;\n }\n },\n\n async findIssue(title: string): Promise<Issue | null> {\n const issueList = await platform.getIssueList();\n const issue = issueList.find(\n (i) => i.state === 'open' && i.title === title,\n );\n\n if (!issue) {\n return null;\n }\n // TODO: types (#22198)\n logger.debug(`Found Issue #${issue.number!}`);\n // TODO #22198\n return platform.getIssue!(issue.number!);\n },\n\n async ensureIssue({\n title,\n reuseTitle,\n body: content,\n labels: labelNames,\n shouldReOpen,\n once,\n }: EnsureIssueConfig): Promise<'updated' | 'created' | null> {\n logger.debug(`ensureIssue(${title})`);\n if (config.hasIssuesEnabled === false) {\n logger.info(\n 'Cannot ensure issue because issues are disabled in this repository',\n );\n return null;\n }\n try {\n const body = smartLinks(content);\n\n const issueList = await platform.getIssueList();\n let issues = issueList.filter((i) => i.title === title);\n if (!issues.length) {\n issues = issueList.filter((i) => i.title === reuseTitle);\n }\n\n const labels = Array.isArray(labelNames)\n ? (\n await Promise.all(\n labelNames.map((name) => lookupLabelByName(http, config, name)),\n )\n ).filter(isNumber)\n : undefined;\n\n // Update any matching issues which currently exist\n if (issues.length) {\n let activeIssue = issues.find((i) => i.state === 'open');\n\n // If no active issue was found, decide if it shall be skipped, re-opened or updated without state change\n if (!activeIssue) {\n if (once) {\n logger.debug('Issue already closed - skipping update');\n return null;\n }\n if (shouldReOpen) {\n logger.debug('Reopening previously closed Issue');\n }\n\n // Pick the last issue in the list as the active one\n activeIssue = issues.at(-1)!;\n }\n\n // Close any duplicate issues\n for (const issue of issues) {\n if (issue.state === 'open' && issue.number !== activeIssue.number) {\n // TODO: types (#22198)\n logger.warn(\n { issueNo: issue.number! },\n 'Closing duplicate issue',\n );\n // TODO #22198\n await helper.closeIssue(http, config.repository, issue.number!);\n }\n }\n\n // Check if issue has already correct state\n if (\n activeIssue.title === title &&\n activeIssue.body === body &&\n activeIssue.state === 'open'\n ) {\n logger.debug(\n // TODO: types (#22198)\n `Issue #${activeIssue.number!} is open and up to date - nothing to do`,\n );\n return null;\n }\n\n if (shouldReOpen || activeIssue.state === 'open') {\n // Update issue body and re-open\n logger.debug(`Updating Issue #${activeIssue.number}`);\n const existingIssue = await helper.updateIssue(\n http,\n config.repository,\n // TODO #22198\n activeIssue.number!,\n {\n body,\n title,\n state: 'open',\n },\n );\n\n // Test whether the issues need to be updated\n const existingLabelIds = coerceArray(existingIssue.labels).map(\n (label) => label.id,\n );\n if (\n labels &&\n (labels.length !== existingLabelIds.length ||\n labels.filter((labelId) => !existingLabelIds.includes(labelId))\n .length !== 0)\n ) {\n await helper.updateIssueLabels(\n http,\n config.repository,\n // TODO #22198\n activeIssue.number!,\n {\n labels,\n },\n );\n }\n\n return 'updated';\n }\n }\n\n // Create new issue and reset cache\n const issue = await helper.createIssue(http, config.repository, {\n body,\n title,\n labels,\n });\n logger.debug(`Created new Issue #${issue.number}`);\n config.issueList = null;\n\n return 'created';\n } catch (err) {\n logger.warn({ err }, 'Could not ensure issue');\n }\n\n return null;\n },\n\n async ensureIssueClosing(title: string): Promise<void> {\n logger.debug(`ensureIssueClosing(${title})`);\n if (config.hasIssuesEnabled === false) {\n return;\n }\n const issueList = await platform.getIssueList();\n for (const issue of issueList) {\n if (issue.state === 'open' && issue.title === title) {\n logger.debug(`Closing issue...issueNo: ${issue.number!}`);\n // TODO #22198\n await helper.closeIssue(http, config.repository, issue.number!);\n }\n }\n },\n\n async deleteLabel(issue: number, labelName: string): Promise<void> {\n logger.debug(`Deleting label ${labelName} from Issue #${issue}`);\n const label = await lookupLabelByName(http, config, labelName);\n if (label) {\n await helper.unassignLabel(http, config.repository, issue, label);\n } else {\n logger.warn(\n { issue, labelName },\n 'Failed to lookup label for deletion',\n );\n }\n },\n\n async ensureComment({\n number: issue,\n topic,\n content,\n }: EnsureCommentConfig): Promise<boolean> {\n try {\n let body = sanitize(content);\n const commentList = await helper.getComments(\n http,\n config.repository,\n issue,\n );\n\n // Search comment by either topic or exact body\n let comment: Comment | null = null;\n if (topic) {\n comment = findCommentByTopic(commentList, topic);\n body = `### ${topic}\\n\\n${body}`;\n } else {\n comment = findCommentByContent(commentList, body);\n }\n\n // Create a new comment if no match has been found, otherwise update if necessary\n if (!comment) {\n comment = await helper.createComment(\n http,\n config.repository,\n issue,\n body,\n );\n logger.info(\n { repository: config.repository, issue, comment: comment.id },\n 'Comment added',\n );\n } else if (comment.body === body) {\n logger.debug(`Comment #${comment.id} is already up-to-date`);\n } else {\n await helper.updateComment(http, config.repository, comment.id, body);\n logger.debug(\n { repository: config.repository, issue, comment: comment.id },\n 'Comment updated',\n );\n }\n\n return true;\n } catch (err) {\n logger.warn({ err, issue, subject: topic }, 'Error ensuring comment');\n return false;\n }\n },\n\n async ensureCommentRemoval(\n deleteConfig: EnsureCommentRemovalConfig,\n ): Promise<void> {\n const { number: issue } = deleteConfig;\n const key =\n deleteConfig.type === 'by-topic'\n ? deleteConfig.topic\n : deleteConfig.content;\n logger.debug(`Ensuring comment \"${key}\" in #${issue} is removed`);\n const commentList = await helper.getComments(\n http,\n config.repository,\n issue,\n );\n\n let comment: Comment | null = null;\n // v8 ignore else -- TODO: add test #40625\n if (deleteConfig.type === 'by-topic') {\n comment = findCommentByTopic(commentList, deleteConfig.topic);\n } else if (deleteConfig.type === 'by-content') {\n const body = sanitize(deleteConfig.content);\n comment = findCommentByContent(commentList, body);\n }\n\n // Abort and do nothing if no matching comment was found\n if (!comment) {\n return;\n }\n\n // Try to delete comment\n try {\n await helper.deleteComment(http, config.repository, comment.id);\n } catch (err) {\n logger.warn(\n { err, issue, config: deleteConfig },\n 'Error deleting comment',\n );\n }\n },\n\n async getBranchPr(branchName: string): Promise<Pr | null> {\n logger.debug(`getBranchPr(${branchName})`);\n const pr = await platform.findPr({ branchName, state: 'open' });\n return pr ? platform.getPr(pr.number) : null;\n },\n\n async addAssignees(number: number, assignees: string[]): Promise<void> {\n logger.debug(\n `Updating assignees '${assignees?.join(', ')}' on Issue #${number}`,\n );\n await helper.updateIssue(http, config.repository, number, {\n assignees,\n });\n },\n\n async addReviewers(number: number, reviewers: string[]): Promise<void> {\n logger.debug(`Adding reviewers '${reviewers?.join(', ')}' to #${number}`);\n if (\n minReviewerVersion &&\n semver.lt(defaults.version, minReviewerVersion)\n ) {\n logger.debug(\n { version: defaults.version },\n 'Adding reviewer not yet supported.',\n );\n return;\n }\n try {\n const teamReviewers = new Set(\n reviewers\n .filter((r) => r.startsWith('team:'))\n .map((r) => r.substring(5)),\n );\n const userReviewers = new Set(\n reviewers.filter((r) => !r.startsWith('team:')),\n );\n\n await helper.requestPrReviewers(http, config.repository, number, {\n reviewers: [...userReviewers],\n ...(teamReviewers.size && {\n team_reviewers: [...teamReviewers],\n }),\n });\n } catch (err) {\n logger.warn({ err, number, reviewers }, 'Failed to assign reviewer');\n }\n },\n\n massageMarkdown(prBody: string): string {\n return smartTruncate(smartLinks(prBody), maxBodyLength());\n },\n\n maxBodyLength,\n };\n\n function maxBodyLength(): number {\n return 1000000;\n }\n\n return { platform, resetPlatform };\n}\n\n/**\n * Forgejo reports the Gitea version it is compatible with as part of its own\n * version, for example `11.0.1-99-c504062+gitea-1.22.0`.\n */\nfunction isForgejo(version: string): boolean {\n return version.includes('gitea-');\n}\n\nfunction logDetectedVersion(version: string): void {\n if (isForgejo(version)) {\n logger.info(\n `Detected Forgejo instance, please use 'forgejo' platform instead`,\n );\n }\n logger.debug(\n `${isForgejo(version) ? 'Forgejo' : 'Gitea'} version: ${version}`,\n );\n}\n\nfunction checkNativeAutomerge(version: string): string | null {\n // Only Gitea v1.24.0+ and Forgejo v10.0.0+ support delete_branch_after_merge.\n const minVersion = isForgejo(version) ? '10.0.0' : '1.24.0';\n if (semver.gte(version, minVersion)) {\n return null;\n }\n return `Gitea-native automerge: not supported on this version of ${isForgejo(version) ? 'Forgejo' : 'Gitea'}. Use ${minVersion} or newer.`;\n}\n\nconst { platform, resetPlatform } = createPlatform({\n id,\n defaultEndpoint: 'https://gitea.com/',\n http: giteaHttp,\n setBaseUrl,\n logDetectedVersion,\n checkNativeAutomerge,\n // Requesting reviewers is only supported since Gitea v1.14.0.\n minReviewerVersion: '1.14.0',\n});\n\nexport { resetPlatform };\n\n/* oxlint-disable typescript/unbound-method */\nexport const {\n addAssignees,\n addReviewers,\n createPr,\n deleteLabel,\n ensureComment,\n ensureCommentRemoval,\n ensureIssue,\n ensureIssueClosing,\n findIssue,\n findPr,\n getBranchPr,\n getBranchStatus,\n getBranchStatusCheck,\n getIssue,\n getRawFile,\n getJsonFile,\n getIssueList,\n getPr,\n massageMarkdown,\n maxBodyLength,\n getPrList,\n getRepos,\n initPlatform,\n initRepo,\n mergePr,\n setBranchStatus,\n updatePr,\n} = platform;\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["helper.searchIssues","helper.searchRepos","helper.getCurrentUser","helper.getVersion","helper.getRepo","helper.isOrg","git.initRepo","helper.orgListRepos","git.getBranchCommit","helper.createCommitStatus","helper.toPlatformStatusMapping","helper.getCombinedCommitStatus","helper.toRenovateStatusMapping","helper.getPR","helper.getPRByBranch","helper.createPR","helper.mergePR","helper.updatePR","helper.getIssue","helper.closeIssue","helper.updateIssue","helper.updateIssueLabels","helper.createIssue","helper.unassignLabel","helper.getComments","helper.createComment","helper.updateComment","helper.deleteComment","helper.requestPrReviewers"],"sources":["../../../../lib/modules/platform/gitea/index.ts"],"sourcesContent":["import { isNumber, isString } from '@sindresorhus/is';\nimport semver from 'semver';\nimport { GlobalConfig } from '../../../config/global.ts';\nimport {\n REPOSITORY_ACCESS_FORBIDDEN,\n REPOSITORY_ARCHIVED,\n REPOSITORY_BLOCKED,\n REPOSITORY_CHANGED,\n REPOSITORY_EMPTY,\n REPOSITORY_MIRRORED,\n} from '../../../constants/error-messages.ts';\nimport { logger } from '../../../logger/index.ts';\nimport type { BranchStatus } from '../../../types/index.ts';\nimport { coerceArray, deduplicateArray } from '../../../util/array.ts';\nimport { parseJson } from '../../../util/common.ts';\nimport { getEnv } from '../../../util/env.ts';\nimport * as git from '../../../util/git/index.ts';\nimport { GiteaHttp, setBaseUrl } from '../../../util/http/gitea.ts';\nimport { isConflict, isNotFound } from '../../../util/http/status.ts';\nimport { map } from '../../../util/promises.ts';\nimport { sanitize } from '../../../util/sanitize.ts';\nimport { ensureTrailingSlash, joinUrlParts } from '../../../util/url.ts';\nimport { getPrBodyStruct, hashBody } from '../pr-body.ts';\nimport type {\n AutodiscoverConfig,\n BranchStatusConfig,\n CreatePRConfig,\n EnsureCommentConfig,\n EnsureCommentRemovalConfig,\n EnsureIssueConfig,\n FindPRConfig,\n Issue,\n MergePRConfig,\n Platform,\n PlatformParams,\n PlatformResult,\n Pr,\n RepoParams,\n RepoResult,\n RepoSortMethod,\n SortMethod,\n UpdatePrConfig,\n} from '../types.ts';\nimport { repoFingerprint } from '../util.ts';\nimport { smartTruncate } from '../utils/pr-body.ts';\nimport { getRepoFile } from './files.ts';\nimport * as helper from './gitea-helper.ts';\nimport { lookupLabelByName } from './labels.ts';\nimport { GiteaPrCache } from './pr-cache.ts';\nimport type { Comment, Label, Repo } from './schema.ts';\nimport { PRMergeMethod } from './schema.ts';\nimport type {\n AllowedMergeMethods,\n CombinedCommitStatus,\n GiteaPlatform,\n GiteaPlatformOptions,\n PRUpdateParams,\n} from './types.ts';\nimport {\n API_PATH,\n DRAFT_PREFIX,\n getMergeMethod,\n getRepoUrl,\n isAllowed,\n platformDisplayName,\n smartLinks,\n toRenovatePR,\n trimTrailingApiPath,\n usableRepo,\n} from './utils.ts';\n\ninterface GiteaRepoConfig {\n ignorePrAuthor: boolean;\n repository: string;\n mergeMethod: PRMergeMethod;\n /** The set of merge styles allowed by the repository, used to pick the\n * best matching Gitea/Forgejo merge style for a given `MergeStrategy`. */\n allowedMergeMethods: AllowedMergeMethods;\n\n issueList: Promise<Issue[]> | null;\n labelList: Promise<Label[]> | null;\n defaultBranch: string;\n cloneSubmodules: boolean;\n cloneSubmodulesFilter: string[] | undefined;\n hasIssuesEnabled: boolean;\n isOrgRepo: boolean;\n orgName: string;\n}\n\nexport const id = 'gitea';\n\nexport const giteaHttp = new GiteaHttp();\n\nfunction toRenovateIssue(data: Issue): Issue {\n return {\n number: data.number,\n state: data.state,\n title: data.title,\n body: data.body,\n };\n}\n\nfunction haveLabelsChanged(\n labels: number[],\n existingLabelIds: number[],\n): boolean {\n return (\n labels.length !== existingLabelIds.length ||\n labels.some((labelId) => !existingLabelIds.includes(labelId))\n );\n}\n\nfunction matchesState(actual: string, expected: string): boolean {\n if (expected === 'all') {\n return true;\n }\n if (expected.startsWith('!')) {\n return actual !== expected.substring(1);\n }\n\n return actual === expected;\n}\n\nfunction findCommentByTopic(\n comments: Comment[],\n topic: string,\n): Comment | null {\n return comments.find((c) => c.body.startsWith(`### ${topic}\\n\\n`)) ?? null;\n}\n\nfunction findCommentByContent(\n comments: Comment[],\n content: string,\n): Comment | null {\n return comments.find((c) => c.body.trim() === content) ?? null;\n}\n\ninterface FetchRepositoriesArgs {\n topic?: string;\n sort?: RepoSortMethod;\n order?: SortMethod;\n}\n\n/**\n * Builds the platform implementation shared by every platform which speaks the\n * Gitea API. Each call owns its own module state, so `gitea` and `forgejo` do\n * not share caches or configuration.\n */\nexport function createPlatform(options: GiteaPlatformOptions): GiteaPlatform {\n const {\n id,\n http,\n setBaseUrl,\n logDetectedVersion,\n checkNativeAutomerge,\n minReviewerVersion,\n } = options;\n const name = platformDisplayName[id];\n\n const defaults = {\n endpoint: options.defaultEndpoint,\n version: '0.0.0',\n };\n\n let config: GiteaRepoConfig = {} as any;\n let botUserID: number;\n let botUserName: string;\n const prCache = new GiteaPrCache(http, id);\n\n function resetPlatform(): void {\n config = {} as any;\n prCache.reset();\n botUserID = undefined as never;\n botUserName = undefined as never;\n defaults.endpoint = options.defaultEndpoint;\n defaults.version = '0.0.0';\n setBaseUrl(defaults.endpoint);\n }\n\n async function fetchIssueList(): Promise<Issue[]> {\n const issues = await helper.searchIssues(\n http,\n config.repository,\n { state: 'all' },\n { memCache: false },\n );\n const issueList = issues.map(toRenovateIssue);\n logger.debug(`Retrieved ${issueList.length} Issues`);\n return issueList;\n }\n\n async function fetchRepositories({\n topic,\n sort,\n order,\n }: FetchRepositoriesArgs): Promise<string[]> {\n const repos = await helper.searchRepos(http, {\n uid: botUserID,\n archived: false,\n ...(topic && {\n topic: true,\n q: topic,\n }),\n ...(sort && {\n sort,\n }),\n ...(order && {\n order,\n }),\n });\n return repos.filter(usableRepo).map((r) => r.full_name);\n }\n\n const platform: Platform = {\n async initPlatform({\n endpoint,\n token,\n }: PlatformParams): Promise<PlatformResult> {\n if (!token) {\n throw new Error(\n `Init: You must configure a ${name} personal access token`,\n );\n }\n\n if (endpoint) {\n let baseEndpoint = trimTrailingApiPath(endpoint);\n baseEndpoint = ensureTrailingSlash(baseEndpoint);\n defaults.endpoint = baseEndpoint;\n } else {\n logger.debug(`Using default ${name} endpoint: ${defaults.endpoint}`);\n }\n setBaseUrl(defaults.endpoint);\n\n let gitAuthor: string;\n try {\n const user = await helper.getCurrentUser(http, { token });\n // oxlint-disable-next-line typescript/prefer-nullish-coalescing -- `full_name` can be emtpy string\n gitAuthor = `${user.full_name || user.login} <${user.email}>`;\n botUserID = user.id;\n botUserName = user.login;\n const env = getEnv();\n /* v8 ignore if: experimental feature */\n if (semver.valid(env.RENOVATE_X_PLATFORM_VERSION)) {\n defaults.version = env.RENOVATE_X_PLATFORM_VERSION!;\n } else {\n defaults.version = await helper.getVersion(http, { token });\n }\n\n logDetectedVersion(defaults.version);\n } catch (err) {\n logger.debug(\n { err },\n `Error authenticating with ${name}. Check your token`,\n );\n throw new Error('Init: Authentication failure');\n }\n\n return {\n endpoint: defaults.endpoint,\n gitAuthor,\n };\n },\n\n async getRawFile(\n fileName: string,\n repoName?: string,\n branchOrTag?: string,\n ): Promise<string | null> {\n const repo = repoName ?? config.repository;\n const contents = await getRepoFile(http, repo, fileName, branchOrTag, {\n baseUrl: joinUrlParts(defaults.endpoint, API_PATH),\n });\n if (contents.type !== 'file') {\n return null;\n }\n return contents.contentString;\n },\n\n async getJsonFile(\n fileName: string,\n repoName?: string,\n branchOrTag?: string,\n ): Promise<any> {\n // TODO #22198\n const raw = await platform.getRawFile(fileName, repoName, branchOrTag);\n return parseJson(raw, fileName);\n },\n\n async initRepo({\n repository,\n cloneSubmodules,\n cloneSubmodulesFilter,\n gitUrl,\n }: RepoParams): Promise<RepoResult> {\n let repo: Repo;\n\n config = {} as any;\n config.repository = repository;\n config.cloneSubmodules = !!cloneSubmodules;\n config.cloneSubmodulesFilter = cloneSubmodulesFilter;\n config.ignorePrAuthor = GlobalConfig.get('ignorePrAuthor');\n\n // Try to fetch information about repository\n try {\n repo = await helper.getRepo(http, repository);\n } catch (err) {\n logger.debug({ err }, `Unknown ${name} initRepo error`);\n throw err;\n }\n\n // Ensure appropriate repository state and permissions\n if (repo.archived) {\n logger.debug('Repository is archived - aborting renovation');\n throw new Error(REPOSITORY_ARCHIVED);\n }\n if (repo.mirror) {\n logger.debug('Repository is a mirror - aborting renovation');\n throw new Error(REPOSITORY_MIRRORED);\n }\n if (!repo.permissions.pull || !repo.permissions.push) {\n logger.debug(\n 'Repository does not permit pull or push - aborting renovation',\n );\n throw new Error(REPOSITORY_ACCESS_FORBIDDEN);\n }\n if (repo.empty) {\n logger.debug('Repository is empty - aborting renovation');\n throw new Error(REPOSITORY_EMPTY);\n }\n\n if (repo.has_pull_requests === false) {\n logger.debug('Repo has disabled pull requests - aborting renovation');\n throw new Error(REPOSITORY_BLOCKED);\n }\n\n // if default merge style is allowed, use this; else fall back to\n // predefined order. Order chosen to minimize commits - see\n // https://github.com/renovatebot/renovate/pull/37768 for discussion.\n const preferredOrder: PRMergeMethod[] = [\n ...(repo.default_merge_style ? [repo.default_merge_style] : []),\n 'fast-forward-only',\n 'squash',\n 'merge',\n 'rebase',\n 'rebase-merge',\n ];\n\n const mergeStyle = preferredOrder.find((style) => isAllowed(style, repo));\n\n if (mergeStyle) {\n config.mergeMethod = mergeStyle;\n config.allowedMergeMethods = new Set(\n PRMergeMethod.options.filter((style) => isAllowed(style, repo)),\n );\n } else {\n logger.debug(\n 'Repository has no allowed merge methods - aborting renovation',\n );\n throw new Error(REPOSITORY_BLOCKED);\n }\n\n try {\n config.isOrgRepo = await helper.isOrg(http, id, repo.owner.login);\n } catch (err) {\n logger.debug({ err }, `${name} initRepo() error`);\n throw err;\n }\n\n // Determine author email and branches\n config.defaultBranch = repo.default_branch;\n logger.debug(`${repository} default branch = ${config.defaultBranch}`);\n\n const url = getRepoUrl(repo, gitUrl, defaults.endpoint, id);\n\n // Initialize Git storage\n await git.initRepo({\n ...config,\n url,\n });\n\n // Reset cached resources\n config.issueList = null;\n config.labelList = null;\n prCache.initRepo(config.repository, config.ignorePrAuthor, botUserName);\n config.hasIssuesEnabled = !repo.external_tracker && repo.has_issues;\n config.orgName = repo.owner.login;\n\n return {\n defaultBranch: config.defaultBranch,\n isFork: !!repo.fork,\n repoFingerprint: repoFingerprint(repo.id, defaults.endpoint),\n };\n },\n\n async getRepos(config?: AutodiscoverConfig): Promise<string[]> {\n logger.debug(`Auto-discovering ${name} repositories`);\n try {\n if (config?.topics) {\n logger.debug({ topics: config.topics }, 'Auto-discovering by topics');\n const fetchRepoArgs: FetchRepositoriesArgs[] = config.topics.map(\n (topic) => {\n return {\n topic,\n sort: config.sort,\n order: config.order,\n };\n },\n );\n const repos = await map(fetchRepoArgs, fetchRepositories);\n return deduplicateArray(repos.flat());\n }\n if (config?.namespaces) {\n logger.debug(\n { namespaces: config.namespaces },\n 'Auto-discovering by organization',\n );\n const repos = await map(\n config.namespaces,\n async (organization: string) => {\n const orgRepos = await helper.orgListRepos(http, organization);\n return orgRepos\n .filter((r) => !r.mirror && !r.archived)\n .map((r) => r.full_name);\n },\n );\n return deduplicateArray(repos.flat());\n }\n return await fetchRepositories({\n sort: config?.sort,\n order: config?.order,\n });\n } catch (err) {\n logger.error(\n { err, platform: id },\n 'Error auto-discovering repositories',\n );\n throw err;\n }\n },\n\n async setBranchStatus({\n branchName,\n context,\n description,\n state,\n url: target_url,\n }: BranchStatusConfig): Promise<void> {\n try {\n // Create new status for branch commit\n const branchCommit = git.getBranchCommit(branchName);\n // TODO: check branchCommit\n\n await helper.createCommitStatus(\n http,\n config.repository,\n branchCommit!,\n {\n state: helper.toPlatformStatusMapping[state] || 'pending',\n context,\n description,\n ...(target_url && { target_url }),\n },\n );\n\n // Refresh caches by re-fetching commit status for branch\n await helper.getCombinedCommitStatus(\n http,\n config.repository,\n branchName,\n {\n memCache: false,\n },\n );\n } catch (err) {\n logger.warn({ err }, 'Failed to set branch status');\n }\n },\n\n async getBranchStatus(\n branchName: string,\n internalChecksAsSuccess: boolean,\n ): Promise<BranchStatus> {\n let ccs: CombinedCommitStatus;\n try {\n ccs = await helper.getCombinedCommitStatus(\n http,\n config.repository,\n branchName,\n );\n } catch (err) {\n if (isNotFound(err)) {\n logger.debug(\n 'Received 404 when checking branch status, assuming branch deletion',\n );\n throw new Error(REPOSITORY_CHANGED);\n }\n\n logger.debug('Unknown error when checking branch status');\n throw err;\n }\n\n logger.debug({ ccs }, 'Branch status check result');\n if (\n !internalChecksAsSuccess &&\n ccs.worstStatus === 'success' &&\n ccs.statuses.every((status) => status.context?.startsWith('renovate/'))\n ) {\n logger.debug(\n 'Successful checks are all internal renovate/ checks, so returning \"pending\" branch status',\n );\n return 'yellow';\n }\n\n return helper.toRenovateStatusMapping[ccs.worstStatus];\n },\n\n async getBranchStatusCheck(\n branchName: string,\n context: string,\n ): Promise<BranchStatus | null> {\n const ccs = await helper.getCombinedCommitStatus(\n http,\n config.repository,\n branchName,\n );\n const cs = ccs.statuses.find((s) => s.context === context);\n if (!cs) {\n return null;\n } // no status check exists\n return helper.toRenovateStatusMapping[cs.status];\n },\n\n getPrList(): Promise<Pr[]> {\n return prCache.getPrs();\n },\n\n async getPr(number: number): Promise<Pr | null> {\n // Search for pull request in cached list or attempt to query directly\n const prList = await platform.getPrList();\n let pr = prList.find((p) => p.number === number) ?? null;\n if (pr) {\n logger.debug('Returning from cached PRs');\n } else {\n logger.debug('PR not found in cached PRs - trying to fetch directly');\n const gpr = await helper.getPR(http, config.repository, number);\n pr = toRenovatePR(gpr, botUserName);\n\n // Add pull request to cache for further lookups / queries\n if (pr) {\n await prCache.setPr(pr);\n }\n }\n\n // Abort and return null if no match was found\n if (!pr) {\n return null;\n }\n\n return pr;\n },\n\n async findPr({\n branchName,\n prTitle: title,\n state = 'all',\n includeOtherAuthors,\n targetBranch,\n }: FindPRConfig): Promise<Pr | null> {\n logger.debug(`findPr(${branchName}, ${title!}, ${state})`);\n if (includeOtherAuthors && isString(targetBranch)) {\n // do not use pr cache as it only fetches prs created by the Renovate account\n const pr = await helper.getPRByBranch(\n http,\n config.repository,\n targetBranch,\n branchName,\n );\n if (!pr) {\n return null;\n }\n\n return toRenovatePR(pr, null);\n }\n const prList = await platform.getPrList();\n const pr = prList.find((p) => {\n if (\n p.sourceRepo !== config.repository ||\n p.sourceBranch !== branchName ||\n !matchesState(p.state, state)\n ) {\n return false;\n }\n return !title || p.title === title;\n });\n\n if (pr) {\n logger.debug(`Found PR #${pr.number}`);\n }\n return pr ?? null;\n },\n\n async createPr({\n sourceBranch,\n targetBranch,\n prTitle,\n prBody: rawBody,\n labels: labelNames,\n platformPrOptions,\n draftPR,\n }: CreatePRConfig): Promise<Pr> {\n let title = prTitle;\n const base = targetBranch;\n const head = sourceBranch;\n const body = sanitize(rawBody);\n if (draftPR) {\n title = DRAFT_PREFIX + title;\n }\n\n logger.debug(`Creating pull request: ${title} (${head} => ${base})`);\n try {\n const labels = Array.isArray(labelNames)\n ? await map(labelNames, (name) =>\n lookupLabelByName(http, config, name),\n )\n : [];\n const gpr = await helper.createPR(http, config.repository, {\n base,\n head,\n title,\n body,\n labels: labels.filter(isNumber),\n });\n\n if (platformPrOptions?.usePlatformAutomerge) {\n // `delete_branch_after_merge` is required to not have undesired\n // behavior when renovate finds existing branches on next run.\n const unsupportedReason = checkNativeAutomerge(defaults.version);\n if (unsupportedReason === null) {\n try {\n await helper.mergePR(http, config.repository, gpr.number, {\n Do:\n getMergeMethod(\n platformPrOptions?.automergeStrategy,\n config.allowedMergeMethods,\n ) ?? config.mergeMethod,\n merge_when_checks_succeed: true,\n delete_branch_after_merge: true,\n });\n\n logger.debug(\n { prNumber: gpr.number },\n `${name}-native automerge: success`,\n );\n } catch (err) {\n logger.warn(\n { err, prNumber: gpr.number, platform: id },\n 'Platform-native automerge: fail',\n );\n }\n } else {\n logger.debug({ prNumber: gpr.number }, unsupportedReason);\n }\n }\n\n const pr = toRenovatePR(gpr, botUserName);\n if (!pr) {\n throw new Error('Can not parse newly created Pull Request');\n }\n\n await prCache.setPr(pr);\n return pr;\n } catch (err) {\n // When the user manually deletes a branch from Renovate, the PR remains but is no longer linked to any branch. In\n // the most recent versions of the platform, the PR gets automatically closed when that happens, but older versions\n // do not handle this properly and keep the PR open. As pushing a branch with the same name resurrects the PR, this\n // would cause a HTTP 409 conflict error, which we hereby gracefully handle.\n if (isConflict(err)) {\n logger.warn(\n { prTitle: title, sourceBranch },\n 'Attempting to gracefully recover from 409 Conflict response in createPr()',\n );\n\n // Refresh cached PR list and search for pull request with matching information\n prCache.forceSync();\n const pr = await platform.findPr({\n branchName: sourceBranch,\n state: 'open',\n });\n\n // If a valid PR was found, return and gracefully recover from the error. Otherwise, abort and throw error.\n // v8 ignore else -- TODO: add test #40625\n if (pr?.bodyStruct) {\n if (pr.title !== title || pr.bodyStruct.hash !== hashBody(body)) {\n logger.debug(\n `Recovered from 409 Conflict, but PR for ${sourceBranch} is outdated. Updating...`,\n );\n await platform.updatePr({\n number: pr.number,\n prTitle: title,\n prBody: body,\n });\n pr.title = title;\n pr.bodyStruct = getPrBodyStruct(body);\n } else {\n logger.debug(\n `Recovered from 409 Conflict and PR for ${sourceBranch} is up-to-date`,\n );\n }\n\n return pr;\n }\n }\n\n throw err;\n }\n },\n\n async updatePr({\n number,\n prTitle,\n prBody: body,\n labels,\n state,\n targetBranch,\n }: UpdatePrConfig): Promise<void> {\n let title = prTitle;\n if (\n (await platform.getPrList()).find((pr) => pr.number === number)?.isDraft\n ) {\n title = DRAFT_PREFIX + title;\n }\n\n const prUpdateParams: PRUpdateParams = {\n title,\n ...(body && { body }),\n ...(state && { state }),\n };\n if (targetBranch) {\n prUpdateParams.base = targetBranch;\n }\n\n /**\n * Update PR labels.\n * In the Gitea API, labels are replaced on each update if the field is present.\n * If the field is not present (i.e., undefined), labels aren't updated.\n * However, the labels array must contain label IDs instead of names,\n * so a lookup is performed to fetch the details (including the ID) of each label.\n */\n if (Array.isArray(labels)) {\n prUpdateParams.labels = (\n await map(labels, (name) => lookupLabelByName(http, config, name))\n ).filter(isNumber);\n if (labels.length !== prUpdateParams.labels.length) {\n logger.warn(\n 'Some labels could not be looked up. Renovate may halt label updates assuming changes by others.',\n );\n }\n }\n\n const gpr = await helper.updatePR(\n http,\n config.repository,\n number,\n prUpdateParams,\n );\n const pr = toRenovatePR(gpr, botUserName);\n if (pr) {\n await prCache.setPr(pr);\n }\n },\n\n async mergePr({ id: prNumber, strategy }: MergePRConfig): Promise<boolean> {\n try {\n await helper.mergePR(http, config.repository, prNumber, {\n Do:\n getMergeMethod(strategy, config.allowedMergeMethods) ??\n config.mergeMethod,\n });\n return true;\n } catch (err) {\n logger.warn({ err, id: prNumber }, 'Merging of PR failed');\n return false;\n }\n },\n\n getIssueList(): Promise<Issue[]> {\n if (config.hasIssuesEnabled === false) {\n return Promise.resolve([]);\n }\n config.issueList ??= fetchIssueList();\n\n return config.issueList;\n },\n\n async getIssue(number: number, memCache = true): Promise<Issue | null> {\n if (config.hasIssuesEnabled === false) {\n return null;\n }\n try {\n const body = (\n await helper.getIssue(http, config.repository, number, { memCache })\n ).body;\n return {\n number,\n body,\n };\n } catch (err) {\n logger.debug({ err, number }, 'Error getting issue');\n return null;\n }\n },\n\n async findIssue(title: string): Promise<Issue | null> {\n const issueList = await platform.getIssueList();\n const issue = issueList.find(\n (i) => i.state === 'open' && i.title === title,\n );\n\n if (!issue) {\n return null;\n }\n // TODO: types (#22198)\n logger.debug(`Found Issue #${issue.number!}`);\n // TODO #22198\n return platform.getIssue!(issue.number!);\n },\n\n async ensureIssue({\n title,\n reuseTitle,\n body: content,\n labels: labelNames,\n shouldReOpen,\n once,\n }: EnsureIssueConfig): Promise<'updated' | 'created' | null> {\n logger.debug(`ensureIssue(${title})`);\n if (config.hasIssuesEnabled === false) {\n logger.info(\n 'Cannot ensure issue because issues are disabled in this repository',\n );\n return null;\n }\n try {\n const body = smartLinks(content);\n\n const issueList = await platform.getIssueList();\n let issues = issueList.filter((i) => i.title === title);\n if (!issues.length) {\n issues = issueList.filter((i) => i.title === reuseTitle);\n }\n\n const labels = Array.isArray(labelNames)\n ? (\n await Promise.all(\n labelNames.map((name) => lookupLabelByName(http, config, name)),\n )\n ).filter(isNumber)\n : undefined;\n\n // Update any matching issues which currently exist\n if (issues.length) {\n let activeIssue = issues.find((i) => i.state === 'open');\n\n // If no active issue was found, decide if it shall be skipped, re-opened or updated without state change\n if (!activeIssue) {\n if (once) {\n logger.debug('Issue already closed - skipping update');\n return null;\n }\n if (shouldReOpen) {\n logger.debug('Reopening previously closed Issue');\n }\n\n // Pick the last issue in the list as the active one\n activeIssue = issues.at(-1)!;\n }\n\n // Close any duplicate issues\n for (const issue of issues) {\n if (issue.state === 'open' && issue.number !== activeIssue.number) {\n // TODO: types (#22198)\n logger.warn(\n { issueNo: issue.number! },\n 'Closing duplicate issue',\n );\n // TODO #22198\n await helper.closeIssue(http, config.repository, issue.number!);\n }\n }\n\n // Check if issue has already correct state\n if (\n activeIssue.title === title &&\n activeIssue.body === body &&\n activeIssue.state === 'open'\n ) {\n logger.debug(\n // TODO: types (#22198)\n `Issue #${activeIssue.number!} is open and up to date - nothing to do`,\n );\n return null;\n }\n\n if (shouldReOpen || activeIssue.state === 'open') {\n // Update issue body and re-open\n logger.debug(`Updating Issue #${activeIssue.number}`);\n const existingIssue = await helper.updateIssue(\n http,\n config.repository,\n // TODO #22198\n activeIssue.number!,\n {\n body,\n title,\n state: 'open',\n },\n );\n\n // Test whether the issues need to be updated\n const existingLabelIds = coerceArray(existingIssue.labels).map(\n (label) => label.id,\n );\n if (labels && haveLabelsChanged(labels, existingLabelIds)) {\n await helper.updateIssueLabels(\n http,\n config.repository,\n // TODO #22198\n activeIssue.number!,\n {\n labels,\n },\n );\n }\n\n return 'updated';\n }\n }\n\n // Create new issue and reset cache\n const issue = await helper.createIssue(http, config.repository, {\n body,\n title,\n labels,\n });\n logger.debug(`Created new Issue #${issue.number}`);\n config.issueList = null;\n\n return 'created';\n } catch (err) {\n logger.warn({ err }, 'Could not ensure issue');\n }\n\n return null;\n },\n\n async ensureIssueClosing(title: string): Promise<void> {\n logger.debug(`ensureIssueClosing(${title})`);\n if (config.hasIssuesEnabled === false) {\n return;\n }\n const issueList = await platform.getIssueList();\n for (const issue of issueList) {\n if (issue.state === 'open' && issue.title === title) {\n logger.debug(`Closing issue...issueNo: ${issue.number!}`);\n // TODO #22198\n await helper.closeIssue(http, config.repository, issue.number!);\n }\n }\n },\n\n async deleteLabel(issue: number, labelName: string): Promise<void> {\n logger.debug(`Deleting label ${labelName} from Issue #${issue}`);\n const label = await lookupLabelByName(http, config, labelName);\n if (label) {\n await helper.unassignLabel(http, config.repository, issue, label);\n } else {\n logger.warn(\n { issue, labelName },\n 'Failed to lookup label for deletion',\n );\n }\n },\n\n async ensureComment({\n number: issue,\n topic,\n content,\n }: EnsureCommentConfig): Promise<boolean> {\n try {\n let body = sanitize(content);\n const commentList = await helper.getComments(\n http,\n config.repository,\n issue,\n );\n\n // Search comment by either topic or exact body\n let comment: Comment | null = null;\n if (topic) {\n comment = findCommentByTopic(commentList, topic);\n body = `### ${topic}\\n\\n${body}`;\n } else {\n comment = findCommentByContent(commentList, body);\n }\n\n // Create a new comment if no match has been found, otherwise update if necessary\n if (!comment) {\n comment = await helper.createComment(\n http,\n config.repository,\n issue,\n body,\n );\n logger.info(\n { repository: config.repository, issue, comment: comment.id },\n 'Comment added',\n );\n } else if (comment.body === body) {\n logger.debug(`Comment #${comment.id} is already up-to-date`);\n } else {\n await helper.updateComment(http, config.repository, comment.id, body);\n logger.debug(\n { repository: config.repository, issue, comment: comment.id },\n 'Comment updated',\n );\n }\n\n return true;\n } catch (err) {\n logger.warn({ err, issue, subject: topic }, 'Error ensuring comment');\n return false;\n }\n },\n\n async ensureCommentRemoval(\n deleteConfig: EnsureCommentRemovalConfig,\n ): Promise<void> {\n const { number: issue } = deleteConfig;\n const key =\n deleteConfig.type === 'by-topic'\n ? deleteConfig.topic\n : deleteConfig.content;\n logger.debug(`Ensuring comment \"${key}\" in #${issue} is removed`);\n const commentList = await helper.getComments(\n http,\n config.repository,\n issue,\n );\n\n let comment: Comment | null = null;\n // v8 ignore else -- TODO: add test #40625\n if (deleteConfig.type === 'by-topic') {\n comment = findCommentByTopic(commentList, deleteConfig.topic);\n } else if (deleteConfig.type === 'by-content') {\n const body = sanitize(deleteConfig.content);\n comment = findCommentByContent(commentList, body);\n }\n\n // Abort and do nothing if no matching comment was found\n if (!comment) {\n return;\n }\n\n // Try to delete comment\n try {\n await helper.deleteComment(http, config.repository, comment.id);\n } catch (err) {\n logger.warn(\n { err, issue, config: deleteConfig },\n 'Error deleting comment',\n );\n }\n },\n\n async getBranchPr(branchName: string): Promise<Pr | null> {\n logger.debug(`getBranchPr(${branchName})`);\n const pr = await platform.findPr({ branchName, state: 'open' });\n return pr ? platform.getPr(pr.number) : null;\n },\n\n async addAssignees(number: number, assignees: string[]): Promise<void> {\n logger.debug(\n `Updating assignees '${assignees?.join(', ')}' on Issue #${number}`,\n );\n await helper.updateIssue(http, config.repository, number, {\n assignees,\n });\n },\n\n async addReviewers(number: number, reviewers: string[]): Promise<void> {\n logger.debug(`Adding reviewers '${reviewers?.join(', ')}' to #${number}`);\n if (\n minReviewerVersion &&\n semver.lt(defaults.version, minReviewerVersion)\n ) {\n logger.debug(\n { version: defaults.version },\n 'Adding reviewer not yet supported.',\n );\n return;\n }\n try {\n const teamReviewers = new Set(\n reviewers\n .filter((r) => r.startsWith('team:'))\n .map((r) => r.substring(5)),\n );\n const userReviewers = new Set(\n reviewers.filter((r) => !r.startsWith('team:')),\n );\n\n await helper.requestPrReviewers(http, config.repository, number, {\n reviewers: [...userReviewers],\n ...(teamReviewers.size && {\n team_reviewers: [...teamReviewers],\n }),\n });\n } catch (err) {\n logger.warn({ err, number, reviewers }, 'Failed to assign reviewer');\n }\n },\n\n massageMarkdown(prBody: string): string {\n return smartTruncate(smartLinks(prBody), maxBodyLength());\n },\n\n maxBodyLength,\n };\n\n function maxBodyLength(): number {\n return 1000000;\n }\n\n return { platform, resetPlatform };\n}\n\n/**\n * Forgejo reports the Gitea version it is compatible with as part of its own\n * version, for example `11.0.1-99-c504062+gitea-1.22.0`.\n */\nfunction isForgejo(version: string): boolean {\n return version.includes('gitea-');\n}\n\nfunction logDetectedVersion(version: string): void {\n if (isForgejo(version)) {\n logger.info(\n `Detected Forgejo instance, please use 'forgejo' platform instead`,\n );\n }\n logger.debug(\n `${isForgejo(version) ? 'Forgejo' : 'Gitea'} version: ${version}`,\n );\n}\n\nfunction checkNativeAutomerge(version: string): string | null {\n // Only Gitea v1.24.0+ and Forgejo v10.0.0+ support delete_branch_after_merge.\n const minVersion = isForgejo(version) ? '10.0.0' : '1.24.0';\n if (semver.gte(version, minVersion)) {\n return null;\n }\n return `Gitea-native automerge: not supported on this version of ${isForgejo(version) ? 'Forgejo' : 'Gitea'}. Use ${minVersion} or newer.`;\n}\n\nconst { platform, resetPlatform } = createPlatform({\n id,\n defaultEndpoint: 'https://gitea.com/',\n http: giteaHttp,\n setBaseUrl,\n logDetectedVersion,\n checkNativeAutomerge,\n // Requesting reviewers is only supported since Gitea v1.14.0.\n minReviewerVersion: '1.14.0',\n});\n\nexport { resetPlatform };\n\n/* oxlint-disable typescript/unbound-method */\nexport const {\n addAssignees,\n addReviewers,\n createPr,\n deleteLabel,\n ensureComment,\n ensureCommentRemoval,\n ensureIssue,\n ensureIssueClosing,\n findIssue,\n findPr,\n getBranchPr,\n getBranchStatus,\n getBranchStatusCheck,\n getIssue,\n getRawFile,\n getJsonFile,\n getIssueList,\n getPr,\n massageMarkdown,\n maxBodyLength,\n getPrList,\n getRepos,\n initPlatform,\n initRepo,\n mergePr,\n setBranchStatus,\n updatePr,\n} = platform;\n"],"mappings":"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"}
@@ -9,6 +9,7 @@ import { looseEquals } from "../../../util/string.js";
9
9
  import { sanitize } from "../../../util/sanitize.js";
10
10
  import { logger } from "../../../logger/index.js";
11
11
  import { ensureTrailingSlash, isHttpUrl, parseUrl } from "../../../util/url.js";
12
+ import { isForbidden, isGone, isMethodNotAllowed, isNotFound, isUnprocessableContent } from "../../../util/http/status.js";
12
13
  import { instrument } from "../../../instrumentation/index.js";
13
14
  import { find } from "../../../util/host-rules.js";
14
15
  import { parseJson } from "../../../util/common.js";
@@ -86,6 +87,15 @@ var github_exports = /* @__PURE__ */ __exportAll({
86
87
  const id = "github";
87
88
  let config;
88
89
  let platformConfig;
90
+ function isGhesVersionSatisfying(range) {
91
+ if (!isGithubEnterpriseServer(platformConfig.host)) return false;
92
+ return semver.satisfies(platformConfig.host.version ?? "", range);
93
+ }
94
+ function isGhesVersionUnknownOrBelow(minVersion) {
95
+ if (!isGithubEnterpriseServer(platformConfig.host)) return false;
96
+ const { version } = platformConfig.host;
97
+ return !version || semver.lt(version, minVersion);
98
+ }
89
99
  const defaultGithubApiUrl = "https://api.github.com/";
90
100
  const GitHubMaxPrBodyLen = 58e3;
91
101
  const noteAlertRegex = regEx(/> ℹ️? \*\*Note\*\*\n> ?\n/g);
@@ -148,7 +158,7 @@ async function initPlatform({ endpoint, token: originalToken, username, gitAutho
148
158
  * GHE requires version >=3.10 to support fine-grained access tokens
149
159
  * https://docs.github.com/en/enterprise-server@3.10/admin/release-notes#authentication
150
160
  */
151
- if (isGithubFineGrainedPersonalAccessToken(token) && isGithubEnterpriseServer(platformConfig.host) && (!platformConfig.host.version || semver.lt(platformConfig.host.version, "3.10.0"))) throw new Error("Init: Fine-grained Personal Access Tokens do not support GitHub Enterprise Server API version <3.10 and cannot be used with Renovate.");
161
+ if (isGithubFineGrainedPersonalAccessToken(token) && isGhesVersionUnknownOrBelow("3.10.0")) throw new Error("Init: Fine-grained Personal Access Tokens do not support GitHub Enterprise Server API version <3.10 and cannot be used with Renovate.");
152
162
  let renovateUsername;
153
163
  if (username) renovateUsername = username;
154
164
  else if (platformConfig.isGHApp) {
@@ -250,7 +260,7 @@ async function getBranchRulesets(branchName) {
250
260
  try {
251
261
  return (await githubApi.getJson(`repos/${config.repository}/rules/branches/${escapeHash(branchName)}`, { cacheProvider: repoCacheProvider }, GithubBranchRulesets)).body;
252
262
  } catch (err) {
253
- if (err.statusCode === 404) {
263
+ if (isNotFound(err)) {
254
264
  logger.debug(`No branch rulesets found for ${branchName}`);
255
265
  return [];
256
266
  }
@@ -279,7 +289,7 @@ async function listForks(token, repository) {
279
289
  logger.debug(`Found ${repos.length} forked repo(s)`);
280
290
  return repos;
281
291
  } catch (err) {
282
- if (err.statusCode === 404) logger.debug("Cannot list repo forks - it is likely private");
292
+ if (isNotFound(err)) logger.debug("Cannot list repo forks - it is likely private");
283
293
  else logger.debug({ err }, "Unknown error listing repository forks");
284
294
  throw new Error(REPOSITORY_CANNOT_FORK);
285
295
  }
@@ -349,12 +359,12 @@ async function initRepo({ repository, forkCreation, forkOrg, forkToken, gitUrl,
349
359
  let forkSshUrl = null;
350
360
  try {
351
361
  let infoQuery = repoInfoQuery;
352
- if (isGithubEnterpriseServer(platformConfig.host) && semver.satisfies(platformConfig.host.version ?? "", "<3.3.0")) {
362
+ if (isGhesVersionSatisfying("<3.3.0")) {
353
363
  infoQuery = infoQuery.replace(regEx(/\n\s*autoMergeAllowed\s*\n/), "\n");
354
364
  infoQuery = infoQuery.replace(regEx(/\n\s*hasIssuesEnabled\s*\n/), "\n");
355
365
  }
356
- if (isGithubEnterpriseServer(platformConfig.host) && semver.satisfies(platformConfig.host.version ?? "", "<3.9.0")) infoQuery = infoQuery.replace(regEx(/\n\s*hasVulnerabilityAlertsEnabled\s*\n/), "\n");
357
- if (isGithubEnterpriseServer(platformConfig.host) && semver.satisfies(platformConfig.host.version ?? "", "<3.12.0")) infoQuery = infoQuery.replace(regEx(/\n\s*mergeQueue\s*\{\s*id\s*\}\s*\n/), "\n");
366
+ if (isGhesVersionSatisfying("<3.9.0")) infoQuery = infoQuery.replace(regEx(/\n\s*hasVulnerabilityAlertsEnabled\s*\n/), "\n");
367
+ if (isGhesVersionSatisfying("<3.12.0")) infoQuery = infoQuery.replace(regEx(/\n\s*mergeQueue\s*\{\s*id\s*\}\s*\n/), "\n");
358
368
  const res = await githubApi.requestGraphql(infoQuery, {
359
369
  variables: {
360
370
  owner: config.repositoryOwner,
@@ -405,8 +415,8 @@ async function initRepo({ repository, forkCreation, forkOrg, forkToken, gitUrl,
405
415
  } catch (err) /* v8 ignore next -- initRepo error mapping needs failure shapes not mocked in specs */ {
406
416
  logger.debug({ err }, "Caught initRepo error");
407
417
  if (err.message === "archived" || err.message === "renamed" || err.message === "not-found") throw err;
408
- if (err.statusCode === 403) throw new Error(REPOSITORY_ACCESS_FORBIDDEN);
409
- if (err.statusCode === 404) throw new Error(REPOSITORY_NOT_FOUND);
418
+ if (isForbidden(err)) throw new Error(REPOSITORY_ACCESS_FORBIDDEN);
419
+ if (isNotFound(err)) throw new Error(REPOSITORY_NOT_FOUND);
410
420
  if (err.message.startsWith("Repository access blocked")) throw new Error(REPOSITORY_BLOCKED);
411
421
  if (err.message === "fork-mode-forked") throw err;
412
422
  if (err.message === "fork") throw err;
@@ -546,11 +556,11 @@ async function getBranchForceRebase(branchName) {
546
556
  return config.branchForceRebase[branchName];
547
557
  }
548
558
  function handleBranchProtectionError(protection, err, branchName) {
549
- if (err.statusCode === 404) {
559
+ if (isNotFound(err)) {
550
560
  logger.debug(`No ${protection} found for ${branchName}`);
551
561
  return;
552
562
  }
553
- if (err.message === "integration-unauthorized" || err.statusCode === 403) {
563
+ if (err.message === "integration-unauthorized" || isForbidden(err)) {
554
564
  logger.once.debug(`Branch protection: Do not have permissions to detect ${protection} for ${branchName}`);
555
565
  return;
556
566
  }
@@ -648,7 +658,7 @@ async function ensureBranchSha(branchName, sha) {
648
658
  } });
649
659
  return;
650
660
  } catch (err) {
651
- if (err.err?.response?.statusCode === 422) logger.debug({ err }, "Branch update failed due to reference not existing - will try to create");
661
+ if (isUnprocessableContent(err.err)) logger.debug({ err }, "Branch update failed due to reference not existing - will try to create");
652
662
  else {
653
663
  logger.warn({
654
664
  refUrl,
@@ -725,7 +735,7 @@ async function getBranchStatus(branchName, internalChecksAsSuccess) {
725
735
  try {
726
736
  commitStatus = await getStatus(branchName);
727
737
  } catch (err) /* v8 ignore next -- 404-to-REPOSITORY_CHANGED mapping for deleted branches is not mocked in specs */ {
728
- if (err.statusCode === 404) {
738
+ if (isNotFound(err)) {
729
739
  logger.debug("Received 404 when checking branch status, assuming that branch has been deleted");
730
740
  throw new Error(REPOSITORY_CHANGED);
731
741
  }
@@ -764,7 +774,7 @@ async function getBranchStatus(branchName, internalChecksAsSuccess) {
764
774
  } else logger.debug({ result: checkRunsRaw }, "No check runs found");
765
775
  } catch (err) /* v8 ignore next -- check-run permission errors (403) are mapped to empty results, not mocked in specs */ {
766
776
  if (err instanceof ExternalHostError) throw err;
767
- if (err.statusCode === 403 || err.message === "integration-unauthorized") logger.debug("No permission to view check runs");
777
+ if (isForbidden(err) || err.message === "integration-unauthorized") logger.debug("No permission to view check runs");
768
778
  else logger.warn({ err }, "Error retrieving check runs");
769
779
  }
770
780
  if (checkRuns.length === 0) {
@@ -798,7 +808,7 @@ async function getBranchStatusCheck(branchName, context) {
798
808
  for (const check of res) if (check.context === context) return githubToRenovateStatusMapping[check.state] || "yellow";
799
809
  return null;
800
810
  } catch (err) /* v8 ignore next -- 404-to-REPOSITORY_CHANGED mapping for missing commits is not mocked in specs */ {
801
- if (err.statusCode === 404) {
811
+ if (isNotFound(err)) {
802
812
  logger.debug("Commit not found when checking statuses");
803
813
  throw new Error(REPOSITORY_CHANGED);
804
814
  }
@@ -879,7 +889,7 @@ async function getIssue(number) {
879
889
  err,
880
890
  number
881
891
  }, "Error getting issue");
882
- if (err.response?.statusCode === 410) {
892
+ if (isGone(err)) {
883
893
  logger.debug(`Issue #${number} has been deleted`);
884
894
  GithubIssueCache.deleteIssue(number);
885
895
  }
@@ -900,8 +910,7 @@ async function closeIssue(issueNumber) {
900
910
  const { body: closedIssue } = await githubApi.patchJson(`repos/${repo}/issues/${issueNumber}`, { body: { state: "closed" } }, GithubIssue);
901
911
  GithubIssueCache.updateIssue(closedIssue);
902
912
  } catch (err) {
903
- const statusCode = err.response?.statusCode;
904
- if (statusCode === 404 || statusCode === 410) {
913
+ if (isNotFound(err) || isGone(err)) {
905
914
  logger.debug(`Issue #${issueNumber} no longer exists on the platform, removing from cache`);
906
915
  GithubIssueCache.deleteIssue(issueNumber);
907
916
  return;
@@ -1014,7 +1023,7 @@ async function addAssignees(issueNo, assignees) {
1014
1023
  GithubIssueCache.updateIssue(updatedIssue);
1015
1024
  return;
1016
1025
  } catch (err) {
1017
- if (err.statusCode !== 404) throw err;
1026
+ if (!isNotFound(err)) throw err;
1018
1027
  lastErr = err;
1019
1028
  logger.debug({ attempt: attempt + 1 }, `Retrying addAssignees for #${issueNo} after 404`);
1020
1029
  await setTimeout(1e3);
@@ -1080,7 +1089,7 @@ async function getComments(issueNo) {
1080
1089
  logger.debug(`Found ${comments.length} comments`);
1081
1090
  return comments;
1082
1091
  } catch (err) /* v8 ignore next -- comment-fetch 404s are wrapped as ExternalHostError, not mocked in specs */ {
1083
- if (err.statusCode === 404) {
1092
+ if (isNotFound(err)) {
1084
1093
  logger.debug("404 response when retrieving comments");
1085
1094
  throw new ExternalHostError(err, "github");
1086
1095
  }
@@ -1168,7 +1177,7 @@ async function ensureCommentRemoval(deleteConfig) {
1168
1177
  }
1169
1178
  async function tryPrAutomerge(prNumber, prNodeId, platformPrOptions) {
1170
1179
  if (!platformPrOptions?.usePlatformAutomerge) return;
1171
- if (isGithubEnterpriseServer(platformConfig.host) && semver.satisfies(platformConfig.host.version ?? "", "<3.3.0")) {
1180
+ if (isGhesVersionSatisfying("<3.3.0")) {
1172
1181
  logger.debug({ prNumber }, "GitHub-native automerge: not supported on this version of GHE. Use 3.3.0 or newer.");
1173
1182
  return;
1174
1183
  }
@@ -1255,7 +1264,7 @@ async function createPr({ sourceBranch, targetBranch, prTitle: title, prBody: ra
1255
1264
  async function isBranchMergeQueueEnabled(baseBranch) {
1256
1265
  const cachedResult = config.mergeQueueEnabled[baseBranch];
1257
1266
  if (cachedResult !== void 0) return cachedResult;
1258
- if (isGithubEnterpriseServer(platformConfig.host) && semver.satisfies(platformConfig.host.version ?? "", "<3.12.0")) {
1267
+ if (isGhesVersionSatisfying("<3.12.0")) {
1259
1268
  config.mergeQueueEnabled[baseBranch] = false;
1260
1269
  return false;
1261
1270
  }
@@ -1386,13 +1395,17 @@ async function directMergePr(prNo, strategy) {
1386
1395
  automergeResult = await githubApi.putJson(url, options);
1387
1396
  automerged = true;
1388
1397
  } catch (err) /* v8 ignore next -- merge rejection handling (404/405 status-check bodies) is not fully mocked in specs */ {
1389
- if (err.statusCode === 404 || err.statusCode === 405) {
1398
+ if (isNotFound(err) || isMethodNotAllowed(err)) {
1390
1399
  const body = err.response?.body;
1391
1400
  if (isNonEmptyString(body?.message) && regEx(/^Required status check ".+" is expected\.$/).test(body.message)) {
1392
1401
  logger.debug({ response: body }, `GitHub blocking PR merge -- Missing required status check(s)`);
1393
1402
  return false;
1394
1403
  }
1395
- if (isNonEmptyString(body?.message) && (body.message.includes("approving review") || body.message.includes("code owner review") || body.message.includes("New changes require approval from someone other than the last pusher"))) {
1404
+ if (isNonEmptyString(body?.message) && [
1405
+ "approving review",
1406
+ "code owner review",
1407
+ "New changes require approval from someone other than the last pusher"
1408
+ ].some((text) => body.message.includes(text))) {
1396
1409
  logger.debug({ response: body }, `GitHub blocking PR merge -- Needs approving review(s)`);
1397
1410
  return false;
1398
1411
  }