Skip to content

Commit 2eb0da3

Browse files
committed
feat(events,github-org): add support for EventsService, events at new backend
Adds optional support for the EventsService passed as argument to the factory method. For the new backend, the EventsService is used as dependency and passed on. Events support will be active always. The support for the deprecated EventBroker and its interfaces was kept for easier migration and will be removed as a separate follow-up change that could go into a following release. Signed-off-by: Patrick Jungermann <Patrick.Jungermann@gmail.com>
1 parent 2c61fae commit 2eb0da3

File tree

8 files changed

+124
-16
lines changed

8 files changed

+124
-16
lines changed

.changeset/happy-walls-think.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
---
2+
'@backstage/plugin-catalog-backend-module-github-org': patch
3+
'@backstage/plugin-catalog-backend-module-github': patch
4+
---
5+
6+
Support EventsService and events with the new backend system (through EventsService) for `GithubOrgEntityProvider` and `GithubMultiOrgEntityProvider`.
7+
8+
_New/Current Backend System:_
9+
10+
The events support for the provider will be enabled always, making it ready to consume events from its subscribed topics.
11+
In order to receive events and make use of this feature, you still need to set up receiving events from the event source as before.
12+
13+
_Legacy Backend System:_
14+
15+
You can pass the `EventsService` instance to the factory method as one of its options:
16+
17+
```diff
18+
// packages/backend/src/plugins/catalog.ts
19+
const githubOrgProvider = GithubOrgEntityProvider.fromConfig(env.config, {
20+
events: env.events,
21+
// ...
22+
});
23+
- env.eventBroker.subscribe(githubOrgProvider);
24+
```
25+
26+
```diff
27+
// packages/backend/src/plugins/catalog.ts
28+
const githubMultiOrgProvider = GithubMultiOrgEntityProvider.fromConfig(env.config, {
29+
events: env.events,
30+
// ...
31+
});
32+
- env.eventBroker.subscribe(githubMultiOrgProvider);
33+
```

docs/integrations/github/org.md

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,32 @@ export default async function createPlugin(
103103

104104
## Installation with Events Support
105105

106+
_For the legacy backend system, please read the subsection below._
107+
108+
The catalog module `github-org` comes with events support enabled for the `GithubMultiOrgEntityProvider`.
109+
This will make it subscribe to its relevant topics and expects these events to be published via the `EventsService`.
110+
111+
Topics:
112+
113+
- `github.installation`
114+
- `github.membership`
115+
- `github.organization`
116+
- `github.team`
117+
118+
Additionally, you should install the
119+
[event router by `events-backend-module-github`](https://github.com/backstage/backstage/tree/master/plugins/events-backend-module-github/README.md)
120+
which will route received events from the generic topic `github` to more specific ones
121+
based on the event type (e.g., `github.membership`).
122+
123+
In order to receive Webhook events by GitHub, you have to decide how you want them
124+
to be ingested into Backstage and published to its `EventsService`.
125+
You can decide between the following options (extensible):
126+
127+
- [via HTTP endpoint](https://github.com/backstage/backstage/tree/master/plugins/events-backend/README.md)
128+
- [via an AWS SQS queue](https://github.com/backstage/backstage/tree/master/plugins/events-backend-module-aws-sqs/README.md)
129+
130+
### Legacy Backend System
131+
106132
Please follow the installation instructions at
107133

108134
- <https://github.com/backstage/backstage/tree/master/plugins/events-backend/README.md>
@@ -133,12 +159,12 @@ export default async function createPlugin(
133159
id: 'production',
134160
orgUrl: 'https://github.com/backstage',
135161
logger: env.logger,
162+
events: env.events,
136163
schedule: env.scheduler.createScheduledTaskRunner({
137164
frequency: { minutes: 60 },
138165
timeout: { minutes: 15 },
139166
}),
140167
});
141-
env.eventBroker.subscribe(githubOrgProvider);
142168
builder.addEntityProvider(githubOrgProvider);
143169
/* highlight-add-end */
144170
const { processingEngine, router } = await builder.build();
@@ -169,12 +195,11 @@ export default async function createPlugin(
169195
// also omit this option to ingest all orgs accessible by your GitHub integration
170196
orgs: ['org-a', 'org-b'],
171197
logger: env.logger,
198+
events: env.events,
172199
schedule: env.scheduler.createScheduledTaskRunner({
173200
frequency: { minutes: 60 },
174201
timeout: { minutes: 15 },
175202
}),
176-
// Pass in the eventBroker to allow this provider to subscribe to GitHub events
177-
eventBroker: env.eventBroker,
178203
}),
179204
);
180205
/* highlight-add-end */

plugins/catalog-backend-module-github-org/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@
3636
"@backstage/backend-tasks": "workspace:^",
3737
"@backstage/config": "workspace:^",
3838
"@backstage/plugin-catalog-backend-module-github": "workspace:^",
39-
"@backstage/plugin-catalog-node": "workspace:^"
39+
"@backstage/plugin-catalog-node": "workspace:^",
40+
"@backstage/plugin-events-node": "workspace:^"
4041
},
4142
"devDependencies": {
4243
"@backstage/backend-test-utils": "workspace:^",

plugins/catalog-backend-module-github-org/src/module.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import {
3131
UserTransformer,
3232
} from '@backstage/plugin-catalog-backend-module-github';
3333
import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha';
34+
import { eventsServiceRef } from '@backstage/plugin-events-node';
3435

3536
/**
3637
* Interface for {@link githubOrgEntityProviderTransformsExtensionPoint}.
@@ -95,16 +96,18 @@ export const catalogModuleGithubOrgEntityProvider = createBackendModule({
9596
deps: {
9697
catalog: catalogProcessingExtensionPoint,
9798
config: coreServices.rootConfig,
99+
events: eventsServiceRef,
98100
logger: coreServices.logger,
99101
scheduler: coreServices.scheduler,
100102
},
101-
async init({ catalog, config, logger, scheduler }) {
103+
async init({ catalog, config, events, logger, scheduler }) {
102104
for (const definition of readDefinitionsFromConfig(config)) {
103105
catalog.addEntityProvider(
104106
GithubMultiOrgEntityProvider.fromConfig(config, {
105107
id: definition.id,
106108
githubUrl: definition.githubUrl,
107109
orgs: definition.orgs,
110+
events,
108111
schedule: scheduler.createScheduledTaskRunner(
109112
definition.schedule,
110113
),

plugins/catalog-backend-module-github/api-report.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ export type GithubMultiOrgConfig = Array<{
142142
// @public
143143
export class GithubMultiOrgEntityProvider implements EntityProvider {
144144
constructor(options: {
145+
events?: EventsService;
145146
id: string;
146147
gitHubConfig: GithubIntegrationConfig;
147148
githubCredentialsProvider: GithubCredentialsProvider;
@@ -165,7 +166,9 @@ export class GithubMultiOrgEntityProvider implements EntityProvider {
165166

166167
// @public
167168
export interface GithubMultiOrgEntityProviderOptions {
169+
// @deprecated
168170
eventBroker?: EventBroker;
171+
events?: EventsService;
169172
githubCredentialsProvider?: GithubCredentialsProvider;
170173
githubUrl: string;
171174
id: string;
@@ -220,6 +223,7 @@ export class GithubOrgEntityProvider
220223
implements EntityProvider, EventSubscriber
221224
{
222225
constructor(options: {
226+
events?: EventsService;
223227
id: string;
224228
orgUrl: string;
225229
gitHubConfig: GithubIntegrationConfig;
@@ -249,6 +253,7 @@ export type GitHubOrgEntityProviderOptions = GithubOrgEntityProviderOptions;
249253

250254
// @public
251255
export interface GithubOrgEntityProviderOptions {
256+
events?: EventsService;
252257
githubCredentialsProvider?: GithubCredentialsProvider;
253258
id: string;
254259
logger: Logger;

plugins/catalog-backend-module-github/src/providers/GithubMultiOrgEntityProvider.ts

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,11 @@ import {
3838
EntityProvider,
3939
EntityProviderConnection,
4040
} from '@backstage/plugin-catalog-node';
41-
import { EventBroker, EventParams } from '@backstage/plugin-events-node';
41+
import {
42+
EventBroker,
43+
EventParams,
44+
EventsService,
45+
} from '@backstage/plugin-events-node';
4246
import { graphql } from '@octokit/graphql';
4347
import {
4448
InstallationCreatedEvent,
@@ -80,6 +84,13 @@ import {
8084
import { splitTeamSlug } from '../lib/util';
8185
import { areGroupEntities, areUserEntities } from '../lib/guards';
8286

87+
const EVENT_TOPICS = [
88+
'github.installation',
89+
'github.membership',
90+
'github.organization',
91+
'github.team',
92+
];
93+
8394
/**
8495
* Options for {@link GithubMultiOrgEntityProvider}.
8596
*
@@ -101,11 +112,16 @@ export interface GithubMultiOrgEntityProviderOptions {
101112
githubUrl: string;
102113

103114
/**
104-
* The list of the GitHub orgs to consume. By default will consume all accessible
115+
* The list of the GitHub orgs to consume. By default, it will consume all accessible
105116
* orgs on the given GitHub instance (support for GitHub App integration only).
106117
*/
107118
orgs?: string[];
108119

120+
/**
121+
* Passing the optional EventsService enables event-based delta updates.
122+
*/
123+
events?: EventsService;
124+
109125
/**
110126
* The refresh schedule to use.
111127
*
@@ -138,12 +154,14 @@ export interface GithubMultiOrgEntityProviderOptions {
138154

139155
/**
140156
* Optionally include a team transformer for transforming from GitHub teams to Group Entities.
141-
* By default groups will be namespaced according to their GitHub org.
157+
* By default, groups will be namespaced according to their GitHub org.
142158
*/
143159
teamTransformer?: TeamTransformer;
144160

145161
/**
146162
* An EventBroker to subscribe this provider to GitHub events to trigger delta mutations
163+
*
164+
* @deprecated Use `events` instead.
147165
*/
148166
eventBroker?: EventBroker;
149167
}
@@ -206,6 +224,7 @@ export class GithubMultiOrgEntityProvider implements EntityProvider {
206224

207225
constructor(
208226
private readonly options: {
227+
events?: EventsService;
209228
id: string;
210229
gitHubConfig: GithubIntegrationConfig;
211230
githubCredentialsProvider: GithubCredentialsProvider;
@@ -225,6 +244,11 @@ export class GithubMultiOrgEntityProvider implements EntityProvider {
225244
/** {@inheritdoc @backstage/plugin-catalog-backend#EntityProvider.connect} */
226245
async connect(connection: EntityProviderConnection) {
227246
this.connection = connection;
247+
await this.options.events?.subscribe({
248+
id: this.getProviderName(),
249+
topics: EVENT_TOPICS,
250+
onEvent: params => this.onEvent(params),
251+
});
228252
await this.scheduleFn?.();
229253
}
230254

@@ -312,12 +336,7 @@ export class GithubMultiOrgEntityProvider implements EntityProvider {
312336
}
313337

314338
private supportsEventTopics(): string[] {
315-
return [
316-
'github.installation',
317-
'github.organization',
318-
'github.team',
319-
'github.membership',
320-
];
339+
return EVENT_TOPICS;
321340
}
322341

323342
private async onEvent(params: EventParams): Promise<void> {

plugins/catalog-backend-module-github/src/providers/GithubOrgEntityProvider.ts

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,11 @@ import {
2828
EntityProvider,
2929
EntityProviderConnection,
3030
} from '@backstage/plugin-catalog-node';
31-
import { EventParams, EventSubscriber } from '@backstage/plugin-events-node';
31+
import {
32+
EventParams,
33+
EventsService,
34+
EventSubscriber,
35+
} from '@backstage/plugin-events-node';
3236
import { graphql } from '@octokit/graphql';
3337
import {
3438
MembershipEvent,
@@ -62,6 +66,12 @@ import { parseGithubOrgUrl } from '../lib/util';
6266
import { withLocations } from '../lib/withLocations';
6367
import { areGroupEntities, areUserEntities } from '../lib/guards';
6468

69+
const EVENT_TOPICS = [
70+
'github.membership',
71+
'github.organization',
72+
'github.team',
73+
];
74+
6575
/**
6676
* Options for {@link GithubOrgEntityProvider}.
6777
*
@@ -82,6 +92,11 @@ export interface GithubOrgEntityProviderOptions {
8292
*/
8393
orgUrl: string;
8494

95+
/**
96+
* Passing the optional EventsService enables event-based delta updates.
97+
*/
98+
events?: EventsService;
99+
85100
/**
86101
* The refresh schedule to use.
87102
*
@@ -163,6 +178,7 @@ export class GithubOrgEntityProvider
163178

164179
constructor(
165180
private options: {
181+
events?: EventsService;
166182
id: string;
167183
orgUrl: string;
168184
gitHubConfig: GithubIntegrationConfig;
@@ -185,6 +201,11 @@ export class GithubOrgEntityProvider
185201
/** {@inheritdoc @backstage/plugin-catalog-backend#EntityProvider.connect} */
186202
async connect(connection: EntityProviderConnection) {
187203
this.connection = connection;
204+
await this.options.events?.subscribe({
205+
id: this.getProviderName(),
206+
topics: EVENT_TOPICS,
207+
onEvent: params => this.onEvent(params),
208+
});
188209
await this.scheduleFn?.();
189210
}
190211

@@ -315,7 +336,7 @@ export class GithubOrgEntityProvider
315336

316337
/** {@inheritdoc @backstage/plugin-events-node#EventSubscriber.supportsEventTopics} */
317338
supportsEventTopics(): string[] {
318-
return ['github.organization', 'github.team', 'github.membership'];
339+
return EVENT_TOPICS;
319340
}
320341

321342
private async onTeamEditedInOrganization(

yarn.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5593,6 +5593,7 @@ __metadata:
55935593
"@backstage/config": "workspace:^"
55945594
"@backstage/plugin-catalog-backend-module-github": "workspace:^"
55955595
"@backstage/plugin-catalog-node": "workspace:^"
5596+
"@backstage/plugin-events-node": "workspace:^"
55965597
luxon: ^3.0.0
55975598
languageName: unknown
55985599
linkType: soft

0 commit comments

Comments
 (0)