@@ -149,11 +149,17 @@ def process_repository_batch(repo, org_metrics, start_date, end_date, user_filte
149149 repo_metrics = org_metrics .get_or_create_repository (repo .name )
150150 repo_metrics .default_branch = repo .default_branch
151151
152- # Track PR counts
152+ # Track PR counts for both repo and org
153153 repo_metrics .prs_created += len (relevant_pulls )
154+ org_metrics .prs_created += len (relevant_pulls )
155+
154156 merged_prs = [pr for pr in relevant_pulls if pr .merged ]
155157 repo_metrics .prs_merged += len (merged_prs )
156- repo_metrics .prs_merged_to_main += sum (1 for pr in merged_prs if pr .base .ref == repo_metrics .default_branch )
158+ org_metrics .prs_merged += len (merged_prs )
159+
160+ merged_to_main = sum (1 for pr in merged_prs if pr .base .ref == repo_metrics .default_branch )
161+ repo_metrics .prs_merged_to_main += merged_to_main
162+ org_metrics .prs_merged_to_main += merged_to_main
157163
158164 # Add contributor tracking
159165 for pr in relevant_pulls :
@@ -200,7 +206,6 @@ def process_pr(pr, repo_metrics, org_metrics, start_date, end_date):
200206 repo_metrics , org_metrics )
201207 ]
202208
203- # Wait for all updates to complete
204209 for future in as_completed (futures ):
205210 future .result ()
206211
@@ -279,28 +284,56 @@ def update_review_metrics(pr, pr_data, repo_metrics, org_metrics):
279284
280285def update_time_metrics (pr , commits , repo_metrics , org_metrics , start_date , end_date ):
281286 """Update time metrics for a PR"""
282- if pr .merged_at :
283- merge_time = ensure_datetime (pr .merged_at )
284-
285- # Update merge distribution
286- if merge_time .weekday () >= 5 : # Weekend
287- repo_metrics .time_metrics .merge_distribution ['weekends' ] += 1
288- org_metrics .time_metrics .merge_distribution ['weekends' ] += 1
289- elif 9 <= merge_time .hour < 17 : # Business hours (simplified)
290- repo_metrics .time_metrics .merge_distribution ['business_hours' ] += 1
291- org_metrics .time_metrics .merge_distribution ['business_hours' ] += 1
292- else : # After hours
293- repo_metrics .time_metrics .merge_distribution ['after_hours' ] += 1
294- org_metrics .time_metrics .merge_distribution ['after_hours' ] += 1
287+ try :
288+ if pr .merged_at :
289+ # Convert all times to datetime with timezone
290+ merge_time = ensure_datetime (pr .merged_at )
291+ created_time = ensure_datetime (pr .created_at )
295292
296- # Calculate deployment frequency (merges per day to main branch)
297- if pr .base .ref == repo_metrics .default_branch :
298- one_day_seconds = 24 * 60 * 60
299- days_in_period = (end_date - start_date ).total_seconds () / one_day_seconds
300- repo_metrics .time_metrics .deployment_frequency = repo_metrics .prs_merged_to_main / days_in_period
301- org_metrics .time_metrics .deployment_frequency = org_metrics .prs_merged_to_main / days_in_period
302-
303- # ... rest of existing update_time_metrics code ...
293+ # Calculate time to merge in hours
294+ merge_duration = (merge_time - created_time ).total_seconds () / 3600
295+ repo_metrics .time_metrics .time_to_merge .append (merge_duration )
296+ org_metrics .time_metrics .time_to_merge .append (merge_duration )
297+
298+ # Calculate lead time if we have commits
299+ if commits and len (commits ) > 0 :
300+ first_commit = min (commits , key = lambda c : ensure_datetime (c .commit .author .date ))
301+ first_commit_date = ensure_datetime (first_commit .commit .author .date )
302+ lead_time = (merge_time - first_commit_date ).total_seconds () / 3600
303+ repo_metrics .time_metrics .lead_times .append (lead_time )
304+ org_metrics .time_metrics .lead_times .append (lead_time )
305+
306+ # Calculate cycle time
307+ cycle_time = (merge_time - first_commit_date ).total_seconds () / 3600
308+ repo_metrics .time_metrics .cycle_time .append (cycle_time )
309+ org_metrics .time_metrics .cycle_time .append (cycle_time )
310+
311+ # Update merge distribution
312+ if merge_time .weekday () >= 5 : # Weekend
313+ repo_metrics .time_metrics .merge_distribution ['weekends' ] += 1
314+ org_metrics .time_metrics .merge_distribution ['weekends' ] += 1
315+ elif 9 <= merge_time .hour < 17 : # Business hours
316+ repo_metrics .time_metrics .merge_distribution ['business_hours' ] += 1
317+ org_metrics .time_metrics .merge_distribution ['business_hours' ] += 1
318+ else : # After hours
319+ repo_metrics .time_metrics .merge_distribution ['after_hours' ] += 1
320+ org_metrics .time_metrics .merge_distribution ['after_hours' ] += 1
321+
322+ # Calculate deployment frequency with safety check
323+ if pr .base .ref == repo_metrics .default_branch :
324+ one_day_seconds = 24 * 60 * 60
325+ days_in_period = max ((end_date - start_date ).total_seconds () / one_day_seconds , 1 ) # Ensure minimum 1 day
326+
327+ # Add safety checks for division
328+ if days_in_period > 0 :
329+ if repo_metrics .prs_merged_to_main > 0 :
330+ repo_metrics .time_metrics .deployment_frequency = repo_metrics .prs_merged_to_main / days_in_period
331+ if org_metrics .prs_merged_to_main > 0 :
332+ org_metrics .time_metrics .deployment_frequency = org_metrics .prs_merged_to_main / days_in_period
333+ except Exception as e :
334+ print (f"DEBUG: Error in update_time_metrics: { str (e )} " )
335+ # Continue processing even if there's an error with one PR
336+ pass
304337
305338def process_reviews (pr , reviews , repo_metrics , org_metrics ):
306339 """Process reviews for a PR"""
@@ -323,8 +356,8 @@ def process_reviews(pr, reviews, repo_metrics, org_metrics):
323356 repo_metrics .review_metrics .update_from_review (review , pr )
324357 org_metrics .review_metrics .update_from_review (review , pr )
325358
326- # Update collaboration metrics
327- update_collaboration_metrics (pr , review , repo_metrics , org_metrics , reviewer_metrics )
359+ # Fix: Remove reviewer_metrics from this call
360+ update_collaboration_metrics (pr , reviews , repo_metrics , org_metrics )
328361
329362def update_collaboration_metrics (pr , reviews , repo_metrics , org_metrics ):
330363 """Update collaboration metrics including participation rate"""
@@ -334,42 +367,46 @@ def update_collaboration_metrics(pr, reviews, repo_metrics, org_metrics):
334367 org_metrics .collaboration_metrics .self_merges += 1
335368
336369 # Update collaboration metrics at all levels
337- repo_metrics .collaboration_metrics .update_from_reviews (
338- reviews , pr ,
339- author_team = pr .user .team ,
340- reviewer_team = reviews [0 ].user .team
341- )
342- org_metrics .collaboration_metrics .update_from_reviews (
343- reviews , pr ,
344- author_team = pr .user .team ,
345- reviewer_team = reviews [0 ].user .team
346- )
347-
348- # Update team reviews
349- if reviews [0 ].user .team and pr .user .team :
350- if reviews [0 ].user .team == pr .user .team :
351- repo_metrics .collaboration_metrics .team_reviews += 1
352- org_metrics .collaboration_metrics .team_reviews += 1
370+ if reviews and len (reviews ) > 0 and hasattr (pr .user , 'team' ) and hasattr (reviews [0 ].user , 'team' ):
371+ repo_metrics .collaboration_metrics .update_from_reviews (
372+ reviews , pr ,
373+ author_team = pr .user .team ,
374+ reviewer_team = reviews [0 ].user .team
375+ )
376+ org_metrics .collaboration_metrics .update_from_reviews (
377+ reviews , pr ,
378+ author_team = pr .user .team ,
379+ reviewer_team = reviews [0 ].user .team
380+ )
381+
382+ # Update team reviews
383+ if reviews [0 ].user .team and pr .user .team :
384+ if reviews [0 ].user .team == pr .user .team :
385+ repo_metrics .collaboration_metrics .team_reviews += 1
386+ org_metrics .collaboration_metrics .team_reviews += 1
387+ else :
388+ repo_metrics .collaboration_metrics .cross_team_reviews += 1
389+ org_metrics .collaboration_metrics .cross_team_reviews += 1
353390 else :
354- repo_metrics .collaboration_metrics .cross_team_reviews += 1
355- org_metrics .collaboration_metrics .cross_team_reviews += 1
356- else :
357- repo_metrics .collaboration_metrics .external_reviews += 1
358- org_metrics .collaboration_metrics .external_reviews += 1
391+ repo_metrics .collaboration_metrics .external_reviews += 1
392+ org_metrics .collaboration_metrics .external_reviews += 1
393+
394+ # Calculate review participation rate for repository
395+ repo_total_reviews = (repo_metrics .collaboration_metrics .team_reviews +
396+ repo_metrics .collaboration_metrics .cross_team_reviews +
397+ repo_metrics .collaboration_metrics .external_reviews )
398+
399+ if repo_metrics .prs_created > 0 :
400+ repo_metrics .collaboration_metrics .review_participation_rate = repo_total_reviews / repo_metrics .prs_created
359401
360- # Calculate review participation rate
361- total_reviews = repo_metrics .collaboration_metrics .team_reviews + \
362- repo_metrics .collaboration_metrics .cross_team_reviews + \
363- repo_metrics .collaboration_metrics .external_reviews
364- total_prs = repo_metrics .prs_merged + repo_metrics .collaboration_metrics .self_merges
402+ # Calculate review participation rate for organization
403+ org_total_reviews = (org_metrics .collaboration_metrics .team_reviews +
404+ org_metrics .collaboration_metrics .cross_team_reviews +
405+ org_metrics .collaboration_metrics .external_reviews )
365406
366- if total_prs > 0 :
367- repo_metrics .collaboration_metrics .review_participation_rate = total_reviews / total_prs
368- org_metrics .collaboration_metrics .review_participation_rate = \
369- (org_metrics .collaboration_metrics .team_reviews + \
370- org_metrics .collaboration_metrics .cross_team_reviews + \
371- org_metrics .collaboration_metrics .external_reviews ) / \
372- (org_metrics .prs_merged + org_metrics .collaboration_metrics .self_merges )
407+ # Fix: Use prs_created instead of total_prs
408+ if org_metrics .prs_created > 0 : # Changed from total_prs to prs_created
409+ org_metrics .collaboration_metrics .review_participation_rate = org_total_reviews / org_metrics .prs_created
373410
374411def get_team_members (org , team_filter : str ) -> set :
375412 """Get team members for a specific team"""
0 commit comments