Skip to content

Instantly share code, notes, and snippets.

@mikaelvesavuori
Created June 8, 2023 13:24
Show Gist options
  • Save mikaelvesavuori/71b74bca7ae7a4774b60e3ec930b6073 to your computer and use it in GitHub Desktop.
Save mikaelvesavuori/71b74bca7ae7a4774b60e3ec930b6073 to your computer and use it in GitHub Desktop.
Minimal DORA metrics implementation using data from GitHub, as suggested by ChatGPT
// Configuration
const owner = "your-github-username";
const repo = "your-repository-name";
interface PullRequest {
created_at: string;
merged_at: string;
}
interface Deployment {
created_at: string;
recovery_time: string;
status: string;
}
async function getPullRequests(
owner: string,
repo: string
): Promise<PullRequest[]> {
const response = await fetch(
`https://api.github.com/repos/${owner}/${repo}/pulls`
);
const data = await response.json();
return data;
}
async function getDeployments(
owner: string,
repo: string
): Promise<Deployment[]> {
const response = await fetch(
`https://api.github.com/repos/${owner}/${repo}/deployments`
);
const data = await response.json();
return data;
}
function calculateLeadTime(pullRequests: PullRequest[]): number {
const leadTimes = pullRequests.map(
(pr) => new Date(pr.merged_at).getTime() - new Date(pr.created_at).getTime()
);
const totalLeadTime = leadTimes.reduce((sum, leadTime) => sum + leadTime, 0);
return totalLeadTime / leadTimes.length;
}
function calculateDeploymentFrequency(
deployments: Deployment[],
timeframe: number
): number {
const recentDeployments = deployments.filter((deployment) => {
const deploymentDate = new Date(deployment.created_at).getTime();
const currentDate = new Date().getTime();
return currentDate - deploymentDate <= timeframe;
});
return recentDeployments.length;
}
function calculateChangeFailureRate(deployments: Deployment[]): number {
const failedDeployments = deployments.filter(
(deployment) => deployment.status === "failure"
);
return (failedDeployments.length / deployments.length) * 100;
}
function calculateMTTR(deployments: Deployment[]): number {
const recoveryTimes = deployments
.filter((deployment) => deployment.status === "failure")
.map(
(deployment) =>
new Date(deployment.created_at).getTime() -
new Date(deployment.recovery_time).getTime()
);
const totalRecoveryTime = recoveryTimes.reduce(
(sum, recoveryTime) => sum + recoveryTime,
0
);
return totalRecoveryTime / recoveryTimes.length;
}
(async () => {
try {
const pullRequests = await getPullRequests(owner, repo);
const deployments = await getDeployments(owner, repo);
const leadTime = calculateLeadTime(pullRequests);
const deploymentFrequency = calculateDeploymentFrequency(
deployments,
30 * 24 * 60 * 60 * 1000
); // 30 days in milliseconds
const changeFailureRate = calculateChangeFailureRate(deployments);
const mttr = calculateMTTR(deployments);
console.log("Lead Time:", leadTime);
console.log("Deployment Frequency:", deploymentFrequency);
console.log("Change Failure Rate:", changeFailureRate);
console.log("MTTR:", mttr);
} catch (error: any) {
console.error("Error:", error.message);
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment