@backstage/plugin-catalog-backend-module-gitlab 0.3.15 → 0.3.16

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,57 @@
1
1
  # @backstage/plugin-catalog-backend-module-gitlab
2
2
 
3
+ ## 0.3.16
4
+
5
+ ### Patch Changes
6
+
7
+ - a70377d: Added events support for `GitlabDiscoveryEntityProvider` and `GitlabOrgDiscoveryEntityProvider`.
8
+ - Updated dependencies
9
+ - @backstage/plugin-catalog-node@1.12.0
10
+ - @backstage/catalog-model@1.5.0
11
+ - @backstage/backend-common@0.22.0
12
+ - @backstage/backend-plugin-api@0.6.18
13
+ - @backstage/backend-tasks@0.5.23
14
+ - @backstage/plugin-events-node@0.3.4
15
+ - @backstage/integration@1.11.0
16
+ - @backstage/plugin-catalog-common@1.0.23
17
+
18
+ ## 0.3.15-next.4
19
+
20
+ ### Patch Changes
21
+
22
+ - Updated dependencies
23
+ - @backstage/plugin-catalog-node@1.12.0-next.2
24
+ - @backstage/backend-common@0.22.0-next.2
25
+ - @backstage/plugin-events-node@0.3.4-next.2
26
+ - @backstage/integration@1.11.0-next.0
27
+
28
+ ## 0.3.15-next.3
29
+
30
+ ### Patch Changes
31
+
32
+ - Updated dependencies
33
+ - @backstage/backend-common@0.22.0-next.1
34
+ - @backstage/backend-tasks@0.5.23-next.1
35
+ - @backstage/plugin-events-node@0.3.4-next.1
36
+ - @backstage/plugin-catalog-node@1.11.2-next.1
37
+ - @backstage/backend-plugin-api@0.6.18-next.1
38
+
39
+ ## 0.3.15-next.2
40
+
41
+ ### Patch Changes
42
+
43
+ - a70377d: Added events support for `GitlabDiscoveryEntityProvider` and `GitlabOrgDiscoveryEntityProvider`.
44
+ - Updated dependencies
45
+ - @backstage/catalog-model@1.5.0-next.0
46
+ - @backstage/backend-common@0.21.8-next.0
47
+ - @backstage/backend-plugin-api@0.6.18-next.0
48
+ - @backstage/plugin-catalog-common@1.0.23-next.0
49
+ - @backstage/plugin-catalog-node@1.11.2-next.0
50
+ - @backstage/backend-tasks@0.5.23-next.0
51
+ - @backstage/config@1.2.0
52
+ - @backstage/integration@1.10.0
53
+ - @backstage/plugin-events-node@0.3.4-next.0
54
+
3
55
  ## 0.3.15
4
56
 
5
57
  ### Patch Changes
@@ -385,8 +437,8 @@
385
437
 
386
438
  ref:
387
439
 
388
- https://docs.gitlab.com/ee/user/enterprise_user/#get-users-email-addresses-through-the-api
389
- https://docs.gitlab.com/ee/api/members.html#limitations
440
+ <https://docs.gitlab.com/ee/user/enterprise_user/#get-users-email-addresses-through-the-api>
441
+ <https://docs.gitlab.com/ee/api/members.html#limitations>
390
442
 
391
443
  - 890e3b5ad4: Make sure to include the error message when ingestion fails
392
444
  - 0b55f773a7: Removed some unused dependencies
@@ -417,8 +469,8 @@
417
469
 
418
470
  ref:
419
471
 
420
- https://docs.gitlab.com/ee/user/enterprise_user/#get-users-email-addresses-through-the-api
421
- https://docs.gitlab.com/ee/api/members.html#limitations
472
+ <https://docs.gitlab.com/ee/user/enterprise_user/#get-users-email-addresses-through-the-api>
473
+ <https://docs.gitlab.com/ee/api/members.html#limitations>
422
474
 
423
475
  - 0b55f773a7: Removed some unused dependencies
424
476
  - Updated dependencies
@@ -1211,7 +1263,7 @@
1211
1263
  - 81cedb5033: `GitlabDiscoveryEntityProvider`: Add option to configure schedule via `app-config.yaml` instead of in code.
1212
1264
 
1213
1265
  Please find how to configure the schedule at the config at
1214
- https://backstage.io/docs/integrations/gitlab/discovery
1266
+ <https://backstage.io/docs/integrations/gitlab/discovery>
1215
1267
 
1216
1268
  - 4c9f7847e4: Updated dependency `msw` to `^0.48.0` while moving it to be a dev dependency.
1217
1269
  - Updated dependencies
@@ -1250,7 +1302,7 @@
1250
1302
  - 81cedb5033: `GitlabDiscoveryEntityProvider`: Add option to configure schedule via `app-config.yaml` instead of in code.
1251
1303
 
1252
1304
  Please find how to configure the schedule at the config at
1253
- https://backstage.io/docs/integrations/gitlab/discovery
1305
+ <https://backstage.io/docs/integrations/gitlab/discovery>
1254
1306
 
1255
1307
  - Updated dependencies
1256
1308
  - @backstage/backend-common@0.16.0-next.0
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/plugin-catalog-backend-module-gitlab",
3
- "version": "0.3.15",
3
+ "version": "0.3.16",
4
4
  "main": "../dist/alpha.cjs.js",
5
5
  "types": "../dist/alpha.d.ts"
6
6
  }
package/dist/alpha.cjs.js CHANGED
@@ -4,14 +4,16 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var backendPluginApi = require('@backstage/backend-plugin-api');
6
6
  var alpha = require('@backstage/plugin-catalog-node/alpha');
7
- var GitlabDiscoveryEntityProvider = require('./cjs/GitlabDiscoveryEntityProvider-CfW32ioU.cjs.js');
7
+ var pluginEventsNode = require('@backstage/plugin-events-node');
8
+ var GitlabDiscoveryEntityProvider = require('./cjs/GitlabDiscoveryEntityProvider-OBHXu4pm.cjs.js');
8
9
  require('@backstage/catalog-model');
9
10
  require('@backstage/integration');
10
11
  require('lodash');
11
12
  require('uuid');
12
- require('node-fetch');
13
13
  require('@backstage/backend-tasks');
14
+ require('node-fetch');
14
15
  require('@backstage/plugin-catalog-node');
16
+ require('path');
15
17
 
16
18
  const catalogModuleGitlabDiscoveryEntityProvider = backendPluginApi.createBackendModule({
17
19
  pluginId: "catalog",
@@ -22,15 +24,16 @@ const catalogModuleGitlabDiscoveryEntityProvider = backendPluginApi.createBacken
22
24
  config: backendPluginApi.coreServices.rootConfig,
23
25
  catalog: alpha.catalogProcessingExtensionPoint,
24
26
  logger: backendPluginApi.coreServices.logger,
25
- scheduler: backendPluginApi.coreServices.scheduler
27
+ scheduler: backendPluginApi.coreServices.scheduler,
28
+ events: pluginEventsNode.eventsServiceRef
26
29
  },
27
- async init({ config, catalog, logger, scheduler }) {
28
- catalog.addEntityProvider(
29
- GitlabDiscoveryEntityProvider.GitlabDiscoveryEntityProvider.fromConfig(config, {
30
- logger,
31
- scheduler
32
- })
33
- );
30
+ async init({ config, catalog, logger, scheduler, events }) {
31
+ const gitlabDiscoveryEntityProvider = GitlabDiscoveryEntityProvider.GitlabDiscoveryEntityProvider.fromConfig(config, {
32
+ logger,
33
+ events,
34
+ scheduler
35
+ });
36
+ catalog.addEntityProvider(gitlabDiscoveryEntityProvider);
34
37
  }
35
38
  });
36
39
  }
@@ -1 +1 @@
1
- {"version":3,"file":"alpha.cjs.js","sources":["../src/module/catalogModuleGitlabDiscoveryEntityProvider.ts"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n coreServices,\n createBackendModule,\n} from '@backstage/backend-plugin-api';\nimport { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha';\nimport { GitlabDiscoveryEntityProvider } from '../providers';\n\n/**\n * Registers the GitlabDiscoveryEntityProvider with the catalog processing extension point.\n *\n * @alpha\n */\nexport const catalogModuleGitlabDiscoveryEntityProvider = createBackendModule({\n pluginId: 'catalog',\n moduleId: 'gitlab-discovery-entity-provider',\n register(env) {\n env.registerInit({\n deps: {\n config: coreServices.rootConfig,\n catalog: catalogProcessingExtensionPoint,\n logger: coreServices.logger,\n scheduler: coreServices.scheduler,\n },\n async init({ config, catalog, logger, scheduler }) {\n catalog.addEntityProvider(\n GitlabDiscoveryEntityProvider.fromConfig(config, {\n logger,\n scheduler,\n }),\n );\n },\n });\n },\n});\n"],"names":["createBackendModule","coreServices","catalogProcessingExtensionPoint","GitlabDiscoveryEntityProvider"],"mappings":";;;;;;;;;;;;;;;AA4BO,MAAM,6CAA6CA,oCAAoB,CAAA;AAAA,EAC5E,QAAU,EAAA,SAAA;AAAA,EACV,QAAU,EAAA,kCAAA;AAAA,EACV,SAAS,GAAK,EAAA;AACZ,IAAA,GAAA,CAAI,YAAa,CAAA;AAAA,MACf,IAAM,EAAA;AAAA,QACJ,QAAQC,6BAAa,CAAA,UAAA;AAAA,QACrB,OAAS,EAAAC,qCAAA;AAAA,QACT,QAAQD,6BAAa,CAAA,MAAA;AAAA,QACrB,WAAWA,6BAAa,CAAA,SAAA;AAAA,OAC1B;AAAA,MACA,MAAM,IAAK,CAAA,EAAE,QAAQ,OAAS,EAAA,MAAA,EAAQ,WAAa,EAAA;AACjD,QAAQ,OAAA,CAAA,iBAAA;AAAA,UACNE,2DAAA,CAA8B,WAAW,MAAQ,EAAA;AAAA,YAC/C,MAAA;AAAA,YACA,SAAA;AAAA,WACD,CAAA;AAAA,SACH,CAAA;AAAA,OACF;AAAA,KACD,CAAA,CAAA;AAAA,GACH;AACF,CAAC;;;;"}
1
+ {"version":3,"file":"alpha.cjs.js","sources":["../src/module/catalogModuleGitlabDiscoveryEntityProvider.ts"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n coreServices,\n createBackendModule,\n} from '@backstage/backend-plugin-api';\nimport { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha';\nimport { eventsServiceRef } from '@backstage/plugin-events-node';\nimport { GitlabDiscoveryEntityProvider } from '../providers';\n\n/**\n * Registers the GitlabDiscoveryEntityProvider with the catalog processing extension point.\n *\n * @alpha\n */\n\nexport const catalogModuleGitlabDiscoveryEntityProvider = createBackendModule({\n pluginId: 'catalog',\n moduleId: 'gitlab-discovery-entity-provider',\n register(env) {\n env.registerInit({\n deps: {\n config: coreServices.rootConfig,\n catalog: catalogProcessingExtensionPoint,\n logger: coreServices.logger,\n scheduler: coreServices.scheduler,\n events: eventsServiceRef,\n },\n async init({ config, catalog, logger, scheduler, events }) {\n const gitlabDiscoveryEntityProvider =\n GitlabDiscoveryEntityProvider.fromConfig(config, {\n logger,\n events,\n scheduler,\n });\n catalog.addEntityProvider(gitlabDiscoveryEntityProvider);\n },\n });\n },\n});\n"],"names":["createBackendModule","coreServices","catalogProcessingExtensionPoint","eventsServiceRef","GitlabDiscoveryEntityProvider"],"mappings":";;;;;;;;;;;;;;;;;AA8BO,MAAM,6CAA6CA,oCAAoB,CAAA;AAAA,EAC5E,QAAU,EAAA,SAAA;AAAA,EACV,QAAU,EAAA,kCAAA;AAAA,EACV,SAAS,GAAK,EAAA;AACZ,IAAA,GAAA,CAAI,YAAa,CAAA;AAAA,MACf,IAAM,EAAA;AAAA,QACJ,QAAQC,6BAAa,CAAA,UAAA;AAAA,QACrB,OAAS,EAAAC,qCAAA;AAAA,QACT,QAAQD,6BAAa,CAAA,MAAA;AAAA,QACrB,WAAWA,6BAAa,CAAA,SAAA;AAAA,QACxB,MAAQ,EAAAE,iCAAA;AAAA,OACV;AAAA,MACA,MAAM,KAAK,EAAE,MAAA,EAAQ,SAAS,MAAQ,EAAA,SAAA,EAAW,QAAU,EAAA;AACzD,QAAM,MAAA,6BAAA,GACJC,2DAA8B,CAAA,UAAA,CAAW,MAAQ,EAAA;AAAA,UAC/C,MAAA;AAAA,UACA,MAAA;AAAA,UACA,SAAA;AAAA,SACD,CAAA,CAAA;AACH,QAAA,OAAA,CAAQ,kBAAkB,6BAA6B,CAAA,CAAA;AAAA,OACzD;AAAA,KACD,CAAA,CAAA;AAAA,GACH;AACF,CAAC;;;;"}
@@ -3,8 +3,9 @@
3
3
  var integration = require('@backstage/integration');
4
4
  var pluginCatalogNode = require('@backstage/plugin-catalog-node');
5
5
  var uuid = require('uuid');
6
- var fetch = require('node-fetch');
7
6
  var backendTasks = require('@backstage/backend-tasks');
7
+ var fetch = require('node-fetch');
8
+ var path = require('path');
8
9
 
9
10
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
10
11
 
@@ -28,6 +29,55 @@ function _interopNamespaceCompat(e) {
28
29
 
29
30
  var uuid__namespace = /*#__PURE__*/_interopNamespaceCompat(uuid);
30
31
  var fetch__default = /*#__PURE__*/_interopDefaultCompat(fetch);
32
+ var path__namespace = /*#__PURE__*/_interopNamespaceCompat(path);
33
+
34
+ function readGitlabConfig(id, config) {
35
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
36
+ const group = (_a = config.getOptionalString("group")) != null ? _a : "";
37
+ const host = config.getString("host");
38
+ const branch = config.getOptionalString("branch");
39
+ const fallbackBranch = (_b = config.getOptionalString("fallbackBranch")) != null ? _b : "master";
40
+ const catalogFile = (_c = config.getOptionalString("entityFilename")) != null ? _c : "catalog-info.yaml";
41
+ const projectPattern = new RegExp(
42
+ (_d = config.getOptionalString("projectPattern")) != null ? _d : /[\s\S]*/
43
+ );
44
+ const userPattern = new RegExp(
45
+ (_e = config.getOptionalString("userPattern")) != null ? _e : /[\s\S]*/
46
+ );
47
+ const groupPattern = new RegExp(
48
+ (_f = config.getOptionalString("groupPattern")) != null ? _f : /[\s\S]*/
49
+ );
50
+ const orgEnabled = (_g = config.getOptionalBoolean("orgEnabled")) != null ? _g : false;
51
+ const allowInherited = (_h = config.getOptionalBoolean("allowInherited")) != null ? _h : false;
52
+ const skipForkedRepos = (_i = config.getOptionalBoolean("skipForkedRepos")) != null ? _i : false;
53
+ const schedule = config.has("schedule") ? backendTasks.readTaskScheduleDefinitionFromConfig(config.getConfig("schedule")) : void 0;
54
+ return {
55
+ id,
56
+ group,
57
+ branch,
58
+ fallbackBranch,
59
+ host,
60
+ catalogFile,
61
+ projectPattern,
62
+ userPattern,
63
+ groupPattern,
64
+ schedule,
65
+ orgEnabled,
66
+ allowInherited,
67
+ skipForkedRepos
68
+ };
69
+ }
70
+ function readGitlabConfigs(config) {
71
+ const configs = [];
72
+ const providerConfigs = config.getOptionalConfig("catalog.providers.gitlab");
73
+ if (!providerConfigs) {
74
+ return configs;
75
+ }
76
+ for (const id of providerConfigs.keys()) {
77
+ configs.push(readGitlabConfig(id, providerConfigs.getConfig(id)));
78
+ }
79
+ return configs;
80
+ }
31
81
 
32
82
  var __defProp$1 = Object.defineProperty;
33
83
  var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
@@ -60,6 +110,21 @@ class GitLabClient {
60
110
  }
61
111
  return this.pagedRequest(`/projects`, options);
62
112
  }
113
+ async getProjectById(projectId, options) {
114
+ const response = await this.nonPagedRequest(
115
+ `/projects/${projectId}`,
116
+ options
117
+ );
118
+ return response;
119
+ }
120
+ async getGroupById(groupId, options) {
121
+ const response = await this.nonPagedRequest(`/groups/${groupId}`, options);
122
+ return response;
123
+ }
124
+ async getUserById(userId, options) {
125
+ const response = await this.nonPagedRequest(`/users/${userId}`, options);
126
+ return response;
127
+ }
63
128
  async listUsers(options) {
64
129
  return this.pagedRequest(`/users?`, {
65
130
  ...options,
@@ -279,8 +344,11 @@ class GitLabClient {
279
344
  async pagedRequest(endpoint, options) {
280
345
  const request = new URL(`${this.config.apiBaseUrl}${endpoint}`);
281
346
  for (const key in options) {
282
- if (options[key] !== void 0 && options[key] !== "") {
283
- request.searchParams.append(key, options[key].toString());
347
+ if (options.hasOwnProperty(key)) {
348
+ const value = options[key];
349
+ if (value !== void 0 && value !== "") {
350
+ request.searchParams.append(key, value.toString());
351
+ }
284
352
  }
285
353
  }
286
354
  this.logger.debug(`Fetching: ${request.toString()}`);
@@ -301,6 +369,27 @@ class GitLabClient {
301
369
  };
302
370
  });
303
371
  }
372
+ async nonPagedRequest(endpoint, options) {
373
+ const request = new URL(`${this.config.apiBaseUrl}${endpoint}`);
374
+ for (const key in options) {
375
+ if (options.hasOwnProperty(key)) {
376
+ const value = options[key];
377
+ if (value !== void 0 && value !== "") {
378
+ request.searchParams.append(key, value.toString());
379
+ }
380
+ }
381
+ }
382
+ const response = await fetch__default.default(
383
+ request.toString(),
384
+ integration.getGitLabRequestOptions(this.config)
385
+ );
386
+ if (!response.ok) {
387
+ throw new Error(
388
+ `Unexpected response when fetching ${request.toString()}. Expected 200 but got ${response.status} - ${response.statusText}`
389
+ );
390
+ }
391
+ return response.json();
392
+ }
304
393
  }
305
394
  async function* paginated(request, options) {
306
395
  let res;
@@ -313,71 +402,38 @@ async function* paginated(request, options) {
313
402
  } while (res.nextPage);
314
403
  }
315
404
 
316
- function readGitlabConfig(id, config) {
317
- var _a, _b, _c, _d, _e, _f, _g, _h;
318
- const group = (_a = config.getOptionalString("group")) != null ? _a : "";
319
- const host = config.getString("host");
320
- const branch = config.getOptionalString("branch");
321
- const fallbackBranch = (_b = config.getOptionalString("fallbackBranch")) != null ? _b : "master";
322
- const catalogFile = (_c = config.getOptionalString("entityFilename")) != null ? _c : "catalog-info.yaml";
323
- const projectPattern = new RegExp(
324
- (_d = config.getOptionalString("projectPattern")) != null ? _d : /[\s\S]*/
325
- );
326
- const userPattern = new RegExp(
327
- (_e = config.getOptionalString("userPattern")) != null ? _e : /[\s\S]*/
328
- );
329
- const groupPattern = new RegExp(
330
- (_f = config.getOptionalString("groupPattern")) != null ? _f : /[\s\S]*/
331
- );
332
- const orgEnabled = (_g = config.getOptionalBoolean("orgEnabled")) != null ? _g : false;
333
- const skipForkedRepos = (_h = config.getOptionalBoolean("skipForkedRepos")) != null ? _h : false;
334
- const schedule = config.has("schedule") ? backendTasks.readTaskScheduleDefinitionFromConfig(config.getConfig("schedule")) : void 0;
335
- return {
336
- id,
337
- group,
338
- branch,
339
- fallbackBranch,
340
- host,
341
- catalogFile,
342
- projectPattern,
343
- userPattern,
344
- groupPattern,
345
- schedule,
346
- orgEnabled,
347
- skipForkedRepos
348
- };
349
- }
350
- function readGitlabConfigs(config) {
351
- const configs = [];
352
- const providerConfigs = config.getOptionalConfig("catalog.providers.gitlab");
353
- if (!providerConfigs) {
354
- return configs;
355
- }
356
- for (const id of providerConfigs.keys()) {
357
- configs.push(readGitlabConfig(id, providerConfigs.getConfig(id)));
358
- }
359
- return configs;
360
- }
361
-
362
405
  var __defProp = Object.defineProperty;
363
406
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
364
407
  var __publicField = (obj, key, value) => {
365
408
  __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
366
409
  return value;
367
410
  };
411
+ const TOPIC_REPO_PUSH = "gitlab.push";
368
412
  class GitlabDiscoveryEntityProvider {
413
+ /**
414
+ * Constructs a GitlabDiscoveryEntityProvider instance.
415
+ *
416
+ * @param options - Configuration options including config, integration, logger, and taskRunner.
417
+ */
369
418
  constructor(options) {
370
419
  __publicField(this, "config");
371
420
  __publicField(this, "integration");
372
421
  __publicField(this, "logger");
373
422
  __publicField(this, "scheduleFn");
374
423
  __publicField(this, "connection");
424
+ __publicField(this, "events");
425
+ __publicField(this, "gitLabClient");
375
426
  this.config = options.config;
376
427
  this.integration = options.integration;
377
428
  this.logger = options.logger.child({
378
429
  target: this.getProviderName()
379
430
  });
380
431
  this.scheduleFn = this.createScheduleFn(options.taskRunner);
432
+ this.events = options.events;
433
+ this.gitLabClient = new GitLabClient({
434
+ config: this.integration.config,
435
+ logger: this.logger
436
+ });
381
437
  }
382
438
  static fromConfig(config, options) {
383
439
  if (!options.schedule && !options.scheduler) {
@@ -417,7 +473,25 @@ class GitlabDiscoveryEntityProvider {
417
473
  async connect(connection) {
418
474
  this.connection = connection;
419
475
  await this.scheduleFn();
476
+ if (this.events) {
477
+ await this.events.subscribe({
478
+ id: this.getProviderName(),
479
+ topics: [TOPIC_REPO_PUSH],
480
+ onEvent: async (params) => {
481
+ if (params.topic !== TOPIC_REPO_PUSH) {
482
+ return;
483
+ }
484
+ await this.onRepoPush(params.eventPayload);
485
+ }
486
+ });
487
+ }
420
488
  }
489
+ /**
490
+ * Creates a scheduled task runner for refreshing the entity provider.
491
+ *
492
+ * @param taskRunner - The task runner instance.
493
+ * @returns The scheduled function.
494
+ */
421
495
  createScheduleFn(taskRunner) {
422
496
  return async () => {
423
497
  const taskId = `${this.getProviderName()}:refresh`;
@@ -441,19 +515,19 @@ class GitlabDiscoveryEntityProvider {
441
515
  });
442
516
  };
443
517
  }
518
+ /**
519
+ * Performs a full scan on the GitLab instance searching for locations to be ingested
520
+ *
521
+ * @param logger - The logger instance for logging.
522
+ */
444
523
  async refresh(logger) {
445
- var _a, _b, _c, _d;
446
524
  if (!this.connection) {
447
525
  throw new Error(
448
526
  `Gitlab discovery connection not initialized for ${this.getProviderName()}`
449
527
  );
450
528
  }
451
- const client = new GitLabClient({
452
- config: this.integration.config,
453
- logger
454
- });
455
529
  const projects = paginated(
456
- (options) => client.listProjects(options),
530
+ (options) => this.gitLabClient.listProjects(options),
457
531
  {
458
532
  archived: false,
459
533
  group: this.config.group,
@@ -466,27 +540,15 @@ class GitlabDiscoveryEntityProvider {
466
540
  matches: []
467
541
  };
468
542
  for await (const project of projects) {
469
- if (!this.config.projectPattern.test((_a = project.path_with_namespace) != null ? _a : "")) {
470
- continue;
471
- }
472
- res.scanned++;
473
- if (this.config.skipForkedRepos && project.hasOwnProperty("forked_from_project")) {
474
- continue;
475
- }
476
- if (!this.config.branch && this.config.fallbackBranch === "*" && project.default_branch === void 0) {
477
- continue;
478
- }
479
- const project_branch = (_c = (_b = this.config.branch) != null ? _b : project.default_branch) != null ? _c : this.config.fallbackBranch;
480
- const projectHasFile = await client.hasFile(
481
- (_d = project.path_with_namespace) != null ? _d : "",
482
- project_branch,
483
- this.config.catalogFile
484
- );
485
- if (projectHasFile) {
543
+ if (await this.shouldProcessProject(project, this.gitLabClient)) {
544
+ res.scanned++;
486
545
  res.matches.push(project);
487
546
  }
488
547
  }
489
548
  const locations = res.matches.map((p) => this.createLocationSpec(p));
549
+ logger.info(
550
+ `Processed ${locations.length} from scanned ${res.scanned} projects.`
551
+ );
490
552
  await this.connection.applyMutation({
491
553
  type: "full",
492
554
  entities: locations.map((location) => ({
@@ -504,10 +566,184 @@ class GitlabDiscoveryEntityProvider {
504
566
  presence: "optional"
505
567
  };
506
568
  }
569
+ /**
570
+ * Handles the "gitlab.push" event.
571
+ *
572
+ * @param event - The push event payload.
573
+ */
574
+ async onRepoPush(event) {
575
+ var _a, _b;
576
+ if (!this.connection) {
577
+ throw new Error(
578
+ `Gitlab discovery connection not initialized for ${this.getProviderName()}`
579
+ );
580
+ }
581
+ this.logger.info(
582
+ `Received push event for ${event.project.path_with_namespace}`
583
+ );
584
+ const project = await this.gitLabClient.getProjectById(event.project_id);
585
+ if (!project) {
586
+ this.logger.debug(
587
+ `Ignoring push event for ${event.project.path_with_namespace}`
588
+ );
589
+ return;
590
+ }
591
+ if (!await this.shouldProcessProject(project, this.gitLabClient)) {
592
+ this.logger.debug(`Skipping event ${event.project.path_with_namespace}`);
593
+ return;
594
+ }
595
+ const added = this.getFilesMatchingConfig(
596
+ event,
597
+ "added",
598
+ this.config.catalogFile
599
+ );
600
+ const removed = this.getFilesMatchingConfig(
601
+ event,
602
+ "removed",
603
+ this.config.catalogFile
604
+ );
605
+ const modified = this.getFilesMatchingConfig(
606
+ event,
607
+ "modified",
608
+ this.config.catalogFile
609
+ );
610
+ const addedEntities = this.createLocationSpecCommitedFiles(
611
+ event.project,
612
+ added
613
+ );
614
+ const removedEntities = this.createLocationSpecCommitedFiles(
615
+ event.project,
616
+ removed
617
+ );
618
+ if (addedEntities.length > 0 || removedEntities.length > 0) {
619
+ await this.connection.applyMutation({
620
+ type: "delta",
621
+ added: this.toDeferredEntities(
622
+ addedEntities.map((entity) => entity.target)
623
+ ),
624
+ removed: this.toDeferredEntities(
625
+ removedEntities.map((entity) => entity.target)
626
+ )
627
+ });
628
+ }
629
+ if (modified.length > 0) {
630
+ const projectBranch = (_b = (_a = this.config.branch) != null ? _a : event.project.default_branch) != null ? _b : this.config.fallbackBranch;
631
+ await this.connection.refresh({
632
+ keys: [
633
+ ...modified.map(
634
+ (filePath) => `url:${event.project.web_url}/-/tree/${projectBranch}/${filePath}`
635
+ ),
636
+ ...modified.map(
637
+ (filePath) => `url:${event.project.web_url}/-/blob/${projectBranch}/${filePath}`
638
+ )
639
+ ]
640
+ });
641
+ }
642
+ this.logger.info(
643
+ `Processed GitLab push event from ${event.project.web_url}: added ${added.length} - removed ${removed.length} - modified ${modified.length}`
644
+ );
645
+ }
646
+ /**
647
+ * Gets files matching the specified commit action and catalog file name.
648
+ *
649
+ * @param event - The push event payload.
650
+ * @param action - The action type ('added', 'removed', or 'modified').
651
+ * @param catalogFile - The catalog file name.
652
+ * @returns An array of file paths.
653
+ */
654
+ getFilesMatchingConfig(event, action, catalogFile) {
655
+ if (!event.commits) {
656
+ return [];
657
+ }
658
+ const matchingFiles = event.commits.flatMap(
659
+ (element) => element[action].filter(
660
+ (file) => path__namespace.basename(file) === catalogFile
661
+ )
662
+ );
663
+ if (matchingFiles.length === 0) {
664
+ this.logger.debug(
665
+ `No files matching '${catalogFile}' found in the commits.`
666
+ );
667
+ }
668
+ return matchingFiles;
669
+ }
670
+ /**
671
+ * Creates Backstage location specs for committed files.
672
+ *
673
+ * @param project - The GitLab project information.
674
+ * @param addedFiles - The array of added file paths.
675
+ * @returns An array of location specs.
676
+ */
677
+ createLocationSpecCommitedFiles(project, addedFiles) {
678
+ var _a, _b;
679
+ const projectBranch = (_b = (_a = this.config.branch) != null ? _a : project.default_branch) != null ? _b : this.config.fallbackBranch;
680
+ const matchingFiles = addedFiles.filter(
681
+ (file) => path__namespace.basename(file) === this.config.catalogFile
682
+ );
683
+ const locationSpecs = matchingFiles.map((file) => ({
684
+ type: "url",
685
+ target: `${project.web_url}/-/blob/${projectBranch}/${file}`,
686
+ presence: "optional"
687
+ }));
688
+ return locationSpecs;
689
+ }
690
+ /**
691
+ * Converts a target URL to a LocationSpec object.
692
+ *
693
+ * @param {string} target - The target URL to be converted.
694
+ * @returns {LocationSpec} The LocationSpec object representing the URL.
695
+ */
696
+ toLocationSpec(target) {
697
+ return {
698
+ type: "url",
699
+ target,
700
+ presence: "optional"
701
+ };
702
+ }
703
+ toDeferredEntities(targets) {
704
+ return targets.map((target) => {
705
+ const location = this.toLocationSpec(target);
706
+ return pluginCatalogNode.locationSpecToLocationEntity({ location });
707
+ }).map((entity) => {
708
+ return {
709
+ locationKey: this.getProviderName(),
710
+ entity
711
+ };
712
+ });
713
+ }
714
+ async shouldProcessProject(project, client) {
715
+ var _a, _b, _c, _d, _e;
716
+ if (!this.config.projectPattern.test((_a = project.path_with_namespace) != null ? _a : "")) {
717
+ this.logger.debug(
718
+ `Skipping project ${project.path_with_namespace} as it does not match the project pattern ${this.config.projectPattern}.`
719
+ );
720
+ return false;
721
+ }
722
+ if (this.config.group && !project.path_with_namespace.startsWith(`${this.config.group}/`)) {
723
+ this.logger.debug(
724
+ `Skipping project ${project.path_with_namespace} as it does not match the group pattern ${this.config.group}.`
725
+ );
726
+ return false;
727
+ }
728
+ if (this.config.skipForkedRepos && project.hasOwnProperty("forked_from_project")) {
729
+ this.logger.debug(
730
+ `Skipping project ${project.path_with_namespace} as it is a forked project.`
731
+ );
732
+ return false;
733
+ }
734
+ const customFallbackBranch = this.config.fallbackBranch !== "master" ? this.config.fallbackBranch : void 0;
735
+ const project_branch = (_d = (_c = (_b = this.config.branch) != null ? _b : customFallbackBranch) != null ? _c : project.default_branch) != null ? _d : this.config.fallbackBranch;
736
+ const hasFile = await client.hasFile(
737
+ (_e = project.path_with_namespace) != null ? _e : "",
738
+ project_branch,
739
+ this.config.catalogFile
740
+ );
741
+ return hasFile;
742
+ }
507
743
  }
508
744
 
509
745
  exports.GitLabClient = GitLabClient;
510
746
  exports.GitlabDiscoveryEntityProvider = GitlabDiscoveryEntityProvider;
511
747
  exports.paginated = paginated;
512
748
  exports.readGitlabConfigs = readGitlabConfigs;
513
- //# sourceMappingURL=GitlabDiscoveryEntityProvider-CfW32ioU.cjs.js.map
749
+ //# sourceMappingURL=GitlabDiscoveryEntityProvider-OBHXu4pm.cjs.js.map