Last active
April 22, 2023 01:48
-
-
Save raymyers/2c4a05b08ff00affb0369b50aee7baea to your computer and use it in GitHub Desktop.
GPT4 generated code to extract metrics from GitHub, NOT debugged
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
// Warning: This code is LLM output and has NOT been debugged. | |
const { Octokit } = require("@octokit/rest"); | |
// Initialize the Octokit client | |
const octokit = new Octokit({ auth: "your_personal_access_token" }); | |
// Variables for your specific repository | |
const owner = "your_github_username"; | |
const repo = "your_repository_name"; | |
// Helper function to get the previous month's date | |
function getPreviousMonth(date) { | |
const newDate = new Date(date); | |
newDate.setMonth(date.getMonth() - 1); | |
return newDate; | |
} | |
async function main() { | |
const today = new Date(); | |
let startDate = getPreviousMonth(today); | |
let endDate = today; | |
while (startDate > new Date("2022-01-01")) { // Change to your desired start date | |
try { | |
const deploymentFrequency = await getDeploymentFrequency(owner, repo, startDate, endDate); | |
const mergeFrequency = await getMergeFrequency(owner, repo, startDate, endDate); | |
const reviewTime = await getReviewTime(owner, repo, startDate, endDate); | |
const leadTimeToChange = await getLeadTimeToChange(owner, repo, startDate, endDate); | |
console.log(`Metrics for ${startDate.toISOString().slice(0, 7)}:`); | |
console.log("Deployment Frequency: ", deploymentFrequency); | |
console.log("Merge Frequency: ", mergeFrequency); | |
console.log("Review Time: ", reviewTime); | |
console.log("Lead Time to Change: ", leadTimeToChange); | |
console.log("\n"); | |
endDate = startDate; | |
startDate = getPreviousMonth(startDate); | |
} catch (error) { | |
console.error("Error: ", error); | |
} | |
} | |
} | |
async function getDeploymentFrequency(owner, repo, startDate, endDate) { | |
try { | |
const deployments = await octokit.paginate(octokit.repos.listDeployments, { | |
owner, | |
repo, | |
per_page: 100, | |
}); | |
// Filter deployments based on the date range | |
const deploymentsInRange = deployments.filter((deployment) => { | |
const deploymentDate = new Date(deployment.created_at); | |
return deploymentDate >= startDate && deploymentDate < endDate; | |
}); | |
// Calculate deployment frequency | |
const deploymentFrequency = deploymentsInRange.length; | |
return deploymentFrequency; | |
} catch (error) { | |
console.error("Error in getDeploymentFrequency: ", error); | |
} | |
} | |
async function getMergeFrequency(owner, repo, startDate, endDate) { | |
try { | |
const prs = await octokit.paginate(octokit.pulls.list, { | |
owner, | |
repo, | |
state: "all", | |
per_page: 100, | |
}); | |
// Filter PRs based on the date range and merged state | |
const mergedPrsInRange = prs.filter((pr) => { | |
const mergedDate = new Date(pr.merged_at); | |
return pr.merged_at !== null && mergedDate >= startDate && mergedDate < endDate; | |
}); | |
// Calculate merge frequency | |
const mergeFrequency = mergedPrsInRange.length; | |
return mergeFrequency; | |
} catch (error) { | |
console.error("Error in getMergeFrequency: ", error); | |
} | |
} | |
async function getReviewTime(owner, repo, startDate, endDate) { | |
try { | |
const prs = await octokit.paginate(octokit.pulls.list, { | |
owner, | |
repo, | |
state: "all", | |
per_page: 100, | |
}); | |
const reviewTimes = []; | |
for (const pr of prs) { | |
const createdAt = new Date(pr.created_at); | |
if (createdAt >= startDate && createdAt < endDate) { | |
const reviews = await octokit.paginate(octokit.pulls.listReviews, { | |
owner, | |
repo, | |
pull_number: pr.number, | |
per_page: 100, | |
}); | |
if (reviews.length > 0) { | |
const firstReviewDate = new Date(reviews[0].submitted_at); | |
const reviewTime = (firstReviewDate - createdAt) / (1000 * 60 * 60); // Convert to hours | |
reviewTimes.push(reviewTime); | |
} | |
} | |
} | |
// Calculate average review time | |
const totalReviewTime = reviewTimes.reduce((sum, time) => sum + time, 0); | |
const averageReviewTime = reviewTimes.length > 0 ? totalReviewTime / reviewTimes.length : 0; | |
return averageReviewTime; | |
} catch (error) { | |
console.error("Error in getReviewTime: ", error); | |
} | |
} | |
async function getLeadTimeToChange(owner, repo, startDate, endDate) { | |
try { | |
const prs = await octokit.paginate(octokit.pulls.list, { | |
owner, | |
repo, | |
state: "all", | |
per_page: 100, | |
}); | |
const leadTimes = []; | |
for (const pr of prs) { | |
const createdAt = new Date(pr.created_at); | |
if (pr.merged_at !== null && createdAt >= startDate && createdAt < endDate) { | |
const commit = await octokit.repos.getCommit({ | |
owner, | |
repo, | |
ref: pr.head.sha, | |
}); | |
const commitDate = new Date(commit.data.commit.committer.date); | |
const leadTime = (createdAt - commitDate) / (1000 * 60 * 60); // Convert to hours | |
leadTimes.push(leadTime); | |
} | |
} | |
// Calculate average lead time to change | |
const totalLeadTime = leadTimes.reduce((sum, time) => sum + time, 0); | |
const averageLeadTimeToChange = leadTimes.length > 0 ? totalLeadTime / leadTimes.length : 0; | |
return averageLeadTimeToChange; | |
} catch (error) { | |
console.error("Error in getLeadTimeToChange: ", error); | |
} | |
} | |
main(); |
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
"Act as an experienced software engineer with knowledge of DevOps metrics and DORA. Can you write a high level implementation of an extraction of deployment frequency, merge frequency, review time, and lead time to change in JavaScript using GitHub and GitHub actions (Octokit.js client)? | |
For now it's ok to write calls to functions that don't exist yet, we will fill them in later." | |
"Pretty good but we will need to call this for different periods of time. Lets say that we want this broken out month by month." | |
"Can you fill in getDeploymentFrequency?" | |
"Fill in getMergeFrequency" | |
"Fill in getReviewTime" | |
"Fill in getLeadTimeToChange" | |
Revising, saving in updated.js: | |
"Lets change lead time to mean time from being merged into main to being deployed by GitHub Actions" | |
"Let's update getReviewTime to mean the time between an PR being opened and merged" |
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
// Revised | |
async function getLeadTimeToChange(owner, repo, startDate, endDate) { | |
try { | |
const prs = await octokit.paginate(octokit.pulls.list, { | |
owner, | |
repo, | |
state: "all", | |
per_page: 100, | |
}); | |
const deployments = await octokit.paginate(octokit.repos.listDeployments, { | |
owner, | |
repo, | |
per_page: 100, | |
}); | |
const leadTimes = []; | |
for (const pr of prs) { | |
const mergedAt = new Date(pr.merged_at); | |
if (pr.merged_at !== null && mergedAt >= startDate && mergedAt < endDate) { | |
const deployment = deployments.find((deployment) => { | |
const deploymentDate = new Date(deployment.created_at); | |
return deployment.sha === pr.merge_commit_sha && deploymentDate > mergedAt; | |
}); | |
if (deployment) { | |
const deploymentDate = new Date(deployment.created_at); | |
const leadTime = (deploymentDate - mergedAt) / (1000 * 60 * 60); // Convert to hours | |
leadTimes.push(leadTime); | |
} | |
} | |
} | |
// Calculate average lead time to change | |
const totalLeadTime = leadTimes.reduce((sum, time) => sum + time, 0); | |
const averageLeadTimeToChange = leadTimes.length > 0 ? totalLeadTime / leadTimes.length : 0; | |
return averageLeadTimeToChange; | |
} catch (error) { | |
console.error("Error in getLeadTimeToChange: ", error); | |
} | |
} | |
async function getReviewTime(owner, repo, startDate, endDate) { | |
try { | |
const prs = await octokit.paginate(octokit.pulls.list, { | |
owner, | |
repo, | |
state: "all", | |
per_page: 100, | |
}); | |
const reviewTimes = []; | |
for (const pr of prs) { | |
const createdAt = new Date(pr.created_at); | |
if (pr.merged_at !== null && createdAt >= startDate && createdAt < endDate) { | |
const mergedAt = new Date(pr.merged_at); | |
const reviewTime = (mergedAt - createdAt) / (1000 * 60 * 60); // Convert to hours | |
reviewTimes.push(reviewTime); | |
} | |
} | |
// Calculate average review time | |
const totalReviewTime = reviewTimes.reduce((sum, time) => sum + time, 0); | |
const averageReviewTime = reviewTimes.length > 0 ? totalReviewTime / reviewTimes.length : 0; | |
return averageReviewTime; | |
} catch (error) { | |
console.error("Error in getReviewTime: ", error); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment