Skip to content

Instantly share code, notes, and snippets.

@alexandrius
Last active November 27, 2024 13:57
Show Gist options
  • Save alexandrius/8c8e8dcae92e794b71df4676026b5fb5 to your computer and use it in GitHub Desktop.
Save alexandrius/8c8e8dcae92e794b71df4676026b5fb5 to your computer and use it in GitHub Desktop.
const https = require('https');
const username = ''
const token = ''
async function getPRStats(fromDate) {
let fixPrefixPRCount = 0;
let page = 1;
let hasNextPage = true;
// Fetch the first page to get the total count
const { totalCount, items, nextPage } = await fetchPRs(fromDate, page);
const totalMergedPRs = totalCount; // Get total count only once
page = nextPage;
hasNextPage = nextPage !== null;
const promises = items.map(pr => fetchPRDetails(pr, token));
while (hasNextPage) {
const { items, nextPage } = await fetchPRs(fromDate, page);
page = nextPage;
hasNextPage = nextPage !== null;
promises.push(...items.map(pr => fetchPRDetails(pr, token)));
}
await Promise.all(promises)
.then(results => {
fixPrefixPRCount = results.filter(titleStartsWithFix).length;
})
.catch(error => {
console.error("Error fetching PR details:", error);
});
return { totalMergedPRs, fixPrefixPRCount };
}
async function fetchPRDetails(pr, token) {
return new Promise((resolve, reject) => {
const prOptions = {
hostname: 'api.github.com',
path: `/repos/${pr.repository_url.split('/').slice(-2).join('/')}/pulls/${pr.number}`,
headers: {
'User-Agent': 'PR Stats Script',
'Authorization': `token ${token}`,
},
};
const prReq = https.get(prOptions, (prRes) => {
let prData = '';
prRes.on('data', (chunk) => {
prData += chunk;
});
prRes.on('end', () => {
try {
const prDetails = JSON.parse(prData);
resolve(prDetails.title);
} catch (error) {
reject(error);
}
});
});
prReq.on('error', (error) => {
reject(error);
});
prReq.end();
});
}
function titleStartsWithFix(title) {
return title.toLowerCase().startsWith('fix');
}
async function fetchPRs(fromDate, page) {
return new Promise((resolve, reject) => {
const options = {
hostname: 'api.github.com',
path: `/search/issues?q=is:pr+is:merged+author:${username}+org:ExodusMovement+merged:>=${fromDate}&page=${page}`,
headers: {
'User-Agent': 'PR Stats Script',
'Authorization': `token ${token}`,
},
};
const req = https.get(options, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
try {
const result = JSON.parse(data);
const totalCount = result.total_count;
const items = result.items;
// Extract next page number from Link header
let nextPage = null;
const linkHeader = res.headers.link;
if (linkHeader) {
const nextLink = linkHeader.split(',').find(link => link.includes('rel="next"'));
if (nextLink) {
nextPage = parseInt(new URL(nextLink.split(';')[0].trim().slice(1, -1)).searchParams.get('page'), 10);
}
}
resolve({ totalCount, items, nextPage });
} catch (error) {
reject(error);
}
});
});
req.on('error', (error) => {
reject(error);
});
req.end();
});
}
const fromDate = '2023-11-01';
getPRStats(fromDate)
.then(({ totalMergedPRs, fixPrefixPRCount }) => {
console.log(`Total merged PRs by ${username} since ${fromDate}: ${totalMergedPRs}`);
console.log(`Merged PRs with 'fix' prefix since ${fromDate}: ${fixPrefixPRCount}`);
})
.catch((error) => {
console.error("Error fetching PR data:", error);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment