Skip to content

Instantly share code, notes, and snippets.

@kkeeth
Last active June 18, 2024 09:14
Show Gist options
  • Save kkeeth/c0ef2cca8810e002a562cbe0be92fcf2 to your computer and use it in GitHub Desktop.
Save kkeeth/c0ef2cca8810e002a562cbe0be92fcf2 to your computer and use it in GitHub Desktop.
const axios = require("axios");
const fs = require("fs");
const createCsvWriter = require("csv-writer").createObjectCsvWriter;
// GitHubの認証トークンを設定してください
const githubToken = "GITHUB_TOKEN";
const owner = "OWNER"; // リポジトリの所有者
const repo = "REPOSITORY_NAME"; // リポジトリ名
const startDate = "2024-06-01T00:00:00Z";
const endDate = "2024-06-30T23:59:59Z";
const headers = {
Authorization: `token ${githubToken}`,
Accept: "application/vnd.github.v3+json",
};
function formatDateToJST(dateString) {
const date = new Date(dateString);
date.setHours(date.getHours() + 9); // UTCをJSTに変換
const yyyy = date.getFullYear();
const mm = `0${date.getMonth() + 1}`.slice(-2);
const dd = `0${date.getDate()}`.slice(-2);
const hh = `0${date.getHours()}`.slice(-2);
const min = `0${date.getMinutes()}`.slice(-2);
const ss = `0${date.getSeconds()}`.slice(-2);
return `${yyyy}/${mm}/${dd} ${hh}:${min}:${ss}`;
}
async function fetchPullRequests() {
const url = `https://api.github.com/repos/${owner}/${repo}/pulls?state=all&per_page=100`;
let pullRequests = [];
let page = 1;
while (true) {
const response = await axios.get(`${url}&page=${page}`, { headers });
const data = response.data;
if (data.length === 0) break;
pullRequests = pullRequests.concat(
data
.filter((pr) => {
const createdAt = new Date(pr.created_at);
return (
createdAt >= new Date(startDate) && createdAt <= new Date(endDate)
);
})
.map((pr) => ({
number: pr.number,
title: pr.title,
created_at: formatDateToJST(pr.created_at),
closed_at: pr.closed_at ? formatDateToJST(pr.closed_at) : null,
merged_at: pr.merged_at ? formatDateToJST(pr.merged_at) : null,
})),
);
page++;
}
return pullRequests;
}
async function fetchReviewComments(pullNumber) {
const url = `https://api.github.com/repos/${owner}/${repo}/pulls/${pullNumber}/reviews?per_page=100`;
let comments = [];
let page = 1;
while (true) {
const response = await axios.get(`${url}&page=${page}`, { headers });
const data = response.data;
if (data.length === 0) break;
comments = comments.concat(data);
page++;
}
return comments;
}
async function main() {
const pullRequests = await fetchPullRequests();
let filteredComments = [];
for (const pr of pullRequests) {
const comments = await fetchReviewComments(pr.number);
// const matchingComments = comments
const matchingComments = comments.filter((comment) => {
return comment !== "";
});
filteredComments = filteredComments.concat(
matchingComments.map((comment) => ({
pull_number: pr.number,
pull_title: pr.title,
pr_created_at: pr.created_at,
pr_closed_at: pr.closed_at,
pr_merged_at: pr.merged_at,
reviewer: comment.user.login,
review_url: comment.html_url,
comment: comment.body,
created_at: comment.submitted_at,
})),
);
}
const csvWriter = createCsvWriter({
path: `${repo}_review_comments.csv`,
header: [
{ id: "pull_number", title: "Pull Number" },
{ id: "pull_title", title: "Pull Title" },
{ id: "pr_created_at", title: "PR Created At" },
{ id: "pr_closed_at", title: "PR Closed At" },
{ id: "pr_merged_at", title: "PR Merged At" },
{ id: "reviewer", title: "Reviewer" },
{ id: "comment", title: "Comment" },
],
});
csvWriter
.writeRecords(filteredComments)
.then(() => {
console.log("Comments have been written to review_comments.csv");
})
.catch((error) => {
console.error("Error writing to file", error);
});
// fs.writeFile(`${repo}_review_comments.json`, JSON.stringify(filteredComments, null, 2), (err) => {
// if (err) {
// console.error('Error writing to file', err);
// } else {
// console.log(`Comments have been written to ${repo}_review_comments.json`);
// }
// });
}
main().catch((error) => {
console.error(error);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment