(client: BitbucketClient, projects: string[])
| 260 | } |
| 261 | |
| 262 | async function cloudGetReposForProjects(client: BitbucketClient, projects: string[]): Promise<{repos: CloudRepository[], warnings: string[]}> { |
| 263 | const results = await Promise.allSettled(projects.map(async (project) => { |
| 264 | const [workspace, project_name] = project.split('/'); |
| 265 | if (!workspace || !project_name) { |
| 266 | const warning = `Invalid project ${project}`; |
| 267 | logger.warn(warning); |
| 268 | return { |
| 269 | type: 'warning' as const, |
| 270 | warning |
| 271 | } |
| 272 | } |
| 273 | |
| 274 | logger.debug(`Fetching all repos for project ${project} for workspace ${workspace}...`); |
| 275 | try { |
| 276 | const { durationMs, data: repos } = await measure(async () => { |
| 277 | const fetchFn = () => getPaginatedCloud<CloudRepository>(`/repositories/${workspace}` as CloudGetRequestPath, async (path, query) => { |
| 278 | const { data } = await client.apiClient.GET(path, { |
| 279 | params: { |
| 280 | path: { |
| 281 | workspace, |
| 282 | }, |
| 283 | query: { |
| 284 | ...query, |
| 285 | q: `project.key="${project_name}"` |
| 286 | } |
| 287 | } |
| 288 | }); |
| 289 | return data; |
| 290 | }); |
| 291 | return fetchWithRetry(fetchFn, `project ${project_name} in workspace ${workspace}`, logger); |
| 292 | }); |
| 293 | |
| 294 | logger.debug(`Found ${repos.length} repos for project ${project_name} for workspace ${workspace} in ${durationMs}ms.`); |
| 295 | return { |
| 296 | type: 'valid' as const, |
| 297 | data: repos |
| 298 | } |
| 299 | } catch (e: any) { |
| 300 | Sentry.captureException(e); |
| 301 | logger.error(`Failed to fetch repos for project ${project_name}: ${e}`); |
| 302 | |
| 303 | if (e?.status === 404) { |
| 304 | const warning = `Project ${project_name} not found in ${workspace} or invalid access`; |
| 305 | logger.warn(warning); |
| 306 | return { |
| 307 | type: 'warning' as const, |
| 308 | warning |
| 309 | } |
| 310 | } |
| 311 | throw e; |
| 312 | } |
| 313 | })); |
| 314 | |
| 315 | throwIfAnyFailed(results); |
| 316 | const { validItems: repos, warnings } = processPromiseResults(results); |
| 317 | return { |
| 318 | repos, |
| 319 | warnings |
nothing calls this directly
no test coverage detected