— No reviews yet
0 installs
9 views
0.0% view→install
Install
$ agentstack add skill-cxcscmu-skilllearnbench-github-metrics-processing ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Are you the author of Github Metrics Processing? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claimAbout
GitHub Metrics Processing Skill
Overview
Process JSON data from GitHub queries to calculate publication metrics, including PR merge times, issue categorization, and contributor analysis.
Prerequisites
- Python 3.7+ with
jsonanddatetimemodules (standard library) - Raw GitHub API JSON data from gh CLI queries
Key Metrics to Calculate
Pull Request Metrics
1. Total PR Count
total_prs = len(prs_data)
2. Merged vs Closed PRs
merged_prs = [pr for pr in prs_data if pr.get('mergedAt') is not None]
closed_prs = [pr for pr in prs_data if pr.get('closedAt') is not None and pr.get('mergedAt') is None]
merged_count = len(merged_prs)
closed_count = len(closed_prs)
3. Average Merge Time (days)
from datetime import datetime
def parse_iso8601(timestamp_str):
"""Parse ISO 8601 timestamp to datetime object"""
return datetime.fromisoformat(timestamp_str.replace('Z', '+00:00'))
def calculate_merge_days(prs):
"""Calculate average days from creation to merge"""
merge_times = []
for pr in prs:
if pr.get('mergedAt'): # Only count merged PRs
created = parse_iso8601(pr['createdAt'])
merged = parse_iso8601(pr['mergedAt'])
days = (merged - created).days
merge_times.append(days)
if not merge_times:
return 0.0
avg = sum(merge_times) / len(merge_times)
return round(avg, 1) # Round to one decimal place
4. Top Contributor (Most PRs)
from collections import Counter
def get_top_contributor(prs):
"""Find author who opened the most PRs"""
authors = [pr['author']['login'] for pr in prs if pr.get('author')]
if not authors:
return None
author_counts = Counter(authors)
top_author, _ = author_counts.most_common(1)[0]
return top_author
Issue Metrics
1. Total Issue Count
total_issues = len(issues_data)
2. Bug Reports (label matching)
def count_bug_issues(issues):
"""Count issues with 'bug' in any label name"""
bug_count = 0
for issue in issues:
labels = issue.get('labels', [])
has_bug = any('bug' in label.get('name', '').lower() for label in labels)
if has_bug:
bug_count += 1
return bug_count
bug_count = count_bug_issues(issues_data)
3. Resolved Bugs (closed during month)
def count_resolved_bugs(issues, period_end):
"""Count bugs that were closed during the specified month"""
resolved_count = 0
for issue in issues:
# Must have 'bug' in a label
labels = issue.get('labels', [])
has_bug = any('bug' in label.get('name', '').lower() for label in labels)
# Must be closed
closed_at = issue.get('closedAt')
if has_bug and closed_at:
resolved_count += 1
return resolved_count
Complete Processing Example
import json
from datetime import datetime
from collections import Counter
def parse_iso8601(timestamp_str):
return datetime.fromisoformat(timestamp_str.replace('Z', '+00:00'))
def process_github_data(prs_json, issues_json):
"""Process GitHub data and return metrics"""
prs = json.loads(prs_json)
issues = json.loads(issues_json)
# PR Metrics
merged_prs = [pr for pr in prs if pr.get('mergedAt')]
closed_prs = [pr for pr in prs
if pr.get('closedAt') and not pr.get('mergedAt')]
merge_times = []
for pr in merged_prs:
created = parse_iso8601(pr['createdAt'])
merged = parse_iso8601(pr['mergedAt'])
days = (merged - created).days
merge_times.append(days)
avg_merge_days = round(sum(merge_times) / len(merge_times), 1) if merge_times else 0.0
authors = [pr['author']['login'] for pr in prs if pr.get('author')]
top_contributor = Counter(authors).most_common(1)[0][0] if authors else None
# Issue Metrics
bug_issues = []
for issue in issues:
labels = issue.get('labels', [])
if any('bug' in label.get('name', '').lower() for label in labels):
bug_issues.append(issue)
resolved_bugs = sum(1 for issue in bug_issues if issue.get('closedAt'))
return {
'pr': {
'total': len(prs),
'merged': len(merged_prs),
'closed': len(closed_prs),
'avg_merge_days': avg_merge_days,
'top_contributor': top_contributor
},
'issue': {
'total': len(issues),
'bug': len(bug_issues),
'resolved_bugs': resolved_bugs
}
}
Edge Cases to Handle
- Null values in timestamps (still open/not merged items)
- Case-insensitive label matching for "bug"
- Authors from external contributors (verify .login field exists)
- PRs created but never merged or closed (neither count toward closed)
- Division by zero when no merged PRs exist
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: cxcscmu
- Source: cxcscmu/SkillLearnBench
- License: MIT
- Homepage: https://cxcscmu.github.io/SkillLearnBench
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.