Skip to content

Commit f85774e

Browse files
Closes #2: Adding support for all events alongside specific events trigger
Signed-off-by: Peter Zhu <zhujiaxi@amazon.com>
1 parent c34612b commit f85774e

File tree

6 files changed

+60
-50
lines changed

6 files changed

+60
-50
lines changed

configs/operations/hello-world.yml

+2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
---
22
name: Hello World Operation
33

4+
# You can listen to either `all` events or specific events
45
events:
6+
# - all
57
- issues.labeled
68
- issues.assigned
79

package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
"automation-app"
1414
],
1515
"scripts": {
16-
"build": "npm run clean && npm run format && npm run lint && tsc",
17-
"watch": "tsc -w",
16+
"build": "npm run clean && npm run format && npm run lint && npm run compile",
17+
"compile": "tsc",
1818
"start": "npm run build && probot run ./bin/app.js",
1919
"clean": "rm -rf ./bin/*",
2020
"format": "prettier --write \"src/**/*.{js,ts}\" \"test/**/*.ts\" \"configs/**/*.{yaml,yml}\"",

src/app.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ export default async (app: Probot) => {
66
app.log.info('OpenSearch Automation App is starting now......');
77

88
const srvObj = new Service('Hello World Service');
9-
await srvObj.initService('configs/resources/peterzhu-organization.yml', 'configs/operations/hello-world.yml', app);
10-
await srvObj.registerEvents();
9+
await srvObj.initService(app, 'configs/resources/peterzhu-organization.yml', 'configs/operations/hello-world.yml');
1110

1211
app.log.info('All objects initialized, start listening events......');
1312
};

src/config/operation-config.ts

+1-9
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
1-
import { Probot } from 'probot';
21
import { Operation } from '../service/operation/operation';
32
import { Task } from '../service/operation/task';
43
import { OperationData, TaskData } from './types';
54
import { Config } from './config';
65

76
export class OperationConfig extends Config {
8-
private app: Probot;
9-
107
private static configSchema = {
118
type: 'object',
129
properties: {
@@ -44,16 +41,11 @@ export class OperationConfig extends Config {
4441
required: ['name', 'events', 'tasks'],
4542
};
4643

47-
constructor(configPath: string, app: Probot) {
44+
constructor(configPath: string) {
4845
super('OperationConfig');
4946
this.configData = OperationConfig.readConfig(configPath);
5047
this.configSchema = OperationConfig.configSchema;
5148
OperationConfig.validateConfig(this.configData, this.configSchema);
52-
this.app = app;
53-
}
54-
55-
public getApp(): Probot {
56-
return this.app;
5749
}
5850

5951
private static async _initTasks(taskDataArray: TaskData[]): Promise<Task[]> {

src/config/resource-config.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ export class ResourceConfig extends Config {
6868
required: ['organizations'],
6969
};
7070

71-
constructor(configPath: string, octokit: ProbotOctokit) {
71+
constructor(octokit: ProbotOctokit, configPath: string) {
7272
super('ResourceConfig');
7373
this.configData = ResourceConfig.readConfig(configPath);
7474
this.configSchema = ResourceConfig.configSchema;

src/service/service.ts

+53-36
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type { WebhookEventMap } from '@octokit/webhooks-types';
33
import { access, realpath } from 'fs/promises';
44
import { Resource } from './resource/resource';
55
import { Operation } from './operation/operation';
6+
import { Task } from './operation/task';
67
import { ResourceConfig } from '../config/resource-config';
78
import { OperationConfig } from '../config/operation-config';
89
import { octokitAuth } from '../utility/octokit';
@@ -32,56 +33,72 @@ export class Service {
3233
return this.operation;
3334
}
3435

35-
public async initService(resourceConfigPath: string, operationConfigPath: string, app: Probot): Promise<void> {
36+
public async initService(app: Probot, resourceConfigPath: string, operationConfigPath: string): Promise<void> {
3637
app.log.info(`Initializing Service: ${this.name} `);
38+
this.app = app;
3739
// Get octokit client so Resource object will get context
38-
const octokit = await octokitAuth(app, Number(process.env.INSTALLATION_ID));
39-
const resConfigObj = new ResourceConfig(resourceConfigPath, octokit);
40+
const octokit = await octokitAuth(this.app, Number(process.env.INSTALLATION_ID));
41+
const resConfigObj = new ResourceConfig(octokit, resourceConfigPath);
4042
this.resource = await resConfigObj.initResource();
41-
const opConfigObj = new OperationConfig(operationConfigPath, app);
43+
const opConfigObj = new OperationConfig(operationConfigPath);
4244
this.operation = await opConfigObj.initOperation();
43-
this.app = app;
45+
this._registerEvents();
46+
}
47+
48+
private async _registerTasks(context: any, event: string, tasks: Task[]): Promise<void> {
49+
await tasks.reduce(async (promise, task) => {
50+
await promise; // Make sure tasks are completed in sequential orders
51+
52+
const callPath = await realpath(`./bin/call/${task.getCallName()}.js`);
53+
const callFunc = task.getCallFunc();
54+
const callArgs = task.getCallArgs();
55+
56+
console.log(`[${event}]: Verify call lib: ${callPath}`);
57+
try {
58+
await access(callPath);
59+
} catch (e) {
60+
console.error(`ERROR: ${e}`);
61+
}
62+
63+
const callStack = await import(callPath);
64+
if (callFunc === 'default') {
65+
console.log(`[${event}]: Call default function: [${callStack.default.name}]`);
66+
await callStack.default(this.app, context, { ...callArgs });
67+
} else {
68+
console.log(callStack);
69+
const callFuncCustom = callStack[callFunc];
70+
console.log(`[${event}]: Call custom function: [${callFuncCustom.name}]`);
71+
if (!(typeof callFuncCustom === 'function')) {
72+
throw new Error(`[${event}]: ${callFuncCustom} is not a function, please verify in ${callPath}`);
73+
}
74+
await callFuncCustom(this.app, context, { ...callArgs });
75+
}
76+
}, Promise.resolve());
4477
}
4578

46-
public async registerEvents(): Promise<void> {
79+
private async _registerEvents(): Promise<void> {
4780
const events = this.operation.getEvents();
4881
const tasks = this.operation.getTasks();
4982
console.log(`Evaluate events: [${events}]`);
5083
if (!events) {
5184
throw new Error('No events defined in the operation!');
5285
}
86+
if (events.includes('all') && events.length > 1) {
87+
throw new Error("Either listen to 'all' events or specific events! Not both!");
88+
}
89+
5390
events.forEach((event) => {
5491
console.log(`Register event: "${event}"`);
55-
this.app.on(event as keyof WebhookEventMap, async (context) => {
56-
await tasks.reduce(async (promise, task) => {
57-
await promise; // Make sure tasks are completed in sequential orders
58-
59-
const callPath = await realpath(`./bin/call/${task.getCallName()}.js`);
60-
const callFunc = task.getCallFunc();
61-
const callArgs = task.getCallArgs();
62-
63-
console.log(`[${event}]: Verify call lib: ${callPath}`);
64-
try {
65-
await access(callPath);
66-
} catch (e) {
67-
console.error(`ERROR: ${e}`);
68-
}
69-
70-
const callStack = await import(callPath);
71-
if (callFunc === 'default') {
72-
console.log(`[${event}]: Call default function: [${callStack.default.name}]`);
73-
await callStack.default(this.app, context, { ...callArgs });
74-
} else {
75-
console.log(callStack);
76-
const callFuncCustom = callStack[callFunc];
77-
console.log(`[${event}]: Call custom function: [${callFuncCustom.name}]`);
78-
if (!(typeof callFuncCustom === 'function')) {
79-
throw new Error(`[${event}]: ${callFuncCustom} is not a function, please verify in ${callPath}`);
80-
}
81-
await callFuncCustom(this.app, context, { ...callArgs });
82-
}
83-
}, Promise.resolve());
84-
});
92+
if (event === 'all') {
93+
console.warn('WARNING! All events will be listened based on the config!');
94+
this.app.onAny(async (context) => {
95+
this._registerTasks(context, event, tasks);
96+
});
97+
} else {
98+
this.app.on(event as keyof WebhookEventMap, async (context) => {
99+
this._registerTasks(context, event, tasks);
100+
});
101+
}
85102
});
86103
}
87104
}

0 commit comments

Comments
 (0)