Merge branch 'next'

This commit is contained in:
martin-mfg
2026-01-19 23:15:39 +01:00
12 changed files with 204 additions and 80 deletions
+1 -1
View File
@@ -13,7 +13,7 @@ jobs:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Deployment Prep
run: python ./.github/workflows/deploy-prep.py
- uses: stefanzweifel/git-auto-commit-action@28e16e81777b558cc906c8750092100bbb34c5e3 # v7.0.0
- uses: stefanzweifel/git-auto-commit-action@04702edda442b2e678b25b537cec683a1493fcb9 # v7.1.0
with:
branch: vercel
create_branch: true
+1 -1
View File
@@ -25,7 +25,7 @@ jobs:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Setup Node
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version: ${{ matrix.node-version }}
cache: npm
+2 -1
View File
@@ -3,6 +3,7 @@ on:
push:
branches:
- master
- next
paths:
- "themes/index.js"
workflow_dispatch:
@@ -33,7 +34,7 @@ jobs:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Setup Node
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version: ${{ matrix.node-version }}
cache: npm
+1 -1
View File
@@ -36,7 +36,7 @@ jobs:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Setup Node
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version: ${{ matrix.node-version }}
cache: npm
+1 -1
View File
@@ -42,7 +42,7 @@ jobs:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Setup Node
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version: ${{ matrix.node-version }}
cache: npm
+3 -1
View File
@@ -3,9 +3,11 @@ on:
push:
branches:
- master
- next
pull_request:
branches:
- master
- next
permissions: read-all
@@ -21,7 +23,7 @@ jobs:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Setup Node
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version: ${{ matrix.node-version }}
cache: npm
+4 -2
View File
@@ -28,7 +28,9 @@ permissions:
jobs:
updateLanguages:
if: github.repository == 'anuraghazra/github-readme-stats'
if:
github.repository == 'anuraghazra/github-readme-stats' ||
github.repository == 'stats-organization/github-readme-stats'
name: Update supported languages
runs-on: ubuntu-latest
strategy:
@@ -39,7 +41,7 @@ jobs:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Setup Node
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version: ${{ matrix.node-version }}
cache: npm
+105 -59
View File
@@ -28,9 +28,9 @@
"color-contrast-checker": "^2.1.0",
"eslint": "^9.39.2",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-jsdoc": "^61.5.0",
"eslint-plugin-jsdoc": "^62.0.1",
"express": "^5.2.1",
"globals": "^16.5.0",
"globals": "^17.0.0",
"hjson": "^3.2.2",
"husky": "^9.1.7",
"jest": "^30.2.0",
@@ -39,7 +39,7 @@
"lint-staged": "^16.2.7",
"lodash.snakecase": "^4.1.1",
"parse-diff": "^0.11.1",
"prettier": "^3.7.3"
"prettier": "^3.8.0"
},
"engines": {
"node": "24.x"
@@ -755,19 +755,19 @@
}
},
"node_modules/@es-joy/jsdoccomment": {
"version": "0.76.0",
"resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.76.0.tgz",
"integrity": "sha512-g+RihtzFgGTx2WYCuTHbdOXJeAlGnROws0TeALx9ow/ZmOROOZkVg5wp/B44n0WJgI4SQFP1eWM2iRPlU2Y14w==",
"version": "0.79.0",
"resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.79.0.tgz",
"integrity": "sha512-q/Nc241VsVRC5b1dgbsOI0fnWfrb1S9sdceFewpDHto4+4r2o6SSCpcY+Z+EdLdMPN6Nsj/PjlPcKag6WbU6XQ==",
"dev": true,
"dependencies": {
"@types/estree": "^1.0.8",
"@typescript-eslint/types": "^8.46.0",
"@typescript-eslint/types": "^8.52.0",
"comment-parser": "1.4.1",
"esquery": "^1.6.0",
"jsdoc-type-pratt-parser": "~6.10.0"
"esquery": "^1.7.0",
"jsdoc-type-pratt-parser": "~7.0.0"
},
"engines": {
"node": ">=20.11.0"
"node": "^20.19.0 || ^22.13.0 || >=24"
}
},
"node_modules/@es-joy/resolve.exports": {
@@ -1900,9 +1900,9 @@
"dev": true
},
"node_modules/@typescript-eslint/types": {
"version": "8.46.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.46.1.tgz",
"integrity": "sha512-C+soprGBHwWBdkDpbaRC4paGBrkIXxVlNohadL5o0kfhsXqOC6GYH2S/Obmig+I0HTDl8wMaRySwrfrXVP8/pQ==",
"version": "8.53.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.53.0.tgz",
"integrity": "sha512-Bmh9KX31Vlxa13+PqPvt4RzKRN1XORYSLlAE+sO1i28NkisGbTtSLFVB3l7PWdHtR3E0mVMuC7JilWJ99m2HxQ==",
"dev": true,
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -3342,19 +3342,19 @@
}
},
"node_modules/eslint-plugin-jsdoc": {
"version": "61.5.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-61.5.0.tgz",
"integrity": "sha512-PR81eOGq4S7diVnV9xzFSBE4CDENRQGP0Lckkek8AdHtbj+6Bm0cItwlFnxsLFriJHspiE3mpu8U20eODyToIg==",
"version": "62.0.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-62.0.1.tgz",
"integrity": "sha512-TNeqgrE+xjDGCZVlRIiQcnUWNoMlHE5+oIyGbVFbrdIPOkz5ecWAmB26xSgqm2Mz7wny/ztyqCOUOeJhGrElpA==",
"dev": true,
"dependencies": {
"@es-joy/jsdoccomment": "~0.76.0",
"@es-joy/jsdoccomment": "~0.79.0",
"@es-joy/resolve.exports": "1.2.0",
"are-docs-informative": "^0.0.2",
"comment-parser": "1.4.1",
"debug": "^4.4.3",
"escape-string-regexp": "^4.0.0",
"espree": "^10.4.0",
"esquery": "^1.6.0",
"espree": "^11.0.0",
"esquery": "^1.7.0",
"html-entities": "^2.6.0",
"object-deep-merge": "^2.0.0",
"parse-imports-exports": "^0.2.4",
@@ -3363,7 +3363,7 @@
"to-valid-identifier": "^1.0.0"
},
"engines": {
"node": ">=20.11.0"
"node": "^20.19.0 || ^22.13.0 || >=24"
},
"peerDependencies": {
"eslint": "^7.0.0 || ^8.0.0 || ^9.0.0"
@@ -3381,6 +3381,35 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/eslint-plugin-jsdoc/node_modules/eslint-visitor-keys": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.0.tgz",
"integrity": "sha512-A0XeIi7CXU7nPlfHS9loMYEKxUaONu/hTEzHTGba9Huu94Cq1hPivf+DE5erJozZOky0LfvXAyrV/tcswpLI0Q==",
"dev": true,
"engines": {
"node": "^20.19.0 || ^22.13.0 || >=24"
},
"funding": {
"url": "https://opencollective.com/eslint"
}
},
"node_modules/eslint-plugin-jsdoc/node_modules/espree": {
"version": "11.0.0",
"resolved": "https://registry.npmjs.org/espree/-/espree-11.0.0.tgz",
"integrity": "sha512-+gMeWRrIh/NsG+3NaLeWHuyeyk70p2tbvZIWBYcqQ4/7Xvars6GYTZNhF1sIeLcc6Wb11He5ffz3hsHyXFrw5A==",
"dev": true,
"dependencies": {
"acorn": "^8.15.0",
"acorn-jsx": "^5.3.2",
"eslint-visitor-keys": "^5.0.0"
},
"engines": {
"node": "^20.19.0 || ^22.13.0 || >=24"
},
"funding": {
"url": "https://opencollective.com/eslint"
}
},
"node_modules/eslint-plugin-jsdoc/node_modules/semver": {
"version": "7.7.3",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
@@ -3555,9 +3584,9 @@
}
},
"node_modules/esquery": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz",
"integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz",
"integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==",
"dev": true,
"dependencies": {
"estraverse": "^5.1.0"
@@ -4082,9 +4111,9 @@
}
},
"node_modules/globals": {
"version": "16.5.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-16.5.0.tgz",
"integrity": "sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==",
"version": "17.0.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-17.0.0.tgz",
"integrity": "sha512-gv5BeD2EssA793rlFWVPMMCqefTlpusw6/2TbAVMy0FzcG8wKJn4O+NqJ4+XWmmwrayJgw5TzrmWjFgmz1XPqw==",
"dev": true,
"engines": {
"node": ">=18"
@@ -5487,9 +5516,9 @@
}
},
"node_modules/jsdoc-type-pratt-parser": {
"version": "6.10.0",
"resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-6.10.0.tgz",
"integrity": "sha512-+LexoTRyYui5iOhJGn13N9ZazL23nAHGkXsa1p/C8yeq79WRfLBag6ZZ0FQG2aRoc9yfo59JT9EYCQonOkHKkQ==",
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-7.0.0.tgz",
"integrity": "sha512-c7YbokssPOSHmqTbSAmTtnVgAVa/7lumWNYqomgd5KOMyPrRve2anx6lonfOsXEQacqF9FKVUj7bLg4vRSvdYA==",
"dev": true,
"engines": {
"node": ">=20.0.0"
@@ -6528,9 +6557,9 @@
}
},
"node_modules/prettier": {
"version": "3.7.4",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.7.4.tgz",
"integrity": "sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA==",
"version": "3.8.0",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.0.tgz",
"integrity": "sha512-yEPsovQfpxYfgWNhCfECjG5AQaO+K3dp6XERmOepyPDVqcJm+bjyCVO3pmU+nAPe0N5dDvekfGezt/EIiRe1TA==",
"dev": true,
"bin": {
"prettier": "bin/prettier.cjs"
@@ -8505,16 +8534,16 @@
}
},
"@es-joy/jsdoccomment": {
"version": "0.76.0",
"resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.76.0.tgz",
"integrity": "sha512-g+RihtzFgGTx2WYCuTHbdOXJeAlGnROws0TeALx9ow/ZmOROOZkVg5wp/B44n0WJgI4SQFP1eWM2iRPlU2Y14w==",
"version": "0.79.0",
"resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.79.0.tgz",
"integrity": "sha512-q/Nc241VsVRC5b1dgbsOI0fnWfrb1S9sdceFewpDHto4+4r2o6SSCpcY+Z+EdLdMPN6Nsj/PjlPcKag6WbU6XQ==",
"dev": true,
"requires": {
"@types/estree": "^1.0.8",
"@typescript-eslint/types": "^8.46.0",
"@typescript-eslint/types": "^8.52.0",
"comment-parser": "1.4.1",
"esquery": "^1.6.0",
"jsdoc-type-pratt-parser": "~6.10.0"
"esquery": "^1.7.0",
"jsdoc-type-pratt-parser": "~7.0.0"
}
},
"@es-joy/resolve.exports": {
@@ -9409,9 +9438,9 @@
"dev": true
},
"@typescript-eslint/types": {
"version": "8.46.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.46.1.tgz",
"integrity": "sha512-C+soprGBHwWBdkDpbaRC4paGBrkIXxVlNohadL5o0kfhsXqOC6GYH2S/Obmig+I0HTDl8wMaRySwrfrXVP8/pQ==",
"version": "8.53.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.53.0.tgz",
"integrity": "sha512-Bmh9KX31Vlxa13+PqPvt4RzKRN1XORYSLlAE+sO1i28NkisGbTtSLFVB3l7PWdHtR3E0mVMuC7JilWJ99m2HxQ==",
"dev": true
},
"@ungap/structured-clone": {
@@ -10449,19 +10478,19 @@
"requires": {}
},
"eslint-plugin-jsdoc": {
"version": "61.5.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-61.5.0.tgz",
"integrity": "sha512-PR81eOGq4S7diVnV9xzFSBE4CDENRQGP0Lckkek8AdHtbj+6Bm0cItwlFnxsLFriJHspiE3mpu8U20eODyToIg==",
"version": "62.0.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-62.0.1.tgz",
"integrity": "sha512-TNeqgrE+xjDGCZVlRIiQcnUWNoMlHE5+oIyGbVFbrdIPOkz5ecWAmB26xSgqm2Mz7wny/ztyqCOUOeJhGrElpA==",
"dev": true,
"requires": {
"@es-joy/jsdoccomment": "~0.76.0",
"@es-joy/jsdoccomment": "~0.79.0",
"@es-joy/resolve.exports": "1.2.0",
"are-docs-informative": "^0.0.2",
"comment-parser": "1.4.1",
"debug": "^4.4.3",
"escape-string-regexp": "^4.0.0",
"espree": "^10.4.0",
"esquery": "^1.6.0",
"espree": "^11.0.0",
"esquery": "^1.7.0",
"html-entities": "^2.6.0",
"object-deep-merge": "^2.0.0",
"parse-imports-exports": "^0.2.4",
@@ -10476,6 +10505,23 @@
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
"dev": true
},
"eslint-visitor-keys": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.0.tgz",
"integrity": "sha512-A0XeIi7CXU7nPlfHS9loMYEKxUaONu/hTEzHTGba9Huu94Cq1hPivf+DE5erJozZOky0LfvXAyrV/tcswpLI0Q==",
"dev": true
},
"espree": {
"version": "11.0.0",
"resolved": "https://registry.npmjs.org/espree/-/espree-11.0.0.tgz",
"integrity": "sha512-+gMeWRrIh/NsG+3NaLeWHuyeyk70p2tbvZIWBYcqQ4/7Xvars6GYTZNhF1sIeLcc6Wb11He5ffz3hsHyXFrw5A==",
"dev": true,
"requires": {
"acorn": "^8.15.0",
"acorn-jsx": "^5.3.2",
"eslint-visitor-keys": "^5.0.0"
}
},
"semver": {
"version": "7.7.3",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
@@ -10526,9 +10572,9 @@
"dev": true
},
"esquery": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz",
"integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz",
"integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==",
"dev": true,
"requires": {
"estraverse": "^5.1.0"
@@ -10912,9 +10958,9 @@
}
},
"globals": {
"version": "16.5.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-16.5.0.tgz",
"integrity": "sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==",
"version": "17.0.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-17.0.0.tgz",
"integrity": "sha512-gv5BeD2EssA793rlFWVPMMCqefTlpusw6/2TbAVMy0FzcG8wKJn4O+NqJ4+XWmmwrayJgw5TzrmWjFgmz1XPqw==",
"dev": true
},
"gopd": {
@@ -11931,9 +11977,9 @@
}
},
"jsdoc-type-pratt-parser": {
"version": "6.10.0",
"resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-6.10.0.tgz",
"integrity": "sha512-+LexoTRyYui5iOhJGn13N9ZazL23nAHGkXsa1p/C8yeq79WRfLBag6ZZ0FQG2aRoc9yfo59JT9EYCQonOkHKkQ==",
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-7.0.0.tgz",
"integrity": "sha512-c7YbokssPOSHmqTbSAmTtnVgAVa/7lumWNYqomgd5KOMyPrRve2anx6lonfOsXEQacqF9FKVUj7bLg4vRSvdYA==",
"dev": true
},
"jsdom": {
@@ -12667,9 +12713,9 @@
"dev": true
},
"prettier": {
"version": "3.7.4",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.7.4.tgz",
"integrity": "sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA==",
"version": "3.8.0",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.0.tgz",
"integrity": "sha512-yEPsovQfpxYfgWNhCfECjG5AQaO+K3dp6XERmOepyPDVqcJm+bjyCVO3pmU+nAPe0N5dDvekfGezt/EIiRe1TA==",
"dev": true
},
"pretty-format": {
+3 -3
View File
@@ -47,9 +47,9 @@
"color-contrast-checker": "^2.1.0",
"eslint": "^9.39.2",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-jsdoc": "^61.5.0",
"eslint-plugin-jsdoc": "^62.0.1",
"express": "^5.2.1",
"globals": "^16.5.0",
"globals": "^17.0.0",
"hjson": "^3.2.2",
"husky": "^9.1.7",
"jest": "^30.2.0",
@@ -58,7 +58,7 @@
"lint-staged": "^16.2.7",
"lodash.snakecase": "^4.1.1",
"parse-diff": "^0.11.1",
"prettier": "^3.7.3"
"prettier": "^3.8.0"
},
"dependencies": {
"axios": "^1.13.1",
+2 -1
View File
@@ -83,7 +83,8 @@ const getCardColors = ({
theme,
}) => {
const defaultTheme = themes["default"];
const isThemeProvided = theme !== null && theme !== undefined && theme in themes;
const isThemeProvided =
theme !== null && theme !== undefined && theme in themes;
// @ts-ignore
const selectedTheme = isThemeProvided ? themes[theme] : defaultTheme;
+14
View File
@@ -73,4 +73,18 @@ describe("Test color.js", () => {
borderColor: "#fff",
});
});
it("getCardColors: should fallback to default theme if theme is invalid", () => {
let colors = getCardColors({
theme: "invalidTheme",
});
expect(colors).toStrictEqual({
titleColor: "#2f80ed",
textColor: "#434d58",
iconColor: "#4c71f2",
ringColor: "#2f80ed",
bgColor: "#fffefe",
borderColor: "#e4e2e2",
});
});
});
+67 -9
View File
@@ -1,14 +1,65 @@
# Deploy on your own
Since the GitHub API only allows a limited number of requests per hour, my `https://github-stats-extended.vercel.app/api` could possibly hit the rate limiter. If you host it on your own Vercel server, then you do not have to worry about anything. Also, if you don't want to give my GitHub-Stats-Extended instance access to your private contributions but still want to include these contributions in your stats, you can simply host your own instance.
Since the GitHub API only allows a limited number of requests per hour, my `https://github-stats-extended.vercel.app/api` could possibly hit the rate limiter. If you deploy it yourself via GitHub Actions or your own hosted instance, then you do not have to worry about anything. Also, if you don't want to give my GitHub-Stats-Extended instance access to your private contributions but still want to include these contributions in your stats, you can simply host your own instance.
## First step: get your Personal Access Token (PAT)
GitHub Actions is the simplest setup with static SVGs stored in your repo but less frequent updates, while self-hosting takes more work and can serve fresher stats (with caching).
## GitHub Actions
GitHub Actions generates static SVGs and avoids per-request API calls. By default it uses `GITHUB_TOKEN` (public stats only), for private stats, set a [PAT](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens) as a secret and pass it to the action instead.
Create `/.github/workflows/grs.yml` in your profile repo (`USERNAME/USERNAME`):
```yaml
name: Update README cards
on:
schedule:
- cron: "0 3 * * *"
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Generate stats card
uses: readme-tools/github-readme-stats-action@v1
with:
card: stats
options: username=${{ github.repository_owner }}&show_icons=true
path: profile/stats.svg
token: ${{ secrets.GITHUB_TOKEN }}
- name: Commit cards
run: |
git config user.name "github-actions"
git config user.email "github-actions@users.noreply.github.com"
git add profile/*.svg
git commit -m "Update README cards" || exit 0
git push
```
Then embed from your profile README:
```md
![Stats](./profile/stats.svg)
```
See more options and examples in the [GitHub Readme Stats Action README](https://github.com/stats-organization/github-readme-stats-action#readme).
## Self-hosted (Vercel/Other)
Running your own instance avoids public rate limits and gives you full control over caching, tokens, and private stats.
### First step: get your Personal Access Token (PAT)
For deploying your own instance of GitHub Stats Extended, you will need to create a GitHub Personal Access Token (PAT). Below are the steps to create one and the scopes you need to select for both classic and fine-grained tokens.
Selecting the right scopes for your token is important in case you want to display private contributions on your cards.
### Classic token
#### Classic token
* Go to [Account -> Settings -> Developer Settings -> Personal access tokens -> Tokens (classic)](https://github.com/settings/tokens).
* Click on `Generate new token -> Generate new token (classic)`.
@@ -17,7 +68,7 @@ Selecting the right scopes for your token is important in case you want to displ
* read:user
* Click on `Generate token` and copy it.
### Fine-grained token
#### Fine-grained token
> [!WARNING]\
> This limits the scope of commits to public repositories only.
@@ -35,9 +86,9 @@ Selecting the right scopes for your token is important in case you want to displ
* Pull requests: read-only
* Click on `Generate token` and copy it.
## On Vercel
### On Vercel
### :film\_projector: [Check Out Step By Step Video Tutorial By @codeSTACKr](https://youtu.be/n6d4KHSKqGk?t=107)
<b>:film\_projector: [Check Out Step By Step Video Tutorial By @codeSTACKr](https://youtu.be/n6d4KHSKqGk?t=107)</b>
Click on the deploy button to get started!
@@ -60,6 +111,13 @@ Click on the deploy button to get started!
9. Create a Personal Access Token (PAT) as described in the [previous section](#first-step-get-your-personal-access-token-pat).
10. Add the PAT as an environment variable named `PAT_1` (as shown).
![](https://files.catbox.moe/0yclio.png)
Note: For enhanced security, you can add a variable as a sensitive variable. To do this:
1. Go to `Environment Variables` in `Project Settings`, then choose `Add Environment Variable`.
![](https://files.catbox.moe/heprjw.jpg)
2. Uncheck `Deployment` from `Environments`
![](https://files.catbox.moe/tiqgd0.jpg)
3. Now you can make the variable `Sensitive` by checking the checkbox.
![](https://files.catbox.moe/mla5no.jpg)
11. As `Root directory` select the `backend` folder.
12. Click deploy, and you're good to go. See your domains to use the API!
13. optional: add an SQL database; by using e.g. the ["Nile" integration](https://vercel.com/marketplace/nile) or by manually setting the environment variable `POSTGRES_URL`
@@ -68,7 +126,7 @@ Click on the deploy button to get started!
</details>
## On other platforms
### On other platforms
> [!WARNING]
> This way of using GitHub-Stats-Extended is not officially supported and was added to cater to some particular use cases where Vercel could not be used (e.g. [#2341](https://github.com/anuraghazra/github-readme-stats/discussions/2341)). The support for this method, therefore, is limited.
@@ -85,7 +143,7 @@ Click on the deploy button to get started!
5. You're done 🎉
</details>
## Available environment variables
### Available environment variables
GitHub Readme Stats provides several environment variables that can be used to customize the behavior of your self-hosted instance. These include:
@@ -131,7 +189,7 @@ See [the Vercel documentation](https://vercel.com/docs/concepts/projects/environ
> [!WARNING]
> Please remember to redeploy your instance after making any changes to the environment variables so that the updates take effect. The changes will not be applied to the previous deployments.
## Keep your fork up to date
### Keep your fork up to date
You can keep your fork, and thus your private Vercel instance up to date with the upstream using GitHub's [Sync Fork button](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork). You can also use the [pull](https://github.com/wei/pull) package created by [@wei](https://github.com/wei) to automate this process.