Skip to content

Commit 962e75f

Browse files
feat: allow adding cla label manually (#43)
1 parent 093880f commit 962e75f

File tree

2 files changed

+62
-29
lines changed

2 files changed

+62
-29
lines changed

app.js

+53-21
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,17 @@ import {
1111
isMessageAfterMergeRequired,
1212
} from "./src/helpers.js";
1313

14+
try {
15+
const packageJson = await import("./package.json", {
16+
assert: { type: "json" },
17+
});
18+
var APP_VERSION = packageJson.default.version;
19+
} catch (err) {
20+
console.error("Failed to get the version number");
21+
}
22+
console.log(`Application version: ${APP_VERSION}`);
23+
console.log(`Website address: ${process.env.WEBSITE_ADDRESS}`);
24+
1425
// Load environment variables from .env file
1526
dotenv.config();
1627

@@ -21,14 +32,14 @@ const appId = process.env.APP_ID;
2132
// Then set GITHUB_APP_PRIVATE_KEY_BASE64 environment variable with the value of ./base64EncodedKey.txt content
2233
const GITHUB_APP_PRIVATE_KEY = process.env.GITHUB_APP_PRIVATE_KEY_BASE64
2334
? Buffer.from(process.env.GITHUB_APP_PRIVATE_KEY_BASE64, "base64").toString(
24-
"utf8",
35+
"utf8"
2536
)
2637
: null;
2738
const privateKey =
2839
GITHUB_APP_PRIVATE_KEY ||
2940
fs.readFileSync(
3041
process.env.PRIVATE_KEY_PATH || "./GITHUB_APP_PRIVATE_KEY.pem",
31-
"utf8",
42+
"utf8"
3243
);
3344
const secret = process.env.WEBHOOK_SECRET;
3445
const enterpriseHostname = process.env.ENTERPRISE_HOSTNAME;
@@ -56,26 +67,14 @@ app.octokit.log.debug(`Authenticated as '${data.name}'`);
5667
// Subscribe to the "pull_request.opened" webhook event
5768
app.webhooks.on("pull_request.opened", async ({ octokit, payload }) => {
5869
console.log(
59-
`Received a pull request event for #${payload.pull_request.number} by ${payload.pull_request.user.type}: ${payload.pull_request.user.login}`,
70+
`Received a pull request event for #${payload.pull_request.number} by ${payload.pull_request.user.type}: ${payload.pull_request.user.login}`
6071
);
6172
try {
6273
if (!isCLARequired(payload.pull_request)) {
74+
console.log("CLA not required for this PR");
6375
return;
6476
}
6577
// If the user is not a member of the organization and haven't yet signed CLA,
66-
// ask them to sign the CLA
67-
const comment = getMessage("ask-to-sign-cla", {
68-
username: payload.pull_request.user.login,
69-
org: payload.repository.owner.login,
70-
repo: payload.repository.name,
71-
pr_number: payload.pull_request.number,
72-
});
73-
await octokit.rest.issues.createComment({
74-
owner: payload.repository.owner.login,
75-
repo: payload.repository.name,
76-
issue_number: payload.pull_request.number,
77-
body: comment,
78-
});
7978
// Add a label to the PR
8079
octokit.rest.issues.addLabels({
8180
owner: payload.repository.owner.login,
@@ -86,7 +85,40 @@ app.webhooks.on("pull_request.opened", async ({ octokit, payload }) => {
8685
} catch (error) {
8786
if (error.response) {
8887
console.error(
89-
`Error! Status: ${error.response.status}. Message: ${error.response.data.message}`,
88+
`Error! Status: ${error.response.status}. Message: ${error.response.data.message}`
89+
);
90+
} else {
91+
console.error(error);
92+
}
93+
}
94+
});
95+
96+
app.webhooks.on("pull_request.labeled", async ({ octokit, payload }) => {
97+
const { number, pull_request, label, sender, repository, action } = payload;
98+
console.log(
99+
`Label #${label.name} ${action} by ${sender.login} on ${pull_request.issue_url} : ${pull_request.title}`
100+
);
101+
try {
102+
if (label.name === "Pending CLA") {
103+
console.log("Adding comment to the issue/PR to ask for CLA signature");
104+
// ask them to sign the CLA
105+
const comment = getMessage("ask-to-sign-cla", {
106+
username: pull_request.user.login,
107+
org: repository.owner.login,
108+
repo: repository.name,
109+
pr_number: pull_request.number,
110+
});
111+
await octokit.rest.issues.createComment({
112+
owner: repository.owner.login,
113+
repo: repository.name,
114+
issue_number: pull_request.number,
115+
body: comment,
116+
});
117+
}
118+
} catch (error) {
119+
if (error.response) {
120+
console.error(
121+
`Error! Status: ${error.response.status}. Message: ${error.response.data.message}`
90122
);
91123
} else {
92124
console.error(error);
@@ -96,7 +128,7 @@ app.webhooks.on("pull_request.opened", async ({ octokit, payload }) => {
96128

97129
app.webhooks.on("pull_request.closed", async ({ octokit, payload }) => {
98130
console.log(
99-
`Closed a pull request event for #${payload.pull_request.number}`,
131+
`Closed a pull request event for #${payload.pull_request.number}`
100132
);
101133
if (!payload.pull_request.merged) return;
102134
console.log(`This PR is merged`);
@@ -120,7 +152,7 @@ app.webhooks.on("pull_request.closed", async ({ octokit, payload }) => {
120152
} catch (error) {
121153
if (error.response) {
122154
console.error(
123-
`Error! Status: ${error.response.status}. Message: ${error.response.data.message}`,
155+
`Error! Status: ${error.response.status}. Message: ${error.response.data.message}`
124156
);
125157
} else {
126158
console.error(error);
@@ -140,7 +172,7 @@ app.webhooks.on("issues.opened", async ({ octokit, payload }) => {
140172
} catch (error) {
141173
if (error.response) {
142174
console.error(
143-
`Error! Status: ${error.response.status}. Message: ${error.response.data.message}`,
175+
`Error! Status: ${error.response.status}. Message: ${error.response.data.message}`
144176
);
145177
} else {
146178
console.error(error);
@@ -206,7 +238,7 @@ http
206238
.listen(port, () => {
207239
console.log(`Server is listening for events at: ${localWebhookUrl}`);
208240
console.log(
209-
"Server is also serving the homepage at: http://localhost:" + port,
241+
"Server is also serving the homepage at: http://localhost:" + port
210242
);
211243
console.log("Press Ctrl + C to quit.");
212244
});

src/storage.js

+9-8
Original file line numberDiff line numberDiff line change
@@ -6,34 +6,35 @@ import { PROJECT_ROOT_PATH } from "./helpers.js";
66
const dbPath = process.env.DB_PATH || resolve(PROJECT_ROOT_PATH, "db.json");
77
createFileIfMissing(dbPath);
88

9-
function createFileIfMissing(path){
9+
function createFileIfMissing(path) {
1010
try {
1111
// Try to open the file in read-only mode
12-
const fd = fs.openSync(path, 'r');
12+
const fd = fs.openSync(path, "r");
1313
fs.closeSync(fd);
14-
console.log('DB file exists at '+dbPath);
14+
console.log("DB file exists at " + dbPath);
1515
} catch (err) {
16-
if (err.code === 'ENOENT') {
16+
if (err.code === "ENOENT") {
1717
// If the file does not exist, create it
18-
fs.writeFileSync(path, '[]', { flag: 'wx' }); // 'wx' flag ensures the file is created and not overwritten if it exists
19-
console.log('DB file created at '+dbPath);
18+
fs.writeFileSync(path, "[]", { flag: "wx" }); // 'wx' flag ensures the file is created and not overwritten if it exists
19+
console.log("DB file created at " + dbPath);
2020
} else {
2121
// Some other error occurred
2222
console.error(err);
23-
throw new Error("Failed to create the DB file at "+dbPath);
23+
throw new Error("Failed to create the DB file at " + dbPath);
2424
}
2525
}
2626
}
2727

2828
export const storage = {
2929
save(data) {
30+
createFileIfMissing(dbPath);
3031
const currentData = JSON.parse(fs.readFileSync(dbPath, "utf8"));
3132
currentData.push(data);
3233
fs.writeFileSync(dbPath, JSON.stringify(currentData, null, 2));
3334
},
3435
get(filters) {
3536
const currentData = JSON.parse(fs.readFileSync(dbPath, "utf8"));
36-
if(!filters) return currentData;
37+
if (!filters) return currentData;
3738
return currentData.filter((item) => {
3839
for (const [key, value] of Object.entries(filters)) {
3940
if (item[key] !== value) {

0 commit comments

Comments
 (0)