|
| 1 | +# Contributors Data |
| 2 | + |
| 3 | +This project automatically fetches and displays real contributors from the entire `universal-tool-calling-protocol` GitHub organization. |
| 4 | + |
| 5 | +## How it Works |
| 6 | + |
| 7 | +1. **Data Fetching**: The `scripts/fetch-contributors.js` script queries the GitHub API to: |
| 8 | + - Get all repositories in the `universal-tool-calling-protocol` organization |
| 9 | + - Fetch contributors for each repository |
| 10 | + - **Collect detailed activity metrics**: PRs, reviews, recent commits, last activity dates |
| 11 | + - Aggregate contribution counts across all repositories |
| 12 | + - Enhance data with user profiles from GitHub |
| 13 | + - Calculate hybrid impact scores for each contributor |
| 14 | + |
| 15 | +2. **Data Processing**: The script transforms GitHub API data into a format suitable for the contributors page, including: |
| 16 | + - Automatic role detection based on repository names (TypeScript SDK, Python SDK, etc.) |
| 17 | + - **Hybrid impact scoring** combining recent activity, overall contributions, code quality, and multi-project involvement |
| 18 | + - Status determination based on impact scores and activity recency |
| 19 | + - Real GitHub profile images with emoji fallbacks for errors |
| 20 | + - Badge assignment for notable contributors based on multiple metrics |
| 21 | + |
| 22 | +3. **Automatic Updates**: GitHub Actions automatically updates the contributors data: |
| 23 | + - **Daily**: Runs at 6 AM UTC every day |
| 24 | + - **Manual**: Can be triggered via workflow_dispatch |
| 25 | + - **On Changes**: Runs when the fetch script is updated |
| 26 | + |
| 27 | +## Setup |
| 28 | + |
| 29 | +### Environment Variables |
| 30 | + |
| 31 | +For local development, you can set a GitHub token to avoid rate limiting: |
| 32 | + |
| 33 | +```bash |
| 34 | +export GITHUB_TOKEN=your_github_token_here |
| 35 | +npm run fetch-contributors |
| 36 | +``` |
| 37 | + |
| 38 | +### Running Locally |
| 39 | + |
| 40 | +```bash |
| 41 | +# Fetch contributors data |
| 42 | +npm run fetch-contributors |
| 43 | + |
| 44 | +# Build site with fresh data |
| 45 | +npm run build |
| 46 | + |
| 47 | +# Build without fetching data (faster) |
| 48 | +npm run build:fast |
| 49 | +``` |
| 50 | + |
| 51 | +### Manual Setup |
| 52 | + |
| 53 | +If you need to run the script manually: |
| 54 | + |
| 55 | +```bash |
| 56 | +node scripts/fetch-contributors.js |
| 57 | +``` |
| 58 | + |
| 59 | +## Data Structure |
| 60 | + |
| 61 | +The generated `src/data/contributors.json` file contains: |
| 62 | + |
| 63 | +```json |
| 64 | +{ |
| 65 | + "generated_at": "2024-01-01T12:00:00.000Z", |
| 66 | + "total_contributors": 25, |
| 67 | + "total_contributions": 1500, |
| 68 | + "total_impact_score": 3250, |
| 69 | + "total_recent_activity": 145, |
| 70 | + "scoring_method": "hybrid_impact_score", |
| 71 | + "contributors": [ |
| 72 | + { |
| 73 | + "id": 123456, |
| 74 | + "login": "username", |
| 75 | + "name": "Real Name", |
| 76 | + "avatar_url": "https://github.com/avatar", |
| 77 | + "html_url": "https://github.com/username", |
| 78 | + "bio": "Developer bio", |
| 79 | + "company": "Company Name", |
| 80 | + "location": "City, Country", |
| 81 | + "blog": "https://blog.com", |
| 82 | + "hireable": true, |
| 83 | + "public_repos": 50, |
| 84 | + "followers": 100, |
| 85 | + "following": 80, |
| 86 | + "created_at": "2020-01-01T00:00:00Z", |
| 87 | + "contributions": 150, |
| 88 | + "repositories": ["repo1", "repo2"], |
| 89 | + "repo_count": 2, |
| 90 | + "impact_score": 185, |
| 91 | + "total_prs": 15, |
| 92 | + "total_merged_prs": 12, |
| 93 | + "total_recent_commits": 23, |
| 94 | + "total_reviews": 8, |
| 95 | + "last_activity": "2024-01-15T14:30:00Z", |
| 96 | + "pr_success_rate": 80 |
| 97 | + } |
| 98 | + ] |
| 99 | +} |
| 100 | +``` |
| 101 | + |
| 102 | +## Contributor Display Logic |
| 103 | + |
| 104 | +### Simplified Impact Scoring System |
| 105 | + |
| 106 | +Contributors are ranked using a **simplified impact score** based only on recent activity across all repositories: |
| 107 | + |
| 108 | +#### Scoring Formula |
| 109 | +``` |
| 110 | +Impact Score = Recent Activity × Recency Factor |
| 111 | +``` |
| 112 | + |
| 113 | +Where Recent Activity is the sum of commits across all repositories in the last 6 months. |
| 114 | + |
| 115 | +#### Recency Weighting |
| 116 | +Recent activity receives higher weight to prioritize active contributors: |
| 117 | +- **Last 30 days**: 100% weight (1.0x multiplier) |
| 118 | +- **Last 3 months**: 80% weight (0.8x multiplier) |
| 119 | +- **Last 6 months**: 50% weight (0.5x multiplier) |
| 120 | +- **Last year**: 30% weight (0.3x multiplier) |
| 121 | +- **Older**: 10% weight (0.1x multiplier) |
| 122 | + |
| 123 | +### Roles |
| 124 | +Roles are automatically determined based on repository patterns: |
| 125 | +- `typescript|js-sdk` → "TypeScript/JavaScript SDK" |
| 126 | +- `python|py-sdk` → "Python SDK" |
| 127 | +- `go-sdk|golang` → "Go SDK" |
| 128 | +- `rust-sdk` → "Rust SDK" |
| 129 | +- `java-sdk` → "Java SDK" |
| 130 | +- `csharp|dotnet` → "C# SDK" |
| 131 | +- `specification|docs` → "Specification & Docs" |
| 132 | +- Multiple repos → "Multi-language SDK" |
| 133 | + |
| 134 | +### Status Levels (Impact Score Based) |
| 135 | +- **Core contributor**: 100+ impact score + recent activity |
| 136 | +- **Core contributor (inactive)**: 100+ impact score but no recent activity |
| 137 | +- **Active contributor**: 50+ impact score + recent activity |
| 138 | +- **Regular contributor**: 20+ impact score or inactive but previously active |
| 139 | +- **New contributor**: <20 impact score |
| 140 | + |
| 141 | +### Enhanced Badge System |
| 142 | +- 🏆 **Top Impact Contributor**: 200+ impact score |
| 143 | +- ⭐ **High Impact Contributor**: 100+ impact score |
| 144 | +- 🔥 **Multi-project Contributor**: 3+ repositories |
| 145 | +- 🚀 **Recently Active**: 10+ commits in last 6 months |
| 146 | +- ✨ **Quality Contributor**: 80%+ PR merge rate with 5+ PRs |
| 147 | + |
| 148 | +### Data Collection & Metrics |
| 149 | +For each contributor, the system collects: |
| 150 | +- **Pull Requests**: Total PRs created and merge success rate |
| 151 | +- **Code Reviews**: Participation in reviewing others' code |
| 152 | +- **Recent Activity**: Commits in the last 6 months |
| 153 | +- **Cross-project Work**: Contributions across multiple repositories |
| 154 | +- **Last Activity Date**: Most recent contribution timestamp |
| 155 | + |
| 156 | +### Hiring Status |
| 157 | +Contributors with `hireable: true` in their GitHub profile show an "Open to work" badge. |
| 158 | + |
| 159 | +## Advantages of Simplified Scoring |
| 160 | + |
| 161 | +The simplified impact scoring system provides several benefits: |
| 162 | + |
| 163 | +1. **Recency Focus**: Active contributors rank higher than inactive ones |
| 164 | +2. **Cross-project Aggregation**: Recent commits are summed across all repositories |
| 165 | +3. **Simple and Fair**: Transparent calculation based purely on recent activity |
| 166 | +4. **Prevents Gaming**: Cannot be inflated through historical contributions or metadata manipulation |
| 167 | + |
| 168 | +## Troubleshooting |
| 169 | + |
| 170 | +### Rate Limiting |
| 171 | +The enhanced scoring system makes significantly more API calls (PRs, commits, reviews per contributor per repo). Without authentication, GitHub API limits to 60 requests/hour. The script includes delays to avoid hitting limits, but **using `GITHUB_TOKEN` is highly recommended** for reasonable execution times. |
| 172 | + |
| 173 | +**Expected Runtime**: |
| 174 | +- Without token: 15-30+ minutes (depending on contributor count) |
| 175 | +- With token: 2-5 minutes (much faster due to higher rate limits) |
| 176 | + |
| 177 | +### Missing Data |
| 178 | +If the contributors page shows "Contributors data unavailable": |
| 179 | +1. Run `npm run fetch-contributors` locally |
| 180 | +2. Check if `src/data/contributors.json` was created |
| 181 | +3. Ensure the GitHub API is accessible |
| 182 | +4. Check console for error messages |
| 183 | + |
| 184 | +### Build Integration |
| 185 | +The build process automatically fetches fresh data. For faster builds during development, use `npm run build:fast` to skip the data fetch. |
0 commit comments