From 805d38d380753b83df047f6a2c68557d4c1af8d6 Mon Sep 17 00:00:00 2001 From: Lucas Arcoverde Date: Fri, 1 Nov 2024 15:19:15 -0300 Subject: [PATCH 01/11] docs(vercel): add github action to generate vercel preview deployments --- .github/workflows/preview.yml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 .github/workflows/preview.yml diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml new file mode 100644 index 000000000..eadf76580 --- /dev/null +++ b/.github/workflows/preview.yml @@ -0,0 +1,26 @@ +name: Vercel Preview Deployment +env: + VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }} + VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }} +on: + push: + branches-ignore: + - main +jobs: + Deploy-Preview: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Pull Vercel Environment Information + run: npx vercel pull --yes --environment=preview --token=${{ secrets.VERCEL_TOKEN }} + + - name: Build Project Artifacts + run: npx vercel build --token=${{ secrets.VERCEL_TOKEN }} + + - name: Deploy Project Artifacts to Vercel + run: npx vercel deploy --prebuilt --token=${{ secrets.VERCEL_TOKEN }} \ + --org-id=${{ secrets.VERCEL_ORG_ID }} --project-id=${{ secrets.VERCEL_PROJECT_ID }} From fa5a52e6d4db02ab9defd7fde60b908c46269c41 Mon Sep 17 00:00:00 2001 From: Lucas Arcoverde Date: Fri, 1 Nov 2024 15:22:08 -0300 Subject: [PATCH 02/11] docs(vercel): add missing steps required on the action --- .github/workflows/preview.yml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index eadf76580..41354f0c7 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -6,6 +6,7 @@ on: push: branches-ignore: - main + jobs: Deploy-Preview: runs-on: ubuntu-latest @@ -13,8 +14,26 @@ jobs: - name: Checkout code uses: actions/checkout@v4 with: + token: ${{ secrets.VTEX_GITHUB_BOT_TOKEN }} fetch-depth: 0 + - name: Setup pnpm + uses: pnpm/action-setup@v4 + with: + version: 9.4.0 + + - name: Setup Node.js environment + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: "pnpm" + + - name: Install dependencies + run: pnpm install + + - name: Build + run: pnpm build + - name: Pull Vercel Environment Information run: npx vercel pull --yes --environment=preview --token=${{ secrets.VERCEL_TOKEN }} From b9b8d6b0f6537bf53488addbbeaedb3d07acc409 Mon Sep 17 00:00:00 2001 From: Lucas Arcoverde Date: Fri, 1 Nov 2024 15:31:24 -0300 Subject: [PATCH 03/11] docs(vercel): fix vercel cli command --- .github/workflows/preview.yml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index 41354f0c7..d374bdc45 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -34,12 +34,15 @@ jobs: - name: Build run: pnpm build + - name: Install Vercel CLI + run: npm install vercel -g + - name: Pull Vercel Environment Information - run: npx vercel pull --yes --environment=preview --token=${{ secrets.VERCEL_TOKEN }} + run: vercel pull --yes --environment=preview --token=${{ secrets.VERCEL_TOKEN }} - name: Build Project Artifacts - run: npx vercel build --token=${{ secrets.VERCEL_TOKEN }} + run: vercel build --token=${{ secrets.VERCEL_TOKEN }} - name: Deploy Project Artifacts to Vercel - run: npx vercel deploy --prebuilt --token=${{ secrets.VERCEL_TOKEN }} \ + run: vercel deploy --prebuilt --token=${{ secrets.VERCEL_TOKEN }} \ --org-id=${{ secrets.VERCEL_ORG_ID }} --project-id=${{ secrets.VERCEL_PROJECT_ID }} From f8eda9aa24df40f1eb8c277f55eca9a6dbf3de96 Mon Sep 17 00:00:00 2001 From: Lucas Arcoverde Date: Fri, 1 Nov 2024 15:48:08 -0300 Subject: [PATCH 04/11] docs(vercel): add missing env variable --- .github/workflows/preview.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index d374bdc45..00d935925 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -1,7 +1,6 @@ name: Vercel Preview Deployment env: - VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }} - VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }} + VTEX_GITHUB_BOT_TOKEN: ${{ secrets.VTEX_GITHUB_BOT_TOKEN }} on: push: branches-ignore: From 02632a5702cb8ff98e6638cce3be0e143d897fc8 Mon Sep 17 00:00:00 2001 From: Lucas Arcoverde Date: Fri, 1 Nov 2024 15:59:55 -0300 Subject: [PATCH 05/11] docs(vercel): add missing env variables --- .github/workflows/preview.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index 00d935925..6328107f9 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -1,5 +1,7 @@ name: Vercel Preview Deployment env: + VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }} + VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }} VTEX_GITHUB_BOT_TOKEN: ${{ secrets.VTEX_GITHUB_BOT_TOKEN }} on: push: @@ -40,7 +42,8 @@ jobs: run: vercel pull --yes --environment=preview --token=${{ secrets.VERCEL_TOKEN }} - name: Build Project Artifacts - run: vercel build --token=${{ secrets.VERCEL_TOKEN }} + run: vercel build --token=${{ secrets.VERCEL_TOKEN }} \ + --org-id=${{ secrets.VERCEL_ORG_ID }} --project-id=${{ secrets.VERCEL_PROJECT_ID }} - name: Deploy Project Artifacts to Vercel run: vercel deploy --prebuilt --token=${{ secrets.VERCEL_TOKEN }} \ From 9ff6c5317f5babed6a2d873f30c171ccd6c724dd Mon Sep 17 00:00:00 2001 From: Lucas Arcoverde Date: Fri, 1 Nov 2024 16:03:02 -0300 Subject: [PATCH 06/11] docs(vercel): fix vercel cli commands --- .github/workflows/preview.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index 6328107f9..5afc9ab4c 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -42,9 +42,7 @@ jobs: run: vercel pull --yes --environment=preview --token=${{ secrets.VERCEL_TOKEN }} - name: Build Project Artifacts - run: vercel build --token=${{ secrets.VERCEL_TOKEN }} \ - --org-id=${{ secrets.VERCEL_ORG_ID }} --project-id=${{ secrets.VERCEL_PROJECT_ID }} + run: vercel build --token=${{ secrets.VERCEL_TOKEN }} - name: Deploy Project Artifacts to Vercel - run: vercel deploy --prebuilt --token=${{ secrets.VERCEL_TOKEN }} \ - --org-id=${{ secrets.VERCEL_ORG_ID }} --project-id=${{ secrets.VERCEL_PROJECT_ID }} + run: vercel deploy --prebuilt --token=${{ secrets.VERCEL_TOKEN }} From 705729c553657b0d790d42dbd5d3eac17a918c74 Mon Sep 17 00:00:00 2001 From: Lucas Arcoverde Date: Fri, 1 Nov 2024 16:08:44 -0300 Subject: [PATCH 07/11] docs(vercel): add env variable log to help debugging --- packages/docs/package.json | 94 ++++++++++++++++++-------------------- 1 file changed, 45 insertions(+), 49 deletions(-) diff --git a/packages/docs/package.json b/packages/docs/package.json index e205d3514..1402901c3 100644 --- a/packages/docs/package.json +++ b/packages/docs/package.json @@ -1,51 +1,47 @@ { - "name": "@shoreline/docs", - "version": "1.0.7", - "private": true, - "type": "module", - "scripts": { - "dev": "npm run gen:examples && npm run gen:props && next dev", - "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", - "gen:contributors": "node ./scripts/build-contributors.mjs" - }, - "devDependencies": { - "@types/fs-extra": "11.0.4", - "@types/node": "20.14.9" - }, - "dependencies": { - "@next/third-parties": "^15.0.0", - "@octokit/graphql": "^8.1.1", - "@sentry/nextjs": "^8.35.0", - "@tanstack/react-table": "8.17.3", - "@vtex/shoreline": "workspace:*", - "@vtex/shoreline-ts-table": "workspace:*", - "@vtex/shoreline-utils": "workspace:*", - "fs-extra": "11.2.0", - "google": "link:@next/third-parties/google", - "next": "^15.0.0", - "nextra": "^3.0.15", - "nextra-theme-docs": "^3.0.15", - "prettier": "^3.3.3", - "react": "^18.3.1", - "react-dom": "^18.3.1", - "react-markdown": "^9.0.1", - "shiki": "^1.22.0", - "swr": "^2.2.5", - "ts-morph": "^24.0.0" - }, - "browserslist": { - "production": [ - ">0.5%", - "not dead", - "not op_mini all" - ], - "development": [ - "last 1 chrome version", - "last 1 firefox version", - "last 1 safari version" - ] - } + "name": "@shoreline/docs", + "version": "1.0.7", + "private": true, + "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", + "start": "next start", + "gen:examples": "node ./scripts/build-examples.mjs", + "gen:props": "node ./scripts/build-props.mjs", + "gen:contributors": "node ./scripts/build-contributors.mjs" + }, + "devDependencies": { + "@types/fs-extra": "11.0.4", + "@types/node": "20.14.9" + }, + "dependencies": { + "@next/third-parties": "^15.0.0", + "@octokit/graphql": "^8.1.1", + "@sentry/nextjs": "^8.35.0", + "@tanstack/react-table": "8.17.3", + "@vtex/shoreline": "workspace:*", + "@vtex/shoreline-ts-table": "workspace:*", + "@vtex/shoreline-utils": "workspace:*", + "fs-extra": "11.2.0", + "google": "link:@next/third-parties/google", + "next": "^15.0.0", + "nextra": "^3.0.15", + "nextra-theme-docs": "^3.0.15", + "prettier": "^3.3.3", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "react-markdown": "^9.0.1", + "shiki": "^1.22.0", + "swr": "^2.2.5", + "ts-morph": "^24.0.0" + }, + "browserslist": { + "production": [">0.5%", "not dead", "not op_mini all"], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] + } } From 250b64db9713174f264774fd696ab16f64c63990 Mon Sep 17 00:00:00 2001 From: Lucas Arcoverde Date: Fri, 1 Nov 2024 16:13:19 -0300 Subject: [PATCH 08/11] docs(vercel): add env variable validation log to help debugging --- packages/docs/package.json | 2 +- packages/docs/scripts/build-contributors.mjs | 588 ++++++++++--------- 2 files changed, 298 insertions(+), 292 deletions(-) diff --git a/packages/docs/package.json b/packages/docs/package.json index 1402901c3..357a89288 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 78044c8e4..9421a117a 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(); From 203885bdc3814f1619e1085bcb382f1656c72f6e Mon Sep 17 00:00:00 2001 From: Lucas Arcoverde Date: Fri, 1 Nov 2024 16:19:51 -0300 Subject: [PATCH 09/11] docs(vercel): fix env variable value --- .github/workflows/preview.yml | 2 +- packages/docs/scripts/build-contributors.mjs | 169 ++++++++++--------- 2 files changed, 89 insertions(+), 82 deletions(-) diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index 5afc9ab4c..f690de2c0 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -2,7 +2,7 @@ name: Vercel Preview Deployment env: VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }} VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }} - VTEX_GITHUB_BOT_TOKEN: ${{ secrets.VTEX_GITHUB_BOT_TOKEN }} + VTEX_GITHUB_BOT_TOKEN: ${{ secrets.DOC_GH_TOKEN }} on: push: branches-ignore: diff --git a/packages/docs/scripts/build-contributors.mjs b/packages/docs/scripts/build-contributors.mjs index 9421a117a..fe6806935 100644 --- a/packages/docs/scripts/build-contributors.mjs +++ b/packages/docs/scripts/build-contributors.mjs @@ -14,9 +14,7 @@ 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!"); -} +console.log(`${!token ? "Invalid" : "Valid"} Github token!`); const graphqlWithAuth = graphql.defaults({ headers: { @@ -329,39 +327,42 @@ async function main() { */ const code = ` export interface Contributor { - username: string - image: string - stats: { - issues: number - pulls: number - reviews: number - comments: number - merged: number - assigns: number - rate: number - } + username: string; + image: string; + stats: { + issues: number; + pulls: number; + reviews: number; + comments: number; + merged: number; + assigns: number; + rate: number; + }; } -export const contributors: Contributor[] = ${JSON.stringify(stats)} +export const contributors: Contributor[] = $ +{ + JSON.stringify(stats); +} export function getContributor(username: string) { return contributors.find((contributor) => contributor.username === username) } const maintainers = [ - 'matheusps', - 'davicostalf', - 'lucasaarcoverde', - 'beatrizmilhomem', -] + "matheusps", + "davicostalf", + "lucasaarcoverde", + "beatrizmilhomem", +]; export function getContributors() { - return contributors.filter( - (contributor) => - !maintainers.includes(contributor.username) && contributor.stats.rate > 0 - ) + return contributors.filter( + (contributor) => + !maintainers.includes(contributor.username) && contributor.stats.rate > 0, + ); } - `; +`; const formattedCode = await format(code, { parser: "typescript", @@ -369,18 +370,24 @@ export function getContributors() { singleQuote: true, }); - fse.outputFile(`${statsOutputDirectory}/stats.ts`, formattedCode, (err) => { - if (err) { - console.log(err); - } else { - console.log("✅ Contributor stats generated"); - } - }); + fse.outputFile(`; +$; +{ + statsOutputDirectory; +} +/ (),,.=>C`aaddeeefmoorrrsssttttt{; + if (err) { + console.log(err); + } else { + console.log("✅ Contributor stats generated"); + } +} +) - /** - * Generate issues stats file - */ - const issuesCode = ` +/** + * Generate issues stats file + */ +const issuesCode = ` interface Author { login: string avatarUrl: string @@ -400,29 +407,29 @@ export interface Issue { export const issuesOnFire: Issue[] = ${JSON.stringify(issuesOnFire)} `; - const formattedIssuesCode = await format(issuesCode, { - parser: "typescript", - semi: false, - singleQuote: true, - }); +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"); - } - }, - ); +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 --- @@ -436,31 +443,31 @@ import { getContributor } from '../../../__contributions__/stats'; `; - return format(mdxCode, { - parser: "mdx", - semi: false, - singleQuote: true, - }); + 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`); - } - }, - ); - } +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() From b9e75d3953515d52d6e73b86ae236e3c796d00fe Mon Sep 17 00:00:00 2001 From: Lucas Arcoverde Date: Fri, 1 Nov 2024 16:24:09 -0300 Subject: [PATCH 10/11] docs(vercel): fix broken build --- packages/docs/scripts/build-contributors.mjs | 167 +++++++++---------- 1 file changed, 79 insertions(+), 88 deletions(-) diff --git a/packages/docs/scripts/build-contributors.mjs b/packages/docs/scripts/build-contributors.mjs index fe6806935..9ebbcd055 100644 --- a/packages/docs/scripts/build-contributors.mjs +++ b/packages/docs/scripts/build-contributors.mjs @@ -11,7 +11,7 @@ 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 token = process.env.VTEX_GITHUB_BOT_TOKEN; const startDate = new Date("2024-01-01T00:00:00Z").toISOString(); console.log(`${!token ? "Invalid" : "Valid"} Github token!`); @@ -327,42 +327,39 @@ async function main() { */ const code = ` export interface Contributor { - username: string; - image: string; - stats: { - issues: number; - pulls: number; - reviews: number; - comments: number; - merged: number; - assigns: number; - rate: number; - }; + username: string + image: string + stats: { + issues: number + pulls: number + reviews: number + comments: number + merged: number + assigns: number + rate: number + } } -export const contributors: Contributor[] = $ -{ - JSON.stringify(stats); -} +export const contributors: Contributor[] = ${JSON.stringify(stats)} export function getContributor(username: string) { return contributors.find((contributor) => contributor.username === username) } const maintainers = [ - "matheusps", - "davicostalf", - "lucasaarcoverde", - "beatrizmilhomem", -]; + 'matheusps', + 'davicostalf', + 'lucasaarcoverde', + 'beatrizmilhomem', +] export function getContributors() { - return contributors.filter( - (contributor) => - !maintainers.includes(contributor.username) && contributor.stats.rate > 0, - ); + return contributors.filter( + (contributor) => + !maintainers.includes(contributor.username) && contributor.stats.rate > 0 + ) } -`; + `; const formattedCode = await format(code, { parser: "typescript", @@ -370,24 +367,18 @@ export function getContributors() { singleQuote: true, }); - fse.outputFile(`; -$; -{ - statsOutputDirectory; -} -/ (),,.=>C`aaddeeefmoorrrsssttttt{; - if (err) { - console.log(err); - } else { - console.log("✅ Contributor stats generated"); - } -} -) + fse.outputFile(`${statsOutputDirectory}/stats.ts`, formattedCode, (err) => { + if (err) { + console.log(err); + } else { + console.log("✅ Contributor stats generated"); + } + }); -/** - * Generate issues stats file - */ -const issuesCode = ` + /** + * Generate issues stats file + */ + const issuesCode = ` interface Author { login: string avatarUrl: string @@ -407,29 +398,29 @@ export interface Issue { export const issuesOnFire: Issue[] = ${JSON.stringify(issuesOnFire)} `; -const formattedIssuesCode = await format(issuesCode, { - parser: "typescript", - semi: false, - singleQuote: true, -}); + 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"); - } - }, -); + 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 --- @@ -443,31 +434,31 @@ import { getContributor } from '../../../__contributions__/stats'; `; - return format(mdxCode, { - parser: "mdx", - semi: false, - singleQuote: true, + 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`); - } - }, - ); -} + 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(); From 857d6a0cef6678dbc79225c7244e4d333f7232f3 Mon Sep 17 00:00:00 2001 From: Lucas Arcoverde Date: Fri, 1 Nov 2024 16:34:33 -0300 Subject: [PATCH 11/11] 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()