Skip to content

Commit ca1f51c

Browse files
refactor: move gh ops utility to github service (#89)
1 parent f5e2bc7 commit ca1f51c

File tree

10 files changed

+965
-555
lines changed

10 files changed

+965
-555
lines changed

app.js

Lines changed: 46 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -4,70 +4,59 @@ dotenv.config();
44
import fs from "fs";
55
import http from "http";
66
import url from "url";
7-
import { Octokit, App } from "octokit";
8-
import { createNodeMiddleware } from "@octokit/webhooks";
97
import { routes } from "./src/routes.js";
8+
import GitHub from "./src/services/GitHub.js";
9+
import Slack from "./src/services/Slack.js";
1010
import {
11-
verifyGitHubAppAuthenticationAndAccess,
1211
getMessage,
1312
isCLARequired,
1413
isMessageAfterMergeRequired,
1514
getWebsiteAddress,
1615
} from "./src/helpers.js";
17-
import Slack from "./src/services/Slack.js";
1816

1917
try {
2018
const packageJson = await import("./package.json", {
21-
assert: { type: "json" },
19+
with: { type: "json" },
2220
});
2321
var APP_VERSION = packageJson.default.version;
2422
} catch (err) {
2523
console.error("Failed to get the version number");
2624
}
2725
console.log(`Application version: ${APP_VERSION}`);
2826

29-
// Set configured values
30-
const appId = process.env.APP_ID;
31-
// To add GitHub App Private Key directly as a string config (instead of file), convert it to base64 by running following command
32-
// openssl base64 -in /path/to/original-private-key.pem -out ./base64EncodedKey.txt -A
33-
// Then set GITHUB_APP_PRIVATE_KEY_BASE64 environment variable with the value of ./base64EncodedKey.txt content
34-
const GITHUB_APP_PRIVATE_KEY = process.env.GITHUB_APP_PRIVATE_KEY_BASE64
35-
? Buffer.from(process.env.GITHUB_APP_PRIVATE_KEY_BASE64, "base64").toString(
27+
function bootstrapGitHubApp(){
28+
// Set configured values
29+
const appId = process.env.APP_ID;
30+
// To add GitHub App Private Key directly as a string config (instead of file), convert it to base64 by running following command
31+
// openssl base64 -in /path/to/original-private-key.pem -out ./base64EncodedKey.txt -A
32+
// Then set GITHUB_APP_PRIVATE_KEY_BASE64 environment variable with the value of ./base64EncodedKey.txt content
33+
const GITHUB_APP_PRIVATE_KEY = process.env.GITHUB_APP_PRIVATE_KEY_BASE64
34+
? Buffer.from(process.env.GITHUB_APP_PRIVATE_KEY_BASE64, "base64").toString(
35+
"utf8"
36+
)
37+
: null;
38+
const privateKey =
39+
GITHUB_APP_PRIVATE_KEY ||
40+
fs.readFileSync(
41+
process.env.PRIVATE_KEY_PATH || "./GITHUB_APP_PRIVATE_KEY.pem",
3642
"utf8"
37-
)
38-
: null;
39-
const privateKey =
40-
GITHUB_APP_PRIVATE_KEY ||
41-
fs.readFileSync(
42-
process.env.PRIVATE_KEY_PATH || "./GITHUB_APP_PRIVATE_KEY.pem",
43-
"utf8"
44-
);
45-
const secret = process.env.WEBHOOK_SECRET;
46-
const enterpriseHostname = process.env.ENTERPRISE_HOSTNAME;
47-
48-
// Create an authenticated Octokit client authenticated as a GitHub App
49-
const app = new App({
50-
appId,
51-
privateKey,
52-
webhooks: {
53-
secret,
54-
},
55-
...(enterpriseHostname && {
56-
Octokit: Octokit.defaults({
57-
baseUrl: `https://${enterpriseHostname}/api/v3`,
58-
}),
59-
}),
60-
});
61-
await verifyGitHubAppAuthenticationAndAccess(app);
43+
);
44+
const webhookSecret = process.env.WEBHOOK_SECRET;
45+
const enterpriseHostname = process.env.ENTERPRISE_HOSTNAME;
46+
// Create an authenticated Octokit client authenticated as a GitHub App
47+
GitHub.authenticateApp(appId, privateKey, webhookSecret, enterpriseHostname);
48+
}
6249

50+
bootstrapGitHubApp();
51+
await GitHub.verifyGitHubAppAuthenticationAndAccess();
6352
// Optional: Get & log the authenticated app's name
64-
const { data } = await app.octokit.request("/app");
53+
const data = await GitHub.getAppInfo();
6554

6655
// Read more about custom logging: https://github.com/octokit/core.js#logging
67-
app.octokit.log.debug(`Authenticated as '${data.name}'`);
56+
GitHub.app.octokit.log.debug(`Authenticated as '${data.name}'`);
6857

6958
// Subscribe to the "pull_request.opened" webhook event
70-
app.webhooks.on("pull_request.opened", async ({ octokit, payload }) => {
59+
GitHub.app.webhooks.on("pull_request.opened", async ({ octokit, payload }) => {
7160
console.log(
7261
`Received a pull request event for #${payload.pull_request.number} by ${payload.pull_request.user.type}: ${payload.pull_request.user.login}`
7362
);
@@ -95,7 +84,7 @@ app.webhooks.on("pull_request.opened", async ({ octokit, payload }) => {
9584
}
9685
});
9786

98-
app.webhooks.on("pull_request.labeled", async ({ octokit, payload }) => {
87+
GitHub.app.webhooks.on("pull_request.labeled", async ({ octokit, payload }) => {
9988
const { number, pull_request, label, sender, repository, action } = payload;
10089
console.log(
10190
`Label #${label.name} ${action} by ${sender.login} on ${pull_request.issue_url} : ${pull_request.title}`
@@ -134,7 +123,7 @@ app.webhooks.on("pull_request.labeled", async ({ octokit, payload }) => {
134123
}
135124
});
136125

137-
app.webhooks.on("pull_request.closed", async ({ octokit, payload }) => {
126+
GitHub.app.webhooks.on("pull_request.closed", async ({ octokit, payload }) => {
138127
console.log(
139128
`Closed a pull request event for #${payload.pull_request.number}`
140129
);
@@ -169,7 +158,7 @@ app.webhooks.on("pull_request.closed", async ({ octokit, payload }) => {
169158
}
170159
});
171160

172-
app.webhooks.on("issues.opened", async ({ octokit, payload }) => {
161+
GitHub.app.webhooks.on("issues.opened", async ({ octokit, payload }) => {
173162
console.log(`Received a new issue event for #${payload.issue.number}`);
174163
try {
175164
// Docs for octokit.rest.issues.createComment - https://github.com/octokit/plugin-rest-endpoint-methods.js/tree/main/docs/issues/createComment.md
@@ -190,15 +179,15 @@ app.webhooks.on("issues.opened", async ({ octokit, payload }) => {
190179
}
191180
});
192181

193-
app.webhooks.on("push", async ({ payload }) => {
182+
GitHub.app.webhooks.on("push", async ({ payload }) => {
194183
// Pull out the branch and repo name from the payload
195184
const branch = payload.ref.split("/").pop();
196185
const repo = payload.repository.name;
197186
console.log(`Received a push event on ${branch} branch of ${repo}`);
198187
});
199188

200189
// Optional: Handle errors
201-
app.webhooks.onError((error) => {
190+
GitHub.app.webhooks.onError((error) => {
202191
if (error.name === "AggregateError") {
203192
// Log Secret verification errors
204193
console.log(`Error processing request: ${error.event}`);
@@ -214,16 +203,19 @@ const localWebhookUrl = `http://localhost:${port}${webhookPath}`;
214203
const publicWebhookUrl = getWebsiteAddress() + webhookPath;
215204

216205
// See https://github.com/octokit/webhooks.js/#createnodemiddleware for all options
217-
const middleware = createNodeMiddleware(app.webhooks, { path: webhookPath });
206+
const githubWebhookRequestHandler = GitHub.getWebhookRequestHandler(webhookPath);
218207

219-
http
208+
const server = http
220209
.createServer((req, res) => {
221210
const parsedUrl = url.parse(req.url);
222211
const pathWithoutQuery = parsedUrl.pathname;
223212
const queryString = parsedUrl.query;
224213
console.log(req.method + " " + pathWithoutQuery);
225214
if (queryString) console.log(queryString.substring(0, 20) + "...");
226215
switch (req.method + " " + pathWithoutQuery) {
216+
case "POST /api/webhook":
217+
githubWebhookRequestHandler(req, res);
218+
break;
227219
case "GET /":
228220
routes.home(req, res);
229221
break;
@@ -237,22 +229,19 @@ http
237229
routes.download(req, res);
238230
break;
239231
case "POST /cla":
240-
routes.submitCla(req, res, app);
232+
routes.submitCla(req, res);
241233
break;
242234
case "GET /contributions/sync":
243-
routes.syncPullRequests(req, res, app);
235+
routes.syncPullRequests(req, res);
244236
break;
245237
case "GET /contributions":
246-
routes.listPullRequests(req, res, app);
238+
routes.listPullRequests(req, res);
247239
break;
248240
case "GET /contributions/pr":
249-
routes.getPullRequestDetail(req, res, app);
241+
routes.getPullRequestDetail(req, res);
250242
break;
251243
case "GET /contributions/reset":
252-
routes.resetContributionData(req, res, app);
253-
break;
254-
case "POST /api/webhook":
255-
middleware(req, res);
244+
routes.resetContributionData(req, res);
256245
break;
257246
default:
258247
routes.default(req, res);
@@ -269,3 +258,5 @@ http
269258
`\n Public webhook url: ${publicWebhookUrl}`);
270259
console.log("Press Ctrl + C to quit.");
271260
});
261+
262+
export { server };

0 commit comments

Comments
 (0)