Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: fetch all organization contributors for home page #223

Merged
merged 1 commit into from
Jul 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ jobs:
verify_files:
name: Verify Files
runs-on: ubuntu-latest
env:
GITHUB_TOKEN: ${{ github.token }}
steps:
- name: Checkout
uses: actions/checkout@v3
Expand All @@ -22,6 +24,8 @@ jobs:
run: npm ci
- name: Shape libs-data.json
run: npm run fetch-data
- name: Shape contributors.json
run: npm run fetch-contributors
- name: Shape packages-versions.json
run: npm run get-packages-versions
- name: Lint Files
Expand Down
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ npm-debug.log*
yarn-debug.log*
yarn-error.log*

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

.env
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,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
2 changes: 1 addition & 1 deletion scripts/get-packages-versions.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const packagesMap = {
const packageJsonPath = path.join(path.dirname(fileURLToPath(import.meta.url)), '../package.json');
const packagesVersionsPath = path.join(
path.dirname(fileURLToPath(import.meta.url)),
'../src/packages-versions.json',
'../src/data/packages-versions.json',
);

const getPackagesVersions = () => {
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/data',
CONTRIB_FILENAME,
);

const readLibsData = async () => {
const libsDataPath = path.resolve(
path.dirname(fileURLToPath(import.meta.url)),
'../src/data',
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);
});
2 changes: 1 addition & 1 deletion scripts/prefetch-data.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ dotenv.config();

const libsFetchedData = path.join(
path.dirname(fileURLToPath(import.meta.url)),
'../src/libs-data.json',
'../src/data/libs-data.json',
);

const fetchNpmInfo = () => {
Expand Down
2 changes: 1 addition & 1 deletion src/content/components/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {TARGET_PROFILE} from '../../constants';
import packagesVersions from '../../packages-versions.json';
import packagesVersions from '../../data/packages-versions.json';
import {Repos} from '../../types/common';

const githubTargetProfile = process.env.GITHUB_PROFILE || TARGET_PROFILE;
Expand Down
Empty file added src/data/.gitkeep
Empty file.
25 changes: 4 additions & 21 deletions src/utils/lib.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import _ from 'lodash';
import mm from 'micromatch';

import libsData from '../libs-data.json';
import allContributors from '../data/contributors.json';
import libsData from '../data/libs-data.json';
import packagesVersions from '../data/packages-versions.json';
import {libs} from '../libs.mjs';
import packagesVersions from '../packages-versions.json';

type LibConfig = {
id: string;
Expand All @@ -20,7 +21,7 @@
};

export type Contributor = {
[x: string]: any;

Check warning on line 24 in src/utils/lib.ts

View workflow job for this annotation

GitHub Actions / Verify Files

Unexpected any. Specify a different type
login: string;
url: string;
avatarUrl: string;
Expand Down Expand Up @@ -53,7 +54,7 @@
const result: Lib[] = [];

libs.forEach((config) => {
const data = (libsData as any)[config.id];

Check warning on line 57 in src/utils/lib.ts

View workflow job for this annotation

GitHub Actions / Verify Files

Unexpected any. Specify a different type

if (!data) {
throw new Error(`Can't find fetched data for lib with id – ${config.id}`);
Expand All @@ -75,7 +76,7 @@
throw new Error(`Can't find config for lib with id – ${id}`);
}

const data = (libsData as any)[id];

Check warning on line 79 in src/utils/lib.ts

View workflow job for this annotation

GitHub Actions / Verify Files

Unexpected any. Specify a different type

if (!data) {
throw new Error(`Can't find fetched data for lib with id – ${id}`);
Expand All @@ -95,7 +96,7 @@
}

try {
libraryVersion = (packagesVersions as any)[id];

Check warning on line 99 in src/utils/lib.ts

View workflow job for this annotation

GitHub Actions / Verify Files

Unexpected any. Specify a different type
} catch {
libraryVersion = undefined;
}
Expand All @@ -106,25 +107,7 @@
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 All @@ -144,7 +127,7 @@
const maintainer = contributors.find((contributor) => contributor.login === owner);

if (!maintainer) {
console.warn(`code owner ${owner} is not a contributor`);

Check warning on line 130 in src/utils/lib.ts

View workflow job for this annotation

GitHub Actions / Verify Files

Unexpected console statement

return {
login: owner,
Expand Down
Loading