@@ -35,8 +35,8 @@ interface BitbucketClient {
35
35
getPaginated : < T , V extends CloudGetRequestPath > ( path : V , get : ( url : V ) => Promise < PaginatedResponse < T > > ) => Promise < T [ ] > ;
36
36
getReposForWorkspace : ( client : BitbucketClient , workspace : string ) => Promise < { validRepos : BitbucketRepository [ ] , notFoundWorkspaces : string [ ] } > ;
37
37
getReposForProjects : ( client : BitbucketClient , projects : string [ ] ) => Promise < { validRepos : BitbucketRepository [ ] , notFoundProjects : string [ ] } > ;
38
+ getRepos : ( client : BitbucketClient , repos : string [ ] ) => Promise < { validRepos : BitbucketRepository [ ] , notFoundRepos : string [ ] } > ;
38
39
/*
39
- getRepos: (client: BitbucketClient, workspace: string, project: string) => Promise<Repo[]>;
40
40
countForks: (client: BitbucketClient, repo: Repo) => Promise<number>;
41
41
countWatchers: (client: BitbucketClient, repo: Repo) => Promise<number>;
42
42
getBranches: (client: BitbucketClient, repo: string) => Promise<string[]>;
@@ -89,6 +89,12 @@ export const getBitbucketReposFromConfig = async (config: BitbucketConnectionCon
89
89
notFound . repos = notFoundProjects ;
90
90
}
91
91
92
+ if ( config . repos ) {
93
+ const { validRepos, notFoundRepos } = await client . getRepos ( client , config . repos ) ;
94
+ allRepos = allRepos . concat ( validRepos ) ;
95
+ notFound . repos = notFoundRepos ;
96
+ }
97
+
92
98
return {
93
99
validRepos : allRepos ,
94
100
notFound,
@@ -114,6 +120,7 @@ function cloudClient(token: string | undefined): BitbucketClient {
114
120
getPaginated : getPaginatedCloud ,
115
121
getReposForWorkspace : cloudGetReposForWorkspace ,
116
122
getReposForProjects : cloudGetReposForProjects ,
123
+ getRepos : cloudGetRepos ,
117
124
/*
118
125
getRepos: cloudGetRepos,
119
126
countForks: cloudCountForks,
@@ -170,7 +177,7 @@ async function cloudGetReposForWorkspace(client: BitbucketClient, workspace: str
170
177
} ) ;
171
178
const { data, error } = response ;
172
179
if ( error ) {
173
- throw new Error ( `Failed to fetch projects for workspace ${ workspace } : ${ error . type } ` ) ;
180
+ throw new Error ( `Failed to fetch projects for workspace ${ workspace } : ${ JSON . stringify ( error ) } ` ) ;
174
181
}
175
182
return data ;
176
183
} ) ;
@@ -192,8 +199,15 @@ async function cloudGetReposForWorkspace(client: BitbucketClient, workspace: str
192
199
async function cloudGetReposForProjects ( client : BitbucketClient , projects : string [ ] ) : Promise < { validRepos : CloudRepository [ ] , notFoundProjects : string [ ] } > {
193
200
const results = await Promise . allSettled ( projects . map ( async ( project ) => {
194
201
const [ workspace , project_name ] = project . split ( '/' ) ;
195
- logger . debug ( `Fetching all repos for project ${ project } for workspace ${ workspace } ...` ) ;
202
+ if ( ! workspace || ! project_name ) {
203
+ logger . error ( `Invalid project ${ project } ` ) ;
204
+ return {
205
+ type : 'notFound' as const ,
206
+ value : project
207
+ }
208
+ }
196
209
210
+ logger . debug ( `Fetching all repos for project ${ project } for workspace ${ workspace } ...` ) ;
197
211
try {
198
212
const path = `/repositories/${ workspace } ?q=project.key="${ project_name } "` as CloudGetRequestPath ;
199
213
const repos = await client . getPaginated < CloudRepository , typeof path > ( path , async ( url ) => {
@@ -233,3 +247,50 @@ async function cloudGetReposForProjects(client: BitbucketClient, projects: strin
233
247
notFoundProjects
234
248
}
235
249
}
250
+
251
+ async function cloudGetRepos ( client : BitbucketClient , repos : string [ ] ) : Promise < { validRepos : CloudRepository [ ] , notFoundRepos : string [ ] } > {
252
+ const results = await Promise . allSettled ( repos . map ( async ( repo ) => {
253
+ const [ workspace , repo_slug ] = repo . split ( '/' ) ;
254
+ if ( ! workspace || ! repo_slug ) {
255
+ logger . error ( `Invalid repo ${ repo } ` ) ;
256
+ return {
257
+ type : 'notFound' as const ,
258
+ value : repo
259
+ } ;
260
+ }
261
+
262
+ logger . debug ( `Fetching repo ${ repo_slug } for workspace ${ workspace } ...` ) ;
263
+ try {
264
+ const path = `/repositories/${ workspace } /${ repo_slug } ` as CloudGetRequestPath ;
265
+ const response = await client . apiClient . GET ( path ) ;
266
+ const { data, error } = response ;
267
+ if ( error ) {
268
+ throw new Error ( `Failed to fetch repo ${ repo } : ${ error . type } ` ) ;
269
+ }
270
+ return {
271
+ type : 'valid' as const ,
272
+ data : [ data ]
273
+ } ;
274
+ } catch ( e : any ) {
275
+ Sentry . captureException ( e ) ;
276
+ logger . error ( `Failed to fetch repo ${ repo } : ${ e } ` ) ;
277
+
278
+ const status = e ?. cause ?. response ?. status ;
279
+ if ( status === 404 ) {
280
+ logger . error ( `Repo ${ repo } not found in ${ workspace } or invalid access` ) ;
281
+ return {
282
+ type : 'notFound' as const ,
283
+ value : repo
284
+ } ;
285
+ }
286
+ throw e ;
287
+ }
288
+ } ) ) ;
289
+
290
+ throwIfAnyFailed ( results ) ;
291
+ const { validItems : validRepos , notFoundItems : notFoundRepos } = processPromiseResults ( results ) ;
292
+ return {
293
+ validRepos,
294
+ notFoundRepos
295
+ } ;
296
+ }
0 commit comments