Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: calculate lead time for change metrics #10

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
.venv/
venv/
__pycache__
2 changes: 1 addition & 1 deletion automation.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
total_tickets=total_tickets,
t_releases=t_releases,
existing_codebase=existing_codebase,
target_data_file=target_data_file, isHotFix=isHotFix, includesBugs=includesBugs)
target_data_file=target_data_file, isHotFix=isHotFix, includesBugs=includesBugs, parent_branch=parent_branch)
calculate_releases(
number_of_features=number_of_features,
number_of_bugs=number_of_bugs,
Expand Down
14 changes: 13 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1,13 @@
PyYAML==6.0.1
certifi==2024.6.2
charset-normalizer==3.3.2
DateTime==5.5
idna==3.7
numpy==1.26.4
pandas==2.2.2
python-dateutil==2.9.0.post0
pytz==2024.1
requests==2.32.3
six==1.16.0
tzdata==2024.1
urllib3==2.2.1
zope.interface==6.4.post2
File renamed without changes.
7 changes: 5 additions & 2 deletions utils/calcMetrics.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import os
import yaml
from utils.date import get_current_date
from utils.math import calc_avg, calc_cfr_hotfix_to_release, calc_cfr_bugs_to_tasks_ratio, calc_cfr_bug_to_feature, calc_cfr_bug_release_ratio
from utils.calc import calc_avg, calc_cfr_hotfix_to_release, calc_cfr_bugs_to_tasks_ratio, calc_cfr_bug_to_feature, calc_cfr_bug_release_ratio
from utils.dir import create_directory_and_file
from utils.leadTimeToChange import calcLeadTimeToChange

current_date = get_current_date()

# yields data.yaml


def calculate_metrics(number_of_features, number_of_bugs, number_of_hotfixes, total_tickets, t_releases, existing_codebase=True, target_data_file='metrics/data.yaml', isHotFix="true", includesBugs="true"):
def calculate_metrics(number_of_features, number_of_bugs, number_of_hotfixes, total_tickets, t_releases, existing_codebase=True, target_data_file='metrics/data.yaml', isHotFix="true", includesBugs="true", parent_branch='main'):
if os.path.exists(target_data_file):
print("Found existing target file, updating it with the latest release...")

Expand Down Expand Up @@ -62,6 +63,7 @@ def calculate_metrics(number_of_features, number_of_bugs, number_of_hotfixes, to
average_hotfixes_per_release = calc_avg(
revised_total_hotfixes, current_release)

lead_time_to_chage = calcLeadTimeToChange(parent_branch)
yaml_content = f"""
.total_releases = {current_release} |
.total_feature_releases = {revised_total_features} |
Expand All @@ -71,6 +73,7 @@ def calculate_metrics(number_of_features, number_of_bugs, number_of_hotfixes, to
.average_features_per_release = {average_features_per_release} |
.average_bugs_per_release = {average_bugs_per_release} |
.average_hotfixes_per_release = {average_hotfixes_per_release} |
.lead_time_to_change = {lead_time_to_chage} |
.cfr_hotfix_to_release = "{cfr_hotfix_to_release} %" |
.cfr_bugs_to_tasks_ratio = "{cfr_bugs_to_tasks_ratio} %" |
.cfr_bug_to_feature = "{cfr_bug_to_feature} %" |
Expand Down
79 changes: 79 additions & 0 deletions utils/leadTimeToChange.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# dora_metrics.py
import os
import requests
import pandas as pd
from datetime import datetime

GITHUB_TOKEN = os.getenv('GITHUB_TOKEN')

# GitHub repository details
REPO_OWNER = 'wednesday-solutions'
REPO_NAME = 'gen-ai-audio'

# GitHub API base URL
BASE_URL = f'https://api.github.com/repos/{REPO_OWNER}/{REPO_NAME}'

# Headers for authentication
HEADERS = {
'Authorization': f'token {GITHUB_TOKEN}',
'Accept': 'application/vnd.github.v3+json'
}


def fetch_pull_requests(branch):
url = f'{BASE_URL}/pulls'
params = {
'state': 'closed',
'base': branch
}
response = requests.get(url, headers=HEADERS, params=params)
response.raise_for_status()
return response.json()


def fetch_commits(branch):
url = f'{BASE_URL}/commits'
params = {'sha': branch}
response = requests.get(url, headers=HEADERS, params=params)
response.raise_for_status()
return response.json()


def get_commit_date(commit_url):
response = requests.get(commit_url, headers=HEADERS)
response.raise_for_status()
commit_data = response.json()
return commit_data['commit']['committer']['date']


def calculate_lead_time(pr):
pr_created_at = datetime.strptime(pr['created_at'], '%Y-%m-%dT%H:%M:%SZ')
pr_merged_at = datetime.strptime(pr['merged_at'], '%Y-%m-%dT%H:%M:%SZ')
lead_time = pr_merged_at - pr_created_at
return lead_time


def calcLeadTimeToChange(branch='main'):
# Fetch pull requests merged into the base branch
prs = fetch_pull_requests(branch)
lead_times = []
prCount = len(prs)

if prCount > 0:
for pr in prs:
if pr['merged_at'] is None:
continue
lead_time = calculate_lead_time(pr)
lead_times.append({
'PR': pr['title'],
'Lead Time': lead_time.total_seconds() / 3600 # Convert to hours
})

# Create a DataFrame for analysis
df = pd.DataFrame(lead_times)
print(df)

# Calculate average lead time
average_lead_time = df['Lead Time'].mean()
print(f'Average Lead Time for Changes: {average_lead_time:.2f} hours')
return average_lead_time