(
repoList: string[],
baseUrl: string,
token: string,
useTfsPath: boolean
)
| 283 | } |
| 284 | |
| 285 | async function getRepos( |
| 286 | repoList: string[], |
| 287 | baseUrl: string, |
| 288 | token: string, |
| 289 | useTfsPath: boolean |
| 290 | ) { |
| 291 | const results = await Promise.allSettled(repoList.map(async (repo) => { |
| 292 | try { |
| 293 | const [org, projectName, repoName] = repo.split('/'); |
| 294 | logger.debug(`Fetching repository info for ${repo}...`); |
| 295 | |
| 296 | const { durationMs, data: result } = await measure(async () => { |
| 297 | const fetchFn = async () => { |
| 298 | const orgUrl = buildOrgUrl(baseUrl, org, useTfsPath); |
| 299 | const connection = createAzureDevOpsConnection(orgUrl, token); |
| 300 | const gitApi = await connection.getGitApi(); |
| 301 | |
| 302 | const repo = await gitApi.getRepository(repoName, projectName); |
| 303 | return repo; |
| 304 | }; |
| 305 | |
| 306 | return fetchWithRetry(fetchFn, repo, logger); |
| 307 | }); |
| 308 | |
| 309 | logger.debug(`Found info for repository ${repo} in ${durationMs}ms`); |
| 310 | return { |
| 311 | type: 'valid' as const, |
| 312 | data: [result] |
| 313 | }; |
| 314 | |
| 315 | } catch (error) { |
| 316 | Sentry.captureException(error); |
| 317 | logger.error(`Failed to fetch repository ${repo}.`, error); |
| 318 | |
| 319 | if (error && typeof error === 'object' && 'statusCode' in error && error.statusCode === 404) { |
| 320 | const warning = `Repository ${repo} not found or no access`; |
| 321 | logger.warn(warning); |
| 322 | return { |
| 323 | type: 'warning' as const, |
| 324 | warning |
| 325 | }; |
| 326 | } |
| 327 | throw error; |
| 328 | } |
| 329 | })); |
| 330 | |
| 331 | throwIfAnyFailed(results); |
| 332 | const { validItems: repos, warnings } = processPromiseResults<GitRepository>(results); |
| 333 | |
| 334 | return { |
| 335 | repos, |
| 336 | warnings, |
| 337 | }; |
| 338 | } |
no test coverage detected