@red-hat-developer-hub/backstage-plugin-bulk-import-backend 6.2.0 → 6.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/README.md +28 -0
  3. package/config.d.ts +9 -1
  4. package/dist/catalog/catalogHttpClient.cjs.js +3 -0
  5. package/dist/catalog/catalogHttpClient.cjs.js.map +1 -1
  6. package/dist/catalog/catalogInfoGenerator.cjs.js +1 -0
  7. package/dist/catalog/catalogInfoGenerator.cjs.js.map +1 -1
  8. package/dist/database/migration.cjs.js +20 -0
  9. package/dist/database/migration.cjs.js.map +1 -0
  10. package/dist/database/repositoryDao.cjs.js +117 -0
  11. package/dist/database/repositoryDao.cjs.js.map +1 -0
  12. package/dist/generated/openapidocument.cjs.js +366 -38
  13. package/dist/generated/openapidocument.cjs.js.map +1 -1
  14. package/dist/github/githubApiService.cjs.js +222 -95
  15. package/dist/github/githubApiService.cjs.js.map +1 -1
  16. package/dist/github/utils/orgUtils.cjs.js +2 -0
  17. package/dist/github/utils/orgUtils.cjs.js.map +1 -1
  18. package/dist/github/utils/prUtils.cjs.js +3 -0
  19. package/dist/github/utils/prUtils.cjs.js.map +1 -1
  20. package/dist/github/utils/repoUtils.cjs.js +1 -38
  21. package/dist/github/utils/repoUtils.cjs.js.map +1 -1
  22. package/dist/github/utils/utils.cjs.js +29 -18
  23. package/dist/github/utils/utils.cjs.js.map +1 -1
  24. package/dist/gitlab/GitlabAppManager.cjs.js +54 -0
  25. package/dist/gitlab/GitlabAppManager.cjs.js.map +1 -0
  26. package/dist/gitlab/gitlabApiService.cjs.js +660 -0
  27. package/dist/gitlab/gitlabApiService.cjs.js.map +1 -0
  28. package/dist/gitlab/utils/glUtils.cjs.js +15 -0
  29. package/dist/gitlab/utils/glUtils.cjs.js.map +1 -0
  30. package/dist/gitlab/utils/orgUtils.cjs.js +72 -0
  31. package/dist/gitlab/utils/orgUtils.cjs.js.map +1 -0
  32. package/dist/gitlab/utils/prUtils.cjs.js +73 -0
  33. package/dist/gitlab/utils/prUtils.cjs.js.map +1 -0
  34. package/dist/gitlab/utils/repoUtils.cjs.js +200 -0
  35. package/dist/gitlab/utils/repoUtils.cjs.js.map +1 -0
  36. package/dist/gitlab/utils/utils.cjs.js +131 -0
  37. package/dist/gitlab/utils/utils.cjs.js.map +1 -0
  38. package/dist/helpers/utils.cjs.js +58 -0
  39. package/dist/helpers/utils.cjs.js.map +1 -1
  40. package/dist/index.d.ts +2 -1
  41. package/dist/plugin.cjs.js +6 -3
  42. package/dist/plugin.cjs.js.map +1 -1
  43. package/dist/service/handlers/import/bulkImports.cjs.js +216 -34
  44. package/dist/service/handlers/import/bulkImports.cjs.js.map +1 -1
  45. package/dist/service/handlers/import/execute-template.cjs.js +264 -0
  46. package/dist/service/handlers/import/execute-template.cjs.js.map +1 -0
  47. package/dist/service/handlers/import/importStatus.cjs.js +5 -8
  48. package/dist/service/handlers/import/importStatus.cjs.js.map +1 -1
  49. package/dist/service/handlers/organization/organizations.cjs.js +2 -2
  50. package/dist/service/handlers/organization/organizations.cjs.js.map +1 -1
  51. package/dist/service/handlers/repository/repositories.cjs.js +5 -2
  52. package/dist/service/handlers/repository/repositories.cjs.js.map +1 -1
  53. package/dist/service/router.cjs.js +199 -34
  54. package/dist/service/router.cjs.js.map +1 -1
  55. package/migrations/20250808122501_migrations.js +53 -0
  56. package/package.json +17 -11
@@ -0,0 +1,660 @@
1
+ 'use strict';
2
+
3
+ var integration = require('@backstage/integration');
4
+ var gitUrlParse = require('git-url-parse');
5
+ var catalogUtils = require('../catalog/catalogUtils.cjs.js');
6
+ require('@backstage/errors');
7
+ require('@backstage/plugin-permission-common');
8
+ require('@red-hat-developer-hub/backstage-plugin-bulk-import-common');
9
+ require('just-kebab-case');
10
+ var loggingUtils = require('../helpers/loggingUtils.cjs.js');
11
+ var utils$1 = require('../helpers/utils.cjs.js');
12
+ var handlers = require('../service/handlers/handlers.cjs.js');
13
+ var GitlabAppManager = require('./GitlabAppManager.cjs.js');
14
+ var glUtils = require('./utils/glUtils.cjs.js');
15
+ var orgUtils = require('./utils/orgUtils.cjs.js');
16
+ var prUtils = require('./utils/prUtils.cjs.js');
17
+ var repoUtils = require('./utils/repoUtils.cjs.js');
18
+ var utils = require('./utils/utils.cjs.js');
19
+
20
+ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
21
+
22
+ var gitUrlParse__default = /*#__PURE__*/_interopDefaultCompat(gitUrlParse);
23
+
24
+ class GitlabApiService {
25
+ logger;
26
+ integrations;
27
+ gitlabCredentialsProvider;
28
+ config;
29
+ // Cache for storing ETags (used for efficient caching of unchanged data returned by GitHub)
30
+ cache;
31
+ constructor(logger, config, cacheService) {
32
+ this.logger = logger;
33
+ this.config = config;
34
+ this.integrations = integration.ScmIntegrations.fromConfig(config);
35
+ this.gitlabCredentialsProvider = GitlabAppManager.CustomGitlabCredentialsProvider.fromIntegrations(this.integrations);
36
+ this.cache = cacheService;
37
+ }
38
+ async getRepositoryFromIntegrations(repoUrl) {
39
+ const gitUrl = gitUrlParse__default.default(repoUrl);
40
+ const glConfig = this.integrations.gitlab.byUrl(repoUrl)?.config;
41
+ if (!glConfig) {
42
+ throw new Error(
43
+ `No Gitlab integration config found for repo ${repoUrl}. Please add a configuration entry under 'integrations.gitlab`
44
+ );
45
+ }
46
+ const credentials = await utils.getCredentialsForConfig(
47
+ this.gitlabCredentialsProvider,
48
+ glConfig
49
+ );
50
+ let repository = undefined;
51
+ for (const credential of credentials) {
52
+ const glKit = glUtils.buildGitlab(
53
+ {
54
+ logger: this.logger,
55
+ cache: this.cache
56
+ },
57
+ { credential, owner: gitUrl.owner },
58
+ glConfig.baseUrl
59
+ );
60
+ const repo = await glKit.Projects.show(`${gitUrl.owner}/${gitUrl.name}`);
61
+ if (!repo) {
62
+ continue;
63
+ }
64
+ repository = {
65
+ name: repo.name,
66
+ full_name: repo.path_with_namespace,
67
+ url: repo._links.self,
68
+ html_url: repo.web_url,
69
+ default_branch: repo.default_branch,
70
+ updated_at: repo.updated_at
71
+ };
72
+ break;
73
+ }
74
+ return {
75
+ repository,
76
+ errors: []
77
+ };
78
+ }
79
+ async getOrganizationsFromIntegrations(search, pageNumber = handlers.DefaultPageNumber, pageSize = handlers.DefaultPageSize) {
80
+ const groups = /* @__PURE__ */ new Map();
81
+ const result = await utils.fetchFromAllIntegrations(
82
+ {
83
+ logger: this.logger,
84
+ cache: this.cache,
85
+ gitlabCredentialsProvider: this.gitlabCredentialsProvider
86
+ },
87
+ this.integrations,
88
+ {
89
+ dataFetcher: async (glApi, credential, glConfig) => {
90
+ const dataFetchErrors = /* @__PURE__ */ new Map();
91
+ const resp = await orgUtils.addGitlabTokenGroups(
92
+ {
93
+ logger: this.logger
94
+ },
95
+ glApi,
96
+ credential,
97
+ {
98
+ search,
99
+ groups,
100
+ pageNumber,
101
+ pageSize,
102
+ errors: dataFetchErrors
103
+ }
104
+ );
105
+ this.logger.debug(
106
+ `Got ${resp.totalCount} groups(s) for ${glConfig.host}`
107
+ );
108
+ return {
109
+ result: resp.totalCount ?? 0,
110
+ errors: Array.from(dataFetchErrors.values())
111
+ };
112
+ }
113
+ }
114
+ );
115
+ const groupList = Array.from(groups.values());
116
+ const totalCount = utils$1.computeTotalCount(groupList, result.data, pageSize);
117
+ return {
118
+ organizations: groupList,
119
+ errors: Array.from(result.errors?.values() ?? []),
120
+ totalCount
121
+ };
122
+ }
123
+ async getOrgRepositoriesFromIntegrations(orgName, search, pageNumber = handlers.DefaultPageNumber, pageSize = handlers.DefaultPageSize) {
124
+ const orgRepositories = /* @__PURE__ */ new Map();
125
+ const result = await utils.fetchFromAllIntegrations(
126
+ {
127
+ logger: this.logger,
128
+ cache: this.cache,
129
+ gitlabCredentialsProvider: this.gitlabCredentialsProvider
130
+ },
131
+ this.integrations,
132
+ {
133
+ dataFetcher: async (glApi, credential, glConfig) => {
134
+ const dataFetchErrors = /* @__PURE__ */ new Map();
135
+ const resp = await repoUtils.addGitlabTokenOrgRepositories(
136
+ {
137
+ logger: this.logger
138
+ },
139
+ glApi,
140
+ credential,
141
+ orgName,
142
+ orgRepositories,
143
+ dataFetchErrors,
144
+ {
145
+ search,
146
+ pageNumber,
147
+ pageSize
148
+ }
149
+ );
150
+ this.logger.debug(
151
+ `Got ${resp.totalCount} org repo(s) for ${glConfig.host}`
152
+ );
153
+ return {
154
+ stopFetchingData: true,
155
+ result: resp.totalCount ?? 0,
156
+ errors: Array.from(dataFetchErrors.values())
157
+ };
158
+ }
159
+ }
160
+ );
161
+ const repoList = Array.from(orgRepositories.values());
162
+ const totalCount = utils$1.computeTotalCount(repoList, result.data, pageSize);
163
+ return {
164
+ repositories: repoList,
165
+ errors: Array.from(result.errors?.values() ?? []),
166
+ totalCount
167
+ };
168
+ }
169
+ /**
170
+ * Returns GitlabRepositoryResponse containing:
171
+ * - a list of unique repositories the gitlab integrations have access to
172
+ * - a list of errors encountered by each token (if any exist)
173
+ */
174
+ async getRepositoriesFromIntegrations(search, pageNumber = handlers.DefaultPageNumber, pageSize = handlers.DefaultPageSize) {
175
+ const repositories = /* @__PURE__ */ new Map();
176
+ const result = await utils.fetchFromAllIntegrations(
177
+ {
178
+ logger: this.logger,
179
+ cache: this.cache,
180
+ gitlabCredentialsProvider: this.gitlabCredentialsProvider
181
+ },
182
+ this.integrations,
183
+ {
184
+ dataFetcher: async (glApi, credential, glConfig) => {
185
+ const dataFetchErrors = /* @__PURE__ */ new Map();
186
+ const resp = await repoUtils.addGitlabTokenRepositories(
187
+ {
188
+ logger: this.logger
189
+ },
190
+ glApi,
191
+ credential,
192
+ repositories,
193
+ dataFetchErrors,
194
+ {
195
+ search,
196
+ pageNumber,
197
+ pageSize
198
+ }
199
+ );
200
+ this.logger.debug(
201
+ `Got ${resp.totalCount} repo(s) for ${glConfig.host}`
202
+ );
203
+ return {
204
+ result: resp.totalCount ?? 0,
205
+ errors: Array.from(dataFetchErrors.values())
206
+ };
207
+ }
208
+ }
209
+ );
210
+ const repoList = Array.from(repositories.values());
211
+ const totalCount = utils$1.computeTotalCount(repoList, result.data, pageSize);
212
+ return {
213
+ repositories: repoList,
214
+ errors: Array.from(result.errors?.values() ?? []),
215
+ totalCount
216
+ };
217
+ }
218
+ async filterLocationsAccessibleFromIntegrations(locationUrls) {
219
+ const locationGitOwnerMap = utils$1.extractLocationOwnerMap(locationUrls);
220
+ const allAccessibleTokenOrgs = /* @__PURE__ */ new Set();
221
+ const allAccessibleUsernames = /* @__PURE__ */ new Set();
222
+ await utils.fetchFromAllIntegrations(
223
+ {
224
+ logger: this.logger,
225
+ cache: this.cache,
226
+ gitlabCredentialsProvider: this.gitlabCredentialsProvider
227
+ },
228
+ this.integrations,
229
+ {
230
+ dataFetcher: async (gitlab) => {
231
+ const username = (await gitlab.Users.showCurrentUser()).username;
232
+ if (username) {
233
+ allAccessibleUsernames.add(username);
234
+ }
235
+ const allGroups = await gitlab.Groups.all({
236
+ allAvailable: false
237
+ });
238
+ allGroups.map((org) => org.path)?.forEach((orgName) => allAccessibleTokenOrgs.add(orgName));
239
+ return {};
240
+ }
241
+ }
242
+ );
243
+ return locationUrls.filter((loc) => {
244
+ if (!locationGitOwnerMap.has(loc)) {
245
+ return false;
246
+ }
247
+ const owner = locationGitOwnerMap.get(loc);
248
+ return allAccessibleTokenOrgs.has(owner) || allAccessibleUsernames.has(owner);
249
+ });
250
+ }
251
+ async findImportOpenPr(logger, input) {
252
+ const glConfig = this.integrations.gitlab.byUrl(input.repoUrl)?.config;
253
+ if (!glConfig) {
254
+ throw new Error(`Could not find GL integration from ${input.repoUrl}`);
255
+ }
256
+ const gitUrl = gitUrlParse__default.default(input.repoUrl);
257
+ const owner = gitUrl.organization;
258
+ const repo = gitUrl.name;
259
+ const credentials = await this.gitlabCredentialsProvider.getAllCredentials({
260
+ host: glConfig.host
261
+ });
262
+ if (credentials.length === 0) {
263
+ throw new Error(`No credentials for GL integration`);
264
+ }
265
+ const branchName = catalogUtils.getBranchName(this.config);
266
+ for (const credential of credentials) {
267
+ const glKit = glUtils.buildGitlab(
268
+ {
269
+ logger: this.logger,
270
+ cache: this.cache
271
+ },
272
+ { credential, owner },
273
+ glConfig.baseUrl
274
+ );
275
+ try {
276
+ return await prUtils.findOpenPRForBranch(
277
+ logger,
278
+ this.config,
279
+ glKit,
280
+ owner,
281
+ repo,
282
+ branchName,
283
+ input.includeCatalogInfoContent
284
+ );
285
+ } catch (error) {
286
+ loggingUtils.logErrorIfNeeded(this.logger, "Error fetching pull requests", error);
287
+ }
288
+ }
289
+ return {};
290
+ }
291
+ async submitPrToRepo(logger, input) {
292
+ const fileName = catalogUtils.getCatalogFilename(this.config);
293
+ const errors = [];
294
+ const result = await utils.executeFunctionOnFirstSuccessfulIntegration(
295
+ {
296
+ logger: this.logger,
297
+ cache: this.cache,
298
+ config: this.config,
299
+ gitlabCredentialsProvider: this.gitlabCredentialsProvider
300
+ },
301
+ this.integrations,
302
+ {
303
+ repoUrl: input.repoUrl,
304
+ fn: async (validatedRepo, gitlab) => {
305
+ const { owner, repo, branchName } = validatedRepo;
306
+ try {
307
+ const catalogInfoFileExists = await repoUtils.fileExistsInDefaultBranch(
308
+ logger,
309
+ gitlab,
310
+ owner,
311
+ repo,
312
+ fileName,
313
+ input.defaultBranch
314
+ );
315
+ if (catalogInfoFileExists) {
316
+ return {
317
+ successful: true,
318
+ result: {
319
+ hasChanges: false
320
+ }
321
+ };
322
+ }
323
+ const existingPrForBranch = await prUtils.findOpenPRForBranch(
324
+ logger,
325
+ this.config,
326
+ gitlab,
327
+ owner,
328
+ repo,
329
+ branchName
330
+ );
331
+ const repoData = await gitlab.Projects.show(`${owner}/${repo}`);
332
+ const parentRef = await gitlab.Branches.show(
333
+ `${owner}/${repo}`,
334
+ repoData.default_branch
335
+ );
336
+ if (existingPrForBranch.prNum) {
337
+ await repoUtils.createOrUpdateFileInBranch(
338
+ gitlab,
339
+ owner,
340
+ repo,
341
+ branchName,
342
+ fileName,
343
+ input.catalogInfoContent
344
+ );
345
+ const pullRequestResponse2 = await gitlab.MergeRequests.edit(
346
+ `${owner}/${repo}`,
347
+ existingPrForBranch.prNum,
348
+ {
349
+ description: input.prBody,
350
+ title: input.prTitle,
351
+ targetBranch: repoData.default_branch
352
+ }
353
+ );
354
+ return {
355
+ successful: true,
356
+ result: {
357
+ prNumber: existingPrForBranch.prNum,
358
+ prUrl: pullRequestResponse2.web_url,
359
+ lastUpdate: pullRequestResponse2.updated_at
360
+ }
361
+ };
362
+ }
363
+ try {
364
+ await gitlab.Branches.show(`${owner}/${repo}`, branchName);
365
+ } catch (error) {
366
+ if (error.cause.response.status === 404) {
367
+ await gitlab.Branches.create(
368
+ `${owner}/${repo}`,
369
+ branchName,
370
+ parentRef.name
371
+ );
372
+ } else {
373
+ throw error;
374
+ }
375
+ }
376
+ await repoUtils.createOrUpdateFileInBranch(
377
+ gitlab,
378
+ owner,
379
+ repo,
380
+ branchName,
381
+ fileName,
382
+ input.catalogInfoContent
383
+ );
384
+ const pullRequestResponse = await gitlab.MergeRequests.create(
385
+ `${owner}/${repo}`,
386
+ branchName,
387
+ repoData.default_branch,
388
+ input.prTitle,
389
+ {
390
+ description: input.prBody
391
+ }
392
+ );
393
+ return {
394
+ successful: true,
395
+ result: {
396
+ prNumber: pullRequestResponse.iid,
397
+ prUrl: pullRequestResponse.web_url,
398
+ lastUpdate: pullRequestResponse.updated_at,
399
+ hasChanges: true
400
+ }
401
+ };
402
+ } catch (e) {
403
+ loggingUtils.logErrorIfNeeded(
404
+ this.logger,
405
+ `Couldn't create PR in ${input.repoUrl}`,
406
+ e
407
+ );
408
+ errors.push(e.message);
409
+ return { successful: false };
410
+ }
411
+ }
412
+ }
413
+ );
414
+ if (result) {
415
+ return result;
416
+ }
417
+ logger.warn(
418
+ `Tried all possible Gitlab credentials, but could not create PR in ${input.repoUrl}. Please try again later...`
419
+ );
420
+ return {
421
+ errors
422
+ };
423
+ }
424
+ async hasFileInRepo(input) {
425
+ const fileExists = await utils.executeFunctionOnFirstSuccessfulIntegration(
426
+ {
427
+ logger: this.logger,
428
+ cache: this.cache,
429
+ config: this.config,
430
+ gitlabCredentialsProvider: this.gitlabCredentialsProvider
431
+ },
432
+ this.integrations,
433
+ {
434
+ repoUrl: input.repoUrl,
435
+ fn: async (validatedRepo, gitlab) => {
436
+ const { owner, repo } = validatedRepo;
437
+ const exists = await repoUtils.fileExistsInDefaultBranch(
438
+ this.logger,
439
+ gitlab,
440
+ owner,
441
+ repo,
442
+ input.fileName,
443
+ input.defaultBranch
444
+ );
445
+ if (exists === undefined) {
446
+ return { successful: false };
447
+ }
448
+ return { successful: true, result: exists };
449
+ }
450
+ }
451
+ );
452
+ if (fileExists === undefined) {
453
+ throw new Error(
454
+ `Could not determine if repo at ${input.repoUrl} already has a file named ${input.fileName} in its default branch (${input.defaultBranch})`
455
+ );
456
+ }
457
+ return fileExists;
458
+ }
459
+ async closeImportPR(logger, input) {
460
+ await utils.executeFunctionOnFirstSuccessfulIntegration(
461
+ {
462
+ logger: this.logger,
463
+ cache: this.cache,
464
+ config: this.config,
465
+ gitlabCredentialsProvider: this.gitlabCredentialsProvider
466
+ },
467
+ this.integrations,
468
+ {
469
+ repoUrl: input.repoUrl,
470
+ fn: async (validatedRepo, gitlab) => {
471
+ const { owner, repo, branchName } = validatedRepo;
472
+ try {
473
+ const existingPrForBranch = await prUtils.findOpenPRForBranch(
474
+ logger,
475
+ this.config,
476
+ gitlab,
477
+ owner,
478
+ repo,
479
+ branchName
480
+ );
481
+ if (existingPrForBranch.prNum) {
482
+ await prUtils.closePRWithComment(
483
+ gitlab,
484
+ owner,
485
+ repo,
486
+ existingPrForBranch.prNum,
487
+ input.comment
488
+ );
489
+ }
490
+ return { successful: true };
491
+ } catch (e) {
492
+ loggingUtils.logErrorIfNeeded(
493
+ this.logger,
494
+ `Couldn't close PR in ${input.repoUrl}`,
495
+ e
496
+ );
497
+ return { successful: false };
498
+ }
499
+ }
500
+ }
501
+ );
502
+ }
503
+ async deleteImportBranch(input) {
504
+ await utils.executeFunctionOnFirstSuccessfulIntegration(
505
+ {
506
+ logger: this.logger,
507
+ cache: this.cache,
508
+ config: this.config,
509
+ gitlabCredentialsProvider: this.gitlabCredentialsProvider
510
+ },
511
+ this.integrations,
512
+ {
513
+ repoUrl: input.repoUrl,
514
+ fn: async (validatedRepo, gitlab) => {
515
+ const { owner, repo, branchName } = validatedRepo;
516
+ try {
517
+ await gitlab.Branches.remove(`${owner}/${repo}`, branchName);
518
+ return { successful: true };
519
+ } catch (e) {
520
+ loggingUtils.logErrorIfNeeded(
521
+ this.logger,
522
+ `Couldn't close import PR and/or delete import branch in ${input.repoUrl}`,
523
+ e
524
+ );
525
+ return { successful: false };
526
+ }
527
+ }
528
+ }
529
+ );
530
+ }
531
+ async isRepoEmpty(input) {
532
+ return await utils.executeFunctionOnFirstSuccessfulIntegration(
533
+ {
534
+ logger: this.logger,
535
+ cache: this.cache,
536
+ config: this.config,
537
+ gitlabCredentialsProvider: this.gitlabCredentialsProvider
538
+ },
539
+ this.integrations,
540
+ {
541
+ repoUrl: input.repoUrl,
542
+ fn: async (validatedRepo, gitlab) => {
543
+ const { owner, repo } = validatedRepo;
544
+ const resp = await gitlab.Repositories.allContributors(
545
+ `${owner}/${repo}`,
546
+ {
547
+ showExpanded: true
548
+ }
549
+ );
550
+ return { successful: true, result: resp?.data?.length < 1 };
551
+ }
552
+ }
553
+ );
554
+ }
555
+ async getPullRequest(repoUrl, pullRequestNumber) {
556
+ const glConfig = this.integrations.gitlab.byUrl(repoUrl)?.config;
557
+ if (!glConfig) {
558
+ this.logger.error(
559
+ `No Gitlab integration config found for repo ${repoUrl}`
560
+ );
561
+ return {};
562
+ }
563
+ const gitUrl = gitUrlParse__default.default(repoUrl);
564
+ const owner = gitUrl.owner;
565
+ const repo = gitUrl.name;
566
+ const credentials = await this.gitlabCredentialsProvider.getAllCredentials({
567
+ host: glConfig.host
568
+ });
569
+ if (credentials.length === 0) {
570
+ this.logger.error(`No credentials for GL integration`);
571
+ return {};
572
+ }
573
+ for (const credential of credentials) {
574
+ const glKit = glUtils.buildGitlab(
575
+ {
576
+ logger: this.logger,
577
+ cache: this.cache
578
+ },
579
+ { credential, owner },
580
+ glConfig.baseUrl
581
+ );
582
+ try {
583
+ const pr = await glKit.MergeRequests.show(
584
+ `${owner}/${repo}`,
585
+ pullRequestNumber
586
+ );
587
+ return {
588
+ title: pr.title,
589
+ body: pr.description || void 0,
590
+ merged: pr.state === "merged",
591
+ lastUpdated: pr.updated_at,
592
+ prSha: pr.sha,
593
+ prBranch: pr.source_branch
594
+ };
595
+ } catch (error) {
596
+ this.logger.error(
597
+ `Error fetching pull request ${pullRequestNumber} from ${repoUrl}`,
598
+ error
599
+ );
600
+ }
601
+ }
602
+ return {};
603
+ }
604
+ async getCatalogInfoFile(logger, input) {
605
+ const glConfig = this.integrations.gitlab.byUrl(input.repoUrl)?.config;
606
+ if (!glConfig) {
607
+ logger.error(
608
+ `No Gitlab integration config found for repo ${input.repoUrl}`
609
+ );
610
+ return undefined;
611
+ }
612
+ const gitUrl = gitUrlParse__default.default(input.repoUrl);
613
+ const owner = gitUrl.owner;
614
+ const repo = gitUrl.name;
615
+ const credentials = await this.gitlabCredentialsProvider.getAllCredentials({
616
+ host: glConfig.host
617
+ });
618
+ if (credentials.length === 0) {
619
+ logger.error(`No credentials for GL integration`);
620
+ return undefined;
621
+ }
622
+ for (const credential of credentials) {
623
+ const glKit = glUtils.buildGitlab(
624
+ {
625
+ logger: this.logger,
626
+ cache: this.cache
627
+ },
628
+ { credential, owner },
629
+ glConfig.baseUrl
630
+ );
631
+ try {
632
+ const file = await glKit.RepositoryFiles.show(
633
+ `${owner}/${repo}`,
634
+ catalogUtils.getCatalogFilename(this.config),
635
+ input.prHeadSha
636
+ );
637
+ if (file) {
638
+ const content = Buffer.from(file.content, "base64").toString("utf-8");
639
+ return content;
640
+ }
641
+ } catch (error) {
642
+ if (error.cause?.response?.status === 404) {
643
+ logger.warn(
644
+ `catalog-info.yaml not found in PR ${input.prNumber} of ${input.repoUrl}`
645
+ );
646
+ return undefined;
647
+ }
648
+ logger.error(
649
+ `Error fetching catalog-info.yaml from PR ${input.prNumber} of ${input.repoUrl}`,
650
+ error
651
+ );
652
+ return undefined;
653
+ }
654
+ }
655
+ return undefined;
656
+ }
657
+ }
658
+
659
+ exports.GitlabApiService = GitlabApiService;
660
+ //# sourceMappingURL=gitlabApiService.cjs.js.map