renovate 43.263.0 → 43.263.2

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 (258) hide show
  1. package/dist/config/app-strings.js +1 -1
  2. package/dist/config/app-strings.js.map +1 -1
  3. package/dist/config/decrypt/bcpgp.js +7 -4
  4. package/dist/config/decrypt/bcpgp.js.map +1 -1
  5. package/dist/config/migration.js +4 -6
  6. package/dist/config/migration.js.map +1 -1
  7. package/dist/config/options/index.js +1 -1
  8. package/dist/config/options/index.js.map +1 -1
  9. package/dist/config/validation-helpers/match-base-branches.js +4 -6
  10. package/dist/config/validation-helpers/match-base-branches.js.map +1 -1
  11. package/dist/config/validation-helpers/regex-glob-matchers.js +4 -6
  12. package/dist/config/validation-helpers/regex-glob-matchers.js.map +1 -1
  13. package/dist/config/validation-helpers/utils.js +2 -4
  14. package/dist/config/validation-helpers/utils.js.map +1 -1
  15. package/dist/config/validation.js +4 -6
  16. package/dist/config/validation.js.map +1 -1
  17. package/dist/config-validator.js +1 -3
  18. package/dist/config-validator.js.map +1 -1
  19. package/dist/global-config-option-defaults.generated.js +1 -1
  20. package/dist/global-config-option-defaults.generated.js.map +1 -1
  21. package/dist/modules/datasource/artifactory/index.js +6 -8
  22. package/dist/modules/datasource/artifactory/index.js.map +1 -1
  23. package/dist/modules/datasource/aws-machine-image/index.js +1 -2
  24. package/dist/modules/datasource/aws-machine-image/index.js.map +1 -1
  25. package/dist/modules/datasource/azure-pipelines-tasks/index.js +2 -3
  26. package/dist/modules/datasource/azure-pipelines-tasks/index.js.map +1 -1
  27. package/dist/modules/datasource/conda/index.js +1 -3
  28. package/dist/modules/datasource/conda/index.js.map +1 -1
  29. package/dist/modules/datasource/dart-version/index.js +1 -2
  30. package/dist/modules/datasource/dart-version/index.js.map +1 -1
  31. package/dist/modules/datasource/datasource.js +1 -3
  32. package/dist/modules/datasource/datasource.js.map +1 -1
  33. package/dist/modules/datasource/devbox/index.js +1 -3
  34. package/dist/modules/datasource/devbox/index.js.map +1 -1
  35. package/dist/modules/datasource/docker/ecr.js +2 -1
  36. package/dist/modules/datasource/docker/ecr.js.map +1 -1
  37. package/dist/modules/datasource/docker/index.js +1 -1
  38. package/dist/modules/datasource/docker/index.js.map +1 -1
  39. package/dist/modules/datasource/galaxy-collection/index.js +1 -1
  40. package/dist/modules/datasource/galaxy-collection/index.js.map +1 -1
  41. package/dist/modules/datasource/go/releases-goproxy.js +2 -2
  42. package/dist/modules/datasource/go/releases-goproxy.js.map +1 -1
  43. package/dist/modules/datasource/java-version/index.js +1 -3
  44. package/dist/modules/datasource/java-version/index.js.map +1 -1
  45. package/dist/modules/datasource/maven/util.js +2 -1
  46. package/dist/modules/datasource/maven/util.js.map +1 -1
  47. package/dist/modules/datasource/nuget/common.js +6 -4
  48. package/dist/modules/datasource/nuget/common.js.map +1 -1
  49. package/dist/modules/datasource/util.js +3 -2
  50. package/dist/modules/datasource/util.js.map +1 -1
  51. package/dist/modules/manager/azure-pipelines/extract.js +1 -1
  52. package/dist/modules/manager/azure-pipelines/extract.js.map +1 -1
  53. package/dist/modules/manager/bazel/extract.js +1 -3
  54. package/dist/modules/manager/bazel/extract.js.map +1 -1
  55. package/dist/modules/manager/bazel/parser.js +1 -1
  56. package/dist/modules/manager/bazel/parser.js.map +1 -1
  57. package/dist/modules/manager/buildpacks/extract.js +1 -1
  58. package/dist/modules/manager/buildpacks/extract.js.map +1 -1
  59. package/dist/modules/manager/bundler/common.js +23 -25
  60. package/dist/modules/manager/bundler/common.js.map +1 -1
  61. package/dist/modules/manager/bundler/extract.js +2 -6
  62. package/dist/modules/manager/bundler/extract.js.map +1 -1
  63. package/dist/modules/manager/cargo/extract.js +4 -6
  64. package/dist/modules/manager/cargo/extract.js.map +1 -1
  65. package/dist/modules/manager/dockerfile/extract.js +3 -3
  66. package/dist/modules/manager/dockerfile/extract.js.map +1 -1
  67. package/dist/modules/manager/fingerprint.generated.js +13 -13
  68. package/dist/modules/manager/fingerprint.generated.js.map +1 -1
  69. package/dist/modules/manager/flux/extract.js +2 -1
  70. package/dist/modules/manager/flux/extract.js.map +1 -1
  71. package/dist/modules/manager/github-actions/parse.js +1 -1
  72. package/dist/modules/manager/github-actions/parse.js.map +1 -1
  73. package/dist/modules/manager/gradle/extract/catalog.js +4 -3
  74. package/dist/modules/manager/gradle/extract/catalog.js.map +1 -1
  75. package/dist/modules/manager/gradle/extract.js +2 -2
  76. package/dist/modules/manager/gradle/extract.js.map +1 -1
  77. package/dist/modules/manager/gradle/parser/common.js +1 -1
  78. package/dist/modules/manager/gradle/parser/common.js.map +1 -1
  79. package/dist/modules/manager/gradle/parser/handlers.js +1 -1
  80. package/dist/modules/manager/gradle/parser/handlers.js.map +1 -1
  81. package/dist/modules/manager/helm-values/extract.js.map +1 -1
  82. package/dist/modules/manager/helmfile/extract.js +1 -1
  83. package/dist/modules/manager/helmfile/extract.js.map +1 -1
  84. package/dist/modules/manager/maven/extract.js.map +1 -1
  85. package/dist/modules/manager/maven/update.js +2 -1
  86. package/dist/modules/manager/maven/update.js.map +1 -1
  87. package/dist/modules/manager/mise/utils.js +5 -7
  88. package/dist/modules/manager/mise/utils.js.map +1 -1
  89. package/dist/modules/manager/mix/extract.js +3 -6
  90. package/dist/modules/manager/mix/extract.js.map +1 -1
  91. package/dist/modules/manager/npm/extract/common/overrides.js +1 -1
  92. package/dist/modules/manager/npm/extract/common/overrides.js.map +1 -1
  93. package/dist/modules/manager/npm/extract/yarn.js +1 -1
  94. package/dist/modules/manager/npm/extract/yarn.js.map +1 -1
  95. package/dist/modules/manager/npm/npmrc.js +1 -3
  96. package/dist/modules/manager/npm/npmrc.js.map +1 -1
  97. package/dist/modules/manager/npm/update/dependency/common.js +2 -3
  98. package/dist/modules/manager/npm/update/dependency/common.js.map +1 -1
  99. package/dist/modules/manager/npm/update/dependency/index.js +1 -1
  100. package/dist/modules/manager/npm/update/dependency/index.js.map +1 -1
  101. package/dist/modules/manager/npm/update/dependency/pnpm.js +1 -1
  102. package/dist/modules/manager/npm/update/dependency/pnpm.js.map +1 -1
  103. package/dist/modules/manager/npm/update/dependency/yarn.js +1 -1
  104. package/dist/modules/manager/npm/update/dependency/yarn.js.map +1 -1
  105. package/dist/modules/manager/osgi/extract.js +1 -1
  106. package/dist/modules/manager/osgi/extract.js.map +1 -1
  107. package/dist/modules/manager/pep621/processors/uv.js +1 -1
  108. package/dist/modules/manager/pep621/processors/uv.js.map +1 -1
  109. package/dist/modules/manager/pep621/schema.js.map +1 -1
  110. package/dist/modules/manager/pip_setup/extract.js +1 -1
  111. package/dist/modules/manager/pip_setup/extract.js.map +1 -1
  112. package/dist/modules/manager/pipenv/artifacts.js.map +1 -1
  113. package/dist/modules/manager/poetry/schema.js +2 -2
  114. package/dist/modules/manager/poetry/schema.js.map +1 -1
  115. package/dist/modules/manager/pub/artifacts.js +4 -6
  116. package/dist/modules/manager/pub/artifacts.js.map +1 -1
  117. package/dist/modules/manager/pub/utils.js +2 -2
  118. package/dist/modules/manager/pub/utils.js.map +1 -1
  119. package/dist/modules/manager/puppet/common.js +4 -6
  120. package/dist/modules/manager/puppet/common.js.map +1 -1
  121. package/dist/modules/manager/sbt/extract.js +1 -1
  122. package/dist/modules/manager/sbt/extract.js.map +1 -1
  123. package/dist/modules/manager/sbt/util.js +4 -2
  124. package/dist/modules/manager/sbt/util.js.map +1 -1
  125. package/dist/modules/manager/terraform/lockfile/util.js +1 -1
  126. package/dist/modules/manager/terraform/lockfile/util.js.map +1 -1
  127. package/dist/modules/platform/azure/index.js +15 -19
  128. package/dist/modules/platform/azure/index.js.map +1 -1
  129. package/dist/modules/platform/azure/issue.js +67 -17
  130. package/dist/modules/platform/azure/issue.js.map +1 -1
  131. package/dist/modules/platform/bitbucket/index.js +1 -3
  132. package/dist/modules/platform/bitbucket/index.js.map +1 -1
  133. package/dist/modules/platform/forgejo/index.js +5 -3
  134. package/dist/modules/platform/forgejo/index.js.map +1 -1
  135. package/dist/modules/platform/forgejo/utils.js +1 -1
  136. package/dist/modules/platform/forgejo/utils.js.map +1 -1
  137. package/dist/modules/platform/gerrit/scm.js +5 -7
  138. package/dist/modules/platform/gerrit/scm.js.map +1 -1
  139. package/dist/modules/platform/gitea/index.js +5 -3
  140. package/dist/modules/platform/gitea/index.js.map +1 -1
  141. package/dist/modules/platform/gitea/utils.js +1 -1
  142. package/dist/modules/platform/gitea/utils.js.map +1 -1
  143. package/dist/modules/platform/github/index.js +5 -7
  144. package/dist/modules/platform/github/index.js.map +1 -1
  145. package/dist/modules/platform/github/pr.js +1 -1
  146. package/dist/modules/platform/github/pr.js.map +1 -1
  147. package/dist/modules/platform/gitlab/index.js +2 -1
  148. package/dist/modules/platform/gitlab/index.js.map +1 -1
  149. package/dist/modules/platform/utils/pr-body.js +2 -1
  150. package/dist/modules/platform/utils/pr-body.js.map +1 -1
  151. package/dist/modules/versioning/apk/index.js +3 -3
  152. package/dist/modules/versioning/apk/index.js.map +1 -1
  153. package/dist/modules/versioning/composer/index.js +4 -7
  154. package/dist/modules/versioning/composer/index.js.map +1 -1
  155. package/dist/modules/versioning/conan/common.js +4 -6
  156. package/dist/modules/versioning/conan/common.js.map +1 -1
  157. package/dist/modules/versioning/conan/index.js +1 -3
  158. package/dist/modules/versioning/conan/index.js.map +1 -1
  159. package/dist/modules/versioning/conan/range.js +4 -5
  160. package/dist/modules/versioning/conan/range.js.map +1 -1
  161. package/dist/modules/versioning/conda/index.js +1 -1
  162. package/dist/modules/versioning/conda/index.js.map +1 -1
  163. package/dist/modules/versioning/gradle/index.js +7 -3
  164. package/dist/modules/versioning/gradle/index.js.map +1 -1
  165. package/dist/modules/versioning/hermit/index.js +2 -2
  166. package/dist/modules/versioning/hermit/index.js.map +1 -1
  167. package/dist/modules/versioning/ivy/index.js +1 -1
  168. package/dist/modules/versioning/ivy/index.js.map +1 -1
  169. package/dist/modules/versioning/maven/compare.js +4 -6
  170. package/dist/modules/versioning/maven/compare.js.map +1 -1
  171. package/dist/modules/versioning/npm/range.js +5 -7
  172. package/dist/modules/versioning/npm/range.js.map +1 -1
  173. package/dist/modules/versioning/nuget/version.js +6 -6
  174. package/dist/modules/versioning/nuget/version.js.map +1 -1
  175. package/dist/modules/versioning/pep440/index.js +1 -1
  176. package/dist/modules/versioning/pep440/index.js.map +1 -1
  177. package/dist/modules/versioning/pep440/range.js +2 -6
  178. package/dist/modules/versioning/pep440/range.js.map +1 -1
  179. package/dist/modules/versioning/poetry/index.js +1 -1
  180. package/dist/modules/versioning/poetry/index.js.map +1 -1
  181. package/dist/modules/versioning/pvp/index.js +2 -2
  182. package/dist/modules/versioning/pvp/index.js.map +1 -1
  183. package/dist/modules/versioning/rpm/index.js +4 -3
  184. package/dist/modules/versioning/rpm/index.js.map +1 -1
  185. package/dist/modules/versioning/ruby/range.js +2 -2
  186. package/dist/modules/versioning/ruby/range.js.map +1 -1
  187. package/dist/modules/versioning/ruby/strategies/bump.js +1 -1
  188. package/dist/modules/versioning/ruby/strategies/bump.js.map +1 -1
  189. package/dist/modules/versioning/ruby/strategies/replace.js +13 -12
  190. package/dist/modules/versioning/ruby/strategies/replace.js.map +1 -1
  191. package/dist/modules/versioning/ruby/version.js +1 -1
  192. package/dist/modules/versioning/ruby/version.js.map +1 -1
  193. package/dist/modules/versioning/rust-release-channel/index.js +1 -1
  194. package/dist/modules/versioning/rust-release-channel/index.js.map +1 -1
  195. package/dist/modules/versioning/rust-release-channel/util.js +4 -4
  196. package/dist/modules/versioning/rust-release-channel/util.js.map +1 -1
  197. package/dist/util/common.js +1 -3
  198. package/dist/util/common.js.map +1 -1
  199. package/dist/util/exec/common.js +4 -6
  200. package/dist/util/exec/common.js.map +1 -1
  201. package/dist/util/exec/containerbase.js +1 -3
  202. package/dist/util/exec/containerbase.js.map +1 -1
  203. package/dist/util/git/instrument.js +3 -3
  204. package/dist/util/git/instrument.js.map +1 -1
  205. package/dist/util/github/graphql/datasource-fetcher.js +5 -4
  206. package/dist/util/github/graphql/datasource-fetcher.js.map +1 -1
  207. package/dist/util/http/cache/package-http-cache-provider.js.map +1 -1
  208. package/dist/util/http/github.js +3 -2
  209. package/dist/util/http/github.js.map +1 -1
  210. package/dist/util/http/http.d.ts +1 -1
  211. package/dist/util/http/http.js.map +1 -1
  212. package/dist/util/result.d.ts +8 -8
  213. package/dist/util/result.js +1 -1
  214. package/dist/util/result.js.map +1 -1
  215. package/dist/util/url.js +2 -2
  216. package/dist/util/url.js.map +1 -1
  217. package/dist/workers/global/config/parse/cli.js +18 -20
  218. package/dist/workers/global/config/parse/cli.js.map +1 -1
  219. package/dist/workers/global/config/parse/env.js +3 -5
  220. package/dist/workers/global/config/parse/env.js.map +1 -1
  221. package/dist/workers/repository/config-migration/branch/index.js +3 -5
  222. package/dist/workers/repository/config-migration/branch/index.js.map +1 -1
  223. package/dist/workers/repository/init/merge.js +2 -3
  224. package/dist/workers/repository/init/merge.js.map +1 -1
  225. package/dist/workers/repository/onboarding/branch/check.js +7 -9
  226. package/dist/workers/repository/onboarding/branch/check.js.map +1 -1
  227. package/dist/workers/repository/onboarding/branch/index.js +4 -8
  228. package/dist/workers/repository/onboarding/branch/index.js.map +1 -1
  229. package/dist/workers/repository/onboarding/branch/onboarding-branch-cache.js +2 -2
  230. package/dist/workers/repository/onboarding/branch/onboarding-branch-cache.js.map +1 -1
  231. package/dist/workers/repository/process/extract-update.js.map +1 -1
  232. package/dist/workers/repository/process/fetch.js.map +1 -1
  233. package/dist/workers/repository/process/libyear.js +1 -3
  234. package/dist/workers/repository/process/libyear.js.map +1 -1
  235. package/dist/workers/repository/process/lookup/filter-checks.js +9 -11
  236. package/dist/workers/repository/process/lookup/filter-checks.js.map +1 -1
  237. package/dist/workers/repository/process/lookup/index.js +5 -8
  238. package/dist/workers/repository/process/lookup/index.js.map +1 -1
  239. package/dist/workers/repository/process/vulnerabilities.js +3 -3
  240. package/dist/workers/repository/process/vulnerabilities.js.map +1 -1
  241. package/dist/workers/repository/reconfigure/index.js +3 -5
  242. package/dist/workers/repository/reconfigure/index.js.map +1 -1
  243. package/dist/workers/repository/update/branch/bump-versions.js +1 -1
  244. package/dist/workers/repository/update/branch/bump-versions.js.map +1 -1
  245. package/dist/workers/repository/update/branch/get-updated.js +3 -5
  246. package/dist/workers/repository/update/branch/get-updated.js.map +1 -1
  247. package/dist/workers/repository/update/pr/body/updates-table.js +1 -3
  248. package/dist/workers/repository/update/pr/body/updates-table.js.map +1 -1
  249. package/dist/workers/repository/update/pr/changelog/common.js +1 -1
  250. package/dist/workers/repository/update/pr/changelog/common.js.map +1 -1
  251. package/dist/workers/repository/update/pr/index.js +6 -7
  252. package/dist/workers/repository/update/pr/index.js.map +1 -1
  253. package/dist/workers/repository/updates/flatten.js +1 -1
  254. package/dist/workers/repository/updates/flatten.js.map +1 -1
  255. package/dist/workers/repository/updates/generate.js +1 -1
  256. package/dist/workers/repository/updates/generate.js.map +1 -1
  257. package/package.json +2 -2
  258. package/renovate-schema.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["azureApi.gitApi","hostRules.find","git.initRepo","azureHelper.getMergeMethod","azureApi.coreApi","azureHelper.getAllProjectTeams"],"sources":["../../../../lib/modules/platform/azure/index.ts"],"sourcesContent":["import { setTimeout } from 'node:timers/promises';\nimport { isString } from '@sindresorhus/is';\nimport type {\n GitItem,\n GitPullRequest,\n GitPullRequestCommentThread,\n GitStatus,\n GitVersionDescriptor,\n} from 'azure-devops-node-api/interfaces/GitInterfaces.js';\nimport {\n GitPullRequestMergeStrategy,\n GitStatusState,\n GitVersionType,\n PullRequestStatus,\n} from 'azure-devops-node-api/interfaces/GitInterfaces.js';\nimport {\n REPOSITORY_ARCHIVED,\n REPOSITORY_EMPTY,\n REPOSITORY_NOT_FOUND,\n} from '../../../constants/error-messages.ts';\nimport { logger } from '../../../logger/index.ts';\nimport { ExternalHostError } from '../../../types/errors/external-host-error.ts';\nimport type { BranchStatus } from '../../../types/index.ts';\nimport { parseJson } from '../../../util/common.ts';\nimport * as git from '../../../util/git/index.ts';\nimport * as hostRules from '../../../util/host-rules.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport { sanitize } from '../../../util/sanitize.ts';\nimport { ensureTrailingSlash } from '../../../util/url.ts';\nimport type {\n BranchStatusConfig,\n CreatePRConfig,\n EnsureCommentConfig,\n EnsureCommentRemovalConfig,\n EnsureIssueConfig,\n EnsureIssueResult,\n FindPRConfig,\n Issue,\n MergePRConfig,\n PlatformParams,\n PlatformResult,\n Pr,\n RepoParams,\n RepoResult,\n UpdatePrConfig,\n} from '../types.ts';\nimport { getNewBranchName, repoFingerprint } from '../util.ts';\nimport { smartTruncate } from '../utils/pr-body.ts';\nimport { readOnlyIssueBody } from '../utils/read-only-issue-body.ts';\nimport * as azureApi from './azure-got-wrapper.ts';\nimport * as azureHelper from './azure-helper.ts';\nimport { IssueService } from './issue.ts';\nimport type { AzurePr, Config } from './types.ts';\nimport { AzurePrVote } from './types.ts';\nimport {\n getBranchNameWithoutRefsheadsPrefix,\n getGitStatusContextCombinedName,\n getGitStatusContextFromCombinedName,\n getRenovatePRFormat,\n getRepoByName,\n getStorageExtraCloneOpts,\n mapMergeStrategy,\n max4000Chars,\n} from './util.ts';\n\ninterface User {\n id: string;\n name: string;\n isRequired: boolean;\n}\n\nlet config: Config = {} as any;\nlet issueService: IssueService;\n\nconst defaults: {\n endpoint?: string;\n hostType: string;\n} = {\n hostType: 'azure',\n};\n\nexport const id = 'azure';\n\nexport function initPlatform({\n endpoint,\n token,\n username,\n password,\n}: PlatformParams): Promise<PlatformResult> {\n if (!endpoint) {\n throw new Error('Init: You must configure an Azure DevOps endpoint');\n }\n if (!token && !(username && password)) {\n throw new Error(\n 'Init: You must configure an Azure DevOps token, or a username and password',\n );\n }\n // TODO: Add a connection check that endpoint/token combination are valid (#9593)\n const res = {\n endpoint: ensureTrailingSlash(endpoint),\n };\n defaults.endpoint = res.endpoint;\n azureApi.setEndpoint(res.endpoint);\n const platformConfig: PlatformResult = {\n endpoint: defaults.endpoint,\n };\n return Promise.resolve(platformConfig);\n}\n\nexport async function getRepos(): Promise<string[]> {\n logger.debug('Autodiscovering Azure DevOps repositories');\n const azureApiGit = await azureApi.gitApi();\n const repos = await azureApiGit.getRepositories();\n return repos\n .filter((repo) => repo.isDisabled !== true)\n .map((repo) => `${repo.project?.name}/${repo.name}`);\n}\n\nexport async function getRawFile(\n fileName: string,\n repoName?: string,\n branchOrTag?: string,\n): Promise<string | null> {\n try {\n const azureApiGit = await azureApi.gitApi();\n\n let repoId: string | undefined;\n if (repoName) {\n const repos = await azureApiGit.getRepositories();\n const repo = getRepoByName(repoName, repos);\n repoId = repo?.id;\n } else {\n repoId = config.repoId;\n }\n\n if (!repoId) {\n logger.debug('No repoId so cannot getRawFile');\n return null;\n }\n\n let item: GitItem | undefined;\n const versionDescriptor: GitVersionDescriptor = {\n version: branchOrTag,\n } satisfies GitVersionDescriptor;\n // Try to get file from repo with tag first, if not found, then try with branch #36835\n for (const versionType of [GitVersionType.Tag, GitVersionType.Branch]) {\n versionDescriptor.versionType = versionType;\n\n item = await azureApiGit.getItem(\n repoId, // repositoryId\n fileName, // path\n undefined, // project\n undefined, // scopePath\n undefined, // recursionLevel\n undefined, // includeContentMetadata\n undefined, // latestProcessedChange\n undefined, // download\n branchOrTag ? versionDescriptor : undefined, // versionDescriptor\n true, // includeContent\n );\n if (item) {\n break; // exit loop if item is found\n } else {\n logger.debug(\n `File: ${fileName} not found in ${repoName} with ${versionType}: ${branchOrTag}`,\n );\n }\n }\n return item?.content ?? null;\n } catch (err) /* v8 ignore next */ {\n if (\n err.message?.includes('<title>Azure DevOps Services Unavailable</title>')\n ) {\n logger.debug(\n 'Azure DevOps is currently unavailable when attempting to fetch file - throwing ExternalHostError',\n );\n throw new ExternalHostError(err, id);\n }\n if (err.code === 'ECONNRESET' || err.code === 'ETIMEDOUT') {\n throw new ExternalHostError(err, id);\n }\n if (err.statusCode && err.statusCode >= 500 && err.statusCode < 600) {\n throw new ExternalHostError(err, id);\n }\n throw err;\n }\n}\n\nexport async function getJsonFile(\n fileName: string,\n repoName?: string,\n branchOrTag?: string,\n): Promise<any> {\n const raw = await getRawFile(fileName, repoName, branchOrTag);\n return parseJson(raw, fileName);\n}\n\nexport async function initRepo({\n repository,\n cloneSubmodules,\n cloneSubmodulesFilter,\n}: RepoParams): Promise<RepoResult> {\n logger.debug(`initRepo(\"${repository}\")`);\n config = { repository } as Config;\n const azureApiGit = await azureApi.gitApi();\n const repos = await azureApiGit.getRepositories();\n const repo = getRepoByName(repository, repos);\n if (!repo) {\n logger.error({ repos, repo }, 'Could not find repo in repo list');\n throw new Error(REPOSITORY_NOT_FOUND);\n }\n logger.debug({ repositoryDetails: repo }, 'Repository details');\n if (repo.isDisabled) {\n logger.debug('Repository is disabled- throwing error to abort renovation');\n throw new Error(REPOSITORY_ARCHIVED);\n }\n /* v8 ignore next */\n if (!repo.defaultBranch) {\n logger.debug('Repo is empty');\n throw new Error(REPOSITORY_EMPTY);\n }\n // TODO #22198\n config.repoId = repo.id!;\n\n config.project = repo.project!.name!;\n issueService = new IssueService(config);\n config.owner = '?owner?';\n logger.debug(`${repository} owner = ${config.owner}`);\n const defaultBranch = repo.defaultBranch.replace('refs/heads/', '');\n config.defaultBranch = defaultBranch;\n logger.debug(`${repository} default branch = ${defaultBranch}`);\n config.mergeMethods = {};\n config.repoForceRebase = false;\n\n const [projectName, repoName] = repository.split('/');\n const opts = hostRules.find({\n hostType: defaults.hostType,\n url: defaults.endpoint,\n });\n // TODO: types (#22198)\n const manualUrl = `${defaults.endpoint!}${encodeURIComponent(\n projectName,\n )}/_git/${encodeURIComponent(repoName)}`;\n const url = repo.remoteUrl ?? manualUrl;\n await git.initRepo({\n ...config,\n url,\n extraCloneOpts: getStorageExtraCloneOpts(opts),\n cloneSubmodules,\n cloneSubmodulesFilter,\n });\n const repoConfig: RepoResult = {\n defaultBranch,\n isFork: false,\n repoFingerprint: repoFingerprint(repo.id!, defaults.endpoint),\n };\n return repoConfig;\n}\n\nexport async function getPrList(): Promise<AzurePr[]> {\n logger.debug('getPrList()');\n if (!config.prList) {\n const azureApiGit = await azureApi.gitApi();\n let prs: GitPullRequest[] = [];\n let fetchedPrs: GitPullRequest[];\n let skip = 0;\n do {\n fetchedPrs = await azureApiGit.getPullRequests(\n config.repoId,\n {\n status: 4,\n // fetch only prs directly created on the repo and not by forks\n sourceRepositoryId: config.project,\n },\n config.project,\n 0,\n skip,\n 100,\n );\n prs = prs.concat(fetchedPrs);\n skip += 100;\n } while (fetchedPrs.length > 0);\n\n config.prList = prs.map(getRenovatePRFormat);\n logger.debug(`Retrieved Pull Requests count: ${config.prList.length}`);\n }\n return config.prList;\n}\n\nexport async function getPr(pullRequestId: number): Promise<Pr | null> {\n logger.debug(`getPr(${pullRequestId})`);\n if (!pullRequestId) {\n return null;\n }\n const azurePr = (await getPrList()).find(\n (item) => item.number === pullRequestId,\n );\n\n if (!azurePr) {\n return null;\n }\n\n const azureApiGit = await azureApi.gitApi();\n const labels = await azureApiGit.getPullRequestLabels(\n config.repoId,\n pullRequestId,\n );\n\n azurePr.labels = labels\n .filter((label) => label.active)\n .map((label) => label.name)\n .filter(isString);\n return azurePr;\n}\n\nexport async function findPr({\n branchName,\n prTitle,\n state = 'all',\n targetBranch,\n}: FindPRConfig): Promise<Pr | null> {\n let prsFiltered: Pr[] = [];\n try {\n const prs = await getPrList();\n\n prsFiltered = prs.filter(\n (item) => item.sourceRefName === getNewBranchName(branchName),\n );\n\n if (prTitle) {\n prsFiltered = prsFiltered.filter(\n (item) => item.title.toUpperCase() === prTitle.toUpperCase(),\n );\n }\n\n switch (state) {\n case 'all':\n // no more filter needed, we can go further...\n break;\n case '!open':\n prsFiltered = prsFiltered.filter((item) => item.state !== 'open');\n break;\n default:\n prsFiltered = prsFiltered.filter((item) => item.state === state);\n break;\n }\n } catch (err) {\n logger.error({ err }, 'findPr error');\n }\n if (prsFiltered.length === 0) {\n return null;\n }\n if (targetBranch && prsFiltered.length > 1) {\n const pr = prsFiltered.find((item) => item.targetBranch === targetBranch);\n if (pr) {\n return pr;\n }\n }\n return prsFiltered[0];\n}\n\nexport async function getBranchPr(\n branchName: string,\n targetBranch?: string,\n): Promise<Pr | null> {\n logger.debug(`getBranchPr(${branchName}, ${targetBranch})`);\n const existingPr = await findPr({\n branchName,\n state: 'open',\n targetBranch,\n });\n return existingPr ? getPr(existingPr.number) : null;\n}\n\nasync function getStatusCheck(branchName: string): Promise<GitStatus[]> {\n const azureApiGit = await azureApi.gitApi();\n const branch = await azureApiGit.getBranch(\n config.repoId,\n\n // TODO: fix undefined (#22198)\n getBranchNameWithoutRefsheadsPrefix(branchName)!,\n );\n // only grab the latest statuses, it will group any by context\n return azureApiGit.getStatuses(\n // TODO #22198\n branch.commit!.commitId!,\n config.repoId,\n undefined,\n undefined,\n undefined,\n true,\n );\n}\n\nconst azureToRenovateStatusMapping: Record<GitStatusState, BranchStatus> = {\n [GitStatusState.Succeeded]: 'green',\n [GitStatusState.NotApplicable]: 'green',\n [GitStatusState.NotSet]: 'yellow',\n [GitStatusState.Pending]: 'yellow',\n [GitStatusState.PartiallySucceeded]: 'yellow',\n [GitStatusState.Error]: 'red',\n [GitStatusState.Failed]: 'red',\n};\n\nexport async function getBranchStatusCheck(\n branchName: string,\n context: string,\n): Promise<BranchStatus | null> {\n const res = await getStatusCheck(branchName);\n for (const check of res) {\n if (getGitStatusContextCombinedName(check.context) === context) {\n // TODO #22198\n return azureToRenovateStatusMapping[check.state!] ?? 'yellow';\n }\n }\n return null;\n}\n\nexport async function getBranchStatus(\n branchName: string,\n internalChecksAsSuccess: boolean,\n): Promise<BranchStatus> {\n logger.debug(`getBranchStatus(${branchName})`);\n const statuses = await getStatusCheck(branchName);\n logger.debug({ branch: branchName, statuses }, 'branch status check result');\n if (!statuses.length) {\n logger.debug('empty branch status check result = returning \"pending\"');\n return 'yellow';\n }\n const noOfFailures = statuses.filter(\n (status) =>\n status.state === GitStatusState.Error ||\n status.state === GitStatusState.Failed,\n ).length;\n if (noOfFailures) {\n return 'red';\n }\n const noOfPending = statuses.filter(\n (status) =>\n status.state === GitStatusState.NotSet ||\n status.state === GitStatusState.Pending,\n ).length;\n if (noOfPending) {\n return 'yellow';\n }\n if (\n !internalChecksAsSuccess &&\n statuses.every(\n (status) =>\n status.state === GitStatusState.Succeeded &&\n status.context?.genre === 'renovate',\n )\n ) {\n logger.debug(\n 'Successful checks are all internal renovate/ checks, so returning \"pending\" branch status',\n );\n return 'yellow';\n }\n return 'green';\n}\n\nasync function getMergeStrategy(\n targetRefName: string,\n): Promise<GitPullRequestMergeStrategy> {\n return (\n config.mergeMethods[targetRefName] ??\n (config.mergeMethods[targetRefName] = await azureHelper.getMergeMethod(\n config.repoId,\n config.project,\n targetRefName,\n config.defaultBranch,\n ))\n );\n}\n\nexport async function createPr({\n sourceBranch,\n targetBranch,\n prTitle: title,\n prBody: body,\n labels,\n draftPR = false,\n platformPrOptions,\n}: CreatePRConfig): Promise<Pr> {\n const sourceRefName = getNewBranchName(sourceBranch);\n const targetRefName = getNewBranchName(targetBranch);\n const description = max4000Chars(sanitize(body));\n const azureApiGit = await azureApi.gitApi();\n const workItemRefs = [\n {\n id: platformPrOptions?.azureWorkItemId?.toString(),\n },\n ];\n let pr: GitPullRequest = await azureApiGit.createPullRequest(\n {\n sourceRefName,\n targetRefName,\n title,\n description,\n workItemRefs,\n isDraft: draftPR,\n },\n config.repoId,\n );\n if (platformPrOptions?.usePlatformAutomerge) {\n const mergeStrategy =\n platformPrOptions.automergeStrategy === 'auto'\n ? await getMergeStrategy(pr.targetRefName!)\n : mapMergeStrategy(platformPrOptions.automergeStrategy);\n const prOptions: GitPullRequest = {\n autoCompleteSetBy: {\n // TODO #22198\n id: pr.createdBy!.id,\n },\n completionOptions: {\n mergeStrategy,\n deleteSourceBranch: true,\n mergeCommitMessage: title,\n },\n };\n\n logger.debug(\n {\n prOptions,\n repoId: config.repoId,\n pullRequestId: pr.pullRequestId!,\n },\n // TODO #22198\n `Updating PR ${pr.pullRequestId!} to specify platformAutomerge settings`,\n );\n\n pr = await azureApiGit.updatePullRequest(\n prOptions,\n config.repoId,\n // TODO #22198\n pr.pullRequestId!,\n );\n }\n if (platformPrOptions?.autoApprove) {\n const approver = {\n reviewerUrl: pr.createdBy!.url,\n vote: AzurePrVote.Approved,\n isFlagged: false,\n isRequired: false,\n };\n\n logger.debug(\n {\n approver,\n\n repoId: config.repoId,\n // TODO #22198\n pullRequestId: pr.pullRequestId!,\n prCreatedBy: {\n id: pr.createdBy!.id!,\n },\n },\n // TODO #22198\n `Auto-approving PR ${pr.pullRequestId!}`,\n );\n\n await azureApiGit.createPullRequestReviewer(\n approver,\n config.repoId,\n // TODO #22198\n pr.pullRequestId!,\n pr.createdBy!.id!,\n );\n }\n await Promise.all(\n labels!.map((label) =>\n azureApiGit.createPullRequestLabel(\n {\n name: label,\n },\n config.repoId,\n // TODO #22198\n pr.pullRequestId!,\n ),\n ),\n );\n\n const result = getRenovatePRFormat(pr);\n if (config.prList) {\n config.prList.push(result);\n }\n return result;\n}\n\nexport async function updatePr({\n number: prNo,\n prTitle: title,\n prBody: body,\n state,\n platformPrOptions,\n targetBranch,\n}: UpdatePrConfig): Promise<void> {\n logger.debug(`updatePr(${prNo}, ${title}, body)`);\n\n const azureApiGit = await azureApi.gitApi();\n const objToUpdate: GitPullRequest = {\n title,\n };\n\n if (targetBranch) {\n objToUpdate.targetRefName = getNewBranchName(targetBranch);\n }\n\n if (body) {\n objToUpdate.description = max4000Chars(sanitize(body));\n }\n\n if (state === 'open') {\n await azureApiGit.updatePullRequest(\n {\n status: PullRequestStatus.Active,\n },\n config.repoId,\n prNo,\n );\n } else if (state === 'closed') {\n objToUpdate.status = PullRequestStatus.Abandoned;\n }\n if (platformPrOptions?.autoApprove) {\n const pr = await azureApiGit.getPullRequestById(prNo, config.project);\n await azureApiGit.createPullRequestReviewer(\n {\n reviewerUrl: pr.createdBy!.url,\n vote: AzurePrVote.Approved,\n isFlagged: false,\n isRequired: false,\n },\n config.repoId,\n // TODO #22198\n pr.pullRequestId!,\n pr.createdBy!.id!,\n );\n }\n\n const updatedPr = await azureApiGit.updatePullRequest(\n objToUpdate,\n config.repoId,\n prNo,\n );\n if (config.prList) {\n const prToCache = getRenovatePRFormat(updatedPr);\n // We need to update the cached entry for this PR\n const existingIndex = config.prList.findIndex(\n (item) => item.number === prNo,\n );\n /* v8 ignore next: should not happen */\n if (existingIndex === -1) {\n logger.warn({ prNo }, 'PR not found in cache');\n // Add to cache\n config.prList.push(prToCache);\n } else {\n // overwrite existing PR in cache\n config.prList[existingIndex] = prToCache;\n }\n }\n}\n\nexport async function ensureComment({\n number,\n topic,\n content,\n}: EnsureCommentConfig): Promise<boolean> {\n logger.debug(`ensureComment(${number}, ${topic!}, content)`);\n const header = topic ? `### ${topic}\\n\\n` : '';\n const body = `${header}${sanitize(massageMarkdown(content))}`;\n const azureApiGit = await azureApi.gitApi();\n\n const threads = await azureApiGit.getThreads(config.repoId, number);\n let threadIdFound: number | undefined;\n let commentIdFound: number | undefined;\n let commentNeedsUpdating = false;\n threads.forEach((thread) => {\n const firstCommentContent = thread.comments?.[0].content;\n if (\n (topic && firstCommentContent?.startsWith(header)) === true ||\n (!topic && firstCommentContent === body)\n ) {\n threadIdFound = thread.id;\n commentIdFound = thread.comments?.[0].id;\n commentNeedsUpdating = firstCommentContent !== body;\n }\n });\n\n if (!threadIdFound) {\n await azureApiGit.createThread(\n {\n comments: [{ content: body, commentType: 1, parentCommentId: 0 }],\n status: 1,\n },\n config.repoId,\n number,\n );\n logger.info(\n { repository: config.repository, issueNo: number, topic },\n 'Comment added',\n );\n } else if (commentNeedsUpdating) {\n await azureApiGit.updateComment(\n {\n content: body,\n },\n config.repoId,\n number,\n threadIdFound,\n // TODO #22198\n commentIdFound!,\n );\n logger.debug(\n { repository: config.repository, issueNo: number, topic },\n 'Comment updated',\n );\n } else {\n logger.debug(\n { repository: config.repository, issueNo: number, topic },\n 'Comment is already up-to-date',\n );\n }\n\n return true;\n}\n\nexport async function ensureCommentRemoval(\n removeConfig: EnsureCommentRemovalConfig,\n): Promise<void> {\n const { number: issueNo } = removeConfig;\n const key =\n removeConfig.type === 'by-topic'\n ? removeConfig.topic\n : removeConfig.content;\n logger.debug(`Ensuring comment \"${key}\" in #${issueNo} is removed`);\n\n const azureApiGit = await azureApi.gitApi();\n const threads = await azureApiGit.getThreads(config.repoId, issueNo);\n\n let threadIdFound: number | null | undefined = null;\n if (removeConfig.type === 'by-topic') {\n const thread = threads.find(\n (thread: GitPullRequestCommentThread): boolean =>\n !!thread.comments?.[0].content?.startsWith(\n `### ${removeConfig.topic}\\n\\n`,\n ),\n );\n threadIdFound = thread?.id;\n } else {\n const thread = threads.find(\n (thread: GitPullRequestCommentThread): boolean =>\n thread.comments?.[0].content?.trim() === removeConfig.content,\n );\n threadIdFound = thread?.id;\n }\n\n if (threadIdFound) {\n await azureApiGit.updateThread(\n {\n status: 4, // close\n },\n config.repoId,\n issueNo,\n threadIdFound,\n );\n }\n}\n\nconst renovateToAzureStatusMapping: Record<BranchStatus, GitStatusState> = {\n ['green']: GitStatusState.Succeeded,\n ['yellow']: GitStatusState.Pending,\n ['red']: GitStatusState.Failed,\n};\n\nexport async function setBranchStatus({\n branchName,\n context,\n description,\n state,\n url: targetUrl,\n}: BranchStatusConfig): Promise<void> {\n logger.debug(\n `setBranchStatus(${branchName}, ${context}, ${description}, ${state}, ${targetUrl!})`,\n );\n const azureApiGit = await azureApi.gitApi();\n const branch = await azureApiGit.getBranch(\n config.repoId,\n getBranchNameWithoutRefsheadsPrefix(branchName)!,\n );\n const statusToCreate: GitStatus = {\n description,\n context: getGitStatusContextFromCombinedName(context),\n state: renovateToAzureStatusMapping[state],\n targetUrl,\n };\n await azureApiGit.createCommitStatus(\n statusToCreate,\n // TODO #22198\n branch.commit!.commitId!,\n config.repoId,\n );\n logger.trace(`Created commit status of ${state} on branch ${branchName}`);\n}\n\nexport async function mergePr({\n branchName,\n id: pullRequestId,\n strategy,\n}: MergePRConfig): Promise<boolean> {\n logger.debug(`mergePr(${pullRequestId}, ${branchName!})`);\n const azureApiGit = await azureApi.gitApi();\n\n let pr = await azureApiGit.getPullRequestById(pullRequestId, config.project);\n\n const mergeStrategy =\n strategy === 'auto'\n ? await getMergeStrategy(pr.targetRefName!)\n : mapMergeStrategy(strategy);\n const objToUpdate: GitPullRequest = {\n status: PullRequestStatus.Completed,\n lastMergeSourceCommit: pr.lastMergeSourceCommit,\n completionOptions: {\n mergeStrategy,\n deleteSourceBranch: true,\n mergeCommitMessage: pr.title,\n },\n };\n\n logger.trace(\n `Updating PR ${pullRequestId} to status ${PullRequestStatus.Completed} (${\n PullRequestStatus[PullRequestStatus.Completed]\n }) with lastMergeSourceCommit ${\n // TODO: types (#22198)\n pr.lastMergeSourceCommit?.commitId\n } using mergeStrategy ${mergeStrategy} (${\n GitPullRequestMergeStrategy[mergeStrategy]\n })`,\n );\n\n try {\n const response = await azureApiGit.updatePullRequest(\n objToUpdate,\n config.repoId,\n pullRequestId,\n );\n\n let retries = 0;\n let isClosed = response.status === PullRequestStatus.Completed;\n while (!isClosed && retries < 5) {\n retries += 1;\n const sleepMs = retries * 1000;\n logger.trace(\n { pullRequestId, status: pr.status, retries },\n `Updated PR to closed status but change has not taken effect yet. Retrying...`,\n );\n\n await setTimeout(sleepMs);\n pr = await azureApiGit.getPullRequestById(pullRequestId, config.project);\n isClosed = pr.status === PullRequestStatus.Completed;\n }\n\n if (!isClosed) {\n logger.warn(\n {\n pullRequestId,\n status: pr.status,\n expectedPRStatus: PullRequestStatus[PullRequestStatus.Completed],\n actualPRStatus: PullRequestStatus[pr.status!],\n },\n 'Expected PR to have completed status. However, the PR has a different status',\n );\n }\n return true;\n } catch (err) {\n logger.debug({ err }, 'Failed to set the PR as completed.');\n return false;\n }\n}\n\nexport function massageMarkdown(input: string): string {\n // Remove any HTML we use\n return (\n smartTruncate(readOnlyIssueBody(input), maxBodyLength())\n .replace(\n 'you tick the rebase/retry checkbox',\n 'PR is renamed to start with \"rebase!\"',\n )\n .replace(\n 'checking the rebase/retry box above',\n 'renaming the PR to start with \"rebase!\"',\n )\n .replace(regEx(`\\n---\\n\\n.*?<!-- rebase-check -->.*?\\n`), '')\n .replace(regEx(/<!--renovate-(?:debug|config-hash):.*?-->/g), '')\n // Replace GitHub-style PR links with Azure DevOps format\n .replace(regEx(/\\]\\(\\.\\.\\/pull\\//g), '](!')\n // Replace GitHub-style PR references (#123) with Azure DevOps format, needed for text linking config migration PR.\n // Only match a standalone reference (preceded by start, whitespace or `(`) so we don't corrupt\n // HTML entities like `&#8203;` or URL anchors like `CHANGELOG.md#4780`.\n .replace(regEx(/(^|[\\s(])#(\\d+)/g), '$1!$2')\n );\n}\n\nexport function maxBodyLength(): number {\n return 4000;\n}\n\nexport async function findIssue(title: string): Promise<Issue | null> {\n return await issueService.findIssue(title);\n}\n\nexport async function ensureIssue(\n issueConfig: EnsureIssueConfig,\n): Promise<EnsureIssueResult | null> {\n return await issueService.ensureIssue(issueConfig);\n}\n\nexport async function ensureIssueClosing(title: string): Promise<void> {\n return await issueService.ensureIssueClosing(title);\n}\n\nexport async function getIssueList(titleFilter?: string): Promise<Issue[]> {\n return await issueService.getIssueList(titleFilter);\n}\n\nasync function getUserIds(users: string[]): Promise<User[]> {\n const azureApiGit = await azureApi.gitApi();\n const azureApiCore = await azureApi.coreApi();\n const repos = await azureApiGit.getRepositories();\n const repo = repos.find((c) => c.id === config.repoId)!;\n const requiredReviewerPrefix = 'required:';\n const validReviewers = new Set<string>();\n\n // TODO #22198\n const teams = await azureHelper.getAllProjectTeams(repo.project!.id!);\n const members = await Promise.all(\n teams.map(\n async (t) =>\n await azureApiCore.getTeamMembersWithExtendedProperties(\n // TODO #22198\n repo.project!.id!,\n t.id!,\n ),\n ),\n );\n\n const ids: { id: string; name: string; isRequired: boolean }[] = [];\n members.forEach((listMembers) => {\n listMembers.forEach((m) => {\n users.forEach((r) => {\n let reviewer = r;\n let isRequired = false;\n if (reviewer.startsWith(requiredReviewerPrefix)) {\n reviewer = reviewer.replace(requiredReviewerPrefix, '');\n isRequired = true;\n }\n if (\n reviewer.toLowerCase() === m.identity?.displayName?.toLowerCase() ||\n reviewer.toLowerCase() === m.identity?.uniqueName?.toLowerCase()\n ) {\n if (ids.filter((c) => c.id === m.identity?.id).length === 0) {\n // TODO #22198\n ids.push({\n id: m.identity.id!,\n name: reviewer,\n isRequired,\n });\n\n validReviewers.add(reviewer);\n }\n }\n });\n });\n });\n\n teams.forEach((t) => {\n users.forEach((r) => {\n let reviewer = r;\n let isRequired = false;\n if (reviewer.startsWith(requiredReviewerPrefix)) {\n reviewer = reviewer.replace(requiredReviewerPrefix, '');\n isRequired = true;\n }\n if (reviewer.toLowerCase() === t.name?.toLowerCase()) {\n // v8 ignore else -- TODO: add test #40625\n if (ids.filter((c) => c.id === t.id).length === 0) {\n // TODO #22198\n ids.push({ id: t.id!, name: reviewer, isRequired });\n\n validReviewers.add(reviewer);\n }\n }\n });\n });\n\n for (const u of users) {\n const reviewer = u.replace(requiredReviewerPrefix, '');\n if (!validReviewers.has(reviewer)) {\n logger.once.info(\n `${reviewer} is neither an Azure DevOps Team nor a user associated with a Team`,\n );\n }\n }\n\n return ids;\n}\n\n/**\n *\n * @param {number} issueNo\n * @param {string[]} assignees\n */\nexport async function addAssignees(\n issueNo: number,\n assignees: string[],\n): Promise<void> {\n logger.trace(`addAssignees(${issueNo}, [${assignees.join(', ')}])`);\n const ids = await getUserIds(assignees);\n await ensureComment({\n number: issueNo,\n topic: 'Add Assignees',\n content: ids.map((a) => `@<${a.id}>`).join(', '),\n });\n}\n\n/**\n *\n * @param {number} prNo\n * @param {string[]} reviewers\n */\nexport async function addReviewers(\n prNo: number,\n reviewers: string[],\n): Promise<void> {\n logger.trace(`addReviewers(${prNo}, [${reviewers.join(', ')}])`);\n const azureApiGit = await azureApi.gitApi();\n\n const ids = await getUserIds(reviewers);\n\n await Promise.all(\n ids.map(async (obj) => {\n await azureApiGit.createPullRequestReviewer(\n {\n isRequired: obj.isRequired,\n },\n config.repoId,\n prNo,\n obj.id,\n );\n logger.debug(`Reviewer added: ${obj.name}`);\n }),\n );\n}\n\nexport async function deleteLabel(\n prNumber: number,\n label: string,\n): Promise<void> {\n logger.debug(`Deleting label ${label} from #${prNumber}`);\n const azureApiGit = await azureApi.gitApi();\n await azureApiGit.deletePullRequestLabels(config.repoId, prNumber, label);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["azureApi.gitApi","hostRules.find","git.initRepo","azureHelper.getMergeMethod","azureApi.coreApi","azureHelper.getAllProjectTeams"],"sources":["../../../../lib/modules/platform/azure/index.ts"],"sourcesContent":["import { setTimeout } from 'node:timers/promises';\nimport { isString } from '@sindresorhus/is';\nimport type {\n GitItem,\n GitPullRequest,\n GitPullRequestCommentThread,\n GitStatus,\n GitVersionDescriptor,\n} from 'azure-devops-node-api/interfaces/GitInterfaces.js';\nimport {\n GitPullRequestMergeStrategy,\n GitStatusState,\n GitVersionType,\n PullRequestStatus,\n} from 'azure-devops-node-api/interfaces/GitInterfaces.js';\nimport {\n REPOSITORY_ARCHIVED,\n REPOSITORY_EMPTY,\n REPOSITORY_NOT_FOUND,\n} from '../../../constants/error-messages.ts';\nimport { logger } from '../../../logger/index.ts';\nimport { ExternalHostError } from '../../../types/errors/external-host-error.ts';\nimport type { BranchStatus } from '../../../types/index.ts';\nimport { parseJson } from '../../../util/common.ts';\nimport * as git from '../../../util/git/index.ts';\nimport * as hostRules from '../../../util/host-rules.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport { sanitize } from '../../../util/sanitize.ts';\nimport { ensureTrailingSlash } from '../../../util/url.ts';\nimport type {\n BranchStatusConfig,\n CreatePRConfig,\n EnsureCommentConfig,\n EnsureCommentRemovalConfig,\n EnsureIssueConfig,\n EnsureIssueResult,\n FindPRConfig,\n Issue,\n MergePRConfig,\n PlatformParams,\n PlatformResult,\n Pr,\n RepoParams,\n RepoResult,\n UpdatePrConfig,\n} from '../types.ts';\nimport { getNewBranchName, repoFingerprint } from '../util.ts';\nimport { smartTruncate } from '../utils/pr-body.ts';\nimport { readOnlyIssueBody } from '../utils/read-only-issue-body.ts';\nimport * as azureApi from './azure-got-wrapper.ts';\nimport * as azureHelper from './azure-helper.ts';\nimport { IssueService } from './issue.ts';\nimport type { AzurePr, Config } from './types.ts';\nimport { AzurePrVote } from './types.ts';\nimport {\n getBranchNameWithoutRefsheadsPrefix,\n getGitStatusContextCombinedName,\n getGitStatusContextFromCombinedName,\n getRenovatePRFormat,\n getRepoByName,\n getStorageExtraCloneOpts,\n mapMergeStrategy,\n max4000Chars,\n} from './util.ts';\n\ninterface User {\n id: string;\n name: string;\n isRequired: boolean;\n}\n\nlet config: Config = {} as any;\nlet issueService: IssueService;\n\nconst defaults: {\n endpoint?: string;\n hostType: string;\n} = {\n hostType: 'azure',\n};\n\nexport const id = 'azure';\n\nexport function initPlatform({\n endpoint,\n token,\n username,\n password,\n}: PlatformParams): Promise<PlatformResult> {\n if (!endpoint) {\n throw new Error('Init: You must configure an Azure DevOps endpoint');\n }\n if (!token && !(username && password)) {\n throw new Error(\n 'Init: You must configure an Azure DevOps token, or a username and password',\n );\n }\n // TODO: Add a connection check that endpoint/token combination are valid (#9593)\n const res = {\n endpoint: ensureTrailingSlash(endpoint),\n };\n defaults.endpoint = res.endpoint;\n azureApi.setEndpoint(res.endpoint);\n const platformConfig: PlatformResult = {\n endpoint: defaults.endpoint,\n };\n return Promise.resolve(platformConfig);\n}\n\nexport async function getRepos(): Promise<string[]> {\n logger.debug('Autodiscovering Azure DevOps repositories');\n const azureApiGit = await azureApi.gitApi();\n const repos = await azureApiGit.getRepositories();\n return repos\n .filter((repo) => repo.isDisabled !== true)\n .map((repo) => `${repo.project?.name}/${repo.name}`);\n}\n\nexport async function getRawFile(\n fileName: string,\n repoName?: string,\n branchOrTag?: string,\n): Promise<string | null> {\n try {\n const azureApiGit = await azureApi.gitApi();\n\n let repoId: string | undefined;\n if (repoName) {\n const repos = await azureApiGit.getRepositories();\n const repo = getRepoByName(repoName, repos);\n repoId = repo?.id;\n } else {\n repoId = config.repoId;\n }\n\n if (!repoId) {\n logger.debug('No repoId so cannot getRawFile');\n return null;\n }\n\n let item: GitItem | undefined;\n const versionDescriptor: GitVersionDescriptor = {\n version: branchOrTag,\n } satisfies GitVersionDescriptor;\n // Try to get file from repo with tag first, if not found, then try with branch #36835\n for (const versionType of [GitVersionType.Tag, GitVersionType.Branch]) {\n versionDescriptor.versionType = versionType;\n\n item = await azureApiGit.getItem(\n repoId, // repositoryId\n fileName, // path\n undefined, // project\n undefined, // scopePath\n undefined, // recursionLevel\n undefined, // includeContentMetadata\n undefined, // latestProcessedChange\n undefined, // download\n branchOrTag ? versionDescriptor : undefined, // versionDescriptor\n true, // includeContent\n );\n if (item) {\n break; // exit loop if item is found\n } else {\n logger.debug(\n `File: ${fileName} not found in ${repoName} with ${versionType}: ${branchOrTag}`,\n );\n }\n }\n return item?.content ?? null;\n } catch (err) /* v8 ignore next */ {\n if (\n err.message?.includes('<title>Azure DevOps Services Unavailable</title>')\n ) {\n logger.debug(\n 'Azure DevOps is currently unavailable when attempting to fetch file - throwing ExternalHostError',\n );\n throw new ExternalHostError(err, id);\n }\n if (err.code === 'ECONNRESET' || err.code === 'ETIMEDOUT') {\n throw new ExternalHostError(err, id);\n }\n if (err.statusCode && err.statusCode >= 500 && err.statusCode < 600) {\n throw new ExternalHostError(err, id);\n }\n throw err;\n }\n}\n\nexport async function getJsonFile(\n fileName: string,\n repoName?: string,\n branchOrTag?: string,\n): Promise<any> {\n const raw = await getRawFile(fileName, repoName, branchOrTag);\n return parseJson(raw, fileName);\n}\n\nexport async function initRepo({\n repository,\n cloneSubmodules,\n cloneSubmodulesFilter,\n}: RepoParams): Promise<RepoResult> {\n logger.debug(`initRepo(\"${repository}\")`);\n config = { repository } as Config;\n const azureApiGit = await azureApi.gitApi();\n const repos = await azureApiGit.getRepositories();\n const repo = getRepoByName(repository, repos);\n if (!repo) {\n logger.error({ repos, repo }, 'Could not find repo in repo list');\n throw new Error(REPOSITORY_NOT_FOUND);\n }\n logger.debug({ repositoryDetails: repo }, 'Repository details');\n if (repo.isDisabled) {\n logger.debug('Repository is disabled- throwing error to abort renovation');\n throw new Error(REPOSITORY_ARCHIVED);\n }\n /* v8 ignore next */\n if (!repo.defaultBranch) {\n logger.debug('Repo is empty');\n throw new Error(REPOSITORY_EMPTY);\n }\n // TODO #22198\n config.repoId = repo.id!;\n\n config.project = repo.project!.name!;\n issueService = new IssueService(config);\n config.owner = '?owner?';\n logger.debug(`${repository} owner = ${config.owner}`);\n const defaultBranch = repo.defaultBranch.replace('refs/heads/', '');\n config.defaultBranch = defaultBranch;\n logger.debug(`${repository} default branch = ${defaultBranch}`);\n config.mergeMethods = {};\n config.repoForceRebase = false;\n\n const [projectName, repoName] = repository.split('/');\n const opts = hostRules.find({\n hostType: defaults.hostType,\n url: defaults.endpoint,\n });\n // TODO: types (#22198)\n const manualUrl = `${defaults.endpoint!}${encodeURIComponent(\n projectName,\n )}/_git/${encodeURIComponent(repoName)}`;\n const url = repo.remoteUrl ?? manualUrl;\n await git.initRepo({\n ...config,\n url,\n extraCloneOpts: getStorageExtraCloneOpts(opts),\n cloneSubmodules,\n cloneSubmodulesFilter,\n });\n const repoConfig: RepoResult = {\n defaultBranch,\n isFork: false,\n repoFingerprint: repoFingerprint(repo.id!, defaults.endpoint),\n };\n return repoConfig;\n}\n\nexport async function getPrList(): Promise<AzurePr[]> {\n logger.debug('getPrList()');\n if (!config.prList) {\n const azureApiGit = await azureApi.gitApi();\n let prs: GitPullRequest[] = [];\n let fetchedPrs: GitPullRequest[];\n let skip = 0;\n do {\n fetchedPrs = await azureApiGit.getPullRequests(\n config.repoId,\n {\n status: 4,\n // fetch only prs directly created on the repo and not by forks\n sourceRepositoryId: config.project,\n },\n config.project,\n 0,\n skip,\n 100,\n );\n prs = prs.concat(fetchedPrs);\n skip += 100;\n } while (fetchedPrs.length > 0);\n\n config.prList = prs.map(getRenovatePRFormat);\n logger.debug(`Retrieved Pull Requests count: ${config.prList.length}`);\n }\n return config.prList;\n}\n\nexport async function getPr(pullRequestId: number): Promise<Pr | null> {\n logger.debug(`getPr(${pullRequestId})`);\n if (!pullRequestId) {\n return null;\n }\n const azurePr = (await getPrList()).find(\n (item) => item.number === pullRequestId,\n );\n\n if (!azurePr) {\n return null;\n }\n\n const azureApiGit = await azureApi.gitApi();\n const labels = await azureApiGit.getPullRequestLabels(\n config.repoId,\n pullRequestId,\n );\n\n azurePr.labels = labels\n .filter((label) => label.active)\n .map((label) => label.name)\n .filter(isString);\n return azurePr;\n}\n\nexport async function findPr({\n branchName,\n prTitle,\n state = 'all',\n targetBranch,\n}: FindPRConfig): Promise<Pr | null> {\n let prsFiltered: Pr[] = [];\n try {\n const prs = await getPrList();\n\n prsFiltered = prs.filter(\n (item) => item.sourceRefName === getNewBranchName(branchName),\n );\n\n if (prTitle) {\n prsFiltered = prsFiltered.filter(\n (item) => item.title.toUpperCase() === prTitle.toUpperCase(),\n );\n }\n\n switch (state) {\n case 'all':\n // no more filter needed, we can go further...\n break;\n case '!open':\n prsFiltered = prsFiltered.filter((item) => item.state !== 'open');\n break;\n default:\n prsFiltered = prsFiltered.filter((item) => item.state === state);\n break;\n }\n } catch (err) {\n logger.error({ err }, 'findPr error');\n }\n if (prsFiltered.length === 0) {\n return null;\n }\n if (targetBranch && prsFiltered.length > 1) {\n const pr = prsFiltered.find((item) => item.targetBranch === targetBranch);\n if (pr) {\n return pr;\n }\n }\n return prsFiltered[0];\n}\n\nexport async function getBranchPr(\n branchName: string,\n targetBranch?: string,\n): Promise<Pr | null> {\n logger.debug(`getBranchPr(${branchName}, ${targetBranch})`);\n const existingPr = await findPr({\n branchName,\n state: 'open',\n targetBranch,\n });\n return existingPr ? getPr(existingPr.number) : null;\n}\n\nasync function getStatusCheck(branchName: string): Promise<GitStatus[]> {\n const azureApiGit = await azureApi.gitApi();\n const branch = await azureApiGit.getBranch(\n config.repoId,\n\n // TODO: fix undefined (#22198)\n getBranchNameWithoutRefsheadsPrefix(branchName)!,\n );\n // only grab the latest statuses, it will group any by context\n return azureApiGit.getStatuses(\n // TODO #22198\n branch.commit!.commitId!,\n config.repoId,\n undefined,\n undefined,\n undefined,\n true,\n );\n}\n\nconst azureToRenovateStatusMapping: Record<GitStatusState, BranchStatus> = {\n [GitStatusState.Succeeded]: 'green',\n [GitStatusState.NotApplicable]: 'green',\n [GitStatusState.NotSet]: 'yellow',\n [GitStatusState.Pending]: 'yellow',\n [GitStatusState.PartiallySucceeded]: 'yellow',\n [GitStatusState.Error]: 'red',\n [GitStatusState.Failed]: 'red',\n};\n\nexport async function getBranchStatusCheck(\n branchName: string,\n context: string,\n): Promise<BranchStatus | null> {\n const res = await getStatusCheck(branchName);\n for (const check of res) {\n if (getGitStatusContextCombinedName(check.context) === context) {\n // TODO #22198\n return azureToRenovateStatusMapping[check.state!] ?? 'yellow';\n }\n }\n return null;\n}\n\nexport async function getBranchStatus(\n branchName: string,\n internalChecksAsSuccess: boolean,\n): Promise<BranchStatus> {\n logger.debug(`getBranchStatus(${branchName})`);\n const statuses = await getStatusCheck(branchName);\n logger.debug({ branch: branchName, statuses }, 'branch status check result');\n if (!statuses.length) {\n logger.debug('empty branch status check result = returning \"pending\"');\n return 'yellow';\n }\n const noOfFailures = statuses.filter(\n (status) =>\n status.state === GitStatusState.Error ||\n status.state === GitStatusState.Failed,\n ).length;\n if (noOfFailures) {\n return 'red';\n }\n const noOfPending = statuses.filter(\n (status) =>\n status.state === GitStatusState.NotSet ||\n status.state === GitStatusState.Pending,\n ).length;\n if (noOfPending) {\n return 'yellow';\n }\n if (\n !internalChecksAsSuccess &&\n statuses.every(\n (status) =>\n status.state === GitStatusState.Succeeded &&\n status.context?.genre === 'renovate',\n )\n ) {\n logger.debug(\n 'Successful checks are all internal renovate/ checks, so returning \"pending\" branch status',\n );\n return 'yellow';\n }\n return 'green';\n}\n\nasync function getMergeStrategy(\n targetRefName: string,\n): Promise<GitPullRequestMergeStrategy> {\n return (\n config.mergeMethods[targetRefName] ??\n (config.mergeMethods[targetRefName] = await azureHelper.getMergeMethod(\n config.repoId,\n config.project,\n targetRefName,\n config.defaultBranch,\n ))\n );\n}\n\nexport async function createPr({\n sourceBranch,\n targetBranch,\n prTitle: title,\n prBody: body,\n labels,\n draftPR = false,\n platformPrOptions,\n}: CreatePRConfig): Promise<Pr> {\n const sourceRefName = getNewBranchName(sourceBranch);\n const targetRefName = getNewBranchName(targetBranch);\n const description = max4000Chars(sanitize(body));\n const azureApiGit = await azureApi.gitApi();\n const workItemRefs = [\n {\n id: platformPrOptions?.azureWorkItemId?.toString(),\n },\n ];\n let pr: GitPullRequest = await azureApiGit.createPullRequest(\n {\n sourceRefName,\n targetRefName,\n title,\n description,\n workItemRefs,\n isDraft: draftPR,\n },\n config.repoId,\n );\n if (platformPrOptions?.usePlatformAutomerge) {\n const mergeStrategy =\n platformPrOptions.automergeStrategy === 'auto'\n ? await getMergeStrategy(pr.targetRefName!)\n : mapMergeStrategy(platformPrOptions.automergeStrategy);\n const prOptions: GitPullRequest = {\n autoCompleteSetBy: {\n // TODO #22198\n id: pr.createdBy!.id,\n },\n completionOptions: {\n mergeStrategy,\n deleteSourceBranch: true,\n mergeCommitMessage: title,\n },\n };\n\n logger.debug(\n {\n prOptions,\n repoId: config.repoId,\n pullRequestId: pr.pullRequestId!,\n },\n // TODO #22198\n `Updating PR ${pr.pullRequestId!} to specify platformAutomerge settings`,\n );\n\n pr = await azureApiGit.updatePullRequest(\n prOptions,\n config.repoId,\n // TODO #22198\n pr.pullRequestId!,\n );\n }\n if (platformPrOptions?.autoApprove) {\n const approver = {\n reviewerUrl: pr.createdBy!.url,\n vote: AzurePrVote.Approved,\n isFlagged: false,\n isRequired: false,\n };\n\n logger.debug(\n {\n approver,\n\n repoId: config.repoId,\n // TODO #22198\n pullRequestId: pr.pullRequestId!,\n prCreatedBy: {\n id: pr.createdBy!.id!,\n },\n },\n // TODO #22198\n `Auto-approving PR ${pr.pullRequestId!}`,\n );\n\n await azureApiGit.createPullRequestReviewer(\n approver,\n config.repoId,\n // TODO #22198\n pr.pullRequestId!,\n pr.createdBy!.id!,\n );\n }\n await Promise.all(\n labels!.map((label) =>\n azureApiGit.createPullRequestLabel(\n {\n name: label,\n },\n config.repoId,\n // TODO #22198\n pr.pullRequestId!,\n ),\n ),\n );\n\n const result = getRenovatePRFormat(pr);\n if (config.prList) {\n config.prList.push(result);\n }\n return result;\n}\n\nexport async function updatePr({\n number: prNo,\n prTitle: title,\n prBody: body,\n state,\n platformPrOptions,\n targetBranch,\n}: UpdatePrConfig): Promise<void> {\n logger.debug(`updatePr(${prNo}, ${title}, body)`);\n\n const azureApiGit = await azureApi.gitApi();\n const objToUpdate: GitPullRequest = {\n title,\n };\n\n if (targetBranch) {\n objToUpdate.targetRefName = getNewBranchName(targetBranch);\n }\n\n if (body) {\n objToUpdate.description = max4000Chars(sanitize(body));\n }\n\n if (state === 'open') {\n await azureApiGit.updatePullRequest(\n {\n status: PullRequestStatus.Active,\n },\n config.repoId,\n prNo,\n );\n } else if (state === 'closed') {\n objToUpdate.status = PullRequestStatus.Abandoned;\n }\n if (platformPrOptions?.autoApprove) {\n const pr = await azureApiGit.getPullRequestById(prNo, config.project);\n await azureApiGit.createPullRequestReviewer(\n {\n reviewerUrl: pr.createdBy!.url,\n vote: AzurePrVote.Approved,\n isFlagged: false,\n isRequired: false,\n },\n config.repoId,\n // TODO #22198\n pr.pullRequestId!,\n pr.createdBy!.id!,\n );\n }\n\n const updatedPr = await azureApiGit.updatePullRequest(\n objToUpdate,\n config.repoId,\n prNo,\n );\n if (config.prList) {\n const prToCache = getRenovatePRFormat(updatedPr);\n // We need to update the cached entry for this PR\n const existingIndex = config.prList.findIndex(\n (item) => item.number === prNo,\n );\n /* v8 ignore next: should not happen */\n if (existingIndex === -1) {\n logger.warn({ prNo }, 'PR not found in cache');\n // Add to cache\n config.prList.push(prToCache);\n } else {\n // overwrite existing PR in cache\n config.prList[existingIndex] = prToCache;\n }\n }\n}\n\nexport async function ensureComment({\n number,\n topic,\n content,\n}: EnsureCommentConfig): Promise<boolean> {\n logger.debug(`ensureComment(${number}, ${topic!}, content)`);\n const header = topic ? `### ${topic}\\n\\n` : '';\n const body = `${header}${sanitize(massageMarkdown(content))}`;\n const azureApiGit = await azureApi.gitApi();\n\n const threads = await azureApiGit.getThreads(config.repoId, number);\n let threadIdFound: number | undefined;\n let commentIdFound: number | undefined;\n let commentNeedsUpdating = false;\n threads.forEach((thread) => {\n const firstCommentContent = thread.comments?.[0].content;\n if (\n (topic && firstCommentContent?.startsWith(header)) === true ||\n (!topic && firstCommentContent === body)\n ) {\n threadIdFound = thread.id;\n commentIdFound = thread.comments?.[0].id;\n commentNeedsUpdating = firstCommentContent !== body;\n }\n });\n\n if (!threadIdFound) {\n await azureApiGit.createThread(\n {\n comments: [{ content: body, commentType: 1, parentCommentId: 0 }],\n status: 1,\n },\n config.repoId,\n number,\n );\n logger.info(\n { repository: config.repository, issueNo: number, topic },\n 'Comment added',\n );\n } else if (commentNeedsUpdating) {\n await azureApiGit.updateComment(\n {\n content: body,\n },\n config.repoId,\n number,\n threadIdFound,\n // TODO #22198\n commentIdFound!,\n );\n logger.debug(\n { repository: config.repository, issueNo: number, topic },\n 'Comment updated',\n );\n } else {\n logger.debug(\n { repository: config.repository, issueNo: number, topic },\n 'Comment is already up-to-date',\n );\n }\n\n return true;\n}\n\nexport async function ensureCommentRemoval(\n removeConfig: EnsureCommentRemovalConfig,\n): Promise<void> {\n const { number: issueNo } = removeConfig;\n const key =\n removeConfig.type === 'by-topic'\n ? removeConfig.topic\n : removeConfig.content;\n logger.debug(`Ensuring comment \"${key}\" in #${issueNo} is removed`);\n\n const azureApiGit = await azureApi.gitApi();\n const threads = await azureApiGit.getThreads(config.repoId, issueNo);\n\n let threadIdFound: number | null | undefined = null;\n if (removeConfig.type === 'by-topic') {\n const thread = threads.find(\n (thread: GitPullRequestCommentThread): boolean =>\n !!thread.comments?.[0].content?.startsWith(\n `### ${removeConfig.topic}\\n\\n`,\n ),\n );\n threadIdFound = thread?.id;\n } else {\n const thread = threads.find(\n (thread: GitPullRequestCommentThread): boolean =>\n thread.comments?.[0].content?.trim() === removeConfig.content,\n );\n threadIdFound = thread?.id;\n }\n\n if (threadIdFound) {\n await azureApiGit.updateThread(\n {\n status: 4, // close\n },\n config.repoId,\n issueNo,\n threadIdFound,\n );\n }\n}\n\nconst renovateToAzureStatusMapping: Record<BranchStatus, GitStatusState> = {\n ['green']: GitStatusState.Succeeded,\n ['yellow']: GitStatusState.Pending,\n ['red']: GitStatusState.Failed,\n};\n\nexport async function setBranchStatus({\n branchName,\n context,\n description,\n state,\n url: targetUrl,\n}: BranchStatusConfig): Promise<void> {\n logger.debug(\n `setBranchStatus(${branchName}, ${context}, ${description}, ${state}, ${targetUrl!})`,\n );\n const azureApiGit = await azureApi.gitApi();\n const branch = await azureApiGit.getBranch(\n config.repoId,\n getBranchNameWithoutRefsheadsPrefix(branchName)!,\n );\n const statusToCreate: GitStatus = {\n description,\n context: getGitStatusContextFromCombinedName(context),\n state: renovateToAzureStatusMapping[state],\n targetUrl,\n };\n await azureApiGit.createCommitStatus(\n statusToCreate,\n // TODO #22198\n branch.commit!.commitId!,\n config.repoId,\n );\n logger.trace(`Created commit status of ${state} on branch ${branchName}`);\n}\n\nexport async function mergePr({\n branchName,\n id: pullRequestId,\n strategy,\n}: MergePRConfig): Promise<boolean> {\n logger.debug(`mergePr(${pullRequestId}, ${branchName!})`);\n const azureApiGit = await azureApi.gitApi();\n\n let pr = await azureApiGit.getPullRequestById(pullRequestId, config.project);\n\n const mergeStrategy =\n strategy === 'auto'\n ? await getMergeStrategy(pr.targetRefName!)\n : mapMergeStrategy(strategy);\n const objToUpdate: GitPullRequest = {\n status: PullRequestStatus.Completed,\n lastMergeSourceCommit: pr.lastMergeSourceCommit,\n completionOptions: {\n mergeStrategy,\n deleteSourceBranch: true,\n mergeCommitMessage: pr.title,\n },\n };\n\n logger.trace(\n `Updating PR ${pullRequestId} to status ${PullRequestStatus.Completed} (${\n PullRequestStatus[PullRequestStatus.Completed]\n }) with lastMergeSourceCommit ${\n // TODO: types (#22198)\n pr.lastMergeSourceCommit?.commitId\n } using mergeStrategy ${mergeStrategy} (${\n GitPullRequestMergeStrategy[mergeStrategy]\n })`,\n );\n\n try {\n const response = await azureApiGit.updatePullRequest(\n objToUpdate,\n config.repoId,\n pullRequestId,\n );\n\n let retries = 0;\n let isClosed = response.status === PullRequestStatus.Completed;\n while (!isClosed && retries < 5) {\n retries += 1;\n const sleepMs = retries * 1000;\n logger.trace(\n { pullRequestId, status: pr.status, retries },\n `Updated PR to closed status but change has not taken effect yet. Retrying...`,\n );\n\n await setTimeout(sleepMs);\n pr = await azureApiGit.getPullRequestById(pullRequestId, config.project);\n isClosed = pr.status === PullRequestStatus.Completed;\n }\n\n if (!isClosed) {\n logger.warn(\n {\n pullRequestId,\n status: pr.status,\n expectedPRStatus: PullRequestStatus[PullRequestStatus.Completed],\n actualPRStatus: PullRequestStatus[pr.status!],\n },\n 'Expected PR to have completed status. However, the PR has a different status',\n );\n }\n return true;\n } catch (err) {\n logger.debug({ err }, 'Failed to set the PR as completed.');\n return false;\n }\n}\n\nexport function massageMarkdown(input: string): string {\n // Remove any HTML we use\n return (\n smartTruncate(readOnlyIssueBody(input), maxBodyLength())\n .replace(\n 'you tick the rebase/retry checkbox',\n 'PR is renamed to start with \"rebase!\"',\n )\n .replace(\n 'checking the rebase/retry box above',\n 'renaming the PR to start with \"rebase!\"',\n )\n .replace(regEx(`\\n---\\n\\n.*?<!-- rebase-check -->.*?\\n`), '')\n .replace(regEx(/<!--renovate-(?:debug|config-hash):.*?-->/g), '')\n // Replace GitHub-style PR links with Azure DevOps format\n .replace(regEx(/\\]\\(\\.\\.\\/pull\\//g), '](!')\n // Replace GitHub-style PR references (#123) with Azure DevOps format, needed for text linking config migration PR.\n // Only match a standalone reference (preceded by start, whitespace or `(`) so we don't corrupt\n // HTML entities like `&#8203;` or URL anchors like `CHANGELOG.md#4780`.\n .replace(regEx(/(^|[\\s(])#(\\d+)/g), '$1!$2')\n );\n}\n\nexport function maxBodyLength(): number {\n return 4000;\n}\n\nexport async function findIssue(title: string): Promise<Issue | null> {\n return await issueService.findIssue(title);\n}\n\nexport async function ensureIssue(\n issueConfig: EnsureIssueConfig,\n): Promise<EnsureIssueResult | null> {\n return await issueService.ensureIssue(issueConfig);\n}\n\nexport async function ensureIssueClosing(title: string): Promise<void> {\n return await issueService.ensureIssueClosing(title);\n}\n\nexport async function getIssueList(titleFilter?: string): Promise<Issue[]> {\n return await issueService.getIssueList(titleFilter);\n}\n\nasync function getUserIds(users: string[]): Promise<User[]> {\n const azureApiGit = await azureApi.gitApi();\n const azureApiCore = await azureApi.coreApi();\n const repos = await azureApiGit.getRepositories();\n const repo = repos.find((c) => c.id === config.repoId)!;\n const requiredReviewerPrefix = 'required:';\n const validReviewers = new Set<string>();\n\n // TODO #22198\n const teams = await azureHelper.getAllProjectTeams(repo.project!.id!);\n const members = await Promise.all(\n teams.map(\n async (t) =>\n await azureApiCore.getTeamMembersWithExtendedProperties(\n // TODO #22198\n repo.project!.id!,\n t.id!,\n ),\n ),\n );\n\n const ids: { id: string; name: string; isRequired: boolean }[] = [];\n members.forEach((listMembers) => {\n listMembers.forEach((m) => {\n users.forEach((r) => {\n let reviewer = r;\n let isRequired = false;\n if (reviewer.startsWith(requiredReviewerPrefix)) {\n reviewer = reviewer.replace(requiredReviewerPrefix, '');\n isRequired = true;\n }\n if (\n (reviewer.toLowerCase() === m.identity?.displayName?.toLowerCase() ||\n reviewer.toLowerCase() === m.identity?.uniqueName?.toLowerCase()) &&\n ids.filter((c) => c.id === m.identity?.id).length === 0\n ) {\n // TODO #22198\n ids.push({\n id: m.identity.id!,\n name: reviewer,\n isRequired,\n });\n\n validReviewers.add(reviewer);\n }\n });\n });\n });\n\n teams.forEach((t) => {\n users.forEach((r) => {\n let reviewer = r;\n let isRequired = false;\n if (reviewer.startsWith(requiredReviewerPrefix)) {\n reviewer = reviewer.replace(requiredReviewerPrefix, '');\n isRequired = true;\n }\n // v8 ignore else -- TODO: add test #40625\n if (\n reviewer.toLowerCase() === t.name?.toLowerCase() &&\n ids.filter((c) => c.id === t.id).length === 0\n ) {\n // TODO #22198\n ids.push({ id: t.id!, name: reviewer, isRequired });\n\n validReviewers.add(reviewer);\n }\n });\n });\n\n for (const u of users) {\n const reviewer = u.replace(requiredReviewerPrefix, '');\n if (!validReviewers.has(reviewer)) {\n logger.once.info(\n `${reviewer} is neither an Azure DevOps Team nor a user associated with a Team`,\n );\n }\n }\n\n return ids;\n}\n\n/**\n *\n * @param {number} issueNo\n * @param {string[]} assignees\n */\nexport async function addAssignees(\n issueNo: number,\n assignees: string[],\n): Promise<void> {\n logger.trace(`addAssignees(${issueNo}, [${assignees.join(', ')}])`);\n const ids = await getUserIds(assignees);\n await ensureComment({\n number: issueNo,\n topic: 'Add Assignees',\n content: ids.map((a) => `@<${a.id}>`).join(', '),\n });\n}\n\n/**\n *\n * @param {number} prNo\n * @param {string[]} reviewers\n */\nexport async function addReviewers(\n prNo: number,\n reviewers: string[],\n): Promise<void> {\n logger.trace(`addReviewers(${prNo}, [${reviewers.join(', ')}])`);\n const azureApiGit = await azureApi.gitApi();\n\n const ids = await getUserIds(reviewers);\n\n await Promise.all(\n ids.map(async (obj) => {\n await azureApiGit.createPullRequestReviewer(\n {\n isRequired: obj.isRequired,\n },\n config.repoId,\n prNo,\n obj.id,\n );\n logger.debug(`Reviewer added: ${obj.name}`);\n }),\n );\n}\n\nexport async function deleteLabel(\n prNumber: number,\n label: string,\n): Promise<void> {\n logger.debug(`Deleting label ${label} from #${prNumber}`);\n const azureApiGit = await azureApi.gitApi();\n await azureApiGit.deletePullRequestLabels(config.repoId, prNumber, label);\n}\n"],"mappings":"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"}
@@ -1,12 +1,60 @@
1
1
  import { sanitize } from "../../../util/sanitize.js";
2
2
  import { logger } from "../../../logger/index.js";
3
+ import { Lazy } from "../../../util/lazy.js";
3
4
  import { workItemTrackingApi } from "./azure-got-wrapper.js";
4
5
  import { getWorkItemTitle } from "./util.js";
5
6
  //#region lib/modules/platform/azure/issue.ts
7
+ const workItemType = "Issue";
8
+ const defaultOpenState = "New";
9
+ const defaultClosedState = "Closed";
10
+ const openCategories = ["Proposed", "InProgress"];
11
+ const closedCategories = [
12
+ "Completed",
13
+ "Resolved",
14
+ "Removed"
15
+ ];
16
+ /**
17
+ * Return the names of the states whose category is one of `categories`,
18
+ * preserving the order Azure DevOps returns them in (workflow order).
19
+ */
20
+ function namesByCategory(stateColors, categories) {
21
+ return stateColors.filter((s) => s.category && categories.includes(s.category) && s.name).map((s) => s.name);
22
+ }
6
23
  var IssueService = class {
7
24
  config;
25
+ workItemStates;
8
26
  constructor(config) {
9
27
  this.config = config;
28
+ this.workItemStates = new Lazy(() => this.resolveWorkItemStates());
29
+ }
30
+ /**
31
+ * Resolve the concrete open/closed state names for the `Issue` work item type
32
+ * from its process, so Renovate does not depend on hardcoded state names that
33
+ * only exist in some Azure DevOps processes. Falls back to the historical
34
+ * `New`/`Closed` values if the states cannot be fetched.
35
+ */
36
+ async resolveWorkItemStates() {
37
+ const states = {
38
+ open: defaultOpenState,
39
+ closed: defaultClosedState,
40
+ closedNames: /* @__PURE__ */ new Set([defaultClosedState])
41
+ };
42
+ try {
43
+ const stateColors = await (await workItemTrackingApi()).getWorkItemTypeStates(this.config.project, workItemType);
44
+ if (stateColors?.length) {
45
+ const openNames = namesByCategory(stateColors, openCategories);
46
+ const completed = stateColors.find((s) => s.category === "Completed" && s.name);
47
+ const closedNames = namesByCategory(stateColors, closedCategories);
48
+ states.open = openNames[0] ?? stateColors[0].name ?? states.open;
49
+ if (closedNames.length) {
50
+ states.closed = completed?.name ?? closedNames[0];
51
+ states.closedNames = new Set(closedNames);
52
+ }
53
+ }
54
+ } catch (err) {
55
+ logger.debug({ err }, "Azure: could not resolve work item states, using default state names");
56
+ }
57
+ return states;
10
58
  }
11
59
  async findIssue(title) {
12
60
  logger.debug(`findIssue(${title})`);
@@ -25,7 +73,7 @@ var IssueService = class {
25
73
  let wiql = `
26
74
  SELECT [System.Id]
27
75
  FROM WorkItems
28
- WHERE [System.WorkItemType] = 'Issue'
76
+ WHERE [System.WorkItemType] = '${workItemType}'
29
77
  AND [System.TeamProject] = '${this.config.project}'
30
78
  `;
31
79
  if (titleFilter) {
@@ -38,17 +86,19 @@ var IssueService = class {
38
86
  return [];
39
87
  }
40
88
  const workItemIds = result.workItems.map((wi) => wi.id);
41
- return (await azureApiWit.getWorkItems(workItemIds, [
89
+ const workItems = await azureApiWit.getWorkItems(workItemIds, [
42
90
  "System.Id",
43
91
  "System.Title",
44
92
  "System.State",
45
93
  "System.Description",
46
94
  "System.CreatedDate",
47
95
  "System.ChangedDate"
48
- ])).map((wi) => ({
96
+ ]);
97
+ const { closedNames } = await this.workItemStates.getValue();
98
+ return workItems.map((wi) => ({
49
99
  number: wi.id,
50
100
  title: wi.fields["System.Title"],
51
- state: wi.fields["System.State"] === "Closed" ? "closed" : "open",
101
+ state: closedNames.has(wi.fields["System.State"]) ? "closed" : "open",
52
102
  body: wi.fields["System.Description"],
53
103
  createdAt: wi.fields["System.CreatedDate"],
54
104
  lastModified: wi.fields["System.ChangedDate"]
@@ -63,10 +113,12 @@ var IssueService = class {
63
113
  try {
64
114
  const issue = await this.findIssue(title);
65
115
  if (issue?.state === "open" && issue.number) {
66
- await (await workItemTrackingApi()).updateWorkItem(void 0, [{
116
+ const azureApiWit = await workItemTrackingApi();
117
+ const { closed } = await this.workItemStates.getValue();
118
+ await azureApiWit.updateWorkItem(void 0, [{
67
119
  op: "replace",
68
120
  path: "/fields/System.State",
69
- value: "Closed"
121
+ value: closed
70
122
  }], issue.number, this.config.project);
71
123
  logger.debug(`Closed issue #${issue.number}: ${title}`);
72
124
  }
@@ -80,6 +132,7 @@ var IssueService = class {
80
132
  const azureApiWit = await workItemTrackingApi();
81
133
  const finalTitle = getWorkItemTitle(title, this.config.repository);
82
134
  const issues = await this.getIssueList(finalTitle);
135
+ const { open, closed } = await this.workItemStates.getValue();
83
136
  const openIssues = issues.filter((issue) => issue.state === "open");
84
137
  if (openIssues.length > 1) for (let i = 1; i < openIssues.length; i++) {
85
138
  const issueNumber = openIssues[i].number;
@@ -87,7 +140,7 @@ var IssueService = class {
87
140
  await azureApiWit.updateWorkItem(void 0, [{
88
141
  op: "replace",
89
142
  path: "/fields/System.State",
90
- value: "Closed"
143
+ value: closed
91
144
  }], issueNumber, this.config.project);
92
145
  logger.info(`Closed duplicate issue #${issueNumber}`);
93
146
  }
@@ -97,7 +150,8 @@ var IssueService = class {
97
150
  if (existingIssue.state === "closed" && once) {
98
151
  logger.debug("Issue already closed - skipping update");
99
152
  return null;
100
- } else if (existingIssue.state === "closed" && shouldReOpen) {
153
+ }
154
+ if (existingIssue.state === "closed" && shouldReOpen) {
101
155
  if (!existingIssue.number) {
102
156
  logger.warn("Cannot reopen issue without number");
103
157
  return null;
@@ -106,7 +160,7 @@ var IssueService = class {
106
160
  {
107
161
  op: "replace",
108
162
  path: "/fields/System.State",
109
- value: "New"
163
+ value: open
110
164
  },
111
165
  {
112
166
  op: "replace",
@@ -126,7 +180,8 @@ var IssueService = class {
126
180
  ], existingIssue.number, this.config.project);
127
181
  logger.debug(`Reopened issue #${existingIssue.number}`);
128
182
  return "updated";
129
- } else if (existingIssue.state === "open") {
183
+ }
184
+ if (existingIssue.state === "open") {
130
185
  if (existingIssue.title !== finalTitle || existingIssue.body !== body) {
131
186
  if (!existingIssue.number) {
132
187
  logger.warn("Cannot update issue without number");
@@ -160,7 +215,7 @@ var IssueService = class {
160
215
  {
161
216
  op: "add",
162
217
  path: "/fields/System.WorkItemType",
163
- value: "Issue"
218
+ value: workItemType
164
219
  },
165
220
  {
166
221
  op: "add",
@@ -176,13 +231,8 @@ var IssueService = class {
176
231
  op: "add",
177
232
  path: "/multilineFieldsFormat/System.Description",
178
233
  value: "Markdown"
179
- },
180
- {
181
- op: "add",
182
- path: "/fields/System.State",
183
- value: "New"
184
234
  }
185
- ], this.config.project, "Issue");
235
+ ], this.config.project, workItemType);
186
236
  logger.debug(`Created new issue #${newWorkItem.id}`);
187
237
  return "created";
188
238
  } catch (err) {
@@ -1 +1 @@
1
- {"version":3,"file":"issue.js","names":["azureApi.workItemTrackingApi"],"sources":["../../../../lib/modules/platform/azure/issue.ts"],"sourcesContent":["import type { WorkItem } from 'azure-devops-node-api/interfaces/WorkItemTrackingInterfaces.js';\nimport { logger } from '../../../logger/index.ts';\nimport { sanitize } from '../../../util/sanitize.ts';\nimport type { EnsureIssueConfig, EnsureIssueResult, Issue } from '../types.ts';\nimport * as azureApi from './azure-got-wrapper.ts';\nimport type { Config } from './types.ts';\nimport { getWorkItemTitle } from './util.ts';\n\nexport class IssueService {\n private config: Config;\n\n constructor(config: Config) {\n this.config = config;\n }\n\n async findIssue(title: string): Promise<Issue | null> {\n logger.debug(`findIssue(${title})`);\n try {\n const finalTitle = getWorkItemTitle(title, this.config.repository);\n const issues = await this.getIssueList(finalTitle);\n return issues[0] ?? null;\n } catch (err) {\n logger.error({ err }, 'Error finding issue');\n return null;\n }\n }\n\n async getIssueList(titleFilter?: string): Promise<Issue[]> {\n logger.debug('getIssueList()');\n try {\n const azureApiWit = await azureApi.workItemTrackingApi();\n\n let wiql = `\n SELECT [System.Id]\n FROM WorkItems\n WHERE [System.WorkItemType] = 'Issue'\n AND [System.TeamProject] = '${this.config.project}'\n `;\n\n if (titleFilter) {\n const escapedTitle = titleFilter.replace(/'/g, \"''\");\n wiql += ` AND [System.Title] = '${escapedTitle}'`;\n }\n\n const result = await azureApiWit.queryByWiql({ query: wiql });\n\n if (!result.workItems?.length) {\n logger.debug('getIssueList() no work items found');\n return [];\n }\n\n const workItemIds = result.workItems.map((wi: WorkItem) => wi.id!);\n const workItems = await azureApiWit.getWorkItems(workItemIds, [\n 'System.Id',\n 'System.Title',\n 'System.State',\n 'System.Description',\n 'System.CreatedDate',\n 'System.ChangedDate',\n ]);\n\n return workItems.map((wi: WorkItem) => ({\n number: wi.id!,\n title: wi.fields!['System.Title'],\n state: wi.fields!['System.State'] === 'Closed' ? 'closed' : 'open',\n body: wi.fields!['System.Description'],\n createdAt: wi.fields!['System.CreatedDate'],\n lastModified: wi.fields!['System.ChangedDate'],\n }));\n } catch (err) {\n logger.warn({ err }, 'Error fetching issue list');\n return [];\n }\n }\n\n async ensureIssueClosing(title: string): Promise<void> {\n logger.debug(`ensureIssueClosing(${title})`);\n try {\n const issue = await this.findIssue(title);\n if (issue?.state === 'open' && issue.number) {\n const azureApiWit = await azureApi.workItemTrackingApi();\n await azureApiWit.updateWorkItem(\n undefined,\n [{ op: 'replace', path: '/fields/System.State', value: 'Closed' }],\n issue.number,\n this.config.project,\n );\n logger.debug(`Closed issue #${issue.number}: ${title}`);\n }\n } catch (err) {\n logger.error({ err }, 'Error closing issue');\n }\n }\n\n async ensureIssue({\n title,\n body,\n once = false,\n shouldReOpen = true,\n }: EnsureIssueConfig): Promise<EnsureIssueResult | null> {\n logger.debug(`ensureIssue()`);\n\n try {\n const azureApiWit = await azureApi.workItemTrackingApi();\n const finalTitle = getWorkItemTitle(title, this.config.repository);\n const issues = await this.getIssueList(finalTitle);\n\n // Close duplicate open issues if any\n const openIssues = issues.filter((issue) => issue.state === 'open');\n if (openIssues.length > 1) {\n for (let i = 1; i < openIssues.length; i++) {\n const issueNumber = openIssues[i].number;\n if (issueNumber) {\n await azureApiWit.updateWorkItem(\n undefined,\n [\n {\n op: 'replace',\n path: '/fields/System.State',\n value: 'Closed',\n },\n ],\n issueNumber,\n this.config.project,\n );\n logger.info(`Closed duplicate issue #${issueNumber}`);\n }\n }\n }\n\n const existingIssue =\n openIssues[0] ?? issues.find((issue) => issue.state === 'closed');\n\n if (existingIssue) {\n if (existingIssue.state === 'closed' && once) {\n logger.debug('Issue already closed - skipping update');\n return null;\n } else if (existingIssue.state === 'closed' && shouldReOpen) {\n // Reopen and update work item\n if (!existingIssue.number) {\n logger.warn('Cannot reopen issue without number');\n return null;\n }\n await azureApiWit.updateWorkItem(\n undefined,\n [\n { op: 'replace', path: '/fields/System.State', value: 'New' },\n {\n op: 'replace',\n path: '/fields/System.Title',\n value: finalTitle,\n },\n {\n op: 'replace',\n path: '/fields/System.Description',\n value: sanitize(body),\n },\n {\n op: 'replace',\n path: '/multilineFieldsFormat/System.Description',\n value: 'Markdown',\n },\n ],\n existingIssue.number,\n this.config.project,\n );\n logger.debug(`Reopened issue #${existingIssue.number}`);\n return 'updated';\n } else if (existingIssue.state === 'open') {\n // Update work item if needed\n if (\n existingIssue.title !== finalTitle ||\n existingIssue.body !== body\n ) {\n if (!existingIssue.number) {\n logger.warn('Cannot update issue without number');\n return null;\n }\n await azureApiWit.updateWorkItem(\n undefined,\n [\n {\n op: 'replace',\n path: '/fields/System.Title',\n value: finalTitle,\n },\n {\n op: 'replace',\n path: '/fields/System.Description',\n value: sanitize(body),\n },\n {\n op: 'replace',\n path: '/multilineFieldsFormat/System.Description',\n value: 'Markdown',\n },\n ],\n existingIssue.number,\n this.config.project,\n );\n logger.debug(`Updated issue #${existingIssue.number}`);\n return 'updated';\n }\n logger.debug(`Issue #${existingIssue.number} is already up-to-date`);\n return 'updated';\n }\n }\n\n // Create new work item if none found\n const newWorkItem = await azureApiWit.createWorkItem(\n undefined,\n [\n { op: 'add', path: '/fields/System.WorkItemType', value: 'Issue' },\n { op: 'add', path: '/fields/System.Title', value: finalTitle },\n {\n op: 'add',\n path: '/fields/System.Description',\n value: sanitize(body),\n },\n {\n op: 'add',\n path: '/multilineFieldsFormat/System.Description',\n value: 'Markdown',\n },\n { op: 'add', path: '/fields/System.State', value: 'New' },\n ],\n this.config.project,\n 'Issue',\n );\n\n logger.debug(`Created new issue #${newWorkItem.id}`);\n return 'created';\n } catch (err) {\n logger.warn({ err }, 'Error ensuring issue');\n return null;\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"issue.js","names":["azureApi.workItemTrackingApi"],"sources":["../../../../lib/modules/platform/azure/issue.ts"],"sourcesContent":["import type {\n WorkItem,\n WorkItemStateColor,\n} from 'azure-devops-node-api/interfaces/WorkItemTrackingInterfaces.js';\nimport { logger } from '../../../logger/index.ts';\nimport { Lazy } from '../../../util/lazy.ts';\nimport { sanitize } from '../../../util/sanitize.ts';\nimport type { EnsureIssueConfig, EnsureIssueResult, Issue } from '../types.ts';\nimport * as azureApi from './azure-got-wrapper.ts';\nimport type { Config } from './types.ts';\nimport { getWorkItemTitle } from './util.ts';\n\nconst workItemType = 'Issue';\n\n// Historical fallbacks, used when the work item type's states cannot be\n// resolved from the API (e.g. Azure DevOps Server versions without the\n// endpoint). These match the values Renovate hardcoded previously.\nconst defaultOpenState = 'New';\nconst defaultClosedState = 'Closed';\n\n// Azure Boards groups every work item state into one of these meta-state\n// categories. Which concrete state name maps to a category depends on the\n// project's process (Basic: To Do/Doing/Done, Agile: New/Active/.../Closed,\n// custom inherited processes: anything). Categories are stable, so we resolve\n// the concrete names from them instead of hardcoding process-specific values.\nconst openCategories = ['Proposed', 'InProgress'];\nconst closedCategories = ['Completed', 'Resolved', 'Removed'];\n\ninterface WorkItemStates {\n /** State to move a work item to when (re)opening it. */\n open: string;\n /** State to move a work item to when closing it. */\n closed: string;\n /** All state names that represent a closed/completed work item. */\n closedNames: Set<string>;\n}\n\n/**\n * Return the names of the states whose category is one of `categories`,\n * preserving the order Azure DevOps returns them in (workflow order).\n */\nfunction namesByCategory(\n stateColors: WorkItemStateColor[],\n categories: string[],\n): string[] {\n return stateColors\n .filter((s) => s.category && categories.includes(s.category) && s.name)\n .map((s) => s.name!);\n}\n\nexport class IssueService {\n private config: Config;\n private readonly workItemStates: Lazy<Promise<WorkItemStates>>;\n\n constructor(config: Config) {\n this.config = config;\n // Wrapped in `Lazy` so concurrent callers share a single resolution\n // instead of each firing a duplicate `getWorkItemTypeStates` request.\n this.workItemStates = new Lazy(() => this.resolveWorkItemStates());\n }\n\n /**\n * Resolve the concrete open/closed state names for the `Issue` work item type\n * from its process, so Renovate does not depend on hardcoded state names that\n * only exist in some Azure DevOps processes. Falls back to the historical\n * `New`/`Closed` values if the states cannot be fetched.\n */\n private async resolveWorkItemStates(): Promise<WorkItemStates> {\n const states: WorkItemStates = {\n open: defaultOpenState,\n closed: defaultClosedState,\n closedNames: new Set([defaultClosedState]),\n };\n\n try {\n const azureApiWit = await azureApi.workItemTrackingApi();\n const stateColors = await azureApiWit.getWorkItemTypeStates(\n this.config.project,\n workItemType,\n );\n\n if (stateColors?.length) {\n const openNames = namesByCategory(stateColors, openCategories);\n // A `Completed` state (e.g. Agile's `Closed`) is the true \"done\" state.\n // `Resolved`/`Removed` states also count as closed but must not be\n // picked over `Completed` when moving an item to closed.\n const completed = stateColors.find(\n (s) => s.category === 'Completed' && s.name,\n );\n const closedNames = namesByCategory(stateColors, closedCategories);\n\n // First open-category state, else the type's first state overall. If a\n // process somehow exposes only closed states, this falls back to a\n // closed state name; that is intentional (there is no better reopen\n // target) rather than a bug.\n states.open = openNames[0] ?? stateColors[0].name ?? states.open;\n if (closedNames.length) {\n // Prefer a `Completed` state as the close target so processes that\n // order `Resolved` before `Closed` (e.g. some custom Agile\n // inheritances) still close to `Closed`; fall back to the wider set\n // only when no `Completed` state exists. Keep the full set for\n // recognising already-closed items.\n states.closed = completed?.name ?? closedNames[0];\n states.closedNames = new Set(closedNames);\n }\n }\n } catch (err) {\n logger.debug(\n { err },\n 'Azure: could not resolve work item states, using default state names',\n );\n }\n\n return states;\n }\n\n async findIssue(title: string): Promise<Issue | null> {\n logger.debug(`findIssue(${title})`);\n try {\n const finalTitle = getWorkItemTitle(title, this.config.repository);\n const issues = await this.getIssueList(finalTitle);\n return issues[0] ?? null;\n } catch (err) {\n logger.error({ err }, 'Error finding issue');\n return null;\n }\n }\n\n async getIssueList(titleFilter?: string): Promise<Issue[]> {\n logger.debug('getIssueList()');\n try {\n const azureApiWit = await azureApi.workItemTrackingApi();\n\n let wiql = `\n SELECT [System.Id]\n FROM WorkItems\n WHERE [System.WorkItemType] = '${workItemType}'\n AND [System.TeamProject] = '${this.config.project}'\n `;\n\n if (titleFilter) {\n const escapedTitle = titleFilter.replace(/'/g, \"''\");\n wiql += ` AND [System.Title] = '${escapedTitle}'`;\n }\n\n const result = await azureApiWit.queryByWiql({ query: wiql });\n\n if (!result.workItems?.length) {\n logger.debug('getIssueList() no work items found');\n return [];\n }\n\n const workItemIds = result.workItems.map((wi: WorkItem) => wi.id!);\n const workItems = await azureApiWit.getWorkItems(workItemIds, [\n 'System.Id',\n 'System.Title',\n 'System.State',\n 'System.Description',\n 'System.CreatedDate',\n 'System.ChangedDate',\n ]);\n\n const { closedNames } = await this.workItemStates.getValue();\n\n return workItems.map((wi: WorkItem) => ({\n number: wi.id!,\n title: wi.fields!['System.Title'],\n state: closedNames.has(wi.fields!['System.State']) ? 'closed' : 'open',\n body: wi.fields!['System.Description'],\n createdAt: wi.fields!['System.CreatedDate'],\n lastModified: wi.fields!['System.ChangedDate'],\n }));\n } catch (err) {\n logger.warn({ err }, 'Error fetching issue list');\n return [];\n }\n }\n\n async ensureIssueClosing(title: string): Promise<void> {\n logger.debug(`ensureIssueClosing(${title})`);\n try {\n const issue = await this.findIssue(title);\n if (issue?.state === 'open' && issue.number) {\n const azureApiWit = await azureApi.workItemTrackingApi();\n const { closed } = await this.workItemStates.getValue();\n await azureApiWit.updateWorkItem(\n undefined,\n [{ op: 'replace', path: '/fields/System.State', value: closed }],\n issue.number,\n this.config.project,\n );\n logger.debug(`Closed issue #${issue.number}: ${title}`);\n }\n } catch (err) {\n logger.error({ err }, 'Error closing issue');\n }\n }\n\n async ensureIssue({\n title,\n body,\n once = false,\n shouldReOpen = true,\n }: EnsureIssueConfig): Promise<EnsureIssueResult | null> {\n logger.debug(`ensureIssue()`);\n\n try {\n const azureApiWit = await azureApi.workItemTrackingApi();\n const finalTitle = getWorkItemTitle(title, this.config.repository);\n const issues = await this.getIssueList(finalTitle);\n const { open, closed } = await this.workItemStates.getValue();\n\n // Close duplicate open issues if any\n const openIssues = issues.filter((issue) => issue.state === 'open');\n if (openIssues.length > 1) {\n for (let i = 1; i < openIssues.length; i++) {\n const issueNumber = openIssues[i].number;\n if (issueNumber) {\n await azureApiWit.updateWorkItem(\n undefined,\n [\n {\n op: 'replace',\n path: '/fields/System.State',\n value: closed,\n },\n ],\n issueNumber,\n this.config.project,\n );\n logger.info(`Closed duplicate issue #${issueNumber}`);\n }\n }\n }\n\n const existingIssue =\n openIssues[0] ?? issues.find((issue) => issue.state === 'closed');\n\n if (existingIssue) {\n if (existingIssue.state === 'closed' && once) {\n logger.debug('Issue already closed - skipping update');\n return null;\n }\n if (existingIssue.state === 'closed' && shouldReOpen) {\n // Reopen and update work item\n if (!existingIssue.number) {\n logger.warn('Cannot reopen issue without number');\n return null;\n }\n await azureApiWit.updateWorkItem(\n undefined,\n [\n { op: 'replace', path: '/fields/System.State', value: open },\n {\n op: 'replace',\n path: '/fields/System.Title',\n value: finalTitle,\n },\n {\n op: 'replace',\n path: '/fields/System.Description',\n value: sanitize(body),\n },\n {\n op: 'replace',\n path: '/multilineFieldsFormat/System.Description',\n value: 'Markdown',\n },\n ],\n existingIssue.number,\n this.config.project,\n );\n logger.debug(`Reopened issue #${existingIssue.number}`);\n return 'updated';\n }\n if (existingIssue.state === 'open') {\n // Update work item if needed\n if (\n existingIssue.title !== finalTitle ||\n existingIssue.body !== body\n ) {\n if (!existingIssue.number) {\n logger.warn('Cannot update issue without number');\n return null;\n }\n await azureApiWit.updateWorkItem(\n undefined,\n [\n {\n op: 'replace',\n path: '/fields/System.Title',\n value: finalTitle,\n },\n {\n op: 'replace',\n path: '/fields/System.Description',\n value: sanitize(body),\n },\n {\n op: 'replace',\n path: '/multilineFieldsFormat/System.Description',\n value: 'Markdown',\n },\n ],\n existingIssue.number,\n this.config.project,\n );\n logger.debug(`Updated issue #${existingIssue.number}`);\n return 'updated';\n }\n logger.debug(`Issue #${existingIssue.number} is already up-to-date`);\n return 'updated';\n }\n }\n\n // Create new work item if none found. System.State is intentionally\n // omitted so Azure DevOps applies the work item type's default initial\n // state for the project's process (e.g. `To Do` on Basic, `New`/`Active`\n // on Agile). Passing a hardcoded state fails on processes that lack it.\n const newWorkItem = await azureApiWit.createWorkItem(\n undefined,\n [\n {\n op: 'add',\n path: '/fields/System.WorkItemType',\n value: workItemType,\n },\n { op: 'add', path: '/fields/System.Title', value: finalTitle },\n {\n op: 'add',\n path: '/fields/System.Description',\n value: sanitize(body),\n },\n {\n op: 'add',\n path: '/multilineFieldsFormat/System.Description',\n value: 'Markdown',\n },\n ],\n this.config.project,\n workItemType,\n );\n\n logger.debug(`Created new issue #${newWorkItem.id}`);\n return 'created';\n } catch (err) {\n logger.warn({ err }, 'Error ensuring issue');\n return null;\n }\n }\n}\n"],"mappings":"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"}
@@ -506,9 +506,7 @@ async function sanitizeReviewers(reviewers, err) {
506
506
  const MSG_NOT_WORKSPACE_MEMBER = "is not a member of this workspace and cannot be added to this pull request";
507
507
  for (const msg of err.body.error.fields.reviewers) if (msg === MSG_MALFORMED_REVIEWERS_LIST) {
508
508
  logger.debug({ err }, "PR contains reviewers that may be either inactive or no longer a member of this workspace. Will try setting only active reviewers");
509
- for (const reviewer of reviewers) if ((await bitbucketHttp.getJsonUnchecked(`/2.0/users/${reviewer.uuid}`, { cacheProvider: aggressiveRepoCacheProvider })).body.account_status === "active") {
510
- if (await isAccountMemberOfWorkspace(reviewer, config.repository)) sanitizedReviewers.push(reviewer);
511
- }
509
+ for (const reviewer of reviewers) if ((await bitbucketHttp.getJsonUnchecked(`/2.0/users/${reviewer.uuid}`, { cacheProvider: aggressiveRepoCacheProvider })).body.account_status === "active" && await isAccountMemberOfWorkspace(reviewer, config.repository)) sanitizedReviewers.push(reviewer);
512
510
  } else if (msg.endsWith(MSG_NOT_WORKSPACE_MEMBER)) {
513
511
  logger.debug({ err }, "PR contains reviewer accounts which are no longer member of this workspace. Will try setting only member reviewers");
514
512
  for (const reviewer of reviewers) if (await isAccountMemberOfWorkspace(reviewer, config.repository)) sanitizedReviewers.push(reviewer);