From 857d6a0cef6678dbc79225c7244e4d333f7232f3 Mon Sep 17 00:00:00 2001 From: Lucas Arcoverde Date: Fri, 1 Nov 2024 16:34:33 -0300 Subject: [PATCH] docs(vercel): fix broken build --- packages/docs/scripts/build-contributors.mjs | 597 ++++++++++--------- 1 file changed, 306 insertions(+), 291 deletions(-) diff --git a/packages/docs/scripts/build-contributors.mjs b/packages/docs/scripts/build-contributors.mjs index 9ebbcd055..ea8e96f15 100644 --- a/packages/docs/scripts/build-contributors.mjs +++ b/packages/docs/scripts/build-contributors.mjs @@ -1,36 +1,36 @@ -import { config } from "dotenv"; +import { config } from 'dotenv' -import { graphql } from "@octokit/graphql"; -import path from "node:path"; -import fse from "fs-extra"; -import { format } from "prettier"; +import { graphql } from '@octokit/graphql' +import path from 'node:path' +import fse from 'fs-extra' +import { format } from 'prettier' -config(); +config() -const statsOutputDirectory = `${path.dirname("")}/__contributions__`; -const contributorsOutputDirectory = `${path.dirname("")}/pages/guides/contributor`; -const VTEX_ORG = "vtex"; -const REPO_NAME = "shoreline"; -const token = process.env.VTEX_GITHUB_BOT_TOKEN; -const startDate = new Date("2024-01-01T00:00:00Z").toISOString(); +const statsOutputDirectory = `${path.dirname('')}/__contributions__` +const contributorsOutputDirectory = `${path.dirname('')}/pages/guides/contributor` +const VTEX_ORG = 'vtex' +const REPO_NAME = 'shoreline' +const token = process.env.VTEX_GITHUB_BOT_TOKEN +const startDate = new Date('2024-01-01T00:00:00Z').toISOString() -console.log(`${!token ? "Invalid" : "Valid"} Github token!`); +console.log(`${!token ? 'Invalid' : 'Valid'} Github token!`) const graphqlWithAuth = graphql.defaults({ - headers: { - authorization: `token ${token}`, - }, -}); + headers: { + authorization: `token ${token}`, + }, +}) -const pageSize = 100; +const pageSize = 100 async function fetchAllIssues() { - let hasNextPage = true; - let endCursor = null; - let allIssues = []; + let hasNextPage = true + let endCursor = null + let allIssues = [] - while (hasNextPage) { - const query = ` + while (hasNextPage) { + const query = ` query ($repoOwner: String!, $repoName: String!, $first: Int!, $after: String) { repository(owner: $repoOwner, name: $repoName) { issues(first: $first, after: $after, orderBy: {field: CREATED_AT, direction: DESC}) { @@ -65,63 +65,63 @@ async function fetchAllIssues() { } } } - `; - - try { - const result = await graphqlWithAuth(query, { - repoOwner: VTEX_ORG, - repoName: REPO_NAME, - first: pageSize, - after: endCursor, - }); - - const issuesPage = result.repository.issues; - - allIssues = [...allIssues, ...issuesPage.nodes]; - hasNextPage = issuesPage.pageInfo.hasNextPage; - endCursor = issuesPage.pageInfo.endCursor; - } catch (error) { - console.error("Error fetching issues:", error); - break; - } - } - - return allIssues; + ` + + try { + const result = await graphqlWithAuth(query, { + repoOwner: VTEX_ORG, + repoName: REPO_NAME, + first: pageSize, + after: endCursor, + }) + + const issuesPage = result.repository.issues + + allIssues = [...allIssues, ...issuesPage.nodes] + hasNextPage = issuesPage.pageInfo.hasNextPage + endCursor = issuesPage.pageInfo.endCursor + } catch (error) { + console.error('Error fetching issues:', error) + break + } + } + + return allIssues } function filterIssuesByUser(username, issues = []) { - const issuesCreatedByUser = issues.filter( - (issue) => issue.author.login === username && issue.createdAt >= startDate, - ); + const issuesCreatedByUser = issues.filter( + (issue) => issue.author.login === username && issue.createdAt >= startDate + ) - const issuesAssignedByUser = issues.filter((issue) => { - return ( - issue.createdAt >= startDate && - issue.assignees.nodes.some((assign) => assign.login === username) - ); - }); - - const issuesCommentedByUser = issues.filter((issue) => { - return ( - issue.createdAt >= startDate && - issue.comments.nodes.some((comment) => comment.author.login === username) - ); - }); - - return { - issues: issuesCreatedByUser.length, - assigns: issuesAssignedByUser.length, - comments: issuesCommentedByUser.length, - }; + const issuesAssignedByUser = issues.filter((issue) => { + return ( + issue.createdAt >= startDate && + issue.assignees.nodes.some((assign) => assign.login === username) + ) + }) + + const issuesCommentedByUser = issues.filter((issue) => { + return ( + issue.createdAt >= startDate && + issue.comments.nodes.some((comment) => comment.author.login === username) + ) + }) + + return { + issues: issuesCreatedByUser.length, + assigns: issuesAssignedByUser.length, + comments: issuesCommentedByUser.length, + } } async function fetchAllPullRequests() { - let hasNextPage = true; - let endCursor = null; - let allPullRequests = []; + let hasNextPage = true + let endCursor = null + let allPullRequests = [] - while (hasNextPage) { - const query = ` + while (hasNextPage) { + const query = ` query ($owner: String!, $name: String!, $cursor: String) { repository(owner: $owner, name: $name) { pullRequests(first: 100, after: $cursor) { @@ -156,176 +156,174 @@ async function fetchAllPullRequests() { } } } - `; - - try { - const result = await graphqlWithAuth(query, { - owner: VTEX_ORG, - name: REPO_NAME, - cursor: endCursor, - }); - - const pullRequests = result.repository.pullRequests.nodes; - allPullRequests = [...allPullRequests, ...pullRequests]; - hasNextPage = result.repository.pullRequests.pageInfo.hasNextPage; - endCursor = result.repository.pullRequests.pageInfo.endCursor; - } catch (error) { - console.error("Error fetching pull requests:", error); - break; - } - } - - return allPullRequests; + ` + + try { + const result = await graphqlWithAuth(query, { + owner: VTEX_ORG, + name: REPO_NAME, + cursor: endCursor, + }) + + const pullRequests = result.repository.pullRequests.nodes + allPullRequests = [...allPullRequests, ...pullRequests] + hasNextPage = result.repository.pullRequests.pageInfo.hasNextPage + endCursor = result.repository.pullRequests.pageInfo.endCursor + } catch (error) { + console.error('Error fetching pull requests:', error) + break + } + } + + return allPullRequests } function filterPullsByUser(username, pulls = []) { - const pullsCreatedByUser = pulls.filter( - (pull) => pull.author.login === username && pull.createdAt >= startDate, - ); + const pullsCreatedByUser = pulls.filter( + (pull) => pull.author.login === username && pull.createdAt >= startDate + ) - const pullsReviewedByUser = pulls.filter((pull) => { - return ( - pull.author.login !== username && - pull.createdAt >= startDate && - pull.participants.nodes.some((participant) => { - return participant.login === username; - }) - ); - }); - - const pullsMergedByUser = pullsCreatedByUser.filter( - (pull) => pull.state === "MERGED", - ); + const pullsReviewedByUser = pulls.filter((pull) => { + return ( + pull.author.login !== username && + pull.createdAt >= startDate && + pull.participants.nodes.some((participant) => { + return participant.login === username + }) + ) + }) + + const pullsMergedByUser = pullsCreatedByUser.filter( + (pull) => pull.state === 'MERGED' + ) - return { - pulls: pullsCreatedByUser.length, - reviews: pullsReviewedByUser.length, - merged: pullsMergedByUser.length, - }; + return { + pulls: pullsCreatedByUser.length, + reviews: pullsReviewedByUser.length, + merged: pullsMergedByUser.length, + } } class ContributorsSet { - constructor() { - this.map = {}; - } - - add(contributor) { - if (!contributor || !this.isHumanContributor(contributor)) return; - - if (!this.map[contributor.username]) { - this.map[contributor.username] = contributor; - } - } - - isHumanContributor(contributor) { - const bots = [ - "github-actions", - "changeset-bot", - "vtexgithubbot", - "netlify", - "vercel", - "dependabot", - "renovate", - ]; - return !bots.includes(contributor.username); - } - - toArray() { - return Object.values(this.map); - } + constructor() { + this.map = {} + } + + add(contributor) { + if (!contributor || !this.isHumanContributor(contributor)) return + + if (!this.map[contributor.username]) { + this.map[contributor.username] = contributor + } + } + + isHumanContributor(contributor) { + const bots = [ + 'github-actions', + 'changeset-bot', + 'vtexgithubbot', + 'netlify', + 'vercel', + 'dependabot', + 'renovate', + ] + return !bots.includes(contributor.username) + } + + toArray() { + return Object.values(this.map) + } } function getRepositoryContributors(issues, pulls) { - const contributors = new ContributorsSet(); - - issues.forEach((issue) => { - contributors.add({ - username: issue.author.login, - image: issue.author.avatarUrl, - }); - issue.comments.nodes.forEach((comment) => { - contributors.add({ - username: comment.author.login, - image: comment.author.avatarUrl, - }); - }); - }); - - pulls.forEach((pull) => { - contributors.add({ - username: pull.author.login, - image: pull.author.avatarUrl, - }); - pull.comments.nodes.forEach((comment) => { - contributors.add({ - username: comment.author.login, - image: comment.author.avatarUrl, - }); - }); - }); - - return contributors.toArray(); + const contributors = new ContributorsSet() + + issues.forEach((issue) => { + contributors.add({ + username: issue.author.login, + image: issue.author.avatarUrl, + }) + issue.comments.nodes.forEach((comment) => { + contributors.add({ + username: comment.author.login, + image: comment.author.avatarUrl, + }) + }) + }) + + pulls.forEach((pull) => { + contributors.add({ + username: pull.author.login, + image: pull.author.avatarUrl, + }) + pull.comments.nodes.forEach((comment) => { + contributors.add({ + username: comment.author.login, + image: comment.author.avatarUrl, + }) + }) + }) + + return contributors.toArray() } function getContributorStats(username, issues, pulls) { - const issuesStats = filterIssuesByUser(username, issues); - const pullsStats = filterPullsByUser(username, pulls); - - const rate = - (issuesStats.issues + - issuesStats.assigns + - issuesStats.comments + - pullsStats.pulls + - pullsStats.reviews + - pullsStats.merged) / - 6; - - return { ...issuesStats, ...pullsStats, rate }; + const issuesStats = filterIssuesByUser(username, issues) + const pullsStats = filterPullsByUser(username, pulls) + + const rate = + (issuesStats.issues + + issuesStats.assigns + + issuesStats.comments + + pullsStats.pulls + + pullsStats.reviews + + pullsStats.merged) / + 6 + + return { ...issuesStats, ...pullsStats, rate } } function getIssuesOnFire(issues) { - issues.sort((a, b) => b.comments.nodes.length - a.comments.nodes.length); + issues.sort((a, b) => b.comments.nodes.length - a.comments.nodes.length) - const openedIssues = issues.filter((issue) => issue.state === "OPEN"); + const openedIssues = issues.filter((issue) => issue.state === 'OPEN') - openedIssues.sort( - (a, b) => b.comments.nodes.length - a.comments.nodes.length, - ); + openedIssues.sort((a, b) => b.comments.nodes.length - a.comments.nodes.length) - const issuesOnFire = openedIssues.slice(0, 4); + const issuesOnFire = openedIssues.slice(0, 4) - return issuesOnFire; + return issuesOnFire } async function main() { - if (!token) { - console.log("⚠️ Missing Github token"); - console.log( - "To run this script locally you must create a .env file with the VTEX_GITHUB_BOT_TOKEN which gives access to the public_repo scope", - ); - return; - } - - const pulls = await fetchAllPullRequests(); - const issues = await fetchAllIssues(); - - const contributors = getRepositoryContributors(issues, pulls); - const issuesOnFire = getIssuesOnFire(issues); - const stats = contributors.map((contributor) => { - const stats = getContributorStats(contributor.username, issues, pulls); - - return { - ...contributor, - stats, - }; - }); - - stats.sort((a, b) => b.stats.rate - a.stats.rate); - - /** - * Generate contributors stats file - */ - const code = ` + if (!token) { + console.log('⚠️ Missing Github token') + console.log( + 'To run this script locally you must create a .env file with the VTEX_GITHUB_BOT_TOKEN which gives access to the public_repo scope' + ) + return + } + + const pulls = await fetchAllPullRequests() + const issues = await fetchAllIssues() + + const contributors = getRepositoryContributors(issues, pulls) + const issuesOnFire = getIssuesOnFire(issues) + const stats = contributors.map((contributor) => { + const stats = getContributorStats(contributor.username, issues, pulls) + + return { + ...contributor, + stats, + } + }) + + stats.sort((a, b) => b.stats.rate - a.stats.rate) + + /** + * Generate contributors stats file + */ + const code = ` export interface Contributor { username: string image: string @@ -343,7 +341,24 @@ export interface Contributor { export const contributors: Contributor[] = ${JSON.stringify(stats)} export function getContributor(username: string) { - return contributors.find((contributor) => contributor.username === username) + const emptyContributor = { + username: "", + image: "", + stats: { + issues: 0, + assigns: 0, + comments: 0, + pulls: 0, + reviews: 0, + merged: 0, + rate: 0, + }, + }; + + return ( + contributors.find((contributor) => contributor.username === username) ?? + emptyContributor + ); } const maintainers = [ @@ -359,26 +374,26 @@ export function getContributors() { !maintainers.includes(contributor.username) && contributor.stats.rate > 0 ) } - `; - - const formattedCode = await format(code, { - parser: "typescript", - semi: false, - singleQuote: true, - }); - - fse.outputFile(`${statsOutputDirectory}/stats.ts`, formattedCode, (err) => { - if (err) { - console.log(err); - } else { - console.log("✅ Contributor stats generated"); - } - }); - - /** - * Generate issues stats file - */ - const issuesCode = ` + ` + + const formattedCode = await format(code, { + parser: 'typescript', + semi: false, + singleQuote: true, + }) + + fse.outputFile(`${statsOutputDirectory}/stats.ts`, formattedCode, (err) => { + if (err) { + console.log(err) + } else { + console.log('✅ Contributor stats generated') + } + }) + + /** + * Generate issues stats file + */ + const issuesCode = ` interface Author { login: string avatarUrl: string @@ -396,31 +411,31 @@ export interface Issue { } export const issuesOnFire: Issue[] = ${JSON.stringify(issuesOnFire)} - `; - - const formattedIssuesCode = await format(issuesCode, { - parser: "typescript", - semi: false, - singleQuote: true, - }); - - fse.outputFile( - `${statsOutputDirectory}/issues.ts`, - formattedIssuesCode, - (err) => { - if (err) { - console.log(err); - } else { - console.log("✅ Issues on fire generated"); - } - }, - ); + ` + + const formattedIssuesCode = await format(issuesCode, { + parser: 'typescript', + semi: false, + singleQuote: true, + }) + + fse.outputFile( + `${statsOutputDirectory}/issues.ts`, + formattedIssuesCode, + (err) => { + if (err) { + console.log(err) + } else { + console.log('✅ Issues on fire generated') + } + } + ) - /** - * Generate contributor page files - */ - const contributorsPromises = contributors.map((contributor) => { - const mdxCode = ` + /** + * Generate contributor page files + */ + const contributorsPromises = contributors.map((contributor) => { + const mdxCode = ` --- toc: false --- @@ -432,33 +447,33 @@ import { getContributor } from '../../../__contributions__/stats';
- `; - - return format(mdxCode, { - parser: "mdx", - semi: false, - singleQuote: true, - }); - }); - - const contributorsMDX = await Promise.all(contributorsPromises); - - for (const i in contributors) { - const contributor = contributors[i]; - const contributorMDX = contributorsMDX[i]; - - fse.outputFile( - `${contributorsOutputDirectory}/${contributor.username}.mdx`, - contributorMDX, - (err) => { - if (err) { - console.log(err); - } else { - console.log(`✅ ${contributor.username} page generated`); - } - }, - ); - } + ` + + return format(mdxCode, { + parser: 'mdx', + semi: false, + singleQuote: true, + }) + }) + + const contributorsMDX = await Promise.all(contributorsPromises) + + for (const i in contributors) { + const contributor = contributors[i] + const contributorMDX = contributorsMDX[i] + + fse.outputFile( + `${contributorsOutputDirectory}/${contributor.username}.mdx`, + contributorMDX, + (err) => { + if (err) { + console.log(err) + } else { + console.log(`✅ ${contributor.username} page generated`) + } + } + ) + } } -main(); +main()