diff --git a/packages/docs/package.json b/packages/docs/package.json
index 1402901c35..357a892888 100644
--- a/packages/docs/package.json
+++ b/packages/docs/package.json
@@ -5,7 +5,7 @@
"type": "module",
"scripts": {
"dev": "npm run gen:examples && npm run gen:props && next dev",
- "build-docs": "echo $VTEX_GITHUB_BOT_TOKEN && npm --prefix ../../ run build && npm run gen:contributors && npm run gen:examples && npm run gen:props && next build",
+ "build-docs": "npm --prefix ../../ run build && npm run gen:contributors && npm run gen:examples && npm run gen:props && next build",
"start": "next start",
"gen:examples": "node ./scripts/build-examples.mjs",
"gen:props": "node ./scripts/build-props.mjs",
diff --git a/packages/docs/scripts/build-contributors.mjs b/packages/docs/scripts/build-contributors.mjs
index 78044c8e49..9421a117a8 100644
--- a/packages/docs/scripts/build-contributors.mjs
+++ b/packages/docs/scripts/build-contributors.mjs
@@ -1,34 +1,38 @@
-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();
+
+if (!token) {
+ console.log("Github token invalid!");
+}
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}) {
@@ -63,63 +67,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 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 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,
+ };
}
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) {
@@ -154,174 +158,176 @@ 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 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,
- }
+ 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",
+ );
+
+ 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
@@ -355,26 +361,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
@@ -392,31 +398,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')
- }
- }
- )
-
- /**
- * Generate contributor page files
- */
- const contributorsPromises = contributors.map((contributor) => {
- const mdxCode = `
+ `;
+
+ 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 = `
---
toc: false
---
@@ -428,33 +434,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();