Skip to content

Commit 0ae1838

Browse files
Copilotbenhillis
andcommitted
Add contributor tracking to show who has contributed code but not done reviews
Co-authored-by: benhillis <17727402+benhillis@users.noreply.github.com>
1 parent ada1653 commit 0ae1838

1 file changed

Lines changed: 56 additions & 8 deletions

File tree

.github/workflows/code-review-metrics.yml

Lines changed: 56 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -78,17 +78,25 @@ jobs:
7878
7979
print(f"Processing {len(prs)} PRs...")
8080
81-
# Initialize reviewer metrics - focus on who and how many
81+
# Initialize metrics - track both reviewers and contributors
8282
reviewer_stats = defaultdict(lambda: {
8383
'reviews_given': 0,
8484
'prs_reviewed': set()
8585
})
8686
87+
contributor_stats = defaultdict(lambda: {
88+
'prs_authored': 0
89+
})
90+
8791
total_reviews = 0
8892
89-
# Process each PR to count reviews per reviewer
93+
# Process each PR to count reviews per reviewer and track contributors
9094
for pr in prs:
9195
pr_number = pr['number']
96+
author = pr['author']['login']
97+
98+
# Track PR authors (contributors)
99+
contributor_stats[author]['prs_authored'] += 1
92100
93101
# Process reviews
94102
for review in pr.get('reviews', []):
@@ -106,14 +114,23 @@ jobs:
106114
for reviewer in reviewer_stats:
107115
reviewer_stats[reviewer]['prs_reviewed'] = len(reviewer_stats[reviewer]['prs_reviewed'])
108116
109-
# Save focused metrics
117+
# Find contributors who haven't done reviews
118+
all_contributors = set(contributor_stats.keys())
119+
all_reviewers = set(reviewer_stats.keys())
120+
contributors_not_reviewing = all_contributors - all_reviewers
121+
122+
# Save comprehensive metrics
110123
metrics = {
111124
'summary': {
112125
'total_prs_analyzed': len(prs),
113126
'total_reviews': total_reviews,
114-
'total_reviewers': len(reviewer_stats)
127+
'total_reviewers': len(reviewer_stats),
128+
'total_contributors': len(contributor_stats),
129+
'contributors_not_reviewing': len(contributors_not_reviewing)
115130
},
116-
'reviewer_stats': dict(reviewer_stats)
131+
'reviewer_stats': dict(reviewer_stats),
132+
'contributor_stats': dict(contributor_stats),
133+
'contributors_not_reviewing': list(contributors_not_reviewing)
117134
}
118135
119136
with open('review-data/metrics.json', 'w') as f:
@@ -122,6 +139,8 @@ jobs:
122139
print("Review metrics generated successfully")
123140
print(f"Total reviewers: {len(reviewer_stats)}")
124141
print(f"Total reviews: {total_reviews}")
142+
print(f"Total contributors: {len(contributor_stats)}")
143+
print(f"Contributors not reviewing: {len(contributors_not_reviewing)}")
125144
EOF
126145
127146
- name: Generate Report
@@ -143,14 +162,19 @@ jobs:
143162
144163
summary = metrics['summary']
145164
reviewer_stats = metrics['reviewer_stats']
165+
contributor_stats = metrics['contributor_stats']
166+
contributors_not_reviewing = metrics['contributors_not_reviewing']
146167
147168
# Sort reviewers by review count
148169
sorted_reviewers = sorted(reviewer_stats.items(), key=lambda x: x[1]['reviews_given'], reverse=True)
170+
171+
# Sort contributors by PR count
172+
sorted_contributors = sorted(contributor_stats.items(), key=lambda x: x[1]['prs_authored'], reverse=True)
149173
150174
repo_name = os.environ.get('GITHUB_REPOSITORY', 'Unknown')
151175
analysis_days = os.environ.get('ANALYSIS_DAYS', '30')
152176
153-
# Generate focused markdown report
177+
# Generate comprehensive markdown report
154178
report_lines = [
155179
"# Code Review Metrics Report",
156180
"",
@@ -163,6 +187,8 @@ jobs:
163187
f"- **Total PRs Analyzed:** {summary['total_prs_analyzed']}",
164188
f"- **Total Reviews Given:** {summary['total_reviews']}",
165189
f"- **Active Reviewers:** {summary['total_reviewers']}",
190+
f"- **Total Contributors:** {summary['total_contributors']}",
191+
f"- **Contributors Not Reviewing:** {summary['contributors_not_reviewing']}",
166192
"",
167193
"## Who Is Reviewing Code",
168194
"",
@@ -174,21 +200,41 @@ jobs:
174200
for reviewer, stats in sorted_reviewers:
175201
report_lines.append(f"| {reviewer} | {stats['reviews_given']} | {stats['prs_reviewed']} |")
176202
203+
# Add section for contributors who haven't done reviews
204+
report_lines.extend([
205+
"",
206+
"## Contributors Who Have Not Done Reviews",
207+
""
208+
])
209+
210+
if contributors_not_reviewing:
211+
report_lines.extend([
212+
"| Contributor | PRs Authored |",
213+
"|-------------|--------------|"
214+
])
215+
216+
for contributor in contributors_not_reviewing:
217+
prs_authored = contributor_stats[contributor]['prs_authored']
218+
report_lines.append(f"| {contributor} | {prs_authored} |")
219+
else:
220+
report_lines.append("*All contributors are also participating in code reviews* ✅")
221+
177222
# Add insights focused on reviewer activity
178223
most_active = sorted_reviewers[0] if sorted_reviewers else ('N/A', {'reviews_given': 0})
179224
avg_reviews = summary['total_reviews'] / summary['total_reviewers'] if summary['total_reviewers'] > 0 else 0
225+
review_participation = (summary['total_reviewers'] / summary['total_contributors'] * 100) if summary['total_contributors'] > 0 else 0
180226
181227
report_lines.extend([
182228
"",
183229
"## Key Insights",
184230
"",
185231
f"- **Most Active Reviewer:** {most_active[0]} ({most_active[1]['reviews_given']} reviews)",
186232
f"- **Average Reviews per Reviewer:** {avg_reviews:.1f} reviews",
187-
f"- **Review Participation:** {summary['total_reviewers']} team members actively reviewing code",
233+
f"- **Review Participation Rate:** {review_participation:.1f}% of contributors are also reviewing",
188234
f"- **Review Distribution:** {summary['total_reviews']} total reviews across {summary['total_prs_analyzed']} PRs",
189235
"",
190236
"---",
191-
"*Report focuses on who is reviewing code and review volume per person (bots excluded)*"
237+
"*Report shows who is reviewing code, review volume per person, and contributors who could participate more in reviews (bots excluded)*"
192238
])
193239
194240
# Save report
@@ -253,6 +299,8 @@ jobs:
253299
f.write(f"- **Active Reviewers:** {summary['total_reviewers']}\n")
254300
f.write(f"- **Total Reviews:** {summary['total_reviews']}\n")
255301
f.write(f"- **PRs Analyzed:** {summary['total_prs_analyzed']}\n")
302+
f.write(f"- **Total Contributors:** {summary['total_contributors']}\n")
303+
f.write(f"- **Contributors Not Reviewing:** {summary['contributors_not_reviewing']}\n")
256304
f.write(f"- **Most Active Reviewer:** {top_reviewer_name} ({top_reviewer_stats['reviews_given']} reviews)\n")
257305
EOF
258306
fi

0 commit comments

Comments
 (0)