@backstage/plugin-catalog-backend-module-github 0.0.0-nightly-20221017030331 → 0.0.0-nightly-20221020030155
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 +44 -12
- package/alpha/package.json +1 -1
- package/config.d.ts +1 -1
- package/dist/index.alpha.d.ts +42 -11
- package/dist/index.beta.d.ts +41 -10
- package/dist/index.cjs.js +50 -14
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +41 -10
- package/package.json +13 -13
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,23 @@
|
|
|
1
1
|
# @backstage/plugin-catalog-backend-module-github
|
|
2
2
|
|
|
3
|
-
## 0.0.0-nightly-
|
|
3
|
+
## 0.0.0-nightly-20221020030155
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies
|
|
8
|
+
- @backstage/backend-common@0.0.0-nightly-20221020030155
|
|
9
|
+
- @backstage/backend-plugin-api@0.0.0-nightly-20221020030155
|
|
10
|
+
- @backstage/backend-tasks@0.0.0-nightly-20221020030155
|
|
11
|
+
- @backstage/catalog-client@0.0.0-nightly-20221020030155
|
|
12
|
+
- @backstage/catalog-model@0.0.0-nightly-20221020030155
|
|
13
|
+
- @backstage/config@0.0.0-nightly-20221020030155
|
|
14
|
+
- @backstage/errors@0.0.0-nightly-20221020030155
|
|
15
|
+
- @backstage/integration@0.0.0-nightly-20221020030155
|
|
16
|
+
- @backstage/types@1.0.0
|
|
17
|
+
- @backstage/plugin-catalog-backend@0.0.0-nightly-20221020030155
|
|
18
|
+
- @backstage/plugin-catalog-node@0.0.0-nightly-20221020030155
|
|
19
|
+
|
|
20
|
+
## 0.1.8
|
|
4
21
|
|
|
5
22
|
### Patch Changes
|
|
6
23
|
|
|
@@ -9,7 +26,7 @@
|
|
|
9
26
|
Please find how to configure the schedule at the config at
|
|
10
27
|
https://backstage.io/docs/integrations/github/discovery
|
|
11
28
|
|
|
12
|
-
- 7022aebf35: Added `
|
|
29
|
+
- 7022aebf35: Added `GithubLocationAnalyzer`. This can be used to add to the `CatalogBuilder`. When added this will be used by `RepoLocationAnalyzer` to figure out if the given URL that you are trying to import from the /catalog-import page already contains catalog-info.yaml files.
|
|
13
30
|
- 51046b58b0: Use schedule from config at backend module.
|
|
14
31
|
|
|
15
32
|
Also, it removes `GithubEntityProviderCatalogModuleOptions`
|
|
@@ -17,18 +34,33 @@
|
|
|
17
34
|
like at other similar modules.
|
|
18
35
|
|
|
19
36
|
- 7edb5909e8: Add missing config schema for the `GitHubEntityProvider`.
|
|
37
|
+
- be9474b103: Replaces in-code uses of `GitHub` by `Github` and deprecates old versions.
|
|
38
|
+
|
|
39
|
+
Deprecates
|
|
40
|
+
|
|
41
|
+
- `GitHubEntityProvider` replaced by `GithubEntityProvider`
|
|
42
|
+
- `GitHubLocationAnalyzer` replaced by `GithubLocationAnalyzer`
|
|
43
|
+
- `GitHubLocationAnalyzerOptions` replaced by `GithubLocationAnalyzerOptions`
|
|
44
|
+
- `GitHubOrgEntityProvider` replaced by `GithubOrgEntityProvider`
|
|
45
|
+
- `GitHubOrgEntityProviderOptions` replaced by `GithubOrgEntityProviderOptions`
|
|
46
|
+
|
|
47
|
+
Renames
|
|
48
|
+
|
|
49
|
+
- `GitHubLocationAnalyzer` to `GithubLocationAnalyzer`
|
|
50
|
+
- `GitHubLocationAnalyzerOptions` to `GithubLocationAnalyzerOptions`
|
|
51
|
+
|
|
20
52
|
- a35a27df70: Updated the `moduleId` of the experimental module export.
|
|
21
53
|
- Updated dependencies
|
|
22
|
-
- @backstage/plugin-catalog-node@
|
|
23
|
-
- @backstage/catalog-model@
|
|
24
|
-
- @backstage/
|
|
25
|
-
- @backstage/backend
|
|
26
|
-
- @backstage/backend-
|
|
27
|
-
- @backstage/backend-plugin-api@0.
|
|
28
|
-
- @backstage/catalog-client@
|
|
29
|
-
- @backstage/config@
|
|
30
|
-
- @backstage/errors@
|
|
31
|
-
- @backstage/integration@
|
|
54
|
+
- @backstage/plugin-catalog-node@1.2.0
|
|
55
|
+
- @backstage/catalog-model@1.1.2
|
|
56
|
+
- @backstage/backend-common@0.15.2
|
|
57
|
+
- @backstage/plugin-catalog-backend@1.5.0
|
|
58
|
+
- @backstage/backend-tasks@0.3.6
|
|
59
|
+
- @backstage/backend-plugin-api@0.1.3
|
|
60
|
+
- @backstage/catalog-client@1.1.1
|
|
61
|
+
- @backstage/config@1.0.3
|
|
62
|
+
- @backstage/errors@1.1.2
|
|
63
|
+
- @backstage/integration@1.3.2
|
|
32
64
|
- @backstage/types@1.0.0
|
|
33
65
|
|
|
34
66
|
## 0.1.8-next.2
|
package/alpha/package.json
CHANGED
package/config.d.ts
CHANGED
package/dist/index.alpha.d.ts
CHANGED
|
@@ -55,6 +55,23 @@ export declare class GithubDiscoveryProcessor implements CatalogProcessor {
|
|
|
55
55
|
readLocation(location: LocationSpec, _optional: boolean, emit: CatalogProcessorEmit): Promise<boolean>;
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
+
/**
|
|
59
|
+
* @public
|
|
60
|
+
* @deprecated Use {@link GithubEntityProvider} instead.
|
|
61
|
+
*/
|
|
62
|
+
export declare class GitHubEntityProvider implements EntityProvider {
|
|
63
|
+
private readonly delegate;
|
|
64
|
+
static fromConfig(config: Config, options: {
|
|
65
|
+
logger: Logger;
|
|
66
|
+
schedule?: TaskRunner;
|
|
67
|
+
scheduler?: PluginTaskScheduler;
|
|
68
|
+
}): GitHubEntityProvider[];
|
|
69
|
+
private constructor();
|
|
70
|
+
connect(connection: EntityProviderConnection): Promise<void>;
|
|
71
|
+
getProviderName(): string;
|
|
72
|
+
refresh(logger: Logger): Promise<void>;
|
|
73
|
+
}
|
|
74
|
+
|
|
58
75
|
/**
|
|
59
76
|
* Discovers catalog files located in [GitHub](https://github.com).
|
|
60
77
|
* The provider will search your GitHub account and register catalog files matching the configured path
|
|
@@ -63,7 +80,7 @@ export declare class GithubDiscoveryProcessor implements CatalogProcessor {
|
|
|
63
80
|
*
|
|
64
81
|
* @public
|
|
65
82
|
*/
|
|
66
|
-
export declare class
|
|
83
|
+
export declare class GithubEntityProvider implements EntityProvider {
|
|
67
84
|
private readonly config;
|
|
68
85
|
private readonly logger;
|
|
69
86
|
private readonly integration;
|
|
@@ -74,7 +91,7 @@ export declare class GitHubEntityProvider implements EntityProvider {
|
|
|
74
91
|
logger: Logger;
|
|
75
92
|
schedule?: TaskRunner;
|
|
76
93
|
scheduler?: PluginTaskScheduler;
|
|
77
|
-
}):
|
|
94
|
+
}): GithubEntityProvider[];
|
|
78
95
|
private constructor();
|
|
79
96
|
/** {@inheritdoc @backstage/plugin-catalog-backend#EntityProvider.getProviderName} */
|
|
80
97
|
getProviderName(): string;
|
|
@@ -89,17 +106,17 @@ export declare class GitHubEntityProvider implements EntityProvider {
|
|
|
89
106
|
}
|
|
90
107
|
|
|
91
108
|
/**
|
|
92
|
-
* Registers the
|
|
109
|
+
* Registers the {@link GithubEntityProvider} with the catalog processing extension point.
|
|
93
110
|
*
|
|
94
111
|
* @alpha
|
|
95
112
|
*/
|
|
96
113
|
export declare const githubEntityProviderCatalogModule: (options?: undefined) => BackendFeature;
|
|
97
114
|
|
|
98
115
|
/** @public */
|
|
99
|
-
export declare class
|
|
116
|
+
export declare class GithubLocationAnalyzer implements ScmLocationAnalyzer {
|
|
100
117
|
private readonly catalogClient;
|
|
101
118
|
private readonly config;
|
|
102
|
-
constructor(options:
|
|
119
|
+
constructor(options: GithubLocationAnalyzerOptions);
|
|
103
120
|
supports(url: string): boolean;
|
|
104
121
|
analyze({ url, catalogFilename }: AnalyzeOptions): Promise<{
|
|
105
122
|
existing: {
|
|
@@ -114,7 +131,7 @@ export declare class GitHubLocationAnalyzer implements ScmLocationAnalyzer {
|
|
|
114
131
|
}
|
|
115
132
|
|
|
116
133
|
/** @public */
|
|
117
|
-
export declare type
|
|
134
|
+
export declare type GithubLocationAnalyzerOptions = {
|
|
118
135
|
config: Config;
|
|
119
136
|
discovery: PluginEndpointDiscovery;
|
|
120
137
|
};
|
|
@@ -165,17 +182,25 @@ export declare class GithubMultiOrgReaderProcessor implements CatalogProcessor {
|
|
|
165
182
|
private getAllOrgs;
|
|
166
183
|
}
|
|
167
184
|
|
|
185
|
+
/**
|
|
186
|
+
* @public
|
|
187
|
+
* @deprecated Use {@link GithubOrgEntityProvider} instead.
|
|
188
|
+
*/
|
|
189
|
+
export declare class GitHubOrgEntityProvider extends GithubOrgEntityProvider {
|
|
190
|
+
static fromConfig(config: Config, options: GitHubOrgEntityProviderOptions): GitHubOrgEntityProvider;
|
|
191
|
+
}
|
|
192
|
+
|
|
168
193
|
/**
|
|
169
194
|
* Ingests org data (users and groups) from GitHub.
|
|
170
195
|
*
|
|
171
196
|
* @public
|
|
172
197
|
*/
|
|
173
|
-
export declare class
|
|
198
|
+
export declare class GithubOrgEntityProvider implements EntityProvider {
|
|
174
199
|
private options;
|
|
175
200
|
private readonly credentialsProvider;
|
|
176
201
|
private connection?;
|
|
177
202
|
private scheduleFn?;
|
|
178
|
-
static fromConfig(config: Config, options:
|
|
203
|
+
static fromConfig(config: Config, options: GithubOrgEntityProviderOptions): GithubOrgEntityProvider;
|
|
179
204
|
constructor(options: {
|
|
180
205
|
id: string;
|
|
181
206
|
orgUrl: string;
|
|
@@ -198,11 +223,17 @@ export declare class GitHubOrgEntityProvider implements EntityProvider {
|
|
|
198
223
|
}
|
|
199
224
|
|
|
200
225
|
/**
|
|
201
|
-
*
|
|
226
|
+
* @public
|
|
227
|
+
* @deprecated Use {@link GithubOrgEntityProviderOptions} instead.
|
|
228
|
+
*/
|
|
229
|
+
export declare type GitHubOrgEntityProviderOptions = GithubOrgEntityProviderOptions;
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Options for {@link GithubOrgEntityProvider}.
|
|
202
233
|
*
|
|
203
234
|
* @public
|
|
204
235
|
*/
|
|
205
|
-
export declare interface
|
|
236
|
+
export declare interface GithubOrgEntityProviderOptions {
|
|
206
237
|
/**
|
|
207
238
|
* A unique, stable identifier for this provider.
|
|
208
239
|
*
|
|
@@ -244,7 +275,7 @@ export declare interface GitHubOrgEntityProviderOptions {
|
|
|
244
275
|
*
|
|
245
276
|
* @remarks
|
|
246
277
|
*
|
|
247
|
-
* Consider using {@link
|
|
278
|
+
* Consider using {@link GithubOrgEntityProvider} instead.
|
|
248
279
|
*
|
|
249
280
|
* @public
|
|
250
281
|
*/
|
package/dist/index.beta.d.ts
CHANGED
|
@@ -55,6 +55,23 @@ export declare class GithubDiscoveryProcessor implements CatalogProcessor {
|
|
|
55
55
|
readLocation(location: LocationSpec, _optional: boolean, emit: CatalogProcessorEmit): Promise<boolean>;
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
+
/**
|
|
59
|
+
* @public
|
|
60
|
+
* @deprecated Use {@link GithubEntityProvider} instead.
|
|
61
|
+
*/
|
|
62
|
+
export declare class GitHubEntityProvider implements EntityProvider {
|
|
63
|
+
private readonly delegate;
|
|
64
|
+
static fromConfig(config: Config, options: {
|
|
65
|
+
logger: Logger;
|
|
66
|
+
schedule?: TaskRunner;
|
|
67
|
+
scheduler?: PluginTaskScheduler;
|
|
68
|
+
}): GitHubEntityProvider[];
|
|
69
|
+
private constructor();
|
|
70
|
+
connect(connection: EntityProviderConnection): Promise<void>;
|
|
71
|
+
getProviderName(): string;
|
|
72
|
+
refresh(logger: Logger): Promise<void>;
|
|
73
|
+
}
|
|
74
|
+
|
|
58
75
|
/**
|
|
59
76
|
* Discovers catalog files located in [GitHub](https://github.com).
|
|
60
77
|
* The provider will search your GitHub account and register catalog files matching the configured path
|
|
@@ -63,7 +80,7 @@ export declare class GithubDiscoveryProcessor implements CatalogProcessor {
|
|
|
63
80
|
*
|
|
64
81
|
* @public
|
|
65
82
|
*/
|
|
66
|
-
export declare class
|
|
83
|
+
export declare class GithubEntityProvider implements EntityProvider {
|
|
67
84
|
private readonly config;
|
|
68
85
|
private readonly logger;
|
|
69
86
|
private readonly integration;
|
|
@@ -74,7 +91,7 @@ export declare class GitHubEntityProvider implements EntityProvider {
|
|
|
74
91
|
logger: Logger;
|
|
75
92
|
schedule?: TaskRunner;
|
|
76
93
|
scheduler?: PluginTaskScheduler;
|
|
77
|
-
}):
|
|
94
|
+
}): GithubEntityProvider[];
|
|
78
95
|
private constructor();
|
|
79
96
|
/** {@inheritdoc @backstage/plugin-catalog-backend#EntityProvider.getProviderName} */
|
|
80
97
|
getProviderName(): string;
|
|
@@ -91,10 +108,10 @@ export declare class GitHubEntityProvider implements EntityProvider {
|
|
|
91
108
|
/* Excluded from this release type: githubEntityProviderCatalogModule */
|
|
92
109
|
|
|
93
110
|
/** @public */
|
|
94
|
-
export declare class
|
|
111
|
+
export declare class GithubLocationAnalyzer implements ScmLocationAnalyzer {
|
|
95
112
|
private readonly catalogClient;
|
|
96
113
|
private readonly config;
|
|
97
|
-
constructor(options:
|
|
114
|
+
constructor(options: GithubLocationAnalyzerOptions);
|
|
98
115
|
supports(url: string): boolean;
|
|
99
116
|
analyze({ url, catalogFilename }: AnalyzeOptions): Promise<{
|
|
100
117
|
existing: {
|
|
@@ -109,7 +126,7 @@ export declare class GitHubLocationAnalyzer implements ScmLocationAnalyzer {
|
|
|
109
126
|
}
|
|
110
127
|
|
|
111
128
|
/** @public */
|
|
112
|
-
export declare type
|
|
129
|
+
export declare type GithubLocationAnalyzerOptions = {
|
|
113
130
|
config: Config;
|
|
114
131
|
discovery: PluginEndpointDiscovery;
|
|
115
132
|
};
|
|
@@ -160,17 +177,25 @@ export declare class GithubMultiOrgReaderProcessor implements CatalogProcessor {
|
|
|
160
177
|
private getAllOrgs;
|
|
161
178
|
}
|
|
162
179
|
|
|
180
|
+
/**
|
|
181
|
+
* @public
|
|
182
|
+
* @deprecated Use {@link GithubOrgEntityProvider} instead.
|
|
183
|
+
*/
|
|
184
|
+
export declare class GitHubOrgEntityProvider extends GithubOrgEntityProvider {
|
|
185
|
+
static fromConfig(config: Config, options: GitHubOrgEntityProviderOptions): GitHubOrgEntityProvider;
|
|
186
|
+
}
|
|
187
|
+
|
|
163
188
|
/**
|
|
164
189
|
* Ingests org data (users and groups) from GitHub.
|
|
165
190
|
*
|
|
166
191
|
* @public
|
|
167
192
|
*/
|
|
168
|
-
export declare class
|
|
193
|
+
export declare class GithubOrgEntityProvider implements EntityProvider {
|
|
169
194
|
private options;
|
|
170
195
|
private readonly credentialsProvider;
|
|
171
196
|
private connection?;
|
|
172
197
|
private scheduleFn?;
|
|
173
|
-
static fromConfig(config: Config, options:
|
|
198
|
+
static fromConfig(config: Config, options: GithubOrgEntityProviderOptions): GithubOrgEntityProvider;
|
|
174
199
|
constructor(options: {
|
|
175
200
|
id: string;
|
|
176
201
|
orgUrl: string;
|
|
@@ -193,11 +218,17 @@ export declare class GitHubOrgEntityProvider implements EntityProvider {
|
|
|
193
218
|
}
|
|
194
219
|
|
|
195
220
|
/**
|
|
196
|
-
*
|
|
221
|
+
* @public
|
|
222
|
+
* @deprecated Use {@link GithubOrgEntityProviderOptions} instead.
|
|
223
|
+
*/
|
|
224
|
+
export declare type GitHubOrgEntityProviderOptions = GithubOrgEntityProviderOptions;
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Options for {@link GithubOrgEntityProvider}.
|
|
197
228
|
*
|
|
198
229
|
* @public
|
|
199
230
|
*/
|
|
200
|
-
export declare interface
|
|
231
|
+
export declare interface GithubOrgEntityProviderOptions {
|
|
201
232
|
/**
|
|
202
233
|
* A unique, stable identifier for this provider.
|
|
203
234
|
*
|
|
@@ -239,7 +270,7 @@ export declare interface GitHubOrgEntityProviderOptions {
|
|
|
239
270
|
*
|
|
240
271
|
* @remarks
|
|
241
272
|
*
|
|
242
|
-
* Consider using {@link
|
|
273
|
+
* Consider using {@link GithubOrgEntityProvider} instead.
|
|
243
274
|
*
|
|
244
275
|
* @public
|
|
245
276
|
*/
|
package/dist/index.cjs.js
CHANGED
|
@@ -38,7 +38,7 @@ function _interopNamespace(e) {
|
|
|
38
38
|
var parseGitUrl__default = /*#__PURE__*/_interopDefaultLegacy(parseGitUrl);
|
|
39
39
|
var uuid__namespace = /*#__PURE__*/_interopNamespace(uuid);
|
|
40
40
|
|
|
41
|
-
class
|
|
41
|
+
class GithubLocationAnalyzer {
|
|
42
42
|
constructor(options) {
|
|
43
43
|
this.config = options.config;
|
|
44
44
|
this.catalogClient = new catalogClient.CatalogClient({ discoveryApi: options.discovery });
|
|
@@ -372,7 +372,7 @@ function assignGroupsToUsers(users, groupMemberUsers) {
|
|
|
372
372
|
}
|
|
373
373
|
}
|
|
374
374
|
|
|
375
|
-
function
|
|
375
|
+
function parseGithubOrgUrl(urlString) {
|
|
376
376
|
const path = new URL(urlString).pathname.substr(1).split("/");
|
|
377
377
|
if (path.length === 1 && path[0].length) {
|
|
378
378
|
return { org: decodeURIComponent(path[0]) };
|
|
@@ -641,7 +641,7 @@ class GithubOrgReaderProcessor {
|
|
|
641
641
|
return false;
|
|
642
642
|
}
|
|
643
643
|
const { client, tokenType } = await this.createClient(location.target);
|
|
644
|
-
const { org } =
|
|
644
|
+
const { org } = parseGithubOrgUrl(location.target);
|
|
645
645
|
const startTimestamp = Date.now();
|
|
646
646
|
this.logger.info("Reading GitHub users and groups");
|
|
647
647
|
const { users } = await getOrganizationUsers(client, org, tokenType);
|
|
@@ -738,7 +738,7 @@ function compileRegExp(pattern) {
|
|
|
738
738
|
return new RegExp(fullLinePattern);
|
|
739
739
|
}
|
|
740
740
|
|
|
741
|
-
class
|
|
741
|
+
class GithubEntityProvider {
|
|
742
742
|
static fromConfig(config, options) {
|
|
743
743
|
if (!options.schedule && !options.scheduler) {
|
|
744
744
|
throw new Error("Either schedule or scheduler must be provided.");
|
|
@@ -759,7 +759,7 @@ class GitHubEntityProvider {
|
|
|
759
759
|
);
|
|
760
760
|
}
|
|
761
761
|
const taskRunner = (_a = options.schedule) != null ? _a : options.scheduler.createScheduledTaskRunner(providerConfig.schedule);
|
|
762
|
-
return new
|
|
762
|
+
return new GithubEntityProvider(
|
|
763
763
|
providerConfig,
|
|
764
764
|
integration,
|
|
765
765
|
options.logger,
|
|
@@ -790,7 +790,7 @@ class GitHubEntityProvider {
|
|
|
790
790
|
id: taskId,
|
|
791
791
|
fn: async () => {
|
|
792
792
|
const logger = this.logger.child({
|
|
793
|
-
class:
|
|
793
|
+
class: GithubEntityProvider.prototype.constructor.name,
|
|
794
794
|
taskId,
|
|
795
795
|
taskInstanceId: uuid__namespace.v4()
|
|
796
796
|
});
|
|
@@ -809,7 +809,7 @@ class GitHubEntityProvider {
|
|
|
809
809
|
}
|
|
810
810
|
const targets = await this.findCatalogFiles();
|
|
811
811
|
const matchingTargets = this.matchesFilters(targets);
|
|
812
|
-
const entities = matchingTargets.map((repository) => this.createLocationUrl(repository)).map(
|
|
812
|
+
const entities = matchingTargets.map((repository) => this.createLocationUrl(repository)).map(GithubEntityProvider.toLocationSpec).map((location) => {
|
|
813
813
|
return {
|
|
814
814
|
locationKey: this.getProviderName(),
|
|
815
815
|
entity: pluginCatalogBackend.locationSpecToLocationEntity({ location })
|
|
@@ -868,7 +868,7 @@ class GitHubEntityProvider {
|
|
|
868
868
|
}
|
|
869
869
|
}
|
|
870
870
|
|
|
871
|
-
class
|
|
871
|
+
class GithubOrgEntityProvider {
|
|
872
872
|
constructor(options) {
|
|
873
873
|
this.options = options;
|
|
874
874
|
this.credentialsProvider = options.githubCredentialsProvider || integration.SingleInstanceGithubCredentialsProvider.create(this.options.gitHubConfig);
|
|
@@ -885,7 +885,7 @@ class GitHubOrgEntityProvider {
|
|
|
885
885
|
const logger = options.logger.child({
|
|
886
886
|
target: options.orgUrl
|
|
887
887
|
});
|
|
888
|
-
const provider = new
|
|
888
|
+
const provider = new GithubOrgEntityProvider({
|
|
889
889
|
id: options.id,
|
|
890
890
|
orgUrl: options.orgUrl,
|
|
891
891
|
logger,
|
|
@@ -896,7 +896,7 @@ class GitHubOrgEntityProvider {
|
|
|
896
896
|
return provider;
|
|
897
897
|
}
|
|
898
898
|
getProviderName() {
|
|
899
|
-
return `
|
|
899
|
+
return `GithubOrgEntityProvider:${this.options.id}`;
|
|
900
900
|
}
|
|
901
901
|
async connect(connection) {
|
|
902
902
|
var _a;
|
|
@@ -917,7 +917,7 @@ class GitHubOrgEntityProvider {
|
|
|
917
917
|
baseUrl: this.options.gitHubConfig.apiBaseUrl,
|
|
918
918
|
headers
|
|
919
919
|
});
|
|
920
|
-
const { org } =
|
|
920
|
+
const { org } = parseGithubOrgUrl(this.options.orgUrl);
|
|
921
921
|
const { users } = await getOrganizationUsers(client, org, tokenType);
|
|
922
922
|
const { groups, groupMemberUsers } = await getOrganizationTeams(
|
|
923
923
|
client,
|
|
@@ -949,7 +949,7 @@ class GitHubOrgEntityProvider {
|
|
|
949
949
|
id,
|
|
950
950
|
fn: async () => {
|
|
951
951
|
const logger = this.options.logger.child({
|
|
952
|
-
class:
|
|
952
|
+
class: GithubOrgEntityProvider.prototype.constructor.name,
|
|
953
953
|
taskId: id,
|
|
954
954
|
taskInstanceId: uuid__namespace.v4()
|
|
955
955
|
});
|
|
@@ -1008,7 +1008,7 @@ const githubEntityProviderCatalogModule = backendPluginApi.createBackendModule({
|
|
|
1008
1008
|
},
|
|
1009
1009
|
async init({ catalog, config, logger, scheduler }) {
|
|
1010
1010
|
catalog.addEntityProvider(
|
|
1011
|
-
|
|
1011
|
+
GithubEntityProvider.fromConfig(config, {
|
|
1012
1012
|
logger: backendPluginApi.loggerToWinstonLogger(logger),
|
|
1013
1013
|
scheduler
|
|
1014
1014
|
})
|
|
@@ -1018,11 +1018,47 @@ const githubEntityProviderCatalogModule = backendPluginApi.createBackendModule({
|
|
|
1018
1018
|
}
|
|
1019
1019
|
});
|
|
1020
1020
|
|
|
1021
|
+
class GitHubOrgEntityProvider extends GithubOrgEntityProvider {
|
|
1022
|
+
static fromConfig(config, options) {
|
|
1023
|
+
options.logger.warn(
|
|
1024
|
+
"[Deprecated] Use GithubOrgEntityProvider instead of GitHubOrgEntityProvider."
|
|
1025
|
+
);
|
|
1026
|
+
return GithubOrgEntityProvider.fromConfig(
|
|
1027
|
+
config,
|
|
1028
|
+
options
|
|
1029
|
+
);
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
1032
|
+
class GitHubEntityProvider {
|
|
1033
|
+
constructor(delegate) {
|
|
1034
|
+
this.delegate = delegate;
|
|
1035
|
+
}
|
|
1036
|
+
static fromConfig(config, options) {
|
|
1037
|
+
options.logger.warn(
|
|
1038
|
+
"[Deprecated] Please use GithubEntityProvider instead of GitHubEntityProvider."
|
|
1039
|
+
);
|
|
1040
|
+
return GithubEntityProvider.fromConfig(config, options).map(
|
|
1041
|
+
(delegate) => new GitHubEntityProvider(delegate)
|
|
1042
|
+
);
|
|
1043
|
+
}
|
|
1044
|
+
connect(connection) {
|
|
1045
|
+
return this.delegate.connect(connection);
|
|
1046
|
+
}
|
|
1047
|
+
getProviderName() {
|
|
1048
|
+
return this.delegate.getProviderName();
|
|
1049
|
+
}
|
|
1050
|
+
refresh(logger) {
|
|
1051
|
+
return this.delegate.refresh(logger);
|
|
1052
|
+
}
|
|
1053
|
+
}
|
|
1054
|
+
|
|
1021
1055
|
exports.GitHubEntityProvider = GitHubEntityProvider;
|
|
1022
|
-
exports.GitHubLocationAnalyzer = GitHubLocationAnalyzer;
|
|
1023
1056
|
exports.GitHubOrgEntityProvider = GitHubOrgEntityProvider;
|
|
1024
1057
|
exports.GithubDiscoveryProcessor = GithubDiscoveryProcessor;
|
|
1058
|
+
exports.GithubEntityProvider = GithubEntityProvider;
|
|
1059
|
+
exports.GithubLocationAnalyzer = GithubLocationAnalyzer;
|
|
1025
1060
|
exports.GithubMultiOrgReaderProcessor = GithubMultiOrgReaderProcessor;
|
|
1061
|
+
exports.GithubOrgEntityProvider = GithubOrgEntityProvider;
|
|
1026
1062
|
exports.GithubOrgReaderProcessor = GithubOrgReaderProcessor;
|
|
1027
1063
|
exports.githubEntityProviderCatalogModule = githubEntityProviderCatalogModule;
|
|
1028
1064
|
//# sourceMappingURL=index.cjs.js.map
|
package/dist/index.cjs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs.js","sources":["../src/analyzers/GitHubLocationAnalyzer.ts","../src/lib/config.ts","../src/lib/github.ts","../src/lib/org.ts","../src/lib/util.ts","../src/processors/GithubDiscoveryProcessor.ts","../src/processors/GithubMultiOrgReaderProcessor.ts","../src/processors/GithubOrgReaderProcessor.ts","../src/providers/GitHubEntityProviderConfig.ts","../src/providers/GitHubEntityProvider.ts","../src/providers/GitHubOrgEntityProvider.ts","../src/service/GithubEntityProviderCatalogModule.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 { CatalogApi, CatalogClient } from '@backstage/catalog-client';\nimport { ScmIntegrations } from '@backstage/integration';\nimport { Octokit } from '@octokit/rest';\nimport { trimEnd } from 'lodash';\nimport parseGitUrl from 'git-url-parse';\nimport {\n AnalyzeOptions,\n ScmLocationAnalyzer,\n} from '@backstage/plugin-catalog-backend';\nimport { PluginEndpointDiscovery } from '@backstage/backend-common';\nimport { Config } from '@backstage/config';\n\n/** @public */\nexport type GitHubLocationAnalyzerOptions = {\n config: Config;\n discovery: PluginEndpointDiscovery;\n};\n/** @public */\nexport class GitHubLocationAnalyzer implements ScmLocationAnalyzer {\n private readonly catalogClient: CatalogApi;\n private readonly config: Config;\n\n constructor(options: GitHubLocationAnalyzerOptions) {\n this.config = options.config;\n this.catalogClient = new CatalogClient({ discoveryApi: options.discovery });\n }\n supports(url: string) {\n const integrations = ScmIntegrations.fromConfig(this.config);\n const integration = integrations.byUrl(url);\n return integration?.type === 'github';\n }\n async analyze({ url, catalogFilename }: AnalyzeOptions) {\n const { owner, name: repo } = parseGitUrl(url);\n\n const catalogFile = catalogFilename || 'catalog-info.yaml';\n\n const query = `filename:${catalogFile} repo:${owner}/${repo}`;\n\n const integration = ScmIntegrations.fromConfig(this.config).github.byUrl(\n url,\n );\n if (!integration) {\n throw new Error('Make sure you have a GitHub integration configured');\n }\n\n const octokitClient = new Octokit({\n auth: integration.config.token,\n baseUrl: integration.config.apiBaseUrl,\n });\n\n const searchResult = await octokitClient.search\n .code({ q: query })\n .catch(e => {\n throw new Error(`Couldn't search repository for metadata file, ${e}`);\n });\n\n const exists = searchResult.data.total_count > 0;\n if (exists) {\n const repoInformation = await octokitClient.repos\n .get({ owner, repo })\n .catch(e => {\n throw new Error(`Couldn't fetch repo data, ${e}`);\n });\n const defaultBranch = repoInformation.data.default_branch;\n\n const result = await Promise.all(\n searchResult.data.items\n .map(i => `${trimEnd(url, '/')}/blob/${defaultBranch}/${i.path}`)\n .map(async target => {\n const addLocationResult = await this.catalogClient.addLocation({\n type: 'url',\n target,\n dryRun: true,\n });\n return addLocationResult.entities.map(e => ({\n location: { type: 'url', target },\n isRegistered: !!addLocationResult.exists,\n entity: e,\n }));\n }),\n );\n\n return { existing: result.flat() };\n }\n return { existing: [] };\n }\n}\n","/*\n * Copyright 2020 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 { Config } from '@backstage/config';\n\n/**\n * The configuration parameters for a multi-org GitHub processor.\n * @public\n */\nexport type GithubMultiOrgConfig = Array<{\n /**\n * The name of the GitHub org to process.\n */\n name: string;\n /**\n * The namespace of the group created for this org.\n */\n groupNamespace: string;\n /**\n * The namespace of the users created for this org. If not specified defaults to undefined.\n */\n userNamespace: string | undefined;\n}>;\n\nexport function readGithubMultiOrgConfig(config: Config): GithubMultiOrgConfig {\n const orgConfigs = config.getOptionalConfigArray('orgs') ?? [];\n return orgConfigs.map(c => ({\n name: c.getString('name'),\n groupNamespace: (\n c.getOptionalString('groupNamespace') ?? c.getString('name')\n ).toLowerCase(),\n userNamespace: c.getOptionalString('userNamespace') ?? undefined,\n }));\n}\n","/*\n * Copyright 2020 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 { GroupEntity, UserEntity } from '@backstage/catalog-model';\nimport { GithubCredentialType } from '@backstage/integration';\nimport { graphql } from '@octokit/graphql';\n\n// Graphql types\n\nexport type QueryResponse = {\n organization?: Organization;\n repositoryOwner?: Organization | User;\n};\n\nexport type Organization = {\n membersWithRole?: Connection<User>;\n team?: Team;\n teams?: Connection<Team>;\n repositories?: Connection<Repository>;\n};\n\nexport type PageInfo = {\n hasNextPage: boolean;\n endCursor?: string;\n};\n\nexport type User = {\n login: string;\n bio?: string;\n avatarUrl?: string;\n email?: string;\n name?: string;\n repositories?: Connection<Repository>;\n};\n\nexport type Team = {\n slug: string;\n combinedSlug: string;\n name?: string;\n description?: string;\n avatarUrl?: string;\n editTeamUrl?: string;\n parentTeam?: Team;\n members: Connection<User>;\n};\n\nexport type Repository = {\n name: string;\n url: string;\n isArchived: boolean;\n repositoryTopics: RepositoryTopics;\n defaultBranchRef: {\n name: string;\n } | null;\n};\n\ntype RepositoryTopics = {\n nodes: TopicNodes[];\n};\n\ntype TopicNodes = {\n topic: {\n name: string;\n };\n};\n\nexport type Connection<T> = {\n pageInfo: PageInfo;\n nodes: T[];\n};\n\n/**\n * Gets all the users out of a GitHub organization.\n *\n * Note that the users will not have their memberships filled in.\n *\n * @param client - An octokit graphql client\n * @param org - The slug of the org to read\n */\nexport async function getOrganizationUsers(\n client: typeof graphql,\n org: string,\n tokenType: GithubCredentialType,\n userNamespace?: string,\n): Promise<{ users: UserEntity[] }> {\n const query = `\n query users($org: String!, $email: Boolean!, $cursor: String) {\n organization(login: $org) {\n membersWithRole(first: 100, after: $cursor) {\n pageInfo { hasNextPage, endCursor }\n nodes {\n avatarUrl,\n bio,\n email @include(if: $email),\n login,\n name\n }\n }\n }\n }`;\n\n // There is no user -> teams edge, so we leave the memberships empty for\n // now and let the team iteration handle it instead\n const mapper = (user: User) => {\n const entity: UserEntity = {\n apiVersion: 'backstage.io/v1alpha1',\n kind: 'User',\n metadata: {\n name: user.login,\n annotations: {\n 'github.com/user-login': user.login,\n },\n },\n spec: {\n profile: {},\n memberOf: [],\n },\n };\n\n if (userNamespace) entity.metadata.namespace = userNamespace;\n if (user.bio) entity.metadata.description = user.bio;\n if (user.name) entity.spec.profile!.displayName = user.name;\n if (user.email) entity.spec.profile!.email = user.email;\n if (user.avatarUrl) entity.spec.profile!.picture = user.avatarUrl;\n\n return entity;\n };\n\n const users = await queryWithPaging(\n client,\n query,\n r => r.organization?.membersWithRole,\n mapper,\n { org, email: tokenType === 'token' },\n );\n\n return { users };\n}\n\n/**\n * Gets all the teams out of a GitHub organization.\n *\n * Note that the teams will not have any relations apart from parent filled in.\n *\n * @param client - An octokit graphql client\n * @param org - The slug of the org to read\n */\nexport async function getOrganizationTeams(\n client: typeof graphql,\n org: string,\n orgNamespace?: string,\n): Promise<{\n groups: GroupEntity[];\n groupMemberUsers: Map<string, string[]>;\n}> {\n const query = `\n query teams($org: String!, $cursor: String) {\n organization(login: $org) {\n teams(first: 100, after: $cursor) {\n pageInfo { hasNextPage, endCursor }\n nodes {\n slug\n combinedSlug\n name\n description\n avatarUrl\n editTeamUrl\n parentTeam { slug }\n members(first: 100, membership: IMMEDIATE) {\n pageInfo { hasNextPage }\n nodes { login }\n }\n }\n }\n }\n }`;\n\n // Gets populated inside the mapper below\n const groupMemberUsers = new Map<string, string[]>();\n\n const mapper = async (team: Team) => {\n const annotations: { [annotationName: string]: string } = {\n 'github.com/team-slug': team.combinedSlug,\n };\n\n if (team.editTeamUrl) {\n annotations['backstage.io/edit-url'] = team.editTeamUrl;\n }\n\n const entity: GroupEntity = {\n apiVersion: 'backstage.io/v1alpha1',\n kind: 'Group',\n metadata: {\n name: team.slug,\n annotations,\n },\n spec: {\n type: 'team',\n profile: {},\n children: [],\n },\n };\n\n if (orgNamespace) {\n entity.metadata.namespace = orgNamespace;\n }\n\n if (team.description) {\n entity.metadata.description = team.description;\n }\n if (team.name) {\n entity.spec.profile!.displayName = team.name;\n }\n if (team.avatarUrl) {\n entity.spec.profile!.picture = team.avatarUrl;\n }\n if (team.parentTeam) {\n entity.spec.parent = team.parentTeam.slug;\n }\n\n const memberNames: string[] = [];\n const groupKey = orgNamespace ? `${orgNamespace}/${team.slug}` : team.slug;\n groupMemberUsers.set(groupKey, memberNames);\n\n if (!team.members.pageInfo.hasNextPage) {\n // We got all the members in one go, run the fast path\n for (const user of team.members.nodes) {\n memberNames.push(user.login);\n }\n } else {\n // There were more than a hundred immediate members - run the slow\n // path of fetching them explicitly\n const { members } = await getTeamMembers(client, org, team.slug);\n for (const userLogin of members) {\n memberNames.push(userLogin);\n }\n }\n\n return entity;\n };\n\n const groups = await queryWithPaging(\n client,\n query,\n r => r.organization?.teams,\n mapper,\n { org },\n );\n\n return { groups, groupMemberUsers };\n}\n\nexport async function getOrganizationRepositories(\n client: typeof graphql,\n org: string,\n): Promise<{ repositories: Repository[] }> {\n const query = `\n query repositories($org: String!, $cursor: String) {\n repositoryOwner(login: $org) {\n login\n repositories(first: 100, after: $cursor) {\n nodes {\n name\n url\n isArchived\n repositoryTopics(first: 100) {\n nodes {\n ... on RepositoryTopic {\n topic {\n name\n }\n }\n }\n }\n defaultBranchRef {\n name\n }\n }\n pageInfo {\n hasNextPage\n endCursor\n }\n }\n }\n }`;\n\n const repositories = await queryWithPaging(\n client,\n query,\n r => r.repositoryOwner?.repositories,\n x => x,\n { org },\n );\n\n return { repositories };\n}\n\n/**\n * Gets all the users out of a GitHub organization.\n *\n * Note that the users will not have their memberships filled in.\n *\n * @param client - An octokit graphql client\n * @param org - The slug of the org to read\n * @param teamSlug - The slug of the team to read\n */\nexport async function getTeamMembers(\n client: typeof graphql,\n org: string,\n teamSlug: string,\n): Promise<{ members: string[] }> {\n const query = `\n query members($org: String!, $teamSlug: String!, $cursor: String) {\n organization(login: $org) {\n team(slug: $teamSlug) {\n members(first: 100, after: $cursor, membership: IMMEDIATE) {\n pageInfo { hasNextPage, endCursor }\n nodes { login }\n }\n }\n }\n }`;\n\n const members = await queryWithPaging(\n client,\n query,\n r => r.organization?.team?.members,\n user => user.login,\n { org, teamSlug },\n );\n\n return { members };\n}\n\n//\n// Helpers\n//\n\n/**\n * Assists in repeatedly executing a query with a paged response.\n *\n * Requires that the query accepts a $cursor variable.\n *\n * @param client - The octokit client\n * @param query - The query to execute\n * @param connection - A function that, given the response, picks out the actual\n * Connection object that's being iterated\n * @param mapper - A function that, given one of the nodes in the Connection,\n * returns the model mapped form of it\n * @param variables - The variable values that the query needs, minus the cursor\n */\nexport async function queryWithPaging<\n GraphqlType,\n OutputType,\n Variables extends {},\n Response = QueryResponse,\n>(\n client: typeof graphql,\n query: string,\n connection: (response: Response) => Connection<GraphqlType> | undefined,\n mapper: (item: GraphqlType) => Promise<OutputType> | OutputType,\n variables: Variables,\n): Promise<OutputType[]> {\n const result: OutputType[] = [];\n\n let cursor: string | undefined = undefined;\n for (let j = 0; j < 1000 /* just for sanity */; ++j) {\n const response: Response = await client(query, {\n ...variables,\n cursor,\n });\n\n const conn = connection(response);\n if (!conn) {\n throw new Error(`Found no match for ${JSON.stringify(variables)}`);\n }\n\n for (const node of conn.nodes) {\n result.push(await mapper(node));\n }\n\n if (!conn.pageInfo.hasNextPage) {\n break;\n } else {\n cursor = conn.pageInfo.endCursor;\n }\n }\n\n return result;\n}\n","/*\n * Copyright 2020 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 { GroupEntity, UserEntity } from '@backstage/catalog-model';\n\nexport function buildOrgHierarchy(groups: GroupEntity[]) {\n const groupsByName = new Map(groups.map(g => [g.metadata.name, g]));\n\n //\n // Make sure that g.parent.children contain g\n //\n\n for (const group of groups) {\n const selfName = group.metadata.name;\n const parentName = group.spec.parent;\n if (parentName) {\n const parent = groupsByName.get(parentName);\n if (parent && !parent.spec.children.includes(selfName)) {\n parent.spec.children.push(selfName);\n }\n }\n }\n\n //\n // Make sure that g.children.parent is g\n //\n\n for (const group of groups) {\n const selfName = group.metadata.name;\n for (const childName of group.spec.children) {\n const child = groupsByName.get(childName);\n if (child && !child.spec.parent) {\n child.spec.parent = selfName;\n }\n }\n }\n}\n\n// Ensure that users have their direct group memberships.\nexport function assignGroupsToUsers(\n users: UserEntity[],\n groupMemberUsers: Map<string, string[]>,\n) {\n const usersByName = new Map(users.map(u => [u.metadata.name, u]));\n for (const [groupName, userNames] of groupMemberUsers.entries()) {\n for (const userName of userNames) {\n const user = usersByName.get(userName);\n if (user && !user.spec.memberOf?.includes(groupName)) {\n if (!user.spec.memberOf) {\n user.spec.memberOf = [];\n }\n user.spec.memberOf.push(groupName);\n }\n }\n }\n}\n\n// Ensure that users have their transitive group memberships. Requires that\n// the groups were previously processed with buildOrgHierarchy()\nexport function buildMemberOf(groups: GroupEntity[], users: UserEntity[]) {\n const groupsByName = new Map(groups.map(g => [g.metadata.name, g]));\n\n users.forEach(user => {\n const transitiveMemberOf = new Set<string>();\n\n const todo = [\n ...(user.spec.memberOf ?? []),\n ...groups\n .filter(g => g.spec.members?.includes(user.metadata.name))\n .map(g => g.metadata.name),\n ];\n\n for (;;) {\n const current = todo.pop();\n if (!current) {\n break;\n }\n\n if (!transitiveMemberOf.has(current)) {\n transitiveMemberOf.add(current);\n const group = groupsByName.get(current);\n if (group?.spec.parent) {\n todo.push(group.spec.parent);\n }\n }\n }\n\n user.spec.memberOf = [...transitiveMemberOf];\n });\n}\n","/*\n * Copyright 2021 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 { GithubTopicFilters } from '../providers/GitHubEntityProviderConfig';\n\nexport function parseGitHubOrgUrl(urlString: string): { org: string } {\n const path = new URL(urlString).pathname.substr(1).split('/');\n\n // /backstage\n if (path.length === 1 && path[0].length) {\n return { org: decodeURIComponent(path[0]) };\n }\n\n throw new Error(`Expected a URL pointing to /<org>`);\n}\n\nexport function satisfiesTopicFilter(\n topics: string[],\n topicFilter: GithubTopicFilters | undefined,\n): Boolean {\n // We don't want to do anything if a filter is not configured (or configured but empty)\n if (!topicFilter) return true;\n if (!topicFilter.include && !topicFilter.exclude) return true;\n if (!topicFilter.include?.length && !topicFilter.exclude?.length) return true;\n // If topic.include is in use, a topic MUST be set that matches the inclusion\n // filter in order for a repository to be ingested\n if (topicFilter.include?.length && !topicFilter.exclude) {\n for (const topic of topics) {\n if (topicFilter.include.includes(topic)) return true;\n }\n return false;\n }\n // If topic.exclude is in use, all topics are included by default\n // with anything matching the filter being discarded. It is technically\n // possible for the filter to be explicitly empty meaning all repositories\n // are ingested although doing so would be pointless.\n if (!topicFilter.include && topicFilter.exclude?.length) {\n if (!topics.length) return true;\n for (const topic of topics) {\n if (topicFilter.exclude.includes(topic)) return false;\n }\n return true;\n }\n // Now the tricky part is where we have both include and exclude configured.\n // In this case, exclude wins out so we take everything matching the initial\n // inclusion filter and from that group, we further discard anything matching\n // the exclusion filter. If an item were to have a topic set in both filters,\n // we expect it to be discarded in the end. The use case here is that is that\n // you may want to retrieve all repos with the topic of team-a while excluding\n // matching repos that are marked as experiments.\n if (topicFilter.include && topicFilter.exclude) {\n const matchesInclude = satisfiesTopicFilter(topics, {\n include: topicFilter.include,\n });\n const matchesExclude = !satisfiesTopicFilter(topics, {\n exclude: topicFilter.exclude,\n });\n if (matchesExclude) return false;\n return matchesInclude;\n }\n\n // If the topic filter is somehow ever in a state that is not covered here, we\n // will fail \"open\" so that Backstage is still usable as if the filter was\n // not configured at all.\n return true;\n}\n","/*\n * Copyright 2021 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 { Config } from '@backstage/config';\nimport {\n DefaultGithubCredentialsProvider,\n GithubCredentialsProvider,\n ScmIntegrationRegistry,\n ScmIntegrations,\n} from '@backstage/integration';\nimport {\n CatalogProcessor,\n CatalogProcessorEmit,\n LocationSpec,\n processingResult,\n} from '@backstage/plugin-catalog-backend';\nimport { graphql } from '@octokit/graphql';\nimport { Logger } from 'winston';\nimport { getOrganizationRepositories } from '../lib';\n\n/**\n * Extracts repositories out of a GitHub org.\n *\n * The following will create locations for all projects which have a catalog-info.yaml\n * on the default branch. The first is shorthand for the second.\n *\n * target: \"https://github.com/backstage\"\n * or\n * target: https://github.com/backstage/*\\/blob/-/catalog-info.yaml\n *\n * You may also explicitly specify the source branch:\n *\n * target: https://github.com/backstage/*\\/blob/main/catalog-info.yaml\n *\n * @public\n **/\nexport class GithubDiscoveryProcessor implements CatalogProcessor {\n private readonly integrations: ScmIntegrationRegistry;\n private readonly logger: Logger;\n private readonly githubCredentialsProvider: GithubCredentialsProvider;\n\n static fromConfig(\n config: Config,\n options: {\n logger: Logger;\n githubCredentialsProvider?: GithubCredentialsProvider;\n },\n ) {\n const integrations = ScmIntegrations.fromConfig(config);\n\n return new GithubDiscoveryProcessor({\n ...options,\n integrations,\n });\n }\n\n constructor(options: {\n integrations: ScmIntegrationRegistry;\n logger: Logger;\n githubCredentialsProvider?: GithubCredentialsProvider;\n }) {\n this.integrations = options.integrations;\n this.logger = options.logger;\n this.githubCredentialsProvider =\n options.githubCredentialsProvider ||\n DefaultGithubCredentialsProvider.fromIntegrations(this.integrations);\n }\n getProcessorName(): string {\n return 'GithubDiscoveryProcessor';\n }\n\n async readLocation(\n location: LocationSpec,\n _optional: boolean,\n emit: CatalogProcessorEmit,\n ): Promise<boolean> {\n if (location.type !== 'github-discovery') {\n return false;\n }\n\n const gitHubConfig = this.integrations.github.byUrl(\n location.target,\n )?.config;\n if (!gitHubConfig) {\n throw new Error(\n `There is no GitHub integration that matches ${location.target}. Please add a configuration entry for it under integrations.github`,\n );\n }\n\n const { org, repoSearchPath, catalogPath, branch, host } = parseUrl(\n location.target,\n );\n\n // Building the org url here so that the github creds provider doesn't need to know\n // about how to handle the wild card which is special for this processor.\n const orgUrl = `https://${host}/${org}`;\n\n const { headers } = await this.githubCredentialsProvider.getCredentials({\n url: orgUrl,\n });\n\n const client = graphql.defaults({\n baseUrl: gitHubConfig.apiBaseUrl,\n headers,\n });\n\n // Read out all of the raw data\n const startTimestamp = Date.now();\n this.logger.info(`Reading GitHub repositories from ${location.target}`);\n\n const { repositories } = await getOrganizationRepositories(client, org);\n const matching = repositories.filter(\n r => !r.isArchived && repoSearchPath.test(r.name),\n );\n\n const duration = ((Date.now() - startTimestamp) / 1000).toFixed(1);\n this.logger.debug(\n `Read ${repositories.length} GitHub repositories (${matching.length} matching the pattern) in ${duration} seconds`,\n );\n\n for (const repository of matching) {\n const branchName =\n branch === '-' ? repository.defaultBranchRef?.name : branch;\n\n if (!branchName) {\n this.logger.info(\n `the repository ${repository.url} does not have a default branch, skipping`,\n );\n continue;\n }\n\n const path = `/blob/${branchName}${catalogPath}`;\n\n emit(\n processingResult.location({\n type: 'url',\n target: `${repository.url}${path}`,\n // Not all locations may actually exist, since the user defined them as a wildcard pattern.\n // Thus, we emit them as optional and let the downstream processor find them while not outputting\n // an error if it couldn't.\n presence: 'optional',\n }),\n );\n }\n\n return true;\n }\n}\n\n/*\n * Helpers\n */\n\nexport function parseUrl(urlString: string): {\n org: string;\n repoSearchPath: RegExp;\n catalogPath: string;\n branch: string;\n host: string;\n} {\n const url = new URL(urlString);\n const path = url.pathname.substr(1).split('/');\n\n // /backstage/techdocs-*/blob/master/catalog-info.yaml\n // can also be\n // /backstage\n if (path.length > 2 && path[0].length && path[1].length) {\n return {\n org: decodeURIComponent(path[0]),\n repoSearchPath: escapeRegExp(decodeURIComponent(path[1])),\n branch: decodeURIComponent(path[3]),\n catalogPath: `/${decodeURIComponent(path.slice(4).join('/'))}`,\n host: url.host,\n };\n } else if (path.length === 1 && path[0].length) {\n return {\n org: decodeURIComponent(path[0]),\n host: url.host,\n repoSearchPath: escapeRegExp('*'),\n catalogPath: '/catalog-info.yaml',\n branch: '-',\n };\n }\n\n throw new Error(`Failed to parse ${urlString}`);\n}\n\nexport function escapeRegExp(str: string): RegExp {\n return new RegExp(`^${str.replace(/\\*/g, '.*')}$`);\n}\n","/*\n * Copyright 2021 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 { Config } from '@backstage/config';\nimport {\n DefaultGithubCredentialsProvider,\n GithubAppCredentialsMux,\n GithubCredentialsProvider,\n GitHubIntegrationConfig,\n ScmIntegrationRegistry,\n ScmIntegrations,\n} from '@backstage/integration';\nimport {\n CatalogProcessor,\n CatalogProcessorEmit,\n LocationSpec,\n processingResult,\n} from '@backstage/plugin-catalog-backend';\nimport { graphql } from '@octokit/graphql';\nimport { Logger } from 'winston';\nimport {\n buildOrgHierarchy,\n getOrganizationTeams,\n getOrganizationUsers,\n GithubMultiOrgConfig,\n readGithubMultiOrgConfig,\n} from '../lib';\n\n/**\n * Extracts teams and users out of a multiple GitHub orgs namespaced per org.\n *\n * Be aware that this processor may not be compatible with future org structures in the catalog.\n *\n * @public\n */\nexport class GithubMultiOrgReaderProcessor implements CatalogProcessor {\n private readonly integrations: ScmIntegrationRegistry;\n private readonly orgs: GithubMultiOrgConfig;\n private readonly logger: Logger;\n private readonly githubCredentialsProvider: GithubCredentialsProvider;\n\n static fromConfig(\n config: Config,\n options: {\n logger: Logger;\n githubCredentialsProvider?: GithubCredentialsProvider;\n },\n ) {\n const c = config.getOptionalConfig('catalog.processors.githubMultiOrg');\n const integrations = ScmIntegrations.fromConfig(config);\n\n return new GithubMultiOrgReaderProcessor({\n ...options,\n integrations,\n orgs: c ? readGithubMultiOrgConfig(c) : [],\n });\n }\n\n constructor(options: {\n integrations: ScmIntegrationRegistry;\n logger: Logger;\n orgs: GithubMultiOrgConfig;\n githubCredentialsProvider?: GithubCredentialsProvider;\n }) {\n this.integrations = options.integrations;\n this.logger = options.logger;\n this.orgs = options.orgs;\n this.githubCredentialsProvider =\n options.githubCredentialsProvider ||\n DefaultGithubCredentialsProvider.fromIntegrations(this.integrations);\n }\n getProcessorName(): string {\n return 'GithubMultiOrgReaderProcessor';\n }\n\n async readLocation(\n location: LocationSpec,\n _optional: boolean,\n emit: CatalogProcessorEmit,\n ): Promise<boolean> {\n if (location.type !== 'github-multi-org') {\n return false;\n }\n\n const gitHubConfig = this.integrations.github.byUrl(\n location.target,\n )?.config;\n if (!gitHubConfig) {\n throw new Error(\n `There is no GitHub integration that matches ${location.target}. Please add a configuration entry for it under integrations.github`,\n );\n }\n\n const allUsersMap = new Map();\n const baseUrl = new URL(location.target).origin;\n\n const orgsToProcess = this.orgs.length\n ? this.orgs\n : await this.getAllOrgs(gitHubConfig);\n\n for (const orgConfig of orgsToProcess) {\n try {\n const { headers, type: tokenType } =\n await this.githubCredentialsProvider.getCredentials({\n url: `${baseUrl}/${orgConfig.name}`,\n });\n const client = graphql.defaults({\n baseUrl: gitHubConfig.apiBaseUrl,\n headers,\n });\n\n const startTimestamp = Date.now();\n this.logger.info(\n `Reading GitHub users and teams for org: ${orgConfig.name}`,\n );\n const { users } = await getOrganizationUsers(\n client,\n orgConfig.name,\n tokenType,\n orgConfig.userNamespace,\n );\n const { groups, groupMemberUsers } = await getOrganizationTeams(\n client,\n orgConfig.name,\n orgConfig.groupNamespace,\n );\n\n const duration = ((Date.now() - startTimestamp) / 1000).toFixed(1);\n this.logger.debug(\n `Read ${users.length} GitHub users and ${groups.length} GitHub teams from ${orgConfig.name} in ${duration} seconds`,\n );\n\n let prefix: string = orgConfig.userNamespace ?? '';\n if (prefix.length > 0) prefix += '/';\n\n users.forEach(u => {\n if (!allUsersMap.has(prefix + u.metadata.name)) {\n allUsersMap.set(prefix + u.metadata.name, u);\n }\n });\n\n for (const [groupName, userNames] of groupMemberUsers.entries()) {\n for (const userName of userNames) {\n const user = allUsersMap.get(prefix + userName);\n if (user && !user.spec.memberOf.includes(groupName)) {\n user.spec.memberOf.push(groupName);\n }\n }\n }\n buildOrgHierarchy(groups);\n\n for (const group of groups) {\n emit(processingResult.entity(location, group));\n }\n } catch (e) {\n this.logger.error(\n `Failed to read GitHub org data for ${orgConfig.name}: ${e}`,\n );\n }\n }\n\n const allUsers = Array.from(allUsersMap.values());\n for (const user of allUsers) {\n emit(processingResult.entity(location, user));\n }\n\n return true;\n }\n\n // Note: Does not support usage of PATs\n private async getAllOrgs(\n gitHubConfig: GitHubIntegrationConfig,\n ): Promise<GithubMultiOrgConfig> {\n const githubAppMux = new GithubAppCredentialsMux(gitHubConfig);\n const installs = await githubAppMux.getAllInstallations();\n\n return installs\n .map(install =>\n install.target_type === 'Organization' &&\n install.account &&\n install.account.login\n ? {\n name: install.account.login,\n groupNamespace: install.account.login.toLowerCase(),\n }\n : undefined,\n )\n .filter(Boolean) as GithubMultiOrgConfig;\n }\n}\n","/*\n * Copyright 2020 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 { Config } from '@backstage/config';\nimport {\n DefaultGithubCredentialsProvider,\n GithubCredentialsProvider,\n GithubCredentialType,\n ScmIntegrationRegistry,\n ScmIntegrations,\n} from '@backstage/integration';\nimport {\n CatalogProcessor,\n CatalogProcessorEmit,\n LocationSpec,\n processingResult,\n} from '@backstage/plugin-catalog-backend';\nimport { graphql } from '@octokit/graphql';\nimport { Logger } from 'winston';\nimport {\n assignGroupsToUsers,\n buildOrgHierarchy,\n getOrganizationTeams,\n getOrganizationUsers,\n parseGitHubOrgUrl,\n} from '../lib';\n\ntype GraphQL = typeof graphql;\n\n/**\n * Extracts teams and users out of a GitHub org.\n *\n * @remarks\n *\n * Consider using {@link GitHubOrgEntityProvider} instead.\n *\n * @public\n */\nexport class GithubOrgReaderProcessor implements CatalogProcessor {\n private readonly integrations: ScmIntegrationRegistry;\n private readonly logger: Logger;\n private readonly githubCredentialsProvider: GithubCredentialsProvider;\n\n static fromConfig(\n config: Config,\n options: {\n logger: Logger;\n githubCredentialsProvider?: GithubCredentialsProvider;\n },\n ) {\n const integrations = ScmIntegrations.fromConfig(config);\n\n return new GithubOrgReaderProcessor({\n ...options,\n integrations,\n });\n }\n\n constructor(options: {\n integrations: ScmIntegrationRegistry;\n logger: Logger;\n githubCredentialsProvider?: GithubCredentialsProvider;\n }) {\n this.integrations = options.integrations;\n this.githubCredentialsProvider =\n options.githubCredentialsProvider ||\n DefaultGithubCredentialsProvider.fromIntegrations(this.integrations);\n this.logger = options.logger;\n }\n getProcessorName(): string {\n return 'GithubOrgReaderProcessor';\n }\n\n async readLocation(\n location: LocationSpec,\n _optional: boolean,\n emit: CatalogProcessorEmit,\n ): Promise<boolean> {\n if (location.type !== 'github-org') {\n return false;\n }\n\n const { client, tokenType } = await this.createClient(location.target);\n const { org } = parseGitHubOrgUrl(location.target);\n\n // Read out all of the raw data\n const startTimestamp = Date.now();\n this.logger.info('Reading GitHub users and groups');\n\n const { users } = await getOrganizationUsers(client, org, tokenType);\n const { groups, groupMemberUsers } = await getOrganizationTeams(\n client,\n org,\n );\n\n const duration = ((Date.now() - startTimestamp) / 1000).toFixed(1);\n this.logger.debug(\n `Read ${users.length} GitHub users and ${groups.length} GitHub groups in ${duration} seconds`,\n );\n\n assignGroupsToUsers(users, groupMemberUsers);\n buildOrgHierarchy(groups);\n\n // Done!\n for (const group of groups) {\n emit(processingResult.entity(location, group));\n }\n for (const user of users) {\n emit(processingResult.entity(location, user));\n }\n\n return true;\n }\n\n private async createClient(\n orgUrl: string,\n ): Promise<{ client: GraphQL; tokenType: GithubCredentialType }> {\n const gitHubConfig = this.integrations.github.byUrl(orgUrl)?.config;\n\n if (!gitHubConfig) {\n throw new Error(\n `There is no GitHub Org provider that matches ${orgUrl}. Please add a configuration for an integration.`,\n );\n }\n\n const { headers, type: tokenType } =\n await this.githubCredentialsProvider.getCredentials({\n url: orgUrl,\n });\n\n const client = graphql.defaults({\n baseUrl: gitHubConfig.apiBaseUrl,\n headers,\n });\n\n return { client, tokenType };\n }\n}\n","/*\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 readTaskScheduleDefinitionFromConfig,\n TaskScheduleDefinition,\n} from '@backstage/backend-tasks';\nimport { Config } from '@backstage/config';\n\nconst DEFAULT_CATALOG_PATH = '/catalog-info.yaml';\nconst DEFAULT_PROVIDER_ID = 'default';\n\nexport type GitHubEntityProviderConfig = {\n id: string;\n catalogPath: string;\n organization: string;\n host: string;\n filters?: {\n repository?: RegExp;\n branch?: string;\n topic?: GithubTopicFilters;\n };\n schedule?: TaskScheduleDefinition;\n};\n\nexport type GithubTopicFilters = {\n exclude?: string[];\n include?: string[];\n};\n\nexport function readProviderConfigs(\n config: Config,\n): GitHubEntityProviderConfig[] {\n const providersConfig = config.getOptionalConfig('catalog.providers.github');\n if (!providersConfig) {\n return [];\n }\n\n if (providersConfig.has('organization')) {\n // simple/single config variant\n return [readProviderConfig(DEFAULT_PROVIDER_ID, providersConfig)];\n }\n\n return providersConfig.keys().map(id => {\n const providerConfig = providersConfig.getConfig(id);\n\n return readProviderConfig(id, providerConfig);\n });\n}\n\nfunction readProviderConfig(\n id: string,\n config: Config,\n): GitHubEntityProviderConfig {\n const organization = config.getString('organization');\n const catalogPath =\n config.getOptionalString('catalogPath') ?? DEFAULT_CATALOG_PATH;\n const host = config.getOptionalString('host') ?? 'github.com';\n const repositoryPattern = config.getOptionalString('filters.repository');\n const branchPattern = config.getOptionalString('filters.branch');\n const topicFilterInclude = config?.getOptionalStringArray(\n 'filters.topic.include',\n );\n const topicFilterExclude = config?.getOptionalStringArray(\n 'filters.topic.exclude',\n );\n\n const schedule = config.has('schedule')\n ? readTaskScheduleDefinitionFromConfig(config.getConfig('schedule'))\n : undefined;\n\n return {\n id,\n catalogPath,\n organization,\n host,\n filters: {\n repository: repositoryPattern\n ? compileRegExp(repositoryPattern)\n : undefined,\n branch: branchPattern || undefined,\n topic: {\n include: topicFilterInclude,\n exclude: topicFilterExclude,\n },\n },\n schedule,\n };\n}\n\n/**\n * Compiles a RegExp while enforcing the pattern to contain\n * the start-of-line and end-of-line anchors.\n *\n * @param pattern\n */\nfunction compileRegExp(pattern: string): RegExp {\n let fullLinePattern = pattern;\n if (!fullLinePattern.startsWith('^')) {\n fullLinePattern = `^${fullLinePattern}`;\n }\n if (!fullLinePattern.endsWith('$')) {\n fullLinePattern = `${fullLinePattern}$`;\n }\n\n return new RegExp(fullLinePattern);\n}\n","/*\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 { PluginTaskScheduler, TaskRunner } from '@backstage/backend-tasks';\nimport { Config } from '@backstage/config';\nimport {\n GithubCredentialsProvider,\n ScmIntegrations,\n GitHubIntegrationConfig,\n GitHubIntegration,\n SingleInstanceGithubCredentialsProvider,\n} from '@backstage/integration';\nimport {\n EntityProvider,\n EntityProviderConnection,\n LocationSpec,\n locationSpecToLocationEntity,\n} from '@backstage/plugin-catalog-backend';\n\nimport { graphql } from '@octokit/graphql';\nimport * as uuid from 'uuid';\nimport { Logger } from 'winston';\nimport {\n readProviderConfigs,\n GitHubEntityProviderConfig,\n} from './GitHubEntityProviderConfig';\nimport { getOrganizationRepositories, Repository } from '../lib/github';\nimport { satisfiesTopicFilter } from '../lib/util';\n\n/**\n * Discovers catalog files located in [GitHub](https://github.com).\n * The provider will search your GitHub account and register catalog files matching the configured path\n * as Location entity and via following processing steps add all contained catalog entities.\n * This can be useful as an alternative to static locations or manually adding things to the catalog.\n *\n * @public\n */\nexport class GitHubEntityProvider implements EntityProvider {\n private readonly config: GitHubEntityProviderConfig;\n private readonly logger: Logger;\n private readonly integration: GitHubIntegrationConfig;\n private readonly scheduleFn: () => Promise<void>;\n private connection?: EntityProviderConnection;\n private readonly githubCredentialsProvider: GithubCredentialsProvider;\n\n static fromConfig(\n config: Config,\n options: {\n logger: Logger;\n schedule?: TaskRunner;\n scheduler?: PluginTaskScheduler;\n },\n ): GitHubEntityProvider[] {\n if (!options.schedule && !options.scheduler) {\n throw new Error('Either schedule or scheduler must be provided.');\n }\n\n const integrations = ScmIntegrations.fromConfig(config);\n\n return readProviderConfigs(config).map(providerConfig => {\n const integrationHost = providerConfig.host;\n const integration = integrations.github.byHost(integrationHost);\n\n if (!integration) {\n throw new Error(\n `There is no GitHub config that matches host ${integrationHost}. Please add a configuration entry for it under integrations.github`,\n );\n }\n\n if (!options.schedule && !providerConfig.schedule) {\n throw new Error(\n `No schedule provided neither via code nor config for github-provider:${providerConfig.id}.`,\n );\n }\n\n const taskRunner =\n options.schedule ??\n options.scheduler!.createScheduledTaskRunner(providerConfig.schedule!);\n\n return new GitHubEntityProvider(\n providerConfig,\n integration,\n options.logger,\n taskRunner,\n );\n });\n }\n\n private constructor(\n config: GitHubEntityProviderConfig,\n integration: GitHubIntegration,\n logger: Logger,\n taskRunner: TaskRunner,\n ) {\n this.config = config;\n this.integration = integration.config;\n this.logger = logger.child({\n target: this.getProviderName(),\n });\n this.scheduleFn = this.createScheduleFn(taskRunner);\n this.githubCredentialsProvider =\n SingleInstanceGithubCredentialsProvider.create(integration.config);\n }\n\n /** {@inheritdoc @backstage/plugin-catalog-backend#EntityProvider.getProviderName} */\n getProviderName(): string {\n return `github-provider:${this.config.id}`;\n }\n\n /** {@inheritdoc @backstage/plugin-catalog-backend#EntityProvider.connect} */\n async connect(connection: EntityProviderConnection): Promise<void> {\n this.connection = connection;\n return await this.scheduleFn();\n }\n\n private createScheduleFn(taskRunner: TaskRunner): () => Promise<void> {\n return async () => {\n const taskId = `${this.getProviderName()}:refresh`;\n return taskRunner.run({\n id: taskId,\n fn: async () => {\n const logger = this.logger.child({\n class: GitHubEntityProvider.prototype.constructor.name,\n taskId,\n taskInstanceId: uuid.v4(),\n });\n try {\n await this.refresh(logger);\n } catch (error) {\n logger.error(error);\n }\n },\n });\n };\n }\n\n async refresh(logger: Logger) {\n if (!this.connection) {\n throw new Error('Not initialized');\n }\n\n const targets = await this.findCatalogFiles();\n const matchingTargets = this.matchesFilters(targets);\n const entities = matchingTargets\n .map(repository => this.createLocationUrl(repository))\n .map(GitHubEntityProvider.toLocationSpec)\n .map(location => {\n return {\n locationKey: this.getProviderName(),\n entity: locationSpecToLocationEntity({ location }),\n };\n });\n\n await this.connection.applyMutation({\n type: 'full',\n entities,\n });\n\n logger.info(\n `Read ${targets.length} GitHub repositories (${entities.length} matching the pattern)`,\n );\n }\n\n // go to the server and get all of the repositories\n private async findCatalogFiles(): Promise<Repository[]> {\n const organization = this.config.organization;\n const host = this.integration.host;\n const orgUrl = `https://${host}/${organization}`;\n\n const { headers } = await this.githubCredentialsProvider.getCredentials({\n url: orgUrl,\n });\n\n const client = graphql.defaults({\n baseUrl: this.integration.apiBaseUrl,\n headers,\n });\n\n const { repositories } = await getOrganizationRepositories(\n client,\n organization,\n );\n\n return repositories;\n }\n\n private matchesFilters(repositories: Repository[]) {\n const repositoryFilter = this.config.filters?.repository;\n const topicFilters = this.config.filters?.topic;\n\n const matchingRepositories = repositories.filter(r => {\n const repoTopics: string[] = r.repositoryTopics.nodes.map(\n node => node.topic.name,\n );\n return (\n !r.isArchived &&\n (!repositoryFilter || repositoryFilter.test(r.name)) &&\n satisfiesTopicFilter(repoTopics, topicFilters) &&\n r.defaultBranchRef?.name\n );\n });\n return matchingRepositories;\n }\n\n private createLocationUrl(repository: Repository): string {\n const branch =\n this.config.filters?.branch || repository.defaultBranchRef?.name || '-';\n const catalogFile = this.config.catalogPath.startsWith('/')\n ? this.config.catalogPath.substring(1)\n : this.config.catalogPath;\n return `${repository.url}/blob/${branch}/${catalogFile}`;\n }\n\n private static toLocationSpec(target: string): LocationSpec {\n return {\n type: 'url',\n target: target,\n presence: 'optional',\n };\n }\n}\n\n/*\n * Helpers\n */\n\nexport function parseUrl(urlString: string): {\n org: string;\n repoSearchPath: RegExp;\n catalogPath: string;\n branch: string;\n host: string;\n} {\n const url = new URL(urlString);\n const path = url.pathname.substr(1).split('/');\n\n // /backstage/techdocs-*/blob/master/catalog-info.yaml\n // can also be\n // /backstage\n if (path.length > 2 && path[0].length && path[1].length) {\n return {\n org: decodeURIComponent(path[0]),\n repoSearchPath: escapeRegExp(decodeURIComponent(path[1])),\n catalogPath: `/${decodeURIComponent(path.slice(4).join('/'))}`,\n branch: decodeURIComponent(path[3]),\n host: url.host,\n };\n } else if (path.length === 1 && path[0].length) {\n return {\n org: decodeURIComponent(path[0]),\n repoSearchPath: escapeRegExp('*'),\n catalogPath: '/catalog-info.yaml',\n branch: '-',\n host: url.host,\n };\n }\n\n throw new Error(`Failed to parse ${urlString}`);\n}\n\nexport function escapeRegExp(str: string): RegExp {\n return new RegExp(`^${str.replace(/\\*/g, '.*')}$`);\n}\n","/*\n * Copyright 2021 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 { TaskRunner } from '@backstage/backend-tasks';\nimport {\n ANNOTATION_LOCATION,\n ANNOTATION_ORIGIN_LOCATION,\n Entity,\n} from '@backstage/catalog-model';\nimport { Config } from '@backstage/config';\nimport {\n DefaultGithubCredentialsProvider,\n GithubCredentialsProvider,\n GitHubIntegrationConfig,\n ScmIntegrations,\n SingleInstanceGithubCredentialsProvider,\n} from '@backstage/integration';\nimport {\n EntityProvider,\n EntityProviderConnection,\n} from '@backstage/plugin-catalog-backend';\nimport { graphql } from '@octokit/graphql';\nimport { merge } from 'lodash';\nimport * as uuid from 'uuid';\nimport { Logger } from 'winston';\nimport {\n assignGroupsToUsers,\n buildOrgHierarchy,\n getOrganizationTeams,\n getOrganizationUsers,\n parseGitHubOrgUrl,\n} from '../lib';\n\n/**\n * Options for {@link GitHubOrgEntityProvider}.\n *\n * @public\n */\nexport interface GitHubOrgEntityProviderOptions {\n /**\n * A unique, stable identifier for this provider.\n *\n * @example \"production\"\n */\n id: string;\n\n /**\n * The target that this provider should consume.\n *\n * @example \"https://github.com/backstage\"\n */\n orgUrl: string;\n\n /**\n * The refresh schedule to use.\n *\n * @defaultValue \"manual\"\n * @remarks\n *\n * If you pass in 'manual', you are responsible for calling the `read` method\n * manually at some interval.\n *\n * But more commonly you will pass in the result of\n * {@link @backstage/backend-tasks#PluginTaskScheduler.createScheduledTaskRunner}\n * to enable automatic scheduling of tasks.\n */\n schedule?: 'manual' | TaskRunner;\n\n /**\n * The logger to use.\n */\n logger: Logger;\n\n /**\n * Optionally supply a custom credentials provider, replacing the default one.\n */\n githubCredentialsProvider?: GithubCredentialsProvider;\n}\n\n// TODO: Consider supporting an (optional) webhook that reacts on org changes\n/**\n * Ingests org data (users and groups) from GitHub.\n *\n * @public\n */\nexport class GitHubOrgEntityProvider implements EntityProvider {\n private readonly credentialsProvider: GithubCredentialsProvider;\n private connection?: EntityProviderConnection;\n private scheduleFn?: () => Promise<void>;\n\n static fromConfig(config: Config, options: GitHubOrgEntityProviderOptions) {\n const integrations = ScmIntegrations.fromConfig(config);\n const gitHubConfig = integrations.github.byUrl(options.orgUrl)?.config;\n\n if (!gitHubConfig) {\n throw new Error(\n `There is no GitHub Org provider that matches ${options.orgUrl}. Please add a configuration for an integration.`,\n );\n }\n\n const logger = options.logger.child({\n target: options.orgUrl,\n });\n\n const provider = new GitHubOrgEntityProvider({\n id: options.id,\n orgUrl: options.orgUrl,\n logger,\n gitHubConfig,\n githubCredentialsProvider:\n options.githubCredentialsProvider ||\n DefaultGithubCredentialsProvider.fromIntegrations(integrations),\n });\n\n provider.schedule(options.schedule);\n\n return provider;\n }\n\n constructor(\n private options: {\n id: string;\n orgUrl: string;\n gitHubConfig: GitHubIntegrationConfig;\n logger: Logger;\n githubCredentialsProvider?: GithubCredentialsProvider;\n },\n ) {\n this.credentialsProvider =\n options.githubCredentialsProvider ||\n SingleInstanceGithubCredentialsProvider.create(this.options.gitHubConfig);\n }\n\n /** {@inheritdoc @backstage/plugin-catalog-backend#EntityProvider.getProviderName} */\n getProviderName() {\n return `GitHubOrgEntityProvider:${this.options.id}`;\n }\n\n /** {@inheritdoc @backstage/plugin-catalog-backend#EntityProvider.connect} */\n async connect(connection: EntityProviderConnection) {\n this.connection = connection;\n await this.scheduleFn?.();\n }\n\n /**\n * Runs one single complete ingestion. This is only necessary if you use\n * manual scheduling.\n */\n async read(options?: { logger?: Logger }) {\n if (!this.connection) {\n throw new Error('Not initialized');\n }\n\n const logger = options?.logger ?? this.options.logger;\n const { markReadComplete } = trackProgress(logger);\n\n const { headers, type: tokenType } =\n await this.credentialsProvider.getCredentials({\n url: this.options.orgUrl,\n });\n const client = graphql.defaults({\n baseUrl: this.options.gitHubConfig.apiBaseUrl,\n headers,\n });\n\n const { org } = parseGitHubOrgUrl(this.options.orgUrl);\n const { users } = await getOrganizationUsers(client, org, tokenType);\n const { groups, groupMemberUsers } = await getOrganizationTeams(\n client,\n org,\n );\n assignGroupsToUsers(users, groupMemberUsers);\n buildOrgHierarchy(groups);\n\n const { markCommitComplete } = markReadComplete({ users, groups });\n\n await this.connection.applyMutation({\n type: 'full',\n entities: [...users, ...groups].map(entity => ({\n locationKey: `github-org-provider:${this.options.id}`,\n entity: withLocations(\n `https://${this.options.gitHubConfig.host}`,\n org,\n entity,\n ),\n })),\n });\n\n markCommitComplete();\n }\n\n private schedule(schedule: GitHubOrgEntityProviderOptions['schedule']) {\n if (!schedule || schedule === 'manual') {\n return;\n }\n\n this.scheduleFn = async () => {\n const id = `${this.getProviderName()}:refresh`;\n await schedule.run({\n id,\n fn: async () => {\n const logger = this.options.logger.child({\n class: GitHubOrgEntityProvider.prototype.constructor.name,\n taskId: id,\n taskInstanceId: uuid.v4(),\n });\n\n try {\n await this.read({ logger });\n } catch (error) {\n logger.error(error);\n }\n },\n });\n };\n }\n}\n\n// Helps wrap the timing and logging behaviors\nfunction trackProgress(logger: Logger) {\n let timestamp = Date.now();\n let summary: string;\n\n logger.info('Reading GitHub users and groups');\n\n function markReadComplete(read: { users: unknown[]; groups: unknown[] }) {\n summary = `${read.users.length} GitHub users and ${read.groups.length} GitHub groups`;\n const readDuration = ((Date.now() - timestamp) / 1000).toFixed(1);\n timestamp = Date.now();\n logger.info(`Read ${summary} in ${readDuration} seconds. Committing...`);\n return { markCommitComplete };\n }\n\n function markCommitComplete() {\n const commitDuration = ((Date.now() - timestamp) / 1000).toFixed(1);\n logger.info(`Committed ${summary} in ${commitDuration} seconds.`);\n }\n\n return { markReadComplete };\n}\n\n// Makes sure that emitted entities have a proper location\nexport function withLocations(\n baseUrl: string,\n org: string,\n entity: Entity,\n): Entity {\n const location =\n entity.kind === 'Group'\n ? `url:${baseUrl}/orgs/${org}/teams/${entity.metadata.name}`\n : `url:${baseUrl}/${entity.metadata.name}`;\n return merge(\n {\n metadata: {\n annotations: {\n [ANNOTATION_LOCATION]: location,\n [ANNOTATION_ORIGIN_LOCATION]: location,\n },\n },\n },\n entity,\n ) as Entity;\n}\n","/*\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 createBackendModule,\n loggerToWinstonLogger,\n configServiceRef,\n loggerServiceRef,\n schedulerServiceRef,\n} from '@backstage/backend-plugin-api';\nimport { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node';\nimport { GitHubEntityProvider } from '../providers/GitHubEntityProvider';\n\n/**\n * Registers the GitHubEntityProvider with the catalog processing extension point.\n *\n * @alpha\n */\nexport const githubEntityProviderCatalogModule = createBackendModule({\n pluginId: 'catalog',\n moduleId: 'githubEntityProvider',\n register(env) {\n env.registerInit({\n deps: {\n catalog: catalogProcessingExtensionPoint,\n config: configServiceRef,\n logger: loggerServiceRef,\n scheduler: schedulerServiceRef,\n },\n async init({ catalog, config, logger, scheduler }) {\n catalog.addEntityProvider(\n GitHubEntityProvider.fromConfig(config, {\n logger: loggerToWinstonLogger(logger),\n scheduler,\n }),\n );\n },\n });\n },\n});\n"],"names":["CatalogClient","ScmIntegrations","integration","parseGitUrl","Octokit","trimEnd","_a","DefaultGithubCredentialsProvider","graphql","processingResult","GithubAppCredentialsMux","readTaskScheduleDefinitionFromConfig","SingleInstanceGithubCredentialsProvider","uuid","locationSpecToLocationEntity","merge","ANNOTATION_LOCATION","ANNOTATION_ORIGIN_LOCATION","createBackendModule","catalogProcessingExtensionPoint","configServiceRef","loggerServiceRef","schedulerServiceRef","loggerToWinstonLogger"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs.js","sources":["../src/analyzers/GithubLocationAnalyzer.ts","../src/lib/config.ts","../src/lib/github.ts","../src/lib/org.ts","../src/lib/util.ts","../src/processors/GithubDiscoveryProcessor.ts","../src/processors/GithubMultiOrgReaderProcessor.ts","../src/processors/GithubOrgReaderProcessor.ts","../src/providers/GithubEntityProviderConfig.ts","../src/providers/GithubEntityProvider.ts","../src/providers/GithubOrgEntityProvider.ts","../src/service/GithubEntityProviderCatalogModule.ts","../src/deprecated.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 { CatalogApi, CatalogClient } from '@backstage/catalog-client';\nimport { ScmIntegrations } from '@backstage/integration';\nimport { Octokit } from '@octokit/rest';\nimport { trimEnd } from 'lodash';\nimport parseGitUrl from 'git-url-parse';\nimport {\n AnalyzeOptions,\n ScmLocationAnalyzer,\n} from '@backstage/plugin-catalog-backend';\nimport { PluginEndpointDiscovery } from '@backstage/backend-common';\nimport { Config } from '@backstage/config';\n\n/** @public */\nexport type GithubLocationAnalyzerOptions = {\n config: Config;\n discovery: PluginEndpointDiscovery;\n};\n\n/** @public */\nexport class GithubLocationAnalyzer implements ScmLocationAnalyzer {\n private readonly catalogClient: CatalogApi;\n private readonly config: Config;\n\n constructor(options: GithubLocationAnalyzerOptions) {\n this.config = options.config;\n this.catalogClient = new CatalogClient({ discoveryApi: options.discovery });\n }\n\n supports(url: string) {\n const integrations = ScmIntegrations.fromConfig(this.config);\n const integration = integrations.byUrl(url);\n return integration?.type === 'github';\n }\n\n async analyze({ url, catalogFilename }: AnalyzeOptions) {\n const { owner, name: repo } = parseGitUrl(url);\n\n const catalogFile = catalogFilename || 'catalog-info.yaml';\n\n const query = `filename:${catalogFile} repo:${owner}/${repo}`;\n\n const integration = ScmIntegrations.fromConfig(this.config).github.byUrl(\n url,\n );\n if (!integration) {\n throw new Error('Make sure you have a GitHub integration configured');\n }\n\n const octokitClient = new Octokit({\n auth: integration.config.token,\n baseUrl: integration.config.apiBaseUrl,\n });\n\n const searchResult = await octokitClient.search\n .code({ q: query })\n .catch(e => {\n throw new Error(`Couldn't search repository for metadata file, ${e}`);\n });\n\n const exists = searchResult.data.total_count > 0;\n if (exists) {\n const repoInformation = await octokitClient.repos\n .get({ owner, repo })\n .catch(e => {\n throw new Error(`Couldn't fetch repo data, ${e}`);\n });\n const defaultBranch = repoInformation.data.default_branch;\n\n const result = await Promise.all(\n searchResult.data.items\n .map(i => `${trimEnd(url, '/')}/blob/${defaultBranch}/${i.path}`)\n .map(async target => {\n const addLocationResult = await this.catalogClient.addLocation({\n type: 'url',\n target,\n dryRun: true,\n });\n return addLocationResult.entities.map(e => ({\n location: { type: 'url', target },\n isRegistered: !!addLocationResult.exists,\n entity: e,\n }));\n }),\n );\n\n return { existing: result.flat() };\n }\n return { existing: [] };\n }\n}\n","/*\n * Copyright 2020 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 { Config } from '@backstage/config';\n\n/**\n * The configuration parameters for a multi-org GitHub processor.\n * @public\n */\nexport type GithubMultiOrgConfig = Array<{\n /**\n * The name of the GitHub org to process.\n */\n name: string;\n /**\n * The namespace of the group created for this org.\n */\n groupNamespace: string;\n /**\n * The namespace of the users created for this org. If not specified defaults to undefined.\n */\n userNamespace: string | undefined;\n}>;\n\nexport function readGithubMultiOrgConfig(config: Config): GithubMultiOrgConfig {\n const orgConfigs = config.getOptionalConfigArray('orgs') ?? [];\n return orgConfigs.map(c => ({\n name: c.getString('name'),\n groupNamespace: (\n c.getOptionalString('groupNamespace') ?? c.getString('name')\n ).toLowerCase(),\n userNamespace: c.getOptionalString('userNamespace') ?? undefined,\n }));\n}\n","/*\n * Copyright 2020 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 { GroupEntity, UserEntity } from '@backstage/catalog-model';\nimport { GithubCredentialType } from '@backstage/integration';\nimport { graphql } from '@octokit/graphql';\n\n// Graphql types\n\nexport type QueryResponse = {\n organization?: Organization;\n repositoryOwner?: Organization | User;\n};\n\nexport type Organization = {\n membersWithRole?: Connection<User>;\n team?: Team;\n teams?: Connection<Team>;\n repositories?: Connection<Repository>;\n};\n\nexport type PageInfo = {\n hasNextPage: boolean;\n endCursor?: string;\n};\n\nexport type User = {\n login: string;\n bio?: string;\n avatarUrl?: string;\n email?: string;\n name?: string;\n repositories?: Connection<Repository>;\n};\n\nexport type Team = {\n slug: string;\n combinedSlug: string;\n name?: string;\n description?: string;\n avatarUrl?: string;\n editTeamUrl?: string;\n parentTeam?: Team;\n members: Connection<User>;\n};\n\nexport type Repository = {\n name: string;\n url: string;\n isArchived: boolean;\n repositoryTopics: RepositoryTopics;\n defaultBranchRef: {\n name: string;\n } | null;\n};\n\ntype RepositoryTopics = {\n nodes: TopicNodes[];\n};\n\ntype TopicNodes = {\n topic: {\n name: string;\n };\n};\n\nexport type Connection<T> = {\n pageInfo: PageInfo;\n nodes: T[];\n};\n\n/**\n * Gets all the users out of a GitHub organization.\n *\n * Note that the users will not have their memberships filled in.\n *\n * @param client - An octokit graphql client\n * @param org - The slug of the org to read\n */\nexport async function getOrganizationUsers(\n client: typeof graphql,\n org: string,\n tokenType: GithubCredentialType,\n userNamespace?: string,\n): Promise<{ users: UserEntity[] }> {\n const query = `\n query users($org: String!, $email: Boolean!, $cursor: String) {\n organization(login: $org) {\n membersWithRole(first: 100, after: $cursor) {\n pageInfo { hasNextPage, endCursor }\n nodes {\n avatarUrl,\n bio,\n email @include(if: $email),\n login,\n name\n }\n }\n }\n }`;\n\n // There is no user -> teams edge, so we leave the memberships empty for\n // now and let the team iteration handle it instead\n const mapper = (user: User) => {\n const entity: UserEntity = {\n apiVersion: 'backstage.io/v1alpha1',\n kind: 'User',\n metadata: {\n name: user.login,\n annotations: {\n 'github.com/user-login': user.login,\n },\n },\n spec: {\n profile: {},\n memberOf: [],\n },\n };\n\n if (userNamespace) entity.metadata.namespace = userNamespace;\n if (user.bio) entity.metadata.description = user.bio;\n if (user.name) entity.spec.profile!.displayName = user.name;\n if (user.email) entity.spec.profile!.email = user.email;\n if (user.avatarUrl) entity.spec.profile!.picture = user.avatarUrl;\n\n return entity;\n };\n\n const users = await queryWithPaging(\n client,\n query,\n r => r.organization?.membersWithRole,\n mapper,\n { org, email: tokenType === 'token' },\n );\n\n return { users };\n}\n\n/**\n * Gets all the teams out of a GitHub organization.\n *\n * Note that the teams will not have any relations apart from parent filled in.\n *\n * @param client - An octokit graphql client\n * @param org - The slug of the org to read\n */\nexport async function getOrganizationTeams(\n client: typeof graphql,\n org: string,\n orgNamespace?: string,\n): Promise<{\n groups: GroupEntity[];\n groupMemberUsers: Map<string, string[]>;\n}> {\n const query = `\n query teams($org: String!, $cursor: String) {\n organization(login: $org) {\n teams(first: 100, after: $cursor) {\n pageInfo { hasNextPage, endCursor }\n nodes {\n slug\n combinedSlug\n name\n description\n avatarUrl\n editTeamUrl\n parentTeam { slug }\n members(first: 100, membership: IMMEDIATE) {\n pageInfo { hasNextPage }\n nodes { login }\n }\n }\n }\n }\n }`;\n\n // Gets populated inside the mapper below\n const groupMemberUsers = new Map<string, string[]>();\n\n const mapper = async (team: Team) => {\n const annotations: { [annotationName: string]: string } = {\n 'github.com/team-slug': team.combinedSlug,\n };\n\n if (team.editTeamUrl) {\n annotations['backstage.io/edit-url'] = team.editTeamUrl;\n }\n\n const entity: GroupEntity = {\n apiVersion: 'backstage.io/v1alpha1',\n kind: 'Group',\n metadata: {\n name: team.slug,\n annotations,\n },\n spec: {\n type: 'team',\n profile: {},\n children: [],\n },\n };\n\n if (orgNamespace) {\n entity.metadata.namespace = orgNamespace;\n }\n\n if (team.description) {\n entity.metadata.description = team.description;\n }\n if (team.name) {\n entity.spec.profile!.displayName = team.name;\n }\n if (team.avatarUrl) {\n entity.spec.profile!.picture = team.avatarUrl;\n }\n if (team.parentTeam) {\n entity.spec.parent = team.parentTeam.slug;\n }\n\n const memberNames: string[] = [];\n const groupKey = orgNamespace ? `${orgNamespace}/${team.slug}` : team.slug;\n groupMemberUsers.set(groupKey, memberNames);\n\n if (!team.members.pageInfo.hasNextPage) {\n // We got all the members in one go, run the fast path\n for (const user of team.members.nodes) {\n memberNames.push(user.login);\n }\n } else {\n // There were more than a hundred immediate members - run the slow\n // path of fetching them explicitly\n const { members } = await getTeamMembers(client, org, team.slug);\n for (const userLogin of members) {\n memberNames.push(userLogin);\n }\n }\n\n return entity;\n };\n\n const groups = await queryWithPaging(\n client,\n query,\n r => r.organization?.teams,\n mapper,\n { org },\n );\n\n return { groups, groupMemberUsers };\n}\n\nexport async function getOrganizationRepositories(\n client: typeof graphql,\n org: string,\n): Promise<{ repositories: Repository[] }> {\n const query = `\n query repositories($org: String!, $cursor: String) {\n repositoryOwner(login: $org) {\n login\n repositories(first: 100, after: $cursor) {\n nodes {\n name\n url\n isArchived\n repositoryTopics(first: 100) {\n nodes {\n ... on RepositoryTopic {\n topic {\n name\n }\n }\n }\n }\n defaultBranchRef {\n name\n }\n }\n pageInfo {\n hasNextPage\n endCursor\n }\n }\n }\n }`;\n\n const repositories = await queryWithPaging(\n client,\n query,\n r => r.repositoryOwner?.repositories,\n x => x,\n { org },\n );\n\n return { repositories };\n}\n\n/**\n * Gets all the users out of a GitHub organization.\n *\n * Note that the users will not have their memberships filled in.\n *\n * @param client - An octokit graphql client\n * @param org - The slug of the org to read\n * @param teamSlug - The slug of the team to read\n */\nexport async function getTeamMembers(\n client: typeof graphql,\n org: string,\n teamSlug: string,\n): Promise<{ members: string[] }> {\n const query = `\n query members($org: String!, $teamSlug: String!, $cursor: String) {\n organization(login: $org) {\n team(slug: $teamSlug) {\n members(first: 100, after: $cursor, membership: IMMEDIATE) {\n pageInfo { hasNextPage, endCursor }\n nodes { login }\n }\n }\n }\n }`;\n\n const members = await queryWithPaging(\n client,\n query,\n r => r.organization?.team?.members,\n user => user.login,\n { org, teamSlug },\n );\n\n return { members };\n}\n\n//\n// Helpers\n//\n\n/**\n * Assists in repeatedly executing a query with a paged response.\n *\n * Requires that the query accepts a $cursor variable.\n *\n * @param client - The octokit client\n * @param query - The query to execute\n * @param connection - A function that, given the response, picks out the actual\n * Connection object that's being iterated\n * @param mapper - A function that, given one of the nodes in the Connection,\n * returns the model mapped form of it\n * @param variables - The variable values that the query needs, minus the cursor\n */\nexport async function queryWithPaging<\n GraphqlType,\n OutputType,\n Variables extends {},\n Response = QueryResponse,\n>(\n client: typeof graphql,\n query: string,\n connection: (response: Response) => Connection<GraphqlType> | undefined,\n mapper: (item: GraphqlType) => Promise<OutputType> | OutputType,\n variables: Variables,\n): Promise<OutputType[]> {\n const result: OutputType[] = [];\n\n let cursor: string | undefined = undefined;\n for (let j = 0; j < 1000 /* just for sanity */; ++j) {\n const response: Response = await client(query, {\n ...variables,\n cursor,\n });\n\n const conn = connection(response);\n if (!conn) {\n throw new Error(`Found no match for ${JSON.stringify(variables)}`);\n }\n\n for (const node of conn.nodes) {\n result.push(await mapper(node));\n }\n\n if (!conn.pageInfo.hasNextPage) {\n break;\n } else {\n cursor = conn.pageInfo.endCursor;\n }\n }\n\n return result;\n}\n","/*\n * Copyright 2020 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 { GroupEntity, UserEntity } from '@backstage/catalog-model';\n\nexport function buildOrgHierarchy(groups: GroupEntity[]) {\n const groupsByName = new Map(groups.map(g => [g.metadata.name, g]));\n\n //\n // Make sure that g.parent.children contain g\n //\n\n for (const group of groups) {\n const selfName = group.metadata.name;\n const parentName = group.spec.parent;\n if (parentName) {\n const parent = groupsByName.get(parentName);\n if (parent && !parent.spec.children.includes(selfName)) {\n parent.spec.children.push(selfName);\n }\n }\n }\n\n //\n // Make sure that g.children.parent is g\n //\n\n for (const group of groups) {\n const selfName = group.metadata.name;\n for (const childName of group.spec.children) {\n const child = groupsByName.get(childName);\n if (child && !child.spec.parent) {\n child.spec.parent = selfName;\n }\n }\n }\n}\n\n// Ensure that users have their direct group memberships.\nexport function assignGroupsToUsers(\n users: UserEntity[],\n groupMemberUsers: Map<string, string[]>,\n) {\n const usersByName = new Map(users.map(u => [u.metadata.name, u]));\n for (const [groupName, userNames] of groupMemberUsers.entries()) {\n for (const userName of userNames) {\n const user = usersByName.get(userName);\n if (user && !user.spec.memberOf?.includes(groupName)) {\n if (!user.spec.memberOf) {\n user.spec.memberOf = [];\n }\n user.spec.memberOf.push(groupName);\n }\n }\n }\n}\n\n// Ensure that users have their transitive group memberships. Requires that\n// the groups were previously processed with buildOrgHierarchy()\nexport function buildMemberOf(groups: GroupEntity[], users: UserEntity[]) {\n const groupsByName = new Map(groups.map(g => [g.metadata.name, g]));\n\n users.forEach(user => {\n const transitiveMemberOf = new Set<string>();\n\n const todo = [\n ...(user.spec.memberOf ?? []),\n ...groups\n .filter(g => g.spec.members?.includes(user.metadata.name))\n .map(g => g.metadata.name),\n ];\n\n for (;;) {\n const current = todo.pop();\n if (!current) {\n break;\n }\n\n if (!transitiveMemberOf.has(current)) {\n transitiveMemberOf.add(current);\n const group = groupsByName.get(current);\n if (group?.spec.parent) {\n todo.push(group.spec.parent);\n }\n }\n }\n\n user.spec.memberOf = [...transitiveMemberOf];\n });\n}\n","/*\n * Copyright 2021 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 { GithubTopicFilters } from '../providers/GithubEntityProviderConfig';\n\nexport function parseGithubOrgUrl(urlString: string): { org: string } {\n const path = new URL(urlString).pathname.substr(1).split('/');\n\n // /backstage\n if (path.length === 1 && path[0].length) {\n return { org: decodeURIComponent(path[0]) };\n }\n\n throw new Error(`Expected a URL pointing to /<org>`);\n}\n\nexport function satisfiesTopicFilter(\n topics: string[],\n topicFilter: GithubTopicFilters | undefined,\n): Boolean {\n // We don't want to do anything if a filter is not configured (or configured but empty)\n if (!topicFilter) return true;\n if (!topicFilter.include && !topicFilter.exclude) return true;\n if (!topicFilter.include?.length && !topicFilter.exclude?.length) return true;\n // If topic.include is in use, a topic MUST be set that matches the inclusion\n // filter in order for a repository to be ingested\n if (topicFilter.include?.length && !topicFilter.exclude) {\n for (const topic of topics) {\n if (topicFilter.include.includes(topic)) return true;\n }\n return false;\n }\n // If topic.exclude is in use, all topics are included by default\n // with anything matching the filter being discarded. It is technically\n // possible for the filter to be explicitly empty meaning all repositories\n // are ingested although doing so would be pointless.\n if (!topicFilter.include && topicFilter.exclude?.length) {\n if (!topics.length) return true;\n for (const topic of topics) {\n if (topicFilter.exclude.includes(topic)) return false;\n }\n return true;\n }\n // Now the tricky part is where we have both include and exclude configured.\n // In this case, exclude wins out so we take everything matching the initial\n // inclusion filter and from that group, we further discard anything matching\n // the exclusion filter. If an item were to have a topic set in both filters,\n // we expect it to be discarded in the end. The use case here is that is that\n // you may want to retrieve all repos with the topic of team-a while excluding\n // matching repos that are marked as experiments.\n if (topicFilter.include && topicFilter.exclude) {\n const matchesInclude = satisfiesTopicFilter(topics, {\n include: topicFilter.include,\n });\n const matchesExclude = !satisfiesTopicFilter(topics, {\n exclude: topicFilter.exclude,\n });\n if (matchesExclude) return false;\n return matchesInclude;\n }\n\n // If the topic filter is somehow ever in a state that is not covered here, we\n // will fail \"open\" so that Backstage is still usable as if the filter was\n // not configured at all.\n return true;\n}\n","/*\n * Copyright 2021 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 { Config } from '@backstage/config';\nimport {\n DefaultGithubCredentialsProvider,\n GithubCredentialsProvider,\n ScmIntegrationRegistry,\n ScmIntegrations,\n} from '@backstage/integration';\nimport {\n CatalogProcessor,\n CatalogProcessorEmit,\n LocationSpec,\n processingResult,\n} from '@backstage/plugin-catalog-backend';\nimport { graphql } from '@octokit/graphql';\nimport { Logger } from 'winston';\nimport { getOrganizationRepositories } from '../lib';\n\n/**\n * Extracts repositories out of a GitHub org.\n *\n * The following will create locations for all projects which have a catalog-info.yaml\n * on the default branch. The first is shorthand for the second.\n *\n * target: \"https://github.com/backstage\"\n * or\n * target: https://github.com/backstage/*\\/blob/-/catalog-info.yaml\n *\n * You may also explicitly specify the source branch:\n *\n * target: https://github.com/backstage/*\\/blob/main/catalog-info.yaml\n *\n * @public\n **/\nexport class GithubDiscoveryProcessor implements CatalogProcessor {\n private readonly integrations: ScmIntegrationRegistry;\n private readonly logger: Logger;\n private readonly githubCredentialsProvider: GithubCredentialsProvider;\n\n static fromConfig(\n config: Config,\n options: {\n logger: Logger;\n githubCredentialsProvider?: GithubCredentialsProvider;\n },\n ) {\n const integrations = ScmIntegrations.fromConfig(config);\n\n return new GithubDiscoveryProcessor({\n ...options,\n integrations,\n });\n }\n\n constructor(options: {\n integrations: ScmIntegrationRegistry;\n logger: Logger;\n githubCredentialsProvider?: GithubCredentialsProvider;\n }) {\n this.integrations = options.integrations;\n this.logger = options.logger;\n this.githubCredentialsProvider =\n options.githubCredentialsProvider ||\n DefaultGithubCredentialsProvider.fromIntegrations(this.integrations);\n }\n getProcessorName(): string {\n return 'GithubDiscoveryProcessor';\n }\n\n async readLocation(\n location: LocationSpec,\n _optional: boolean,\n emit: CatalogProcessorEmit,\n ): Promise<boolean> {\n if (location.type !== 'github-discovery') {\n return false;\n }\n\n const gitHubConfig = this.integrations.github.byUrl(\n location.target,\n )?.config;\n if (!gitHubConfig) {\n throw new Error(\n `There is no GitHub integration that matches ${location.target}. Please add a configuration entry for it under integrations.github`,\n );\n }\n\n const { org, repoSearchPath, catalogPath, branch, host } = parseUrl(\n location.target,\n );\n\n // Building the org url here so that the github creds provider doesn't need to know\n // about how to handle the wild card which is special for this processor.\n const orgUrl = `https://${host}/${org}`;\n\n const { headers } = await this.githubCredentialsProvider.getCredentials({\n url: orgUrl,\n });\n\n const client = graphql.defaults({\n baseUrl: gitHubConfig.apiBaseUrl,\n headers,\n });\n\n // Read out all of the raw data\n const startTimestamp = Date.now();\n this.logger.info(`Reading GitHub repositories from ${location.target}`);\n\n const { repositories } = await getOrganizationRepositories(client, org);\n const matching = repositories.filter(\n r => !r.isArchived && repoSearchPath.test(r.name),\n );\n\n const duration = ((Date.now() - startTimestamp) / 1000).toFixed(1);\n this.logger.debug(\n `Read ${repositories.length} GitHub repositories (${matching.length} matching the pattern) in ${duration} seconds`,\n );\n\n for (const repository of matching) {\n const branchName =\n branch === '-' ? repository.defaultBranchRef?.name : branch;\n\n if (!branchName) {\n this.logger.info(\n `the repository ${repository.url} does not have a default branch, skipping`,\n );\n continue;\n }\n\n const path = `/blob/${branchName}${catalogPath}`;\n\n emit(\n processingResult.location({\n type: 'url',\n target: `${repository.url}${path}`,\n // Not all locations may actually exist, since the user defined them as a wildcard pattern.\n // Thus, we emit them as optional and let the downstream processor find them while not outputting\n // an error if it couldn't.\n presence: 'optional',\n }),\n );\n }\n\n return true;\n }\n}\n\n/*\n * Helpers\n */\n\nexport function parseUrl(urlString: string): {\n org: string;\n repoSearchPath: RegExp;\n catalogPath: string;\n branch: string;\n host: string;\n} {\n const url = new URL(urlString);\n const path = url.pathname.substr(1).split('/');\n\n // /backstage/techdocs-*/blob/master/catalog-info.yaml\n // can also be\n // /backstage\n if (path.length > 2 && path[0].length && path[1].length) {\n return {\n org: decodeURIComponent(path[0]),\n repoSearchPath: escapeRegExp(decodeURIComponent(path[1])),\n branch: decodeURIComponent(path[3]),\n catalogPath: `/${decodeURIComponent(path.slice(4).join('/'))}`,\n host: url.host,\n };\n } else if (path.length === 1 && path[0].length) {\n return {\n org: decodeURIComponent(path[0]),\n host: url.host,\n repoSearchPath: escapeRegExp('*'),\n catalogPath: '/catalog-info.yaml',\n branch: '-',\n };\n }\n\n throw new Error(`Failed to parse ${urlString}`);\n}\n\nexport function escapeRegExp(str: string): RegExp {\n return new RegExp(`^${str.replace(/\\*/g, '.*')}$`);\n}\n","/*\n * Copyright 2021 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 { Config } from '@backstage/config';\nimport {\n DefaultGithubCredentialsProvider,\n GithubAppCredentialsMux,\n GithubCredentialsProvider,\n GitHubIntegrationConfig,\n ScmIntegrationRegistry,\n ScmIntegrations,\n} from '@backstage/integration';\nimport {\n CatalogProcessor,\n CatalogProcessorEmit,\n LocationSpec,\n processingResult,\n} from '@backstage/plugin-catalog-backend';\nimport { graphql } from '@octokit/graphql';\nimport { Logger } from 'winston';\nimport {\n buildOrgHierarchy,\n getOrganizationTeams,\n getOrganizationUsers,\n GithubMultiOrgConfig,\n readGithubMultiOrgConfig,\n} from '../lib';\n\n/**\n * Extracts teams and users out of a multiple GitHub orgs namespaced per org.\n *\n * Be aware that this processor may not be compatible with future org structures in the catalog.\n *\n * @public\n */\nexport class GithubMultiOrgReaderProcessor implements CatalogProcessor {\n private readonly integrations: ScmIntegrationRegistry;\n private readonly orgs: GithubMultiOrgConfig;\n private readonly logger: Logger;\n private readonly githubCredentialsProvider: GithubCredentialsProvider;\n\n static fromConfig(\n config: Config,\n options: {\n logger: Logger;\n githubCredentialsProvider?: GithubCredentialsProvider;\n },\n ) {\n const c = config.getOptionalConfig('catalog.processors.githubMultiOrg');\n const integrations = ScmIntegrations.fromConfig(config);\n\n return new GithubMultiOrgReaderProcessor({\n ...options,\n integrations,\n orgs: c ? readGithubMultiOrgConfig(c) : [],\n });\n }\n\n constructor(options: {\n integrations: ScmIntegrationRegistry;\n logger: Logger;\n orgs: GithubMultiOrgConfig;\n githubCredentialsProvider?: GithubCredentialsProvider;\n }) {\n this.integrations = options.integrations;\n this.logger = options.logger;\n this.orgs = options.orgs;\n this.githubCredentialsProvider =\n options.githubCredentialsProvider ||\n DefaultGithubCredentialsProvider.fromIntegrations(this.integrations);\n }\n getProcessorName(): string {\n return 'GithubMultiOrgReaderProcessor';\n }\n\n async readLocation(\n location: LocationSpec,\n _optional: boolean,\n emit: CatalogProcessorEmit,\n ): Promise<boolean> {\n if (location.type !== 'github-multi-org') {\n return false;\n }\n\n const gitHubConfig = this.integrations.github.byUrl(\n location.target,\n )?.config;\n if (!gitHubConfig) {\n throw new Error(\n `There is no GitHub integration that matches ${location.target}. Please add a configuration entry for it under integrations.github`,\n );\n }\n\n const allUsersMap = new Map();\n const baseUrl = new URL(location.target).origin;\n\n const orgsToProcess = this.orgs.length\n ? this.orgs\n : await this.getAllOrgs(gitHubConfig);\n\n for (const orgConfig of orgsToProcess) {\n try {\n const { headers, type: tokenType } =\n await this.githubCredentialsProvider.getCredentials({\n url: `${baseUrl}/${orgConfig.name}`,\n });\n const client = graphql.defaults({\n baseUrl: gitHubConfig.apiBaseUrl,\n headers,\n });\n\n const startTimestamp = Date.now();\n this.logger.info(\n `Reading GitHub users and teams for org: ${orgConfig.name}`,\n );\n const { users } = await getOrganizationUsers(\n client,\n orgConfig.name,\n tokenType,\n orgConfig.userNamespace,\n );\n const { groups, groupMemberUsers } = await getOrganizationTeams(\n client,\n orgConfig.name,\n orgConfig.groupNamespace,\n );\n\n const duration = ((Date.now() - startTimestamp) / 1000).toFixed(1);\n this.logger.debug(\n `Read ${users.length} GitHub users and ${groups.length} GitHub teams from ${orgConfig.name} in ${duration} seconds`,\n );\n\n let prefix: string = orgConfig.userNamespace ?? '';\n if (prefix.length > 0) prefix += '/';\n\n users.forEach(u => {\n if (!allUsersMap.has(prefix + u.metadata.name)) {\n allUsersMap.set(prefix + u.metadata.name, u);\n }\n });\n\n for (const [groupName, userNames] of groupMemberUsers.entries()) {\n for (const userName of userNames) {\n const user = allUsersMap.get(prefix + userName);\n if (user && !user.spec.memberOf.includes(groupName)) {\n user.spec.memberOf.push(groupName);\n }\n }\n }\n buildOrgHierarchy(groups);\n\n for (const group of groups) {\n emit(processingResult.entity(location, group));\n }\n } catch (e) {\n this.logger.error(\n `Failed to read GitHub org data for ${orgConfig.name}: ${e}`,\n );\n }\n }\n\n const allUsers = Array.from(allUsersMap.values());\n for (const user of allUsers) {\n emit(processingResult.entity(location, user));\n }\n\n return true;\n }\n\n // Note: Does not support usage of PATs\n private async getAllOrgs(\n gitHubConfig: GitHubIntegrationConfig,\n ): Promise<GithubMultiOrgConfig> {\n const githubAppMux = new GithubAppCredentialsMux(gitHubConfig);\n const installs = await githubAppMux.getAllInstallations();\n\n return installs\n .map(install =>\n install.target_type === 'Organization' &&\n install.account &&\n install.account.login\n ? {\n name: install.account.login,\n groupNamespace: install.account.login.toLowerCase(),\n }\n : undefined,\n )\n .filter(Boolean) as GithubMultiOrgConfig;\n }\n}\n","/*\n * Copyright 2020 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 { Config } from '@backstage/config';\nimport {\n DefaultGithubCredentialsProvider,\n GithubCredentialsProvider,\n GithubCredentialType,\n ScmIntegrationRegistry,\n ScmIntegrations,\n} from '@backstage/integration';\nimport {\n CatalogProcessor,\n CatalogProcessorEmit,\n LocationSpec,\n processingResult,\n} from '@backstage/plugin-catalog-backend';\nimport { graphql } from '@octokit/graphql';\nimport { Logger } from 'winston';\nimport {\n assignGroupsToUsers,\n buildOrgHierarchy,\n getOrganizationTeams,\n getOrganizationUsers,\n parseGithubOrgUrl,\n} from '../lib';\n\ntype GraphQL = typeof graphql;\n\n/**\n * Extracts teams and users out of a GitHub org.\n *\n * @remarks\n *\n * Consider using {@link GithubOrgEntityProvider} instead.\n *\n * @public\n */\nexport class GithubOrgReaderProcessor implements CatalogProcessor {\n private readonly integrations: ScmIntegrationRegistry;\n private readonly logger: Logger;\n private readonly githubCredentialsProvider: GithubCredentialsProvider;\n\n static fromConfig(\n config: Config,\n options: {\n logger: Logger;\n githubCredentialsProvider?: GithubCredentialsProvider;\n },\n ) {\n const integrations = ScmIntegrations.fromConfig(config);\n\n return new GithubOrgReaderProcessor({\n ...options,\n integrations,\n });\n }\n\n constructor(options: {\n integrations: ScmIntegrationRegistry;\n logger: Logger;\n githubCredentialsProvider?: GithubCredentialsProvider;\n }) {\n this.integrations = options.integrations;\n this.githubCredentialsProvider =\n options.githubCredentialsProvider ||\n DefaultGithubCredentialsProvider.fromIntegrations(this.integrations);\n this.logger = options.logger;\n }\n getProcessorName(): string {\n return 'GithubOrgReaderProcessor';\n }\n\n async readLocation(\n location: LocationSpec,\n _optional: boolean,\n emit: CatalogProcessorEmit,\n ): Promise<boolean> {\n if (location.type !== 'github-org') {\n return false;\n }\n\n const { client, tokenType } = await this.createClient(location.target);\n const { org } = parseGithubOrgUrl(location.target);\n\n // Read out all of the raw data\n const startTimestamp = Date.now();\n this.logger.info('Reading GitHub users and groups');\n\n const { users } = await getOrganizationUsers(client, org, tokenType);\n const { groups, groupMemberUsers } = await getOrganizationTeams(\n client,\n org,\n );\n\n const duration = ((Date.now() - startTimestamp) / 1000).toFixed(1);\n this.logger.debug(\n `Read ${users.length} GitHub users and ${groups.length} GitHub groups in ${duration} seconds`,\n );\n\n assignGroupsToUsers(users, groupMemberUsers);\n buildOrgHierarchy(groups);\n\n // Done!\n for (const group of groups) {\n emit(processingResult.entity(location, group));\n }\n for (const user of users) {\n emit(processingResult.entity(location, user));\n }\n\n return true;\n }\n\n private async createClient(\n orgUrl: string,\n ): Promise<{ client: GraphQL; tokenType: GithubCredentialType }> {\n const gitHubConfig = this.integrations.github.byUrl(orgUrl)?.config;\n\n if (!gitHubConfig) {\n throw new Error(\n `There is no GitHub Org provider that matches ${orgUrl}. Please add a configuration for an integration.`,\n );\n }\n\n const { headers, type: tokenType } =\n await this.githubCredentialsProvider.getCredentials({\n url: orgUrl,\n });\n\n const client = graphql.defaults({\n baseUrl: gitHubConfig.apiBaseUrl,\n headers,\n });\n\n return { client, tokenType };\n }\n}\n","/*\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 readTaskScheduleDefinitionFromConfig,\n TaskScheduleDefinition,\n} from '@backstage/backend-tasks';\nimport { Config } from '@backstage/config';\n\nconst DEFAULT_CATALOG_PATH = '/catalog-info.yaml';\nconst DEFAULT_PROVIDER_ID = 'default';\n\nexport type GithubEntityProviderConfig = {\n id: string;\n catalogPath: string;\n organization: string;\n host: string;\n filters?: {\n repository?: RegExp;\n branch?: string;\n topic?: GithubTopicFilters;\n };\n schedule?: TaskScheduleDefinition;\n};\n\nexport type GithubTopicFilters = {\n exclude?: string[];\n include?: string[];\n};\n\nexport function readProviderConfigs(\n config: Config,\n): GithubEntityProviderConfig[] {\n const providersConfig = config.getOptionalConfig('catalog.providers.github');\n if (!providersConfig) {\n return [];\n }\n\n if (providersConfig.has('organization')) {\n // simple/single config variant\n return [readProviderConfig(DEFAULT_PROVIDER_ID, providersConfig)];\n }\n\n return providersConfig.keys().map(id => {\n const providerConfig = providersConfig.getConfig(id);\n\n return readProviderConfig(id, providerConfig);\n });\n}\n\nfunction readProviderConfig(\n id: string,\n config: Config,\n): GithubEntityProviderConfig {\n const organization = config.getString('organization');\n const catalogPath =\n config.getOptionalString('catalogPath') ?? DEFAULT_CATALOG_PATH;\n const host = config.getOptionalString('host') ?? 'github.com';\n const repositoryPattern = config.getOptionalString('filters.repository');\n const branchPattern = config.getOptionalString('filters.branch');\n const topicFilterInclude = config?.getOptionalStringArray(\n 'filters.topic.include',\n );\n const topicFilterExclude = config?.getOptionalStringArray(\n 'filters.topic.exclude',\n );\n\n const schedule = config.has('schedule')\n ? readTaskScheduleDefinitionFromConfig(config.getConfig('schedule'))\n : undefined;\n\n return {\n id,\n catalogPath,\n organization,\n host,\n filters: {\n repository: repositoryPattern\n ? compileRegExp(repositoryPattern)\n : undefined,\n branch: branchPattern || undefined,\n topic: {\n include: topicFilterInclude,\n exclude: topicFilterExclude,\n },\n },\n schedule,\n };\n}\n\n/**\n * Compiles a RegExp while enforcing the pattern to contain\n * the start-of-line and end-of-line anchors.\n *\n * @param pattern\n */\nfunction compileRegExp(pattern: string): RegExp {\n let fullLinePattern = pattern;\n if (!fullLinePattern.startsWith('^')) {\n fullLinePattern = `^${fullLinePattern}`;\n }\n if (!fullLinePattern.endsWith('$')) {\n fullLinePattern = `${fullLinePattern}$`;\n }\n\n return new RegExp(fullLinePattern);\n}\n","/*\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 { PluginTaskScheduler, TaskRunner } from '@backstage/backend-tasks';\nimport { Config } from '@backstage/config';\nimport {\n GithubCredentialsProvider,\n ScmIntegrations,\n GitHubIntegrationConfig,\n GitHubIntegration,\n SingleInstanceGithubCredentialsProvider,\n} from '@backstage/integration';\nimport {\n EntityProvider,\n EntityProviderConnection,\n LocationSpec,\n locationSpecToLocationEntity,\n} from '@backstage/plugin-catalog-backend';\n\nimport { graphql } from '@octokit/graphql';\nimport * as uuid from 'uuid';\nimport { Logger } from 'winston';\nimport {\n readProviderConfigs,\n GithubEntityProviderConfig,\n} from './GithubEntityProviderConfig';\nimport { getOrganizationRepositories, Repository } from '../lib/github';\nimport { satisfiesTopicFilter } from '../lib/util';\n\n/**\n * Discovers catalog files located in [GitHub](https://github.com).\n * The provider will search your GitHub account and register catalog files matching the configured path\n * as Location entity and via following processing steps add all contained catalog entities.\n * This can be useful as an alternative to static locations or manually adding things to the catalog.\n *\n * @public\n */\nexport class GithubEntityProvider implements EntityProvider {\n private readonly config: GithubEntityProviderConfig;\n private readonly logger: Logger;\n private readonly integration: GitHubIntegrationConfig;\n private readonly scheduleFn: () => Promise<void>;\n private connection?: EntityProviderConnection;\n private readonly githubCredentialsProvider: GithubCredentialsProvider;\n\n static fromConfig(\n config: Config,\n options: {\n logger: Logger;\n schedule?: TaskRunner;\n scheduler?: PluginTaskScheduler;\n },\n ): GithubEntityProvider[] {\n if (!options.schedule && !options.scheduler) {\n throw new Error('Either schedule or scheduler must be provided.');\n }\n\n const integrations = ScmIntegrations.fromConfig(config);\n\n return readProviderConfigs(config).map(providerConfig => {\n const integrationHost = providerConfig.host;\n const integration = integrations.github.byHost(integrationHost);\n\n if (!integration) {\n throw new Error(\n `There is no GitHub config that matches host ${integrationHost}. Please add a configuration entry for it under integrations.github`,\n );\n }\n\n if (!options.schedule && !providerConfig.schedule) {\n throw new Error(\n `No schedule provided neither via code nor config for github-provider:${providerConfig.id}.`,\n );\n }\n\n const taskRunner =\n options.schedule ??\n options.scheduler!.createScheduledTaskRunner(providerConfig.schedule!);\n\n return new GithubEntityProvider(\n providerConfig,\n integration,\n options.logger,\n taskRunner,\n );\n });\n }\n\n private constructor(\n config: GithubEntityProviderConfig,\n integration: GitHubIntegration,\n logger: Logger,\n taskRunner: TaskRunner,\n ) {\n this.config = config;\n this.integration = integration.config;\n this.logger = logger.child({\n target: this.getProviderName(),\n });\n this.scheduleFn = this.createScheduleFn(taskRunner);\n this.githubCredentialsProvider =\n SingleInstanceGithubCredentialsProvider.create(integration.config);\n }\n\n /** {@inheritdoc @backstage/plugin-catalog-backend#EntityProvider.getProviderName} */\n getProviderName(): string {\n return `github-provider:${this.config.id}`;\n }\n\n /** {@inheritdoc @backstage/plugin-catalog-backend#EntityProvider.connect} */\n async connect(connection: EntityProviderConnection): Promise<void> {\n this.connection = connection;\n return await this.scheduleFn();\n }\n\n private createScheduleFn(taskRunner: TaskRunner): () => Promise<void> {\n return async () => {\n const taskId = `${this.getProviderName()}:refresh`;\n return taskRunner.run({\n id: taskId,\n fn: async () => {\n const logger = this.logger.child({\n class: GithubEntityProvider.prototype.constructor.name,\n taskId,\n taskInstanceId: uuid.v4(),\n });\n try {\n await this.refresh(logger);\n } catch (error) {\n logger.error(error);\n }\n },\n });\n };\n }\n\n async refresh(logger: Logger) {\n if (!this.connection) {\n throw new Error('Not initialized');\n }\n\n const targets = await this.findCatalogFiles();\n const matchingTargets = this.matchesFilters(targets);\n const entities = matchingTargets\n .map(repository => this.createLocationUrl(repository))\n .map(GithubEntityProvider.toLocationSpec)\n .map(location => {\n return {\n locationKey: this.getProviderName(),\n entity: locationSpecToLocationEntity({ location }),\n };\n });\n\n await this.connection.applyMutation({\n type: 'full',\n entities,\n });\n\n logger.info(\n `Read ${targets.length} GitHub repositories (${entities.length} matching the pattern)`,\n );\n }\n\n // go to the server and get all of the repositories\n private async findCatalogFiles(): Promise<Repository[]> {\n const organization = this.config.organization;\n const host = this.integration.host;\n const orgUrl = `https://${host}/${organization}`;\n\n const { headers } = await this.githubCredentialsProvider.getCredentials({\n url: orgUrl,\n });\n\n const client = graphql.defaults({\n baseUrl: this.integration.apiBaseUrl,\n headers,\n });\n\n const { repositories } = await getOrganizationRepositories(\n client,\n organization,\n );\n\n return repositories;\n }\n\n private matchesFilters(repositories: Repository[]) {\n const repositoryFilter = this.config.filters?.repository;\n const topicFilters = this.config.filters?.topic;\n\n const matchingRepositories = repositories.filter(r => {\n const repoTopics: string[] = r.repositoryTopics.nodes.map(\n node => node.topic.name,\n );\n return (\n !r.isArchived &&\n (!repositoryFilter || repositoryFilter.test(r.name)) &&\n satisfiesTopicFilter(repoTopics, topicFilters) &&\n r.defaultBranchRef?.name\n );\n });\n return matchingRepositories;\n }\n\n private createLocationUrl(repository: Repository): string {\n const branch =\n this.config.filters?.branch || repository.defaultBranchRef?.name || '-';\n const catalogFile = this.config.catalogPath.startsWith('/')\n ? this.config.catalogPath.substring(1)\n : this.config.catalogPath;\n return `${repository.url}/blob/${branch}/${catalogFile}`;\n }\n\n private static toLocationSpec(target: string): LocationSpec {\n return {\n type: 'url',\n target: target,\n presence: 'optional',\n };\n }\n}\n\n/*\n * Helpers\n */\n\nexport function parseUrl(urlString: string): {\n org: string;\n repoSearchPath: RegExp;\n catalogPath: string;\n branch: string;\n host: string;\n} {\n const url = new URL(urlString);\n const path = url.pathname.substr(1).split('/');\n\n // /backstage/techdocs-*/blob/master/catalog-info.yaml\n // can also be\n // /backstage\n if (path.length > 2 && path[0].length && path[1].length) {\n return {\n org: decodeURIComponent(path[0]),\n repoSearchPath: escapeRegExp(decodeURIComponent(path[1])),\n catalogPath: `/${decodeURIComponent(path.slice(4).join('/'))}`,\n branch: decodeURIComponent(path[3]),\n host: url.host,\n };\n } else if (path.length === 1 && path[0].length) {\n return {\n org: decodeURIComponent(path[0]),\n repoSearchPath: escapeRegExp('*'),\n catalogPath: '/catalog-info.yaml',\n branch: '-',\n host: url.host,\n };\n }\n\n throw new Error(`Failed to parse ${urlString}`);\n}\n\nexport function escapeRegExp(str: string): RegExp {\n return new RegExp(`^${str.replace(/\\*/g, '.*')}$`);\n}\n","/*\n * Copyright 2021 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 { TaskRunner } from '@backstage/backend-tasks';\nimport {\n ANNOTATION_LOCATION,\n ANNOTATION_ORIGIN_LOCATION,\n Entity,\n} from '@backstage/catalog-model';\nimport { Config } from '@backstage/config';\nimport {\n DefaultGithubCredentialsProvider,\n GithubCredentialsProvider,\n GitHubIntegrationConfig,\n ScmIntegrations,\n SingleInstanceGithubCredentialsProvider,\n} from '@backstage/integration';\nimport {\n EntityProvider,\n EntityProviderConnection,\n} from '@backstage/plugin-catalog-backend';\nimport { graphql } from '@octokit/graphql';\nimport { merge } from 'lodash';\nimport * as uuid from 'uuid';\nimport { Logger } from 'winston';\nimport {\n assignGroupsToUsers,\n buildOrgHierarchy,\n getOrganizationTeams,\n getOrganizationUsers,\n parseGithubOrgUrl,\n} from '../lib';\n\n/**\n * Options for {@link GithubOrgEntityProvider}.\n *\n * @public\n */\nexport interface GithubOrgEntityProviderOptions {\n /**\n * A unique, stable identifier for this provider.\n *\n * @example \"production\"\n */\n id: string;\n\n /**\n * The target that this provider should consume.\n *\n * @example \"https://github.com/backstage\"\n */\n orgUrl: string;\n\n /**\n * The refresh schedule to use.\n *\n * @defaultValue \"manual\"\n * @remarks\n *\n * If you pass in 'manual', you are responsible for calling the `read` method\n * manually at some interval.\n *\n * But more commonly you will pass in the result of\n * {@link @backstage/backend-tasks#PluginTaskScheduler.createScheduledTaskRunner}\n * to enable automatic scheduling of tasks.\n */\n schedule?: 'manual' | TaskRunner;\n\n /**\n * The logger to use.\n */\n logger: Logger;\n\n /**\n * Optionally supply a custom credentials provider, replacing the default one.\n */\n githubCredentialsProvider?: GithubCredentialsProvider;\n}\n\n// TODO: Consider supporting an (optional) webhook that reacts on org changes\n/**\n * Ingests org data (users and groups) from GitHub.\n *\n * @public\n */\nexport class GithubOrgEntityProvider implements EntityProvider {\n private readonly credentialsProvider: GithubCredentialsProvider;\n private connection?: EntityProviderConnection;\n private scheduleFn?: () => Promise<void>;\n\n static fromConfig(config: Config, options: GithubOrgEntityProviderOptions) {\n const integrations = ScmIntegrations.fromConfig(config);\n const gitHubConfig = integrations.github.byUrl(options.orgUrl)?.config;\n\n if (!gitHubConfig) {\n throw new Error(\n `There is no GitHub Org provider that matches ${options.orgUrl}. Please add a configuration for an integration.`,\n );\n }\n\n const logger = options.logger.child({\n target: options.orgUrl,\n });\n\n const provider = new GithubOrgEntityProvider({\n id: options.id,\n orgUrl: options.orgUrl,\n logger,\n gitHubConfig,\n githubCredentialsProvider:\n options.githubCredentialsProvider ||\n DefaultGithubCredentialsProvider.fromIntegrations(integrations),\n });\n\n provider.schedule(options.schedule);\n\n return provider;\n }\n\n constructor(\n private options: {\n id: string;\n orgUrl: string;\n gitHubConfig: GitHubIntegrationConfig;\n logger: Logger;\n githubCredentialsProvider?: GithubCredentialsProvider;\n },\n ) {\n this.credentialsProvider =\n options.githubCredentialsProvider ||\n SingleInstanceGithubCredentialsProvider.create(this.options.gitHubConfig);\n }\n\n /** {@inheritdoc @backstage/plugin-catalog-backend#EntityProvider.getProviderName} */\n getProviderName() {\n return `GithubOrgEntityProvider:${this.options.id}`;\n }\n\n /** {@inheritdoc @backstage/plugin-catalog-backend#EntityProvider.connect} */\n async connect(connection: EntityProviderConnection) {\n this.connection = connection;\n await this.scheduleFn?.();\n }\n\n /**\n * Runs one single complete ingestion. This is only necessary if you use\n * manual scheduling.\n */\n async read(options?: { logger?: Logger }) {\n if (!this.connection) {\n throw new Error('Not initialized');\n }\n\n const logger = options?.logger ?? this.options.logger;\n const { markReadComplete } = trackProgress(logger);\n\n const { headers, type: tokenType } =\n await this.credentialsProvider.getCredentials({\n url: this.options.orgUrl,\n });\n const client = graphql.defaults({\n baseUrl: this.options.gitHubConfig.apiBaseUrl,\n headers,\n });\n\n const { org } = parseGithubOrgUrl(this.options.orgUrl);\n const { users } = await getOrganizationUsers(client, org, tokenType);\n const { groups, groupMemberUsers } = await getOrganizationTeams(\n client,\n org,\n );\n assignGroupsToUsers(users, groupMemberUsers);\n buildOrgHierarchy(groups);\n\n const { markCommitComplete } = markReadComplete({ users, groups });\n\n await this.connection.applyMutation({\n type: 'full',\n entities: [...users, ...groups].map(entity => ({\n locationKey: `github-org-provider:${this.options.id}`,\n entity: withLocations(\n `https://${this.options.gitHubConfig.host}`,\n org,\n entity,\n ),\n })),\n });\n\n markCommitComplete();\n }\n\n private schedule(schedule: GithubOrgEntityProviderOptions['schedule']) {\n if (!schedule || schedule === 'manual') {\n return;\n }\n\n this.scheduleFn = async () => {\n const id = `${this.getProviderName()}:refresh`;\n await schedule.run({\n id,\n fn: async () => {\n const logger = this.options.logger.child({\n class: GithubOrgEntityProvider.prototype.constructor.name,\n taskId: id,\n taskInstanceId: uuid.v4(),\n });\n\n try {\n await this.read({ logger });\n } catch (error) {\n logger.error(error);\n }\n },\n });\n };\n }\n}\n\n// Helps wrap the timing and logging behaviors\nfunction trackProgress(logger: Logger) {\n let timestamp = Date.now();\n let summary: string;\n\n logger.info('Reading GitHub users and groups');\n\n function markReadComplete(read: { users: unknown[]; groups: unknown[] }) {\n summary = `${read.users.length} GitHub users and ${read.groups.length} GitHub groups`;\n const readDuration = ((Date.now() - timestamp) / 1000).toFixed(1);\n timestamp = Date.now();\n logger.info(`Read ${summary} in ${readDuration} seconds. Committing...`);\n return { markCommitComplete };\n }\n\n function markCommitComplete() {\n const commitDuration = ((Date.now() - timestamp) / 1000).toFixed(1);\n logger.info(`Committed ${summary} in ${commitDuration} seconds.`);\n }\n\n return { markReadComplete };\n}\n\n// Makes sure that emitted entities have a proper location\nexport function withLocations(\n baseUrl: string,\n org: string,\n entity: Entity,\n): Entity {\n const location =\n entity.kind === 'Group'\n ? `url:${baseUrl}/orgs/${org}/teams/${entity.metadata.name}`\n : `url:${baseUrl}/${entity.metadata.name}`;\n return merge(\n {\n metadata: {\n annotations: {\n [ANNOTATION_LOCATION]: location,\n [ANNOTATION_ORIGIN_LOCATION]: location,\n },\n },\n },\n entity,\n ) as Entity;\n}\n","/*\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 createBackendModule,\n loggerToWinstonLogger,\n configServiceRef,\n loggerServiceRef,\n schedulerServiceRef,\n} from '@backstage/backend-plugin-api';\nimport { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node';\nimport { GithubEntityProvider } from '../providers/GithubEntityProvider';\n\n/**\n * Registers the {@link GithubEntityProvider} with the catalog processing extension point.\n *\n * @alpha\n */\nexport const githubEntityProviderCatalogModule = createBackendModule({\n pluginId: 'catalog',\n moduleId: 'githubEntityProvider',\n register(env) {\n env.registerInit({\n deps: {\n catalog: catalogProcessingExtensionPoint,\n config: configServiceRef,\n logger: loggerServiceRef,\n scheduler: schedulerServiceRef,\n },\n async init({ catalog, config, logger, scheduler }) {\n catalog.addEntityProvider(\n GithubEntityProvider.fromConfig(config, {\n logger: loggerToWinstonLogger(logger),\n scheduler,\n }),\n );\n },\n });\n },\n});\n","/*\n * Copyright 2020 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 { PluginTaskScheduler, TaskRunner } from '@backstage/backend-tasks';\nimport { Config } from '@backstage/config';\nimport {\n EntityProvider,\n EntityProviderConnection,\n} from '@backstage/plugin-catalog-backend';\nimport { Logger } from 'winston';\nimport { GithubEntityProvider } from './providers/GithubEntityProvider';\nimport {\n GithubOrgEntityProvider,\n GithubOrgEntityProviderOptions,\n} from './providers/GithubOrgEntityProvider';\n\n/**\n * @public\n * @deprecated Use {@link GithubOrgEntityProvider} instead.\n */\nexport class GitHubOrgEntityProvider extends GithubOrgEntityProvider {\n static fromConfig(config: Config, options: GitHubOrgEntityProviderOptions) {\n options.logger.warn(\n '[Deprecated] Use GithubOrgEntityProvider instead of GitHubOrgEntityProvider.',\n );\n return GithubOrgEntityProvider.fromConfig(\n config,\n options as GithubOrgEntityProviderOptions,\n ) as GitHubOrgEntityProvider;\n }\n}\n\n/**\n * @public\n * @deprecated Use {@link GithubOrgEntityProviderOptions} instead.\n */\nexport type GitHubOrgEntityProviderOptions = GithubOrgEntityProviderOptions;\n\n/**\n * @public\n * @deprecated Use {@link GithubEntityProvider} instead.\n */\nexport class GitHubEntityProvider implements EntityProvider {\n static fromConfig(\n config: Config,\n options: {\n logger: Logger;\n schedule?: TaskRunner;\n scheduler?: PluginTaskScheduler;\n },\n ): GitHubEntityProvider[] {\n options.logger.warn(\n '[Deprecated] Please use GithubEntityProvider instead of GitHubEntityProvider.',\n );\n return GithubEntityProvider.fromConfig(config, options).map(\n delegate => new GitHubEntityProvider(delegate),\n );\n }\n\n private constructor(private readonly delegate: GithubEntityProvider) {}\n\n connect(connection: EntityProviderConnection): Promise<void> {\n return this.delegate.connect(connection);\n }\n\n getProviderName(): string {\n return this.delegate.getProviderName();\n }\n\n refresh(logger: Logger): Promise<void> {\n return this.delegate.refresh(logger);\n }\n}\n"],"names":["CatalogClient","ScmIntegrations","integration","parseGitUrl","Octokit","trimEnd","_a","DefaultGithubCredentialsProvider","graphql","processingResult","GithubAppCredentialsMux","readTaskScheduleDefinitionFromConfig","SingleInstanceGithubCredentialsProvider","uuid","locationSpecToLocationEntity","merge","ANNOTATION_LOCATION","ANNOTATION_ORIGIN_LOCATION","createBackendModule","catalogProcessingExtensionPoint","configServiceRef","loggerServiceRef","schedulerServiceRef","loggerToWinstonLogger"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -55,6 +55,23 @@ export declare class GithubDiscoveryProcessor implements CatalogProcessor {
|
|
|
55
55
|
readLocation(location: LocationSpec, _optional: boolean, emit: CatalogProcessorEmit): Promise<boolean>;
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
+
/**
|
|
59
|
+
* @public
|
|
60
|
+
* @deprecated Use {@link GithubEntityProvider} instead.
|
|
61
|
+
*/
|
|
62
|
+
export declare class GitHubEntityProvider implements EntityProvider {
|
|
63
|
+
private readonly delegate;
|
|
64
|
+
static fromConfig(config: Config, options: {
|
|
65
|
+
logger: Logger;
|
|
66
|
+
schedule?: TaskRunner;
|
|
67
|
+
scheduler?: PluginTaskScheduler;
|
|
68
|
+
}): GitHubEntityProvider[];
|
|
69
|
+
private constructor();
|
|
70
|
+
connect(connection: EntityProviderConnection): Promise<void>;
|
|
71
|
+
getProviderName(): string;
|
|
72
|
+
refresh(logger: Logger): Promise<void>;
|
|
73
|
+
}
|
|
74
|
+
|
|
58
75
|
/**
|
|
59
76
|
* Discovers catalog files located in [GitHub](https://github.com).
|
|
60
77
|
* The provider will search your GitHub account and register catalog files matching the configured path
|
|
@@ -63,7 +80,7 @@ export declare class GithubDiscoveryProcessor implements CatalogProcessor {
|
|
|
63
80
|
*
|
|
64
81
|
* @public
|
|
65
82
|
*/
|
|
66
|
-
export declare class
|
|
83
|
+
export declare class GithubEntityProvider implements EntityProvider {
|
|
67
84
|
private readonly config;
|
|
68
85
|
private readonly logger;
|
|
69
86
|
private readonly integration;
|
|
@@ -74,7 +91,7 @@ export declare class GitHubEntityProvider implements EntityProvider {
|
|
|
74
91
|
logger: Logger;
|
|
75
92
|
schedule?: TaskRunner;
|
|
76
93
|
scheduler?: PluginTaskScheduler;
|
|
77
|
-
}):
|
|
94
|
+
}): GithubEntityProvider[];
|
|
78
95
|
private constructor();
|
|
79
96
|
/** {@inheritdoc @backstage/plugin-catalog-backend#EntityProvider.getProviderName} */
|
|
80
97
|
getProviderName(): string;
|
|
@@ -91,10 +108,10 @@ export declare class GitHubEntityProvider implements EntityProvider {
|
|
|
91
108
|
/* Excluded from this release type: githubEntityProviderCatalogModule */
|
|
92
109
|
|
|
93
110
|
/** @public */
|
|
94
|
-
export declare class
|
|
111
|
+
export declare class GithubLocationAnalyzer implements ScmLocationAnalyzer {
|
|
95
112
|
private readonly catalogClient;
|
|
96
113
|
private readonly config;
|
|
97
|
-
constructor(options:
|
|
114
|
+
constructor(options: GithubLocationAnalyzerOptions);
|
|
98
115
|
supports(url: string): boolean;
|
|
99
116
|
analyze({ url, catalogFilename }: AnalyzeOptions): Promise<{
|
|
100
117
|
existing: {
|
|
@@ -109,7 +126,7 @@ export declare class GitHubLocationAnalyzer implements ScmLocationAnalyzer {
|
|
|
109
126
|
}
|
|
110
127
|
|
|
111
128
|
/** @public */
|
|
112
|
-
export declare type
|
|
129
|
+
export declare type GithubLocationAnalyzerOptions = {
|
|
113
130
|
config: Config;
|
|
114
131
|
discovery: PluginEndpointDiscovery;
|
|
115
132
|
};
|
|
@@ -160,17 +177,25 @@ export declare class GithubMultiOrgReaderProcessor implements CatalogProcessor {
|
|
|
160
177
|
private getAllOrgs;
|
|
161
178
|
}
|
|
162
179
|
|
|
180
|
+
/**
|
|
181
|
+
* @public
|
|
182
|
+
* @deprecated Use {@link GithubOrgEntityProvider} instead.
|
|
183
|
+
*/
|
|
184
|
+
export declare class GitHubOrgEntityProvider extends GithubOrgEntityProvider {
|
|
185
|
+
static fromConfig(config: Config, options: GitHubOrgEntityProviderOptions): GitHubOrgEntityProvider;
|
|
186
|
+
}
|
|
187
|
+
|
|
163
188
|
/**
|
|
164
189
|
* Ingests org data (users and groups) from GitHub.
|
|
165
190
|
*
|
|
166
191
|
* @public
|
|
167
192
|
*/
|
|
168
|
-
export declare class
|
|
193
|
+
export declare class GithubOrgEntityProvider implements EntityProvider {
|
|
169
194
|
private options;
|
|
170
195
|
private readonly credentialsProvider;
|
|
171
196
|
private connection?;
|
|
172
197
|
private scheduleFn?;
|
|
173
|
-
static fromConfig(config: Config, options:
|
|
198
|
+
static fromConfig(config: Config, options: GithubOrgEntityProviderOptions): GithubOrgEntityProvider;
|
|
174
199
|
constructor(options: {
|
|
175
200
|
id: string;
|
|
176
201
|
orgUrl: string;
|
|
@@ -193,11 +218,17 @@ export declare class GitHubOrgEntityProvider implements EntityProvider {
|
|
|
193
218
|
}
|
|
194
219
|
|
|
195
220
|
/**
|
|
196
|
-
*
|
|
221
|
+
* @public
|
|
222
|
+
* @deprecated Use {@link GithubOrgEntityProviderOptions} instead.
|
|
223
|
+
*/
|
|
224
|
+
export declare type GitHubOrgEntityProviderOptions = GithubOrgEntityProviderOptions;
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Options for {@link GithubOrgEntityProvider}.
|
|
197
228
|
*
|
|
198
229
|
* @public
|
|
199
230
|
*/
|
|
200
|
-
export declare interface
|
|
231
|
+
export declare interface GithubOrgEntityProviderOptions {
|
|
201
232
|
/**
|
|
202
233
|
* A unique, stable identifier for this provider.
|
|
203
234
|
*
|
|
@@ -239,7 +270,7 @@ export declare interface GitHubOrgEntityProviderOptions {
|
|
|
239
270
|
*
|
|
240
271
|
* @remarks
|
|
241
272
|
*
|
|
242
|
-
* Consider using {@link
|
|
273
|
+
* Consider using {@link GithubOrgEntityProvider} instead.
|
|
243
274
|
*
|
|
244
275
|
* @public
|
|
245
276
|
*/
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backstage/plugin-catalog-backend-module-github",
|
|
3
3
|
"description": "A Backstage catalog backend module that helps integrate towards GitHub",
|
|
4
|
-
"version": "0.0.0-nightly-
|
|
4
|
+
"version": "0.0.0-nightly-20221020030155",
|
|
5
5
|
"main": "dist/index.cjs.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"license": "Apache-2.0",
|
|
@@ -33,16 +33,16 @@
|
|
|
33
33
|
"start": "backstage-cli package start"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@backstage/backend-common": "^0.0.0-nightly-
|
|
37
|
-
"@backstage/backend-plugin-api": "^0.0.0-nightly-
|
|
38
|
-
"@backstage/backend-tasks": "^0.0.0-nightly-
|
|
39
|
-
"@backstage/catalog-client": "^0.0.0-nightly-
|
|
40
|
-
"@backstage/catalog-model": "^0.0.0-nightly-
|
|
41
|
-
"@backstage/config": "^0.0.0-nightly-
|
|
42
|
-
"@backstage/errors": "^0.0.0-nightly-
|
|
43
|
-
"@backstage/integration": "^0.0.0-nightly-
|
|
44
|
-
"@backstage/plugin-catalog-backend": "^0.0.0-nightly-
|
|
45
|
-
"@backstage/plugin-catalog-node": "^0.0.0-nightly-
|
|
36
|
+
"@backstage/backend-common": "^0.0.0-nightly-20221020030155",
|
|
37
|
+
"@backstage/backend-plugin-api": "^0.0.0-nightly-20221020030155",
|
|
38
|
+
"@backstage/backend-tasks": "^0.0.0-nightly-20221020030155",
|
|
39
|
+
"@backstage/catalog-client": "^0.0.0-nightly-20221020030155",
|
|
40
|
+
"@backstage/catalog-model": "^0.0.0-nightly-20221020030155",
|
|
41
|
+
"@backstage/config": "^0.0.0-nightly-20221020030155",
|
|
42
|
+
"@backstage/errors": "^0.0.0-nightly-20221020030155",
|
|
43
|
+
"@backstage/integration": "^0.0.0-nightly-20221020030155",
|
|
44
|
+
"@backstage/plugin-catalog-backend": "^0.0.0-nightly-20221020030155",
|
|
45
|
+
"@backstage/plugin-catalog-node": "^0.0.0-nightly-20221020030155",
|
|
46
46
|
"@backstage/types": "^1.0.0",
|
|
47
47
|
"@octokit/graphql": "^5.0.0",
|
|
48
48
|
"@octokit/rest": "^19.0.3",
|
|
@@ -54,8 +54,8 @@
|
|
|
54
54
|
"winston": "^3.2.1"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
|
-
"@backstage/backend-test-utils": "^0.0.0-nightly-
|
|
58
|
-
"@backstage/cli": "^0.0.0-nightly-
|
|
57
|
+
"@backstage/backend-test-utils": "^0.0.0-nightly-20221020030155",
|
|
58
|
+
"@backstage/cli": "^0.0.0-nightly-20221020030155",
|
|
59
59
|
"@types/lodash": "^4.14.151",
|
|
60
60
|
"luxon": "^3.0.0"
|
|
61
61
|
},
|