Skip to content

Commit

Permalink
added badging-bot logic
Browse files Browse the repository at this point in the history
  • Loading branch information
kaxada committed Jan 24, 2024
1 parent d82d3a8 commit 91a1d96
Show file tree
Hide file tree
Showing 14 changed files with 632 additions and 9 deletions.
52 changes: 52 additions & 0 deletions event_badging/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
const {
welcome,
getResults,
// TODO: implement the help automation,
endReview,
assignChecklist,
updateReadme,
} = require("./logic/index.js");

const event_badging = async (name, octokit, payload) => {
// perform actions on application issues only
if (payload.issue.title.match(/event/i)) {
// when applicant issue is open, welcome the applicant
if (name === "issues" && payload.action === "opened") {
welcome(octokit, payload);
}

// when issue is assigned, triger the assign algorithm
if (name === "issues" && payload.action === "assigned") {
assignChecklist(octokit, payload);
}

// comment commands
if (name === "issue_comment" && payload.action === "created") {
// get results
if (payload.comment.body.match("/result")) {
getResults(octokit, payload);
}

// end review
if (payload.comment.body.match("/end")) {
endReview(octokit, payload);
}
}

// when issue is closed, update the readme with the event
if (name === "issues" && payload.action === "closed") {
updateReadme(octokit, payload);
}
} else if (
name === "installation" &&
payload.action === "new_permissions_accepted"
) {
console.info("New permissions accepted");
} else if (name === "*") {
console.info(
`Webhook: ${name}.${payload.action} not yet automated or needed`
);
}
};

module.exports = event_badging;
204 changes: 204 additions & 0 deletions event_badging/logic/assignChecklist.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
require("dotenv").config();

const assignChecklist = async (octokit, payload) => {
// get the checklist
let newChecklist;

// generate new checklist for In-Person Events

if (payload.issue.title.substring(0, 15) == "[Virtual Event]") {
const {
data: { content },
} = await octokit.rest.repos.getContent({
owner: payload.repository.owner.login,
repo: payload.repository.name,
path: ".github/checklist-virtual.md",
});

const checklist = Buffer.from(content, "base64").toString(); // convert checklist content to string
let {
issue: { body },
} = payload; // get content of issue

body = body.replace(/- \[x\]|- \[ \]/g, ""); // remove checks

/****combine issue content and checklist into one ******/
newChecklist =
body.slice(0, body.indexOf("## Event Demographics")) +
"\n" +
checklist.slice(
checklist.indexOf("## Initial checks"),
checklist.indexOf("## Metric based checks")
) +
"\n" +
"\n" +
body.slice(
body.indexOf("## Event Demographics"),
body.indexOf("## Inclusive Experience at Event")
) +
"\n" +
checklist.slice(
checklist.indexOf("### Event Demographics"),
checklist.indexOf("### Inclusive Experience at Event")
) +
"\n" +
"\n" +
body.slice(
body.indexOf("## Inclusive Experience at Event"),
body.indexOf("## Time Inclusion for Virtual Events")
) +
"\n" +
checklist.slice(
checklist.indexOf("### Inclusive Experience at Event"),
checklist.indexOf("### Time Inclusion for Virtual Events")
) +
"\n" +
"\n" +
body.slice(
body.indexOf("## Time Inclusion for Virtual Events"),
body.indexOf("## Code of Conduct at Event")
) +
"\n" +
checklist.slice(
checklist.indexOf("### Time Inclusion for Virtual Events"),
checklist.indexOf("### Code of Conduct at Event")
) +
"\n" +
"\n" +
body.slice(
body.indexOf("## Code of Conduct at Event"),
body.indexOf("## Diversity Access Tickets")
) +
"\n" +
checklist.slice(
checklist.indexOf("### Code of Conduct at Event"),
checklist.indexOf("### Diversity Access tickets")
) +
"\n" +
"\n" +
body.slice(body.indexOf("## Diversity Access Tickets")) +
"\n" +
checklist.slice(checklist.indexOf("### Diversity Access tickets")) +
"\n";
/******************************************************************/
} else {
const {
data: { content },
} = await octokit.rest.repos.getContent({
owner: payload.repository.owner.login,
repo: payload.repository.name,
path: ".github/checklist.md",
});

const checklist = Buffer.from(content, "base64").toString(); // convert checklist content to string
let {
issue: { body },
} = payload; // get content of issue

body = body.replace(/- \[x\]|- \[ \]/g, ""); // remove checks

/****combine issue content and checklist into one ******/
newChecklist =
body.slice(0, body.indexOf("## Event Demographics")) +
"\n" +
checklist.slice(
checklist.indexOf("## Initial checks"),
checklist.indexOf("## Metric based checks")
) +
"\n" +
"\n" +
body.slice(
body.indexOf("## Event Demographics"),
body.indexOf("## Inclusive Experience at Event")
) +
"\n" +
checklist.slice(
checklist.indexOf("### Event Demographics"),
checklist.indexOf("### Inclusive Experience at Event")
) +
"\n" +
"\n" +
body.slice(
body.indexOf("## Inclusive Experience at Event"),
body.indexOf("## Code of Conduct at Event")
) +
"\n" +
checklist.slice(
checklist.indexOf("### Inclusive Experience at Event"),
checklist.indexOf("### Code of Conduct at Event")
) +
"\n" +
"\n" +
body.slice(
body.indexOf("## Code of Conduct at Event"),
body.indexOf("## Diversity Access Tickets")
) +
"\n" +
checklist.slice(
checklist.indexOf("### Code of Conduct at Event"),
checklist.indexOf("### Diversity Access tickets")
) +
"\n" +
"\n" +
body.slice(
body.indexOf("## Diversity Access Tickets"),
body.indexOf("## Family Friendliness")
) +
"\n" +
checklist.slice(
checklist.indexOf("### Diversity Access tickets"),
checklist.indexOf("### Family Friendliness")
) +
"\n" +
"\n" +
body.slice(body.indexOf("## Family Friendliness")) +
"\n" +
checklist.slice(checklist.indexOf("### Family Friendliness")) +
"\n";
/******************************************************************/
}

// get reviewer welcome information and convert it to string
const reviewerGuide = await octokit.rest.repos.getContent({
owner: payload.repository.owner.login,
repo: payload.repository.name,
path: ".github/reviewer-welcome.md",
});
const reviewerWelcome = Buffer.from(
reviewerGuide.data.content,
"base64"
).toString();

// heading for the checklist
const heading = `# Checklist for @${payload.assignee.login}`;

// combine all the strings to make one body
let reviewerMessage =
"@" + payload.assignee.login + " " + reviewerWelcome + newChecklist;

// create issue comment with newChecklist
await octokit.rest.issues
.createComment({
owner: payload.repository.owner.login,
repo: payload.repository.name,
issue_number: payload.issue.number,
body: heading + "\n" + reviewerMessage,
})
.then((res) => console.log(res.status))
.catch((err) => console.error(err));

// assign label if assignees are two
if (payload.issue.assignees.length == 2) {
await octokit.rest.issues
.addLabels({
owner: payload.repository.owner.login,
repo: payload.repository.name,
issue_number: payload.issue.number,
labels: ["review-begin"],
})
.then((res) => console.log(res.status))
.catch((err) => console.error(err));
}
};

module.exports = assignChecklist;
92 changes: 92 additions & 0 deletions event_badging/logic/calculate.badge.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
let messageObj;

const calculateBadge = async (octokit, payload) => {
let initialCheckCount = 6,
issueURL = payload.issue.html_url;
payload.repository.name === "event-diversity-and-inclusion"
? (initialCheckCount = 4)
: initialCheckCount;

const comments = await octokit.rest.issues.listComments({
owner: payload.repository.owner.login,
repo: payload.repository.name,
issue_number: payload.issue.number,
});

let checklists = comments.data.filter((comment) => {
return (
comment.user.type == "Bot" &&
comment.body.substring(0, 15) == "# Checklist for"
);
});

let totalCheckCount = checklists.map(function (element) {
return (
(element.body.match(/\[x\]/g) || []).length +
(element.body.match(/\[ \]/g) || []).length
);
});

totalCheckCount = totalCheckCount.map(function (element) {
return element - initialCheckCount;
});

let positiveCheckCount = checklists.map(function (element) {
let checkCount =
+(element.body.match(/\[x\]/g) || []).length - initialCheckCount;
if (checkCount <= 0) return 0;
else return checkCount;
});

let percentages = positiveCheckCount.map(function (element) {
let p = Math.floor((element / totalCheckCount[0]) * 100);
return p;
});

let reviewerCount = percentages.length;
let reviewResult = 0;
percentages.forEach((element) => {
reviewResult += element;
});
reviewResult /= reviewerCount;

const badgeAssigned =
reviewResult < 40
? ["Pending", "D%26I-Pending-red"]
: reviewResult < 60
? ["Passing", "D%26I-Passing-passing"]
: reviewResult < 80
? ["Silver", "D%26I-Silver-silver"]
: reviewResult <= 100
? ["Gold", "D%26I-Gold-yellow"]
: ["pending", "D%26I-Pending-red"];

const url =
"https://img.shields.io/badge/" +
badgeAssigned[1] +
"?style=flat-square&labelColor=583586&&link=" +
issueURL +
"/&logo=data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDI1MCAyNTAiPgo8cGF0aCBmaWxsPSIjMUM5QkQ2IiBkPSJNOTcuMSw0OS4zYzE4LTYuNywzNy44LTYuOCw1NS45LTAuMmwxNy41LTMwLjJjLTI5LTEyLjMtNjEuOC0xMi4yLTkwLjgsMC4zTDk3LjEsNDkuM3oiLz4KPHBhdGggZmlsbD0iIzZBQzdCOSIgZD0iTTE5NC42LDMyLjhMMTc3LjIsNjNjMTQuOCwxMi4zLDI0LjcsMjkuNSwyNy45LDQ4LjVoMzQuOUMyMzYuMiw4MC4yLDIxOS45LDUxLjcsMTk0LjYsMzIuOHoiLz4KPHBhdGggZmlsbD0iI0JGOUNDOSIgZD0iTTIwNC45LDEzOS40Yy03LjksNDMuOS00OS45LDczLTkzLjgsNjUuMWMtMTMuOC0yLjUtMjYuOC04LjYtMzcuNS0xNy42bC0yNi44LDIyLjQKCWM0Ni42LDQzLjQsMTE5LjUsNDAuOSwxNjIuOS01LjdjMTYuNS0xNy43LDI3LTQwLjIsMzAuMS02NC4ySDIwNC45eiIvPgo8cGF0aCBmaWxsPSIjRDYxRDVGIiBkPSJNNTUuNiwxNjUuNkMzNS45LDEzMS44LDQzLjMsODguOCw3My4xLDYzLjVMNTUuNywzMy4yQzcuNSw2OS44LTQuMiwxMzcuNCwyOC44LDE4OEw1NS42LDE2NS42eiIvPgo8L3N2Zz4K";

const markdownBadgeImage =
"![Assigned badge: " + badgeAssigned[0] + "](" + url + ")";

const htmlBadgeImage =
"<img src='" +
url +
"' alt='" +
"D&I Badging badge state: " +
badgeAssigned[0] +
"'/>";
messageObj = {
markdownBadgeImage: markdownBadgeImage,
htmlBadgeImage: htmlBadgeImage,
reviewResult: reviewResult,
reviewerCount: reviewerCount,
assignedBadge: badgeAssigned[0],
};

return messageObj;
};

module.exports = calculateBadge;
26 changes: 26 additions & 0 deletions event_badging/logic/checkModerator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
const checkModerator = async (octokit, payload) => {
// get moderators list
const moderators = await octokit.rest.repos
.getContent({
owner: payload.repository.owner.login,
repo: payload.repository.name,
path: ".github/moderators.md",
})
.then((res) => Buffer.from(res, "base64").toString())
.catch((err) => console.err(err));

let moderatorUsername = payload.issue.user.login;
let moderatorList = moderators.split("\n");

let list = moderatorList.filter((element) => {
return element[0] == "-";
});

list = list.map(function (element) {
return element.substring(2);
});

return list.includes(moderatorUsername);
};

module.exports = checkModerator;
Loading

0 comments on commit 91a1d96

Please sign in to comment.