Skip to content

Commit 2a4e54f

Browse files
feat(providers): add indivudal GitHub contributions (#18)
1 parent d4e3c8e commit 2a4e54f

File tree

6 files changed

+440
-4
lines changed

6 files changed

+440
-4
lines changed

README.md

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ Supports:
1313

1414
- Contributors:
1515
- [**CrowdIn**](https://crowdin.com)
16-
- [**GitHub**](https://github.com)
16+
- [**GitHub Contributors**](https://github.com) (contributors to a specific repository)
17+
- [**GitHub Contributions**](https://github.com) (merged PRs aggregated by repository owner across all repos for a single user)
1718
- [**Gitlab**](https://gitlab.com)
1819
- Sponsors:
1920
- [**GitHub Sponsors**](https://github.com/sponsors)
@@ -37,11 +38,25 @@ CONTRIBKIT_CROWDIN_MIN_TRANSLATIONS=1
3738

3839
; GitHubContributors provider.
3940
; Token requires the `public_repo` and `read:user` scopes.
41+
; This provider tracks all contributors to a specific repository.
4042
CONTRIBKIT_GITHUB_CONTRIBUTORS_TOKEN=
4143
CONTRIBKIT_GITHUB_CONTRIBUTORS_LOGIN=
4244
CONTRIBKIT_GITHUB_CONTRIBUTORS_MIN=1
4345
CONTRIBKIT_GITHUB_CONTRIBUTORS_REPO=
4446

47+
; GitHubContributions provider.
48+
; Token requires the `read:user` scope.
49+
; This provider aggregates merged pull requests across all repositories by repository owner (user or organization).
50+
; Each owner appears once with the total merged PRs you authored to their repos.
51+
; Avatar and link point to the owner (or to the repo if only one repo per owner).
52+
; Only merged PRs are counted - open or closed-without-merge PRs are excluded.
53+
CONTRIBKIT_GITHUB_CONTRIBUTIONS_TOKEN=
54+
CONTRIBKIT_GITHUB_CONTRIBUTIONS_LOGIN=
55+
; Optional: Cap the maximum contribution count per org/user (useful for circles visualization)
56+
CONTRIBKIT_GITHUB_CONTRIBUTIONS_MAX=
57+
; Optional: Apply logarithmic scaling to reduce dominance of high contributors (true/false)
58+
CONTRIBKIT_GITHUB_CONTRIBUTIONS_LOGARITHMIC=
59+
4560
; GitlabContributors provider.
4661
; Token requires the `read_api` and `read_user` scopes.
4762
CONTRIBKIT_GITLAB_CONTRIBUTORS_TOKEN=
@@ -96,9 +111,26 @@ CONTRIBKIT_LIBERAPAY_LOGIN=
96111
> This will require different env variables to be set for each provider, and to be created from separate
97112
> commands.
98113
114+
#### GitHub Provider Options
115+
116+
There are two GitHub contributor providers available:
117+
118+
- **GitHubContributors**: Tracks all contributors to a specific repository (e.g., `owner/repo`). Each contributor appears once with their actual contribution count to that repository.
119+
- **GitHubContributions**: Aggregates a single user's **merged pull requests** across all repositories, grouped by repository owner (user or organization). Each owner appears once with the total merged PRs. The avatar and link point to the owner (or to the specific repo if only one repo per owner).
120+
121+
Use **GitHubContributors** when you want to showcase everyone who has contributed to your project with their contribution counts.
122+
Use **GitHubContributions** when you want to understand where a single user's completed contributions (merged PRs) have gone, without overwhelming duplicates per repo under the same owner.
123+
124+
**GitHubContributions accuracy**:
125+
- Counts only **merged** pull requests - open or closed-without-merge PRs are excluded
126+
- Discovers repos via **2 sources**:
127+
1. **contributionsCollection** - Yearly commit timeline (full history) for discovering repositories you have committed to
128+
2. **Search API** - Repositories where you have merged PRs (`is:pr is:merged author:login`)
129+
- When an owner has only one repo, the link points to that repo; otherwise to the owner profile
130+
99131
Run:
100132

101-
```base
133+
```bash
102134
npx contribkit
103135
```
104136

@@ -133,6 +165,11 @@ export default defineConfig({
133165
// ...
134166
},
135167

168+
// For contributor providers:
169+
githubContributions: {
170+
login: 'username',
171+
},
172+
136173
// Rendering configs
137174
width: 800,
138175
renderer: 'tiers', // or 'circles'

src/configs/env.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,12 @@ export function loadEnv(): Partial<ContribkitConfig> {
5757
projectId: Number(process.env.CONTRIBKIT_CROWDIN_PROJECT_ID),
5858
minTranslations: Number(process.env.CONTRIBKIT_CROWDIN_MIN_TRANSLATIONS) || 1,
5959
},
60+
githubContributions: {
61+
login: process.env.CONTRIBKIT_GITHUB_CONTRIBUTIONS_LOGIN,
62+
token: process.env.CONTRIBKIT_GITHUB_CONTRIBUTIONS_TOKEN,
63+
maxContributions: Number(process.env.CONTRIBKIT_GITHUB_CONTRIBUTIONS_MAX) || undefined,
64+
logarithmicScaling: process.env.CONTRIBKIT_GITHUB_CONTRIBUTIONS_LOGARITHMIC === 'true',
65+
},
6066
}
6167

6268
// remove undefined keys

src/processing/svg.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ export function genSvgImage(
1010
base64Image: string,
1111
imageFormat: ImageFormat,
1212
) {
13-
const cropId = `c${crypto.createHash('md5').update(base64Image).digest('hex').slice(0, 6)}`
13+
// Unique clipPath id per element, ensuring duplicated images are properly rendered.
14+
const hashInput = `${x}:${y}:${size}:${radius}:${base64Image}`
15+
const cropId = `c${crypto.createHash('sha256').update(hashInput).digest('hex').slice(0, 6)}`
1416
return `
1517
<clipPath id="${cropId}">
1618
<rect x="${x}" y="${y}" width="${size}" height="${size}" rx="${size * radius}" ry="${size * radius}" />

0 commit comments

Comments
 (0)