/
run.ts
150 lines (128 loc) 路 3.79 KB
/
run.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
import pkgConf from "pkg-conf";
import { ApplicationFunction, Options, ServerOptions } from "./types";
import { Probot } from "./index";
import { setupAppFactory } from "./apps/setup";
import { getLog, GetLogOptions } from "./helpers/get-log";
import { readCliOptions } from "./bin/read-cli-options";
import { readEnvOptions } from "./bin/read-env-options";
import { Server } from "./server/server";
import { defaultApp } from "./apps/default";
import { resolveAppFunction } from "./helpers/resolve-app-function";
type AdditionalOptions = {
env: Record<string, string | undefined>;
};
/**
*
* @param appFnOrArgv set to either a probot application function: `(app) => { ... }` or to process.argv
*/
export async function run(
appFnOrArgv: ApplicationFunction | string[],
additionalOptions?: AdditionalOptions
) {
require("dotenv").config();
const envOptions = readEnvOptions(additionalOptions?.env);
const cliOptions = Array.isArray(appFnOrArgv)
? readCliOptions(appFnOrArgv)
: {};
const {
// log options
logLevel: level,
logFormat,
logLevelInString,
logMessageKey,
sentryDsn,
// server options
host,
port,
webhookPath,
webhookProxy,
// probot options
appId,
privateKey,
redisConfig,
secret,
baseUrl,
// others
args,
} = { ...envOptions, ...cliOptions };
const logOptions: GetLogOptions = {
level,
logFormat,
logLevelInString,
logMessageKey,
sentryDsn,
};
const log = getLog(logOptions);
const probotOptions: Options = {
appId,
privateKey,
redisConfig,
secret,
baseUrl,
log: log.child({ name: "probot" }),
};
const serverOptions: ServerOptions = {
host,
port,
webhookPath,
webhookProxy,
log: log.child({ name: "server" }),
Probot: Probot.defaults(probotOptions),
};
let server: Server;
if (!appId || !privateKey) {
if (process.env.NODE_ENV === "production") {
if (!appId) {
throw new Error(
"App ID is missing, and is required to run in production mode. " +
"To resolve, ensure the APP_ID environment variable is set."
);
} else if (!privateKey) {
throw new Error(
"Certificate is missing, and is required to run in production mode. " +
"To resolve, ensure either the PRIVATE_KEY or PRIVATE_KEY_PATH environment variable is set and contains a valid certificate"
);
}
}
// Workaround for setup (#1512)
// When probot is started for the first time, it gets into a setup mode
// where `appId` and `privateKey` are not present. The setup mode gets
// these credentials. In order to not throw an error, we set the values
// to anything, as the Probot instance is not used in setup it makes no
// difference anyway.
server = new Server({
...serverOptions,
Probot: Probot.defaults({
...probotOptions,
appId: 1,
privateKey: "dummy value for setup, see #1512",
}),
});
await server.load(setupAppFactory(host, port));
await server.start();
return server;
}
if (Array.isArray(appFnOrArgv)) {
const pkg = await pkgConf("probot");
const combinedApps: ApplicationFunction = async (app) => {
await server.load(defaultApp);
if (Array.isArray(pkg.apps)) {
for (const appPath of pkg.apps) {
const appFn = await resolveAppFunction(appPath);
await server.load(appFn);
}
}
const [appPath] = args;
const appFn = await resolveAppFunction(appPath);
await server.load(appFn);
};
server = new Server(serverOptions);
await server.load(combinedApps);
await server.start();
return server;
}
server = new Server(serverOptions);
await server.load(appFnOrArgv);
await server.start();
return server;
}