Skip to content

Commit

Permalink
feat: fetch github stats json
Browse files Browse the repository at this point in the history
  • Loading branch information
SukkaW committed Jan 14, 2025
1 parent da01c7a commit 768c76b
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 9 deletions.
9 changes: 4 additions & 5 deletions .github/workflows/update.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,20 @@ jobs:
contents: write

steps:
- name: Checkout
uses: actions/checkout@v4
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: pnpm/action-setup@v4
name: Install pnpm
with:
run_install: false
- name: Use Node.js
uses: actions/setup-node@v4
- uses: actions/setup-node@v4
with:
node-version-file: '.node-version'
cache: 'pnpm'
- run: pnpm i
- run: pnpm run download
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Deploy
uses: peaceiris/actions-gh-pages@v3
with:
Expand Down
112 changes: 112 additions & 0 deletions github-stats-json.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
// query userInfo($login: String!) {
// user(login: $login) {
// name
// login
// contributionsCollection {
// restrictedContributionsCount
// }
// repositoriesContributedTo(first: 1, contributionTypes: [COMMIT, ISSUE, PULL_REQUEST, REPOSITORY]) {
// totalCount
// }
// pullRequests(first: 1) {
// totalCount
// }
// openIssues: issues(states: OPEN) {
// totalCount
// }
// closedIssues: issues(states: CLOSED) {
// totalCount
// }
// followers {
// totalCount
// }
// repositories(first: 100, ownerAffiliations: OWNER, orderBy: {direction: DESC, field: STARGAZERS}) {
// totalCount
// nodes {
// stargazers {
// totalCount
// }
// forks {
// totalCount
// }
// }
// }
// }
// }

function fetcher(ghPAT: string) {
return fetch(
'https://api.github.com/graphql',
{
method: 'POST',
headers: {
Authorization: `Bearer ${ghPAT}`,
'User-Agent': 'Sukka API - Fetch My GitHub User Info'
},
body: JSON.stringify({
variables: {
login: 'sukkaw'
},
query: 'query userInfo($login:String!){user(login:$login){name login contributionsCollection{restrictedContributionsCount}repositoriesContributedTo(first:1,contributionTypes:[COMMIT,ISSUE,PULL_REQUEST,REPOSITORY]){totalCount}pullRequests(first:1){totalCount}openIssues:issues(states:OPEN){totalCount}closedIssues:issues(states:CLOSED){totalCount}followers{totalCount}repositories(first:100,ownerAffiliations:OWNER,orderBy:{direction:DESC,field:STARGAZERS}){totalCount nodes{stargazers{totalCount}forks{totalCount}}}}}'
})
}
);
}

function fetcherTotalCommit(ghPAT: string) {
return fetch('https://api.github.com/search/commits?q=author:sukkaw', {
headers: {
Accept: 'application/vnd.github.cloak-preview',
'User-Agent': 'Sukka API - Fetch My GitHub User Info',
Authorization: `Bearer ${ghPAT}`
}
});
}

export async function githubSukka(ghPAT: string) {
const stats = {
totalPRs: 'N/A',
followers: 'N/A',
totalCommits: 'N/A',
totalIssues: 'N/A',
totalStars: 'N/A',
totalForks: 'N/A',
contributedTo: 'N/A'
};

const [statDataResp, totalCommitData] = await Promise.all([
fetcher(ghPAT).then((res) => {
if (res.ok) return res.json();
return null;
}),
fetcherTotalCommit(ghPAT).then((res) => {
if (res.ok) return res.json();
return null;
})
]);

try {
if (statDataResp) {
const statData = (statDataResp).data.user;
stats.totalIssues = statData.openIssues.totalCount + statData.closedIssues.totalCount;
stats.followers = statData.followers.totalCount;
stats.totalPRs = statData.pullRequests.totalCount;
stats.contributedTo = statData.repositoriesContributedTo.totalCount;
stats.totalStars = statData.repositories.nodes.reduce((prev: number, curr: any) => prev + curr.stargazers.totalCount, 0);
stats.totalForks = statData.repositories.nodes.reduce((prev: number, curr: any) => prev + curr.forks.totalCount, 0);
if (totalCommitData) {
stats.totalCommits = (totalCommitData).total_count + statData.contributionsCollection.restrictedContributionsCount;
}
}
} catch (e) {
console.log(e);
}

return stats;
// return new Response(JSON.stringify(stats), {
// headers: {
// 'access-control-allow-origin': '*',
// 'cache-control': 'public, max-age=28800, stale-while-revalidate=3600, stale-if-error=3600'
// }
// });
};
8 changes: 7 additions & 1 deletion index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import fs from 'fs';
import retry from 'async-retry';
import path from 'path';
import { githubSukka } from './github-stats-json';
import { nullthrow } from 'foxts/guard';

const baseUrl = new URL('https://github-readme-stats.vercel.app/api');
baseUrl.searchParams.set('username', 'sukkaw');
Expand Down Expand Up @@ -43,12 +45,16 @@ const publicDir = path.resolve(__dirname, 'public');

(async () => {
try {
const pat = nullthrow(process.env.GITHUB_TOKEN);
const githubStats = await retry(() => githubSukka(pat), { retries: 10 });

fs.writeFileSync(path.resolve(publicDir, 'github-stats.json'), JSON.stringify(githubStats));

const [light, dark] = await Promise.all([
retry(() => fetchSvg(lightUrl), { retries: 10 }),
retry(() => fetchSvg(darkUrl), { retries: 10 })
]);


fs.writeFileSync(path.resolve(publicDir, 'light.svg'), light);
fs.writeFileSync(path.resolve(publicDir, 'dark.svg'), dark);
} catch (e) {
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
},
"author": "",
"dependencies": {
"async-retry": "^1.3.3"
"async-retry": "^1.3.3",
"foxts": "^1.1.5"
},
"devDependencies": {
"@eslint-sukka/node": "^6.1.6",
Expand Down
8 changes: 8 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,18 @@
"moduleDetection": "force",
"module": "esnext",
"moduleResolution": "bundler",
"esModuleInterop": true,
"allowImportingTsExtensions": true,
"allowJs": true,
"noEmit": true,
"downlevelIteration": true,
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true
},
"include": [
"./index.ts"
"./index.ts",
"./github-stats-json.ts"
]
}

0 comments on commit 768c76b

Please sign in to comment.