Skip to content

Commit

Permalink
feat: fetch all organization contributors for home page
Browse files Browse the repository at this point in the history
  • Loading branch information
Aleksandr Burobin committed Jun 28, 2024
1 parent 8ac022f commit d59e1ea
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 21 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,6 @@ yarn-error.log*

/src/libs-data.json
/src/packages-versions.json
/src/contributors.json

.env
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,9 @@
"start": "next dev",
"build": "next build",
"fetch-data": "node ./scripts/prefetch-data.mjs",
"fetch-contributors": "node ./scripts/prefetch-contributors.mjs",
"get-packages-versions": "node ./scripts/get-packages-versions.mjs",
"prepare-metadata": "npm run fetch-data && npm run get-packages-versions",
"prepare-metadata": "npm run fetch-data && npm run fetch-contributors && npm run get-packages-versions",
"prestart": "npm run prepare-metadata",
"prebuild": "npm run prepare-metadata",
"pretest": "npm run prepare-metadata",
Expand Down
13 changes: 12 additions & 1 deletion scripts/github.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import {Octokit} from '@octokit/rest';

const octokit = new Octokit();
const octokit = new Octokit({
auth: process.env.GITHUB_TOKEN,
});

const CONTRIBUTOR_IGNORE_LIST = ['dependabot', 'dependabot[bot]', 'gravity-ui-bot', 'yc-ui-bot'];

Expand All @@ -29,6 +31,15 @@ export async function getRepositoryContributors(repoOwner, repo) {
return contributors;
}

export async function getOrganizationRepositories(org) {
return await octokit.paginate('GET /orgs/{org}/repos', {
org,
headers: {
'X-GitHub-Api-Version': '2022-11-28',
},
});
}

export async function fetchRepositoryCodeOwners(repoOwner, repo) {
const url = `https://raw.githubusercontent.com/${repoOwner}/${repo}/main/CODEOWNERS`;
const res = await fetch(url);
Expand Down
83 changes: 83 additions & 0 deletions scripts/prefetch-contributors.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/**
* This script is used to prefetch all organization contributors.
*/

import fs from 'node:fs';
import path from 'node:path';
import {fileURLToPath} from 'node:url';

import * as dotenv from 'dotenv';

import {getOrganizationRepositories, getRepositoryContributors} from './github.mjs';

dotenv.config();

const LIBS_DATA_FILENAME = 'libs-data.json';
const CONTRIB_FILENAME = 'contributors.json';

const contribDataPath = path.resolve(
path.dirname(fileURLToPath(import.meta.url)),
'../src',
CONTRIB_FILENAME,
);

const readLibsData = async () => {
const libsDataPath = path.resolve(
path.dirname(fileURLToPath(import.meta.url)),
'../src',
LIBS_DATA_FILENAME,
);

const libsDataContent = await fs.promises.readFile(libsDataPath, 'utf-8');
return JSON.parse(libsDataContent);
};

const start = async () => {
if (fs.existsSync(contribDataPath) && !process.env.GITHUB_TOKEN) {
console.error(
`The ${CONTRIB_FILENAME} file exists. You can delete it manually for refetch.
Learn more about the limitations of the GitHub API...
https://docs.github.com/ru/rest/overview/resources-in-the-rest-api?apiVersion=2022-11-28#rate-limiting`,
);

return;
}

const libsData = await readLibsData();
const repos = await getOrganizationRepositories('gravity-ui');

const rawContributors = await Promise.all(
repos.map(async (repo) => {
if (libsData[repo.name]) {
return libsData[repo.name].contributors;
}

return await getRepositoryContributors(repo.owner.login, repo.name);
}),
);

const contributors = {};

for (const list of rawContributors) {
for (const contributor of list) {
const {login, contributions} = contributor;

if (contributors[login]) {
contributors[login].contributions += contributions;
} else {
contributors[login] = contributor;
}
}
}

const sortedContributors = Object.values(contributors).sort(
(a, b) => b.contributions - a.contributions,
);

fs.writeFileSync(contribDataPath, JSON.stringify(sortedContributors, null, 4), 'utf8');
};

start().catch((err) => {
console.error(err.message);
process.exit(1);
});
21 changes: 2 additions & 19 deletions src/utils/lib.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import _ from 'lodash';
import mm from 'micromatch';

import allContributors from '../contributors.json';
import libsData from '../libs-data.json';
import {libs} from '../libs.mjs';
import packagesVersions from '../packages-versions.json';
Expand Down Expand Up @@ -106,25 +107,7 @@ export const getLibVersion = (id?: string) => {
export const getLibraryGithubUrl = (library: Lib) =>
`https://github.com/${library.config.githubId}`;

export const getAllContributors = () => {
const libraries = getLibsList();

const contributors: Record<string, Contributor> = {};

for (const {data} of libraries) {
for (const contributor of data.contributors) {
const {login, contributions} = contributor;

if (contributors[login]) {
contributors[login].contributions += contributions;
} else {
contributors[login] = contributor;
}
}
}

return Object.values(contributors).sort((a, b) => b.contributions - a.contributions);
};
export const getAllContributors = () => allContributors;

export const getMaintainers = (lib: Lib, path = '/'): Contributor[] => {
const {contributors, codeOwners} = lib.data;
Expand Down

0 comments on commit d59e1ea

Please sign in to comment.