Skip to content

Commit e11805c

Browse files
ci: adjust contributors logic to include new crowdin project and homarr repository (#178)
Co-authored-by: Meierschlumpf <[email protected]>
1 parent 992b8c1 commit e11805c

File tree

8 files changed

+134
-89
lines changed

8 files changed

+134
-89
lines changed

.github/workflows/dump-api-data.yaml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@ on:
66
workflow_dispatch:
77

88
env:
9-
HOMARR_DOCUMENTATION_GH_TOKEN: "${{ secrets.HOMARR_DOCUMENTATION_GH_TOKEN }}"
9+
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
1010
HOMARR_CROWDIN_TOKEN: "${{ secrets.HOMARR_CROWDIN_TOKEN }}"
11+
HOMARR_LABS_CROWDIN_TOKEN: "${{ secrets.HOMARR_LABS_CROWDIN_TOKEN }}"
1112

1213
permissions:
1314
contents: write
@@ -17,7 +18,7 @@ jobs:
1718
runs-on: ubuntu-latest
1819
strategy:
1920
matrix:
20-
node-version: [20]
21+
node-version: [22]
2122
steps:
2223
- uses: actions/checkout@v4
2324
- uses: pnpm/action-setup@v2

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"serve": "docusaurus serve",
1919
"write-translations": "docusaurus write-translations",
2020
"write-heading-ids": "docusaurus write-heading-ids",
21-
"api-dump-contributors": "node ./scripts/dump-contributors.js"
21+
"api-dump-contributors": "node ./scripts/dump-contributors.mjs"
2222
},
2323
"dependencies": {
2424
"@dipakparmar/docusaurus-plugin-umami": "^2.1.2",

scripts/dump-contributors.js

Lines changed: 0 additions & 74 deletions
This file was deleted.

scripts/dump-contributors.mjs

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
import { z } from 'zod';
2+
import fs from 'fs/promises';
3+
4+
const sources = {
5+
crowdin: [
6+
{ projectId: 534422, tokenName: 'HOMARR_CROWDIN_TOKEN' },
7+
{ projectId: 742587, tokenName: 'HOMARR_LABS_CROWDIN_TOKEN' },
8+
],
9+
github: [
10+
{ repository: 'homarr', slug: 'ajnart' },
11+
{ repository: 'homarr', slug: 'homarr-labs' },
12+
],
13+
};
14+
15+
const schema = z.object({
16+
GITHUB_TOKEN: z.string().nonempty(),
17+
HOMARR_CROWDIN_TOKEN: z.string().nonempty(),
18+
HOMARR_LABS_CROWDIN_TOKEN: z.string().nonempty(),
19+
});
20+
21+
const env = schema.parse(process.env);
22+
23+
const fetchGithubContributors = async (slug, repository) => {
24+
const url = `https://api.github.com/repos/${slug}/${repository}/contributors?per_page=999`;
25+
const options = {
26+
method: 'GET',
27+
headers: {
28+
Authorization: `Bearer ${env.GITHUB_TOKEN}`,
29+
Accept: 'application/vnd.github+json',
30+
'X-GitHub-Api-Version': '2022-11-28',
31+
},
32+
};
33+
34+
const response = await fetch(url, options);
35+
const data = await response.json();
36+
37+
const dataSchema = z.array(
38+
z.object({
39+
login: z.string(),
40+
avatar_url: z.string().url(),
41+
contributions: z.number(),
42+
})
43+
);
44+
45+
return dataSchema.parse(data);
46+
};
47+
48+
const fetchCrowdinMembers = async (projectId, tokenName) => {
49+
const url = `https://crowdin.com/api/v2/projects/${projectId}/members`;
50+
const options = {
51+
method: 'GET',
52+
headers: {
53+
Accept: 'application/json',
54+
Authorization: `Bearer ${env[tokenName]}`,
55+
},
56+
};
57+
58+
const response = await fetch(url, options);
59+
const data = await response.json();
60+
61+
const dataSchema = z.object({
62+
data: z.array(
63+
z.object({
64+
data: z.object({
65+
username: z.string(),
66+
avatarUrl: z.string().url(),
67+
}),
68+
})
69+
),
70+
});
71+
72+
const contributionsData = dataSchema.parse(data);
73+
74+
return contributionsData.data.flatMap((data) => data.data);
75+
};
76+
77+
const distinctBy = (callback) => (value, index, self) => {
78+
return self.findIndex((item) => callback(item) == callback(value)) === index;
79+
};
80+
81+
const githubContributors = [];
82+
const crowdinContributors = [];
83+
84+
for (const { repository, slug } of sources.github) {
85+
githubContributors.push(...(await fetchGithubContributors(slug, repository)));
86+
}
87+
const distinctGithubContributors = githubContributors
88+
.filter(distinctBy((contributor) => contributor.login))
89+
.sort((a, b) => b.contributions - a.contributions)
90+
.map(({ contributions, ...props }) => props)
91+
.filter((contributor) => !contributor.login.includes('[bot]'));
92+
await fs.writeFile('./static/data/contributions.json', JSON.stringify(distinctGithubContributors));
93+
94+
for (const { projectId, tokenName } of sources.crowdin) {
95+
crowdinContributors.push(...(await fetchCrowdinMembers(projectId, tokenName)));
96+
}
97+
const distinctCrowdinContributors = crowdinContributors.filter(
98+
distinctBy((contributor) => contributor.username)
99+
);
100+
await fs.writeFile(
101+
'./static/data/translation-contributions.json',
102+
JSON.stringify(distinctCrowdinContributors)
103+
);

src/components/pages/about/code-contributors/code-contributor-list.tsx

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,26 +6,37 @@ type Contributor = {
66
};
77

88
// do not add any real users here
9-
const blacklistedUsernames = ['deepsource-autofix[bot]', 'deepsource-io[bot]', 'renovate[bot]', 'dependabot[bot]'];
9+
const blacklistedUsernames = [
10+
'deepsource-autofix[bot]',
11+
'deepsource-io[bot]',
12+
'renovate[bot]',
13+
'dependabot[bot]',
14+
];
1015

1116
export const CodeContributorList = () => {
1217
const [contributors, setContributors] = useState<Contributor[]>([]);
1318

1419
useEffect(() => {
15-
fetch('./data/contributions.json').then(async (response) => {
20+
fetch('/data/contributions.json').then(async (response) => {
1621
const data = await response.json();
17-
setContributors(data.filter((contributor: Contributor) => !blacklistedUsernames.includes(contributor.login)));
22+
setContributors(
23+
data.filter((contributor: Contributor) => !blacklistedUsernames.includes(contributor.login))
24+
);
1825
});
1926
}, []);
2027

2128
return (
2229
<div className={'flex flex-wrap gap-3'}>
2330
{contributors.map((contributor: Contributor) => (
2431
<div className={'flex flex-col items-center w-24'}>
25-
<img className={'w-24 h-24 aspect-square rounded mb-2'} src={contributor.avatar_url} alt={''} />
26-
<h6 className={"truncate text-nowrap max-w-full"}>{contributor.login}</h6>
32+
<img
33+
className={'w-24 h-24 aspect-square rounded mb-2'}
34+
src={contributor.avatar_url}
35+
alt={''}
36+
/>
37+
<h6 className={'truncate text-nowrap max-w-full'}>{contributor.login}</h6>
2738
</div>
2839
))}
2940
</div>
3041
);
31-
};
42+
};

src/components/pages/about/translations-contributors/translation-constributor-list.tsx

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export const TranslationContributorList = () => {
99
const [contributors, setContributors] = useState<Contributor[]>([]);
1010

1111
useEffect(() => {
12-
fetch('./data/translation-contributions.json').then(async (response) => {
12+
fetch('/data/translation-contributions.json').then(async (response) => {
1313
const data = await response.json();
1414
setContributors(data);
1515
});
@@ -19,10 +19,14 @@ export const TranslationContributorList = () => {
1919
<div className={'flex flex-wrap gap-3'}>
2020
{contributors.map((contributor: Contributor) => (
2121
<div className={'flex flex-col items-center w-24'}>
22-
<img className={'w-24 h-24 aspect-square rounded mb-2'} src={contributor.avatarUrl} alt={''} />
23-
<h6 className={"truncate text-nowrap max-w-full"}>{contributor.username}</h6>
22+
<img
23+
className={'w-24 h-24 aspect-square rounded mb-2'}
24+
src={contributor.avatarUrl}
25+
alt={''}
26+
/>
27+
<h6 className={'truncate text-nowrap max-w-full'}>{contributor.username}</h6>
2428
</div>
2529
))}
2630
</div>
2731
);
28-
};
32+
};

static/data/contributions.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
[{"login":"ajnart","avatar_url":"https://avatars.githubusercontent.com/u/49837342?v=4"},{"login":"manuel-rw","avatar_url":"https://avatars.githubusercontent.com/u/30572287?v=4"},{"login":"Meierschlumpf","avatar_url":"https://avatars.githubusercontent.com/u/63781622?v=4"},{"login":"renovate[bot]","avatar_url":"https://avatars.githubusercontent.com/in/2740?v=4"},{"login":"SeDemal","avatar_url":"https://avatars.githubusercontent.com/u/26098587?v=4"},{"login":"walkxcode","avatar_url":"https://avatars.githubusercontent.com/u/71191962?v=4"},{"login":"LarveyOfficial","avatar_url":"https://avatars.githubusercontent.com/u/39219859?v=4"},{"login":"c00ldude1oo","avatar_url":"https://avatars.githubusercontent.com/u/15677803?v=4"},{"login":"InterN0te","avatar_url":"https://avatars.githubusercontent.com/u/10882916?v=4"},{"login":"Aimsucks","avatar_url":"https://avatars.githubusercontent.com/u/1828486?v=4"},{"login":"JannesV","avatar_url":"https://avatars.githubusercontent.com/u/5984244?v=4"},{"login":"MauriceNino","avatar_url":"https://avatars.githubusercontent.com/u/18658092?v=4"},{"login":"hillaliy","avatar_url":"https://avatars.githubusercontent.com/u/950010?v=4"},{"login":"Skeeww","avatar_url":"https://avatars.githubusercontent.com/u/9639992?v=4"},{"login":"deepsource-autofix[bot]","avatar_url":"https://avatars.githubusercontent.com/in/57168?v=4"},{"login":"RichyHBM","avatar_url":"https://avatars.githubusercontent.com/u/5472275?v=4"},{"login":"Bonfire","avatar_url":"https://avatars.githubusercontent.com/u/5704760?v=4"},{"login":"wieli99","avatar_url":"https://avatars.githubusercontent.com/u/46794825?v=4"},{"login":"ishaanparlikar","avatar_url":"https://avatars.githubusercontent.com/u/43013132?v=4"},{"login":"Zareix","avatar_url":"https://avatars.githubusercontent.com/u/29818713?v=4"},{"login":"tuggan","avatar_url":"https://avatars.githubusercontent.com/u/4325608?v=4"},{"login":"dependabot[bot]","avatar_url":"https://avatars.githubusercontent.com/in/29110?v=4"},{"login":"deepsource-io[bot]","avatar_url":"https://avatars.githubusercontent.com/in/16372?v=4"},{"login":"Spillebulle","avatar_url":"https://avatars.githubusercontent.com/u/46653946?v=4"},{"login":"tancak","avatar_url":"https://avatars.githubusercontent.com/u/11760749?v=4"},{"login":"spkesDE","avatar_url":"https://avatars.githubusercontent.com/u/1682314?v=4"},{"login":"j3lte","avatar_url":"https://avatars.githubusercontent.com/u/2557568?v=4"},{"login":"dslatt","avatar_url":"https://avatars.githubusercontent.com/u/5211001?v=4"},{"login":"Malong11-007","avatar_url":"https://avatars.githubusercontent.com/u/40298510?v=4"},{"login":"Lollyde","avatar_url":"https://avatars.githubusercontent.com/u/11347524?v=4"}]
1+
[{"login":"ajnart","avatar_url":"https://avatars.githubusercontent.com/u/49837342?v=4"},{"login":"manuel-rw","avatar_url":"https://avatars.githubusercontent.com/u/30572287?v=4"},{"login":"Meierschlumpf","avatar_url":"https://avatars.githubusercontent.com/u/63781622?v=4"},{"login":"SeDemal","avatar_url":"https://avatars.githubusercontent.com/u/26098587?v=4"},{"login":"walkxcode","avatar_url":"https://avatars.githubusercontent.com/u/71191962?v=4"},{"login":"LarveyOfficial","avatar_url":"https://avatars.githubusercontent.com/u/39219859?v=4"},{"login":"c00ldude1oo","avatar_url":"https://avatars.githubusercontent.com/u/15677803?v=4"},{"login":"InterN0te","avatar_url":"https://avatars.githubusercontent.com/u/10882916?v=4"},{"login":"Aimsucks","avatar_url":"https://avatars.githubusercontent.com/u/1828486?v=4"},{"login":"JannesV","avatar_url":"https://avatars.githubusercontent.com/u/5984244?v=4"},{"login":"MauriceNino","avatar_url":"https://avatars.githubusercontent.com/u/18658092?v=4"},{"login":"hillaliy","avatar_url":"https://avatars.githubusercontent.com/u/950010?v=4"},{"login":"Skeeww","avatar_url":"https://avatars.githubusercontent.com/u/9639992?v=4"},{"login":"RichyHBM","avatar_url":"https://avatars.githubusercontent.com/u/5472275?v=4"},{"login":"Bonfire","avatar_url":"https://avatars.githubusercontent.com/u/5704760?v=4"},{"login":"wieli99","avatar_url":"https://avatars.githubusercontent.com/u/46794825?v=4"},{"login":"ishaanparlikar","avatar_url":"https://avatars.githubusercontent.com/u/43013132?v=4"},{"login":"Zareix","avatar_url":"https://avatars.githubusercontent.com/u/29818713?v=4"},{"login":"tuggan","avatar_url":"https://avatars.githubusercontent.com/u/4325608?v=4"},{"login":"Spillebulle","avatar_url":"https://avatars.githubusercontent.com/u/46653946?v=4"},{"login":"tancak","avatar_url":"https://avatars.githubusercontent.com/u/11760749?v=4"},{"login":"spkesDE","avatar_url":"https://avatars.githubusercontent.com/u/1682314?v=4"},{"login":"j3lte","avatar_url":"https://avatars.githubusercontent.com/u/2557568?v=4"},{"login":"dslatt","avatar_url":"https://avatars.githubusercontent.com/u/5211001?v=4"},{"login":"Malong11-007","avatar_url":"https://avatars.githubusercontent.com/u/40298510?v=4"},{"login":"MaienM","avatar_url":"https://avatars.githubusercontent.com/u/583129?v=4"},{"login":"toineenzo","avatar_url":"https://avatars.githubusercontent.com/u/4921397?v=4"},{"login":"Lollyde","avatar_url":"https://avatars.githubusercontent.com/u/11347524?v=4"},{"login":"Havock94","avatar_url":"https://avatars.githubusercontent.com/u/7635248?v=4"},{"login":"Lumilias","avatar_url":"https://avatars.githubusercontent.com/u/10852161?v=4"},{"login":"marius-arch","avatar_url":"https://avatars.githubusercontent.com/u/72494359?v=4"},{"login":"Momcilo42","avatar_url":"https://avatars.githubusercontent.com/u/10118137?v=4"},{"login":"stark1tty","avatar_url":"https://avatars.githubusercontent.com/u/69326376?v=4"},{"login":"No-Maines-Land","avatar_url":"https://avatars.githubusercontent.com/u/20687725?v=4"},{"login":"NormanJS","avatar_url":"https://avatars.githubusercontent.com/u/83409549?v=4"},{"login":"Rikpat","avatar_url":"https://avatars.githubusercontent.com/u/33869814?v=4"},{"login":"SR3u","avatar_url":"https://avatars.githubusercontent.com/u/2380522?v=4"},{"login":"souravghosh01","avatar_url":"https://avatars.githubusercontent.com/u/37548139?v=4"},{"login":"StefanB7","avatar_url":"https://avatars.githubusercontent.com/u/22056509?v=4"},{"login":"devtobi","avatar_url":"https://avatars.githubusercontent.com/u/28538704?v=4"},{"login":"TyxTang","avatar_url":"https://avatars.githubusercontent.com/u/90897955?v=4"},{"login":"VinnyVynce","avatar_url":"https://avatars.githubusercontent.com/u/19630511?v=4"},{"login":"Willy-JL","avatar_url":"https://avatars.githubusercontent.com/u/49810075?v=4"},{"login":"anonysoul","avatar_url":"https://avatars.githubusercontent.com/u/105715150?v=4"},{"login":"cospeedster","avatar_url":"https://avatars.githubusercontent.com/u/52749645?v=4"},{"login":"diederbert","avatar_url":"https://avatars.githubusercontent.com/u/162878798?v=4"},{"login":"digdilem","avatar_url":"https://avatars.githubusercontent.com/u/4052275?v=4"},{"login":"dinghino","avatar_url":"https://avatars.githubusercontent.com/u/14729459?v=4"},{"login":"gfomichev","avatar_url":"https://avatars.githubusercontent.com/u/1596146?v=4"},{"login":"gnattu","avatar_url":"https://avatars.githubusercontent.com/u/12995396?v=4"},{"login":"tuxpizza","avatar_url":"https://avatars.githubusercontent.com/u/84710786?v=4"},{"login":"huanga","avatar_url":"https://avatars.githubusercontent.com/u/732970?v=4"},{"login":"taos15","avatar_url":"https://avatars.githubusercontent.com/u/122130728?v=4"},{"login":"arghyadipchak","avatar_url":"https://avatars.githubusercontent.com/u/32430374?v=4"},{"login":"AuthorShin","avatar_url":"https://avatars.githubusercontent.com/u/4959043?v=4"},{"login":"benniblot","avatar_url":"https://avatars.githubusercontent.com/u/47495914?v=4"},{"login":"bebsworthy","avatar_url":"https://avatars.githubusercontent.com/u/5266759?v=4"},{"login":"catrielmuller","avatar_url":"https://avatars.githubusercontent.com/u/2272323?v=4"},{"login":"Vysp3r","avatar_url":"https://avatars.githubusercontent.com/u/62019735?v=4"},{"login":"singular0","avatar_url":"https://avatars.githubusercontent.com/u/1925883?v=4"},{"login":"diogovalentte","avatar_url":"https://avatars.githubusercontent.com/u/49578155?v=4"},{"login":"codezninja","avatar_url":"https://avatars.githubusercontent.com/u/4400773?v=4"},{"login":"fabricionaweb","avatar_url":"https://avatars.githubusercontent.com/u/15933?v=4"},{"login":"nyok1912","avatar_url":"https://avatars.githubusercontent.com/u/32163949?v=4"},{"login":"bo3bdo","avatar_url":"https://avatars.githubusercontent.com/u/5271380?v=4"},{"login":"hskrtich","avatar_url":"https://avatars.githubusercontent.com/u/1214484?v=4"},{"login":"ishults","avatar_url":"https://avatars.githubusercontent.com/u/7275442?v=4"},{"login":"jelliuk","avatar_url":"https://avatars.githubusercontent.com/u/4790959?v=4"},{"login":"Moohan","avatar_url":"https://avatars.githubusercontent.com/u/5982260?v=4"},{"login":"jbruell","avatar_url":"https://avatars.githubusercontent.com/u/31685172?v=4"},{"login":"JasonLeeB06","avatar_url":"https://avatars.githubusercontent.com/u/82266978?v=4"},{"login":"jeffersonraimon","avatar_url":"https://avatars.githubusercontent.com/u/80064475?v=4"},{"login":"joser93","avatar_url":"https://avatars.githubusercontent.com/u/6912089?v=4"},{"login":"justijndepover","avatar_url":"https://avatars.githubusercontent.com/u/9008623?v=4"},{"login":"krishnamuppaneni","avatar_url":"https://avatars.githubusercontent.com/u/4703366?v=4"},{"login":"oben01","avatar_url":"https://avatars.githubusercontent.com/u/22369027?v=4"}]

static/data/translation-contributions.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)