Last active
November 27, 2024 13:57
-
-
Save alexandrius/8c8e8dcae92e794b71df4676026b5fb5 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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