@backstage/plugin-catalog-backend-module-github 0.2.7-next.0 → 0.2.7-next.1
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 +19 -0
- package/alpha/package.json +1 -1
- package/dist/alpha.cjs.js +8 -481
- package/dist/alpha.cjs.js.map +1 -1
- package/dist/cjs/GithubEntityProvider-15bc2fa6.cjs.js +1266 -0
- package/dist/cjs/GithubEntityProvider-15bc2fa6.cjs.js.map +1 -0
- package/dist/index.cjs.js +23 -1265
- package/dist/index.cjs.js.map +1 -1
- package/package.json +11 -11
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# @backstage/plugin-catalog-backend-module-github
|
|
2
2
|
|
|
3
|
+
## 0.2.7-next.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies
|
|
8
|
+
- @backstage/plugin-catalog-backend@1.8.1-next.1
|
|
9
|
+
- @backstage/backend-tasks@0.5.1-next.1
|
|
10
|
+
- @backstage/integration@1.4.4-next.0
|
|
11
|
+
- @backstage/backend-common@0.18.4-next.1
|
|
12
|
+
- @backstage/backend-plugin-api@0.5.1-next.1
|
|
13
|
+
- @backstage/catalog-client@1.4.0
|
|
14
|
+
- @backstage/catalog-model@1.2.1
|
|
15
|
+
- @backstage/config@1.0.7
|
|
16
|
+
- @backstage/errors@1.1.5
|
|
17
|
+
- @backstage/types@1.0.2
|
|
18
|
+
- @backstage/plugin-catalog-common@1.0.13-next.0
|
|
19
|
+
- @backstage/plugin-catalog-node@1.3.5-next.1
|
|
20
|
+
- @backstage/plugin-events-node@0.2.5-next.1
|
|
21
|
+
|
|
3
22
|
## 0.2.7-next.0
|
|
4
23
|
|
|
5
24
|
### Patch Changes
|
package/alpha/package.json
CHANGED
package/dist/alpha.cjs.js
CHANGED
|
@@ -5,488 +5,15 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
5
5
|
var backendPluginApi = require('@backstage/backend-plugin-api');
|
|
6
6
|
var backendCommon = require('@backstage/backend-common');
|
|
7
7
|
var alpha = require('@backstage/plugin-catalog-node/alpha');
|
|
8
|
-
var
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
var GithubEntityProvider = require('./cjs/GithubEntityProvider-15bc2fa6.cjs.js');
|
|
9
|
+
require('@backstage/integration');
|
|
10
|
+
require('@backstage/plugin-catalog-node');
|
|
11
|
+
require('@octokit/graphql');
|
|
12
|
+
require('uuid');
|
|
13
|
+
require('@backstage/backend-tasks');
|
|
13
14
|
require('@backstage/catalog-model');
|
|
14
15
|
require('lodash');
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
function _interopNamespace(e) {
|
|
18
|
-
if (e && e.__esModule) return e;
|
|
19
|
-
var n = Object.create(null);
|
|
20
|
-
if (e) {
|
|
21
|
-
Object.keys(e).forEach(function (k) {
|
|
22
|
-
if (k !== 'default') {
|
|
23
|
-
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
24
|
-
Object.defineProperty(n, k, d.get ? d : {
|
|
25
|
-
enumerable: true,
|
|
26
|
-
get: function () { return e[k]; }
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
n["default"] = e;
|
|
32
|
-
return Object.freeze(n);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
var uuid__namespace = /*#__PURE__*/_interopNamespace(uuid);
|
|
36
|
-
|
|
37
|
-
const DEFAULT_CATALOG_PATH = "/catalog-info.yaml";
|
|
38
|
-
const DEFAULT_PROVIDER_ID = "default";
|
|
39
|
-
function readProviderConfigs(config) {
|
|
40
|
-
const providersConfig = config.getOptionalConfig("catalog.providers.github");
|
|
41
|
-
if (!providersConfig) {
|
|
42
|
-
return [];
|
|
43
|
-
}
|
|
44
|
-
if (providersConfig.has("organization")) {
|
|
45
|
-
return [readProviderConfig(DEFAULT_PROVIDER_ID, providersConfig)];
|
|
46
|
-
}
|
|
47
|
-
return providersConfig.keys().map((id) => {
|
|
48
|
-
const providerConfig = providersConfig.getConfig(id);
|
|
49
|
-
return readProviderConfig(id, providerConfig);
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
function readProviderConfig(id, config) {
|
|
53
|
-
var _a, _b, _c, _d;
|
|
54
|
-
const organization = config.getString("organization");
|
|
55
|
-
const catalogPath = (_a = config.getOptionalString("catalogPath")) != null ? _a : DEFAULT_CATALOG_PATH;
|
|
56
|
-
const host = (_b = config.getOptionalString("host")) != null ? _b : "github.com";
|
|
57
|
-
const repositoryPattern = config.getOptionalString("filters.repository");
|
|
58
|
-
const branchPattern = config.getOptionalString("filters.branch");
|
|
59
|
-
const allowForks = (_c = config.getOptionalBoolean("filters.allowForks")) != null ? _c : true;
|
|
60
|
-
const topicFilterInclude = config == null ? void 0 : config.getOptionalStringArray(
|
|
61
|
-
"filters.topic.include"
|
|
62
|
-
);
|
|
63
|
-
const topicFilterExclude = config == null ? void 0 : config.getOptionalStringArray(
|
|
64
|
-
"filters.topic.exclude"
|
|
65
|
-
);
|
|
66
|
-
const validateLocationsExist = (_d = config == null ? void 0 : config.getOptionalBoolean("validateLocationsExist")) != null ? _d : false;
|
|
67
|
-
const catalogPathContainsWildcard = catalogPath.includes("*");
|
|
68
|
-
if (validateLocationsExist && catalogPathContainsWildcard) {
|
|
69
|
-
throw Error(
|
|
70
|
-
`Error while processing GitHub provider config. The catalog path ${catalogPath} contains a wildcard, which is incompatible with validation of locations existing before emitting them. Ensure that validateLocationsExist is set to false.`
|
|
71
|
-
);
|
|
72
|
-
}
|
|
73
|
-
const schedule = config.has("schedule") ? backendTasks.readTaskScheduleDefinitionFromConfig(config.getConfig("schedule")) : void 0;
|
|
74
|
-
return {
|
|
75
|
-
id,
|
|
76
|
-
catalogPath,
|
|
77
|
-
organization,
|
|
78
|
-
host,
|
|
79
|
-
filters: {
|
|
80
|
-
repository: repositoryPattern ? compileRegExp(repositoryPattern) : void 0,
|
|
81
|
-
branch: branchPattern || void 0,
|
|
82
|
-
allowForks,
|
|
83
|
-
topic: {
|
|
84
|
-
include: topicFilterInclude,
|
|
85
|
-
exclude: topicFilterExclude
|
|
86
|
-
}
|
|
87
|
-
},
|
|
88
|
-
schedule,
|
|
89
|
-
validateLocationsExist
|
|
90
|
-
};
|
|
91
|
-
}
|
|
92
|
-
function compileRegExp(pattern) {
|
|
93
|
-
let fullLinePattern = pattern;
|
|
94
|
-
if (!fullLinePattern.startsWith("^")) {
|
|
95
|
-
fullLinePattern = `^${fullLinePattern}`;
|
|
96
|
-
}
|
|
97
|
-
if (!fullLinePattern.endsWith("$")) {
|
|
98
|
-
fullLinePattern = `${fullLinePattern}$`;
|
|
99
|
-
}
|
|
100
|
-
return new RegExp(fullLinePattern);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
function satisfiesTopicFilter(topics, topicFilter) {
|
|
104
|
-
var _a, _b, _c, _d;
|
|
105
|
-
if (!topicFilter)
|
|
106
|
-
return true;
|
|
107
|
-
if (!topicFilter.include && !topicFilter.exclude)
|
|
108
|
-
return true;
|
|
109
|
-
if (!((_a = topicFilter.include) == null ? void 0 : _a.length) && !((_b = topicFilter.exclude) == null ? void 0 : _b.length))
|
|
110
|
-
return true;
|
|
111
|
-
if (((_c = topicFilter.include) == null ? void 0 : _c.length) && !topicFilter.exclude) {
|
|
112
|
-
for (const topic of topics) {
|
|
113
|
-
if (topicFilter.include.includes(topic))
|
|
114
|
-
return true;
|
|
115
|
-
}
|
|
116
|
-
return false;
|
|
117
|
-
}
|
|
118
|
-
if (!topicFilter.include && ((_d = topicFilter.exclude) == null ? void 0 : _d.length)) {
|
|
119
|
-
if (!topics.length)
|
|
120
|
-
return true;
|
|
121
|
-
for (const topic of topics) {
|
|
122
|
-
if (topicFilter.exclude.includes(topic))
|
|
123
|
-
return false;
|
|
124
|
-
}
|
|
125
|
-
return true;
|
|
126
|
-
}
|
|
127
|
-
if (topicFilter.include && topicFilter.exclude) {
|
|
128
|
-
const matchesInclude = satisfiesTopicFilter(topics, {
|
|
129
|
-
include: topicFilter.include
|
|
130
|
-
});
|
|
131
|
-
const matchesExclude = !satisfiesTopicFilter(topics, {
|
|
132
|
-
exclude: topicFilter.exclude
|
|
133
|
-
});
|
|
134
|
-
if (matchesExclude)
|
|
135
|
-
return false;
|
|
136
|
-
return matchesInclude;
|
|
137
|
-
}
|
|
138
|
-
return true;
|
|
139
|
-
}
|
|
140
|
-
function satisfiesForkFilter(allowForks, isFork) {
|
|
141
|
-
if (!allowForks && isFork)
|
|
142
|
-
return false;
|
|
143
|
-
return true;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
async function getOrganizationRepositories(client, org, catalogPath) {
|
|
147
|
-
let relativeCatalogPathRef;
|
|
148
|
-
if (catalogPath.startsWith("/")) {
|
|
149
|
-
relativeCatalogPathRef = catalogPath.substring(1);
|
|
150
|
-
} else {
|
|
151
|
-
relativeCatalogPathRef = catalogPath;
|
|
152
|
-
}
|
|
153
|
-
const catalogPathRef = `HEAD:${relativeCatalogPathRef}`;
|
|
154
|
-
const query = `
|
|
155
|
-
query repositories($org: String!, $catalogPathRef: String!, $cursor: String) {
|
|
156
|
-
repositoryOwner(login: $org) {
|
|
157
|
-
login
|
|
158
|
-
repositories(first: 100, after: $cursor) {
|
|
159
|
-
nodes {
|
|
160
|
-
name
|
|
161
|
-
catalogInfoFile: object(expression: $catalogPathRef) {
|
|
162
|
-
__typename
|
|
163
|
-
... on Blob {
|
|
164
|
-
id
|
|
165
|
-
text
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
url
|
|
169
|
-
isArchived
|
|
170
|
-
isFork
|
|
171
|
-
repositoryTopics(first: 100) {
|
|
172
|
-
nodes {
|
|
173
|
-
... on RepositoryTopic {
|
|
174
|
-
topic {
|
|
175
|
-
name
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
defaultBranchRef {
|
|
181
|
-
name
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
pageInfo {
|
|
185
|
-
hasNextPage
|
|
186
|
-
endCursor
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
}`;
|
|
191
|
-
const repositories = await queryWithPaging(
|
|
192
|
-
client,
|
|
193
|
-
query,
|
|
194
|
-
org,
|
|
195
|
-
(r) => {
|
|
196
|
-
var _a;
|
|
197
|
-
return (_a = r.repositoryOwner) == null ? void 0 : _a.repositories;
|
|
198
|
-
},
|
|
199
|
-
async (x) => x,
|
|
200
|
-
{ org, catalogPathRef }
|
|
201
|
-
);
|
|
202
|
-
return { repositories };
|
|
203
|
-
}
|
|
204
|
-
async function queryWithPaging(client, query, org, connection, transformer, variables) {
|
|
205
|
-
const result = [];
|
|
206
|
-
let cursor = void 0;
|
|
207
|
-
for (let j = 0; j < 1e3; ++j) {
|
|
208
|
-
const response = await client(query, {
|
|
209
|
-
...variables,
|
|
210
|
-
cursor
|
|
211
|
-
});
|
|
212
|
-
const conn = connection(response);
|
|
213
|
-
if (!conn) {
|
|
214
|
-
throw new Error(`Found no match for ${JSON.stringify(variables)}`);
|
|
215
|
-
}
|
|
216
|
-
for (const node of conn.nodes) {
|
|
217
|
-
const transformedNode = await transformer(node, {
|
|
218
|
-
client,
|
|
219
|
-
query,
|
|
220
|
-
org
|
|
221
|
-
});
|
|
222
|
-
if (transformedNode) {
|
|
223
|
-
result.push(transformedNode);
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
if (!conn.pageInfo.hasNextPage) {
|
|
227
|
-
break;
|
|
228
|
-
} else {
|
|
229
|
-
cursor = conn.pageInfo.endCursor;
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
return result;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
const TOPIC_REPO_PUSH = "github.push";
|
|
236
|
-
class GithubEntityProvider {
|
|
237
|
-
static fromConfig(config, options) {
|
|
238
|
-
if (!options.schedule && !options.scheduler) {
|
|
239
|
-
throw new Error("Either schedule or scheduler must be provided.");
|
|
240
|
-
}
|
|
241
|
-
const integrations = integration.ScmIntegrations.fromConfig(config);
|
|
242
|
-
return readProviderConfigs(config).map((providerConfig) => {
|
|
243
|
-
var _a;
|
|
244
|
-
const integrationHost = providerConfig.host;
|
|
245
|
-
const integration = integrations.github.byHost(integrationHost);
|
|
246
|
-
if (!integration) {
|
|
247
|
-
throw new Error(
|
|
248
|
-
`There is no GitHub config that matches host ${integrationHost}. Please add a configuration entry for it under integrations.github`
|
|
249
|
-
);
|
|
250
|
-
}
|
|
251
|
-
if (!options.schedule && !providerConfig.schedule) {
|
|
252
|
-
throw new Error(
|
|
253
|
-
`No schedule provided neither via code nor config for github-provider:${providerConfig.id}.`
|
|
254
|
-
);
|
|
255
|
-
}
|
|
256
|
-
const taskRunner = (_a = options.schedule) != null ? _a : options.scheduler.createScheduledTaskRunner(providerConfig.schedule);
|
|
257
|
-
return new GithubEntityProvider(
|
|
258
|
-
providerConfig,
|
|
259
|
-
integration,
|
|
260
|
-
options.logger,
|
|
261
|
-
taskRunner
|
|
262
|
-
);
|
|
263
|
-
});
|
|
264
|
-
}
|
|
265
|
-
constructor(config, integration$1, logger, taskRunner) {
|
|
266
|
-
this.config = config;
|
|
267
|
-
this.integration = integration$1.config;
|
|
268
|
-
this.logger = logger.child({
|
|
269
|
-
target: this.getProviderName()
|
|
270
|
-
});
|
|
271
|
-
this.scheduleFn = this.createScheduleFn(taskRunner);
|
|
272
|
-
this.githubCredentialsProvider = integration.SingleInstanceGithubCredentialsProvider.create(integration$1.config);
|
|
273
|
-
}
|
|
274
|
-
/** {@inheritdoc @backstage/plugin-catalog-backend#EntityProvider.getProviderName} */
|
|
275
|
-
getProviderName() {
|
|
276
|
-
return `github-provider:${this.config.id}`;
|
|
277
|
-
}
|
|
278
|
-
/** {@inheritdoc @backstage/plugin-catalog-backend#EntityProvider.connect} */
|
|
279
|
-
async connect(connection) {
|
|
280
|
-
this.connection = connection;
|
|
281
|
-
return await this.scheduleFn();
|
|
282
|
-
}
|
|
283
|
-
createScheduleFn(taskRunner) {
|
|
284
|
-
return async () => {
|
|
285
|
-
const taskId = `${this.getProviderName()}:refresh`;
|
|
286
|
-
return taskRunner.run({
|
|
287
|
-
id: taskId,
|
|
288
|
-
fn: async () => {
|
|
289
|
-
const logger = this.logger.child({
|
|
290
|
-
class: GithubEntityProvider.prototype.constructor.name,
|
|
291
|
-
taskId,
|
|
292
|
-
taskInstanceId: uuid__namespace.v4()
|
|
293
|
-
});
|
|
294
|
-
try {
|
|
295
|
-
await this.refresh(logger);
|
|
296
|
-
} catch (error) {
|
|
297
|
-
logger.error(`${this.getProviderName()} refresh failed`, error);
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
});
|
|
301
|
-
};
|
|
302
|
-
}
|
|
303
|
-
async refresh(logger) {
|
|
304
|
-
if (!this.connection) {
|
|
305
|
-
throw new Error("Not initialized");
|
|
306
|
-
}
|
|
307
|
-
const targets = await this.findCatalogFiles();
|
|
308
|
-
const matchingTargets = this.matchesFilters(targets);
|
|
309
|
-
const entities = matchingTargets.map((repository) => this.createLocationUrl(repository)).map(GithubEntityProvider.toLocationSpec).map((location) => {
|
|
310
|
-
return {
|
|
311
|
-
locationKey: this.getProviderName(),
|
|
312
|
-
entity: pluginCatalogNode.locationSpecToLocationEntity({ location })
|
|
313
|
-
};
|
|
314
|
-
});
|
|
315
|
-
await this.connection.applyMutation({
|
|
316
|
-
type: "full",
|
|
317
|
-
entities
|
|
318
|
-
});
|
|
319
|
-
logger.info(
|
|
320
|
-
`Read ${targets.length} GitHub repositories (${entities.length} matching the pattern)`
|
|
321
|
-
);
|
|
322
|
-
}
|
|
323
|
-
// go to the server and get all of the repositories
|
|
324
|
-
async findCatalogFiles() {
|
|
325
|
-
const organization = this.config.organization;
|
|
326
|
-
const host = this.integration.host;
|
|
327
|
-
const catalogPath = this.config.catalogPath;
|
|
328
|
-
const orgUrl = `https://${host}/${organization}`;
|
|
329
|
-
const { headers } = await this.githubCredentialsProvider.getCredentials({
|
|
330
|
-
url: orgUrl
|
|
331
|
-
});
|
|
332
|
-
const client = graphql.graphql.defaults({
|
|
333
|
-
baseUrl: this.integration.apiBaseUrl,
|
|
334
|
-
headers
|
|
335
|
-
});
|
|
336
|
-
const { repositories: repositoriesFromGithub } = await getOrganizationRepositories(client, organization, catalogPath);
|
|
337
|
-
const repositories = repositoriesFromGithub.map((r) => {
|
|
338
|
-
var _a, _b;
|
|
339
|
-
return {
|
|
340
|
-
url: r.url,
|
|
341
|
-
name: r.name,
|
|
342
|
-
defaultBranchRef: (_a = r.defaultBranchRef) == null ? void 0 : _a.name,
|
|
343
|
-
repositoryTopics: r.repositoryTopics.nodes.map((t) => t.topic.name),
|
|
344
|
-
isArchived: r.isArchived,
|
|
345
|
-
isFork: r.isFork,
|
|
346
|
-
isCatalogInfoFilePresent: ((_b = r.catalogInfoFile) == null ? void 0 : _b.__typename) === "Blob" && r.catalogInfoFile.text !== ""
|
|
347
|
-
};
|
|
348
|
-
});
|
|
349
|
-
if (this.config.validateLocationsExist) {
|
|
350
|
-
return repositories.filter(
|
|
351
|
-
(repository) => repository.isCatalogInfoFilePresent
|
|
352
|
-
);
|
|
353
|
-
}
|
|
354
|
-
return repositories;
|
|
355
|
-
}
|
|
356
|
-
matchesFilters(repositories) {
|
|
357
|
-
var _a, _b, _c, _d;
|
|
358
|
-
const repositoryFilter = (_a = this.config.filters) == null ? void 0 : _a.repository;
|
|
359
|
-
const topicFilters = (_b = this.config.filters) == null ? void 0 : _b.topic;
|
|
360
|
-
const allowForks = (_d = (_c = this.config.filters) == null ? void 0 : _c.allowForks) != null ? _d : true;
|
|
361
|
-
const matchingRepositories = repositories.filter((r) => {
|
|
362
|
-
const repoTopics = r.repositoryTopics;
|
|
363
|
-
return !r.isArchived && (!repositoryFilter || repositoryFilter.test(r.name)) && satisfiesTopicFilter(repoTopics, topicFilters) && satisfiesForkFilter(allowForks, r.isFork) && r.defaultBranchRef;
|
|
364
|
-
});
|
|
365
|
-
return matchingRepositories;
|
|
366
|
-
}
|
|
367
|
-
createLocationUrl(repository) {
|
|
368
|
-
var _a;
|
|
369
|
-
const branch = ((_a = this.config.filters) == null ? void 0 : _a.branch) || repository.defaultBranchRef || "-";
|
|
370
|
-
const catalogFile = this.config.catalogPath.startsWith("/") ? this.config.catalogPath.substring(1) : this.config.catalogPath;
|
|
371
|
-
return `${repository.url}/blob/${branch}/${catalogFile}`;
|
|
372
|
-
}
|
|
373
|
-
static toLocationSpec(target) {
|
|
374
|
-
return {
|
|
375
|
-
type: "url",
|
|
376
|
-
target,
|
|
377
|
-
presence: "optional"
|
|
378
|
-
};
|
|
379
|
-
}
|
|
380
|
-
/** {@inheritdoc @backstage/plugin-events-node#EventSubscriber.onEvent} */
|
|
381
|
-
async onEvent(params) {
|
|
382
|
-
this.logger.debug(`Received event from ${params.topic}`);
|
|
383
|
-
if (params.topic !== TOPIC_REPO_PUSH) {
|
|
384
|
-
return;
|
|
385
|
-
}
|
|
386
|
-
await this.onRepoPush(params.eventPayload);
|
|
387
|
-
}
|
|
388
|
-
/** {@inheritdoc @backstage/plugin-events-node#EventSubscriber.supportsEventTopics} */
|
|
389
|
-
supportsEventTopics() {
|
|
390
|
-
return [TOPIC_REPO_PUSH];
|
|
391
|
-
}
|
|
392
|
-
async onRepoPush(event) {
|
|
393
|
-
var _a;
|
|
394
|
-
if (!this.connection) {
|
|
395
|
-
throw new Error("Not initialized");
|
|
396
|
-
}
|
|
397
|
-
const repoName = event.repository.name;
|
|
398
|
-
const repoUrl = event.repository.url;
|
|
399
|
-
this.logger.debug(`handle github:push event for ${repoName} - ${repoUrl}`);
|
|
400
|
-
const branch = ((_a = this.config.filters) == null ? void 0 : _a.branch) || event.repository.default_branch;
|
|
401
|
-
if (!event.ref.includes(branch)) {
|
|
402
|
-
this.logger.debug(`skipping push event from ref ${event.ref}`);
|
|
403
|
-
return;
|
|
404
|
-
}
|
|
405
|
-
const repository = {
|
|
406
|
-
url: event.repository.url,
|
|
407
|
-
name: event.repository.name,
|
|
408
|
-
defaultBranchRef: event.repository.default_branch,
|
|
409
|
-
repositoryTopics: event.repository.topics,
|
|
410
|
-
isArchived: event.repository.archived,
|
|
411
|
-
isFork: event.repository.fork,
|
|
412
|
-
// we can consider this file present because
|
|
413
|
-
// only the catalog file will be recovered from the commits
|
|
414
|
-
isCatalogInfoFilePresent: true
|
|
415
|
-
};
|
|
416
|
-
const matchingTargets = this.matchesFilters([repository]);
|
|
417
|
-
if (matchingTargets.length === 0) {
|
|
418
|
-
this.logger.debug(
|
|
419
|
-
`skipping push event from repository ${repoName} because didn't match provider filters`
|
|
420
|
-
);
|
|
421
|
-
return;
|
|
422
|
-
}
|
|
423
|
-
const added = this.collectDeferredEntitiesFromCommit(
|
|
424
|
-
event.repository.url,
|
|
425
|
-
branch,
|
|
426
|
-
event.commits,
|
|
427
|
-
(commit) => [...commit.added]
|
|
428
|
-
);
|
|
429
|
-
const removed = this.collectDeferredEntitiesFromCommit(
|
|
430
|
-
event.repository.url,
|
|
431
|
-
branch,
|
|
432
|
-
event.commits,
|
|
433
|
-
(commit) => [...commit.removed]
|
|
434
|
-
);
|
|
435
|
-
const modified = this.collectFilesFromCommit(
|
|
436
|
-
event.commits,
|
|
437
|
-
(commit) => [...commit.modified]
|
|
438
|
-
);
|
|
439
|
-
if (modified.length > 0) {
|
|
440
|
-
await this.connection.refresh({
|
|
441
|
-
keys: [
|
|
442
|
-
...modified.map(
|
|
443
|
-
(filePath) => `url:${event.repository.url}/tree/${branch}/${filePath}`
|
|
444
|
-
),
|
|
445
|
-
...modified.map(
|
|
446
|
-
(filePath) => `url:${event.repository.url}/blob/${branch}/${filePath}`
|
|
447
|
-
)
|
|
448
|
-
]
|
|
449
|
-
});
|
|
450
|
-
}
|
|
451
|
-
if (added.length > 0 || removed.length > 0) {
|
|
452
|
-
await this.connection.applyMutation({
|
|
453
|
-
type: "delta",
|
|
454
|
-
added,
|
|
455
|
-
removed
|
|
456
|
-
});
|
|
457
|
-
}
|
|
458
|
-
this.logger.info(
|
|
459
|
-
`Processed Github push event: added ${added.length} - removed ${removed.length} - modified ${modified.length}`
|
|
460
|
-
);
|
|
461
|
-
}
|
|
462
|
-
collectDeferredEntitiesFromCommit(repositoryUrl, branch, commits, transformOperation) {
|
|
463
|
-
const catalogFiles = this.collectFilesFromCommit(
|
|
464
|
-
commits,
|
|
465
|
-
transformOperation
|
|
466
|
-
);
|
|
467
|
-
return this.toDeferredEntities(
|
|
468
|
-
catalogFiles.map(
|
|
469
|
-
(filePath) => `${repositoryUrl}/blob/${branch}/${filePath}`
|
|
470
|
-
)
|
|
471
|
-
);
|
|
472
|
-
}
|
|
473
|
-
collectFilesFromCommit(commits, transformOperation) {
|
|
474
|
-
const catalogFile = this.config.catalogPath.startsWith("/") ? this.config.catalogPath.substring(1) : this.config.catalogPath;
|
|
475
|
-
const matcher = new minimatch.Minimatch(catalogFile);
|
|
476
|
-
return commits.map(transformOperation).flat().filter((file) => matcher.match(file));
|
|
477
|
-
}
|
|
478
|
-
toDeferredEntities(targets) {
|
|
479
|
-
return targets.map((target) => {
|
|
480
|
-
const location = GithubEntityProvider.toLocationSpec(target);
|
|
481
|
-
return pluginCatalogNode.locationSpecToLocationEntity({ location });
|
|
482
|
-
}).map((entity) => {
|
|
483
|
-
return {
|
|
484
|
-
locationKey: this.getProviderName(),
|
|
485
|
-
entity
|
|
486
|
-
};
|
|
487
|
-
});
|
|
488
|
-
}
|
|
489
|
-
}
|
|
16
|
+
require('minimatch');
|
|
490
17
|
|
|
491
18
|
const catalogModuleGithubEntityProvider = backendPluginApi.createBackendModule({
|
|
492
19
|
pluginId: "catalog",
|
|
@@ -501,7 +28,7 @@ const catalogModuleGithubEntityProvider = backendPluginApi.createBackendModule({
|
|
|
501
28
|
},
|
|
502
29
|
async init({ catalog, config, logger, scheduler }) {
|
|
503
30
|
catalog.addEntityProvider(
|
|
504
|
-
GithubEntityProvider.fromConfig(config, {
|
|
31
|
+
GithubEntityProvider.GithubEntityProvider.fromConfig(config, {
|
|
505
32
|
logger: backendCommon.loggerToWinstonLogger(logger),
|
|
506
33
|
scheduler
|
|
507
34
|
})
|