-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[pull] master from anuraghazra:master #87
Changes from 44 commits
2ee803f
41a2ba8
1fb2d1a
12f84f8
65c3300
7bf4a87
5c9ca13
eb2652d
5850506
3312e90
712cb18
52b402a
558af5c
e04d17d
2404f06
5f378b8
3295d5d
79384f4
971fc61
dd68af3
35e4578
88c507c
3b53bed
18763ae
4c7e297
1728bb2
d89edc0
a397851
0fd1ea3
428e97b
28b6592
7b1b78d
1c07f41
b753d49
cd9698b
7c5e998
ee7cf1f
7a6d7b4
4fd52e6
00394cf
ac749b7
d72ae34
6dc6c61
2567a6e
8278980
365dfb7
4e949c2
41d19be
dd528c4
c289b10
bb17789
e7056fb
29c1fef
4dc930b
3dab984
b85225b
bc9076a
885bd1b
ae35637
33beba5
3eedfd3
cb5ac97
edeebeb
f8aa2db
3977b90
c795c72
376aeaa
69b1745
3d0780b
453ab19
8ee18b8
69cdf00
23f9cc7
7fe7c63
6bcc98d
c79fc99
8084ba9
87a3bf3
0691084
db92181
9c6eb22
89fc146
5b72dfb
2feebd0
91a3ac2
10236d8
6cf9bb8
2b90336
1886fe0
2ddcd9c
ff16984
236577f
5b3b920
90c30f2
6d8169f
e5b5da8
79cee30
bc7ea33
a99abe8
843b15e
8d7e9df
dda9647
aa90efc
edf9f74
5ea6595
51eefa2
d654fe5
034ee06
36bbea2
e04e139
e50a9b4
4997308
3a15963
f26b83d
d4f1a5d
ddcc30d
68c49dd
723cdd7
ffe2862
afcb773
a8663a8
b8983dd
1262002
c6c4a88
4793de4
7595456
0616df3
1656ec6
80b2d23
1cba9c1
105e136
91889a3
4412af8
34c67ff
6633d68
23472f4
c31f3e8
2259870
c402a23
f831dad
9c1bb80
beb0172
82699d6
3ea55bb
e30da92
f44ddde
c1e8037
59367dc
7d4c49b
4710f24
d2dbffe
53a1e34
1852db0
5dd50ee
69f5826
258d54d
9406466
62662be
39e8c20
d1540ef
9cce439
14fe8cd
3d996b9
eb3b4d1
9a11163
fa50161
533469d
91db535
4f567cc
734c69a
8b610da
b9fa27b
26f6d7f
0704b5a
319e3d4
547660b
13c25c7
5a05bd2
9533319
91d0ed6
62c7101
3e14baf
1be7d06
5f411be
3ba7666
8ad4eee
a7159aa
e71c63d
2f67ff1
c213f9e
916c51a
c48c4f5
bf937ab
8c268ee
200b703
5796024
663e4f0
918d274
1e30934
364bba7
537862f
c2647d8
1d27c6b
e69427e
4de672c
9ea7535
8282afb
abf9c66
018e7fd
df84138
4761871
0a372d2
fd12c01
a71bb1b
bd5f268
c9f850c
af9b2c8
e93b5d5
0706c26
ee0b0e9
0b3e07a
cb4b630
d739c0a
9d9ad87
daa0432
124225d
e1356e3
0bdc2bf
e06b0d2
7a78036
2ec2716
1a269d6
e26c013
e48d073
127a507
6999c86
66579b1
bf4fbc2
26571ca
62cdee3
b6f5077
0496044
6c6888e
20fb82f
dc4717a
af839e9
13b3660
d91f629
975d38b
bf7a3b0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
themes: themes/index.js | ||
doc-translation: docs/* | ||
card-i18n: src/translations.js | ||
documentation: readme.md |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import os | ||
|
||
file = open('./vercel.json', 'r') | ||
str = file.read() | ||
file = open('./vercel.json', 'w') | ||
|
||
str = str.replace('"maxDuration": 10', '"maxDuration": 30') | ||
|
||
file.write(str) | ||
file.close() |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
name: Deployment Prep | ||
on: | ||
workflow_dispatch: | ||
push: | ||
branches: | ||
- master | ||
|
||
jobs: | ||
config: | ||
if: github.repository == 'anuraghazra/github-readme-stats' | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v3 | ||
Check warning Code scanning / Scorecard Pinned-Dependencies
score is 7: GitHub-owned GitHubAction not pinned by hash
Click Remediation section below to solve this issue
|
||
- name: Deployment Prep | ||
run: python ./.github/workflows/deploy-prep.py | ||
- uses: stefanzweifel/git-auto-commit-action@v4 | ||
Check warning Code scanning / Scorecard Pinned-Dependencies
score is 7: third-party GitHubAction not pinned by hash
Click Remediation section below to solve this issue
|
||
with: | ||
branch: vercel | ||
create_branch: true | ||
push_options: "--force" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
name: Update supported languages | ||
on: | ||
schedule: | ||
- cron: "0 0 */30 * *" | ||
|
||
jobs: | ||
updateLanguages: | ||
if: github.repository == 'anuraghazra/github-readme-stats' | ||
name: Update supported languages | ||
runs-on: ubuntu-latest | ||
strategy: | ||
matrix: | ||
node-version: [16.x] | ||
|
||
steps: | ||
- uses: actions/checkout@v3 | ||
Check warning Code scanning / Scorecard Pinned-Dependencies
score is 7: GitHub-owned GitHubAction not pinned by hash
Click Remediation section below to solve this issue
|
||
|
||
- name: Setup Node | ||
uses: actions/setup-node@v3 | ||
Check warning Code scanning / Scorecard Pinned-Dependencies
score is 7: GitHub-owned GitHubAction not pinned by hash
Click Remediation section below to solve this issue
|
||
with: | ||
node-version: ${{ matrix.node-version }} | ||
cache: npm | ||
|
||
- name: Install dependencies | ||
run: npm ci | ||
env: | ||
CI: true | ||
|
||
- name: Run update-languages-json.js script | ||
run: npm run generate-langs-json | ||
|
||
- name: Create Pull Request if upstream language file is changed | ||
uses: peter-evans/create-pull-request@v4 | ||
Check warning Code scanning / Scorecard Pinned-Dependencies
score is 7: third-party GitHubAction not pinned by hash
Click Remediation section below to solve this issue
|
||
with: | ||
commit-message: "refactor: update languages JSON" | ||
branch: "update_langs/patch" | ||
delete-branch: true | ||
title: Update languages JSON | ||
body: | ||
"The | ||
[update-langs](https://github.com/anuraghazra/github-readme-stats/actions/workflows/update-langs.yaml) | ||
action found new/updated languages in the [upstream languages JSON | ||
file](https://raw.githubusercontent.com/github/linguist/master/lib/linguist/languages.yml)." | ||
labels: "ci, lang-card" |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,3 +10,5 @@ vercel_token | |
# IDE | ||
.vscode | ||
*.code-workspace | ||
|
||
.vercel |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
/** | ||
* @file Contains a simple cloud function that can be used to check which PATs are no | ||
* longer working. It returns a list of valid PATs, expired PATs and PATs with errors. | ||
* | ||
* @description This function is currently rate limited to 1 request per 10 minutes. | ||
*/ | ||
|
||
import { logger, request, dateDiff } from "../../src/common/utils.js"; | ||
export const RATE_LIMIT_SECONDS = 60 * 5; // 1 request per 10 minutes | ||
|
||
/** | ||
* Simple uptime check fetcher for the PATs. | ||
* | ||
* @param {import('axios').AxiosRequestHeaders} variables | ||
* @param {string} token | ||
*/ | ||
const uptimeFetcher = (variables, token) => { | ||
return request( | ||
{ | ||
query: ` | ||
query { | ||
rateLimit { | ||
remaining | ||
resetAt | ||
}, | ||
}`, | ||
variables, | ||
}, | ||
{ | ||
Authorization: `bearer ${token}`, | ||
}, | ||
); | ||
}; | ||
|
||
const getAllPATs = () => { | ||
return Object.keys(process.env).filter((key) => /PAT_\d*$/.exec(key)); | ||
}; | ||
|
||
/** | ||
* Check whether any of the PATs is expired. | ||
*/ | ||
const getPATInfo = async (fetcher, variables) => { | ||
const details = {}; | ||
const PATs = getAllPATs(); | ||
|
||
for (const pat of PATs) { | ||
try { | ||
const response = await fetcher(variables, process.env[pat]); | ||
const errors = response.data.errors; | ||
const hasErrors = Boolean(errors); | ||
const errorType = errors?.[0]?.type; | ||
const isRateLimited = | ||
(hasErrors && errorType === "RATE_LIMITED") || | ||
response.data.data?.rateLimit?.remaining === 0; | ||
|
||
// Store PATs with errors. | ||
if (hasErrors && errorType !== "RATE_LIMITED") { | ||
details[pat] = { | ||
status: "error", | ||
error: { | ||
type: errors[0].type, | ||
message: errors[0].message, | ||
}, | ||
}; | ||
continue; | ||
} else if (isRateLimited) { | ||
const date1 = new Date(); | ||
const date2 = new Date(response.data?.data?.rateLimit?.resetAt); | ||
details[pat] = { | ||
status: "exhausted", | ||
remaining: 0, | ||
resetIn: dateDiff(date2, date1) + " minutes", | ||
}; | ||
} else { | ||
details[pat] = { | ||
status: "valid", | ||
remaining: response.data.data.rateLimit.remaining, | ||
}; | ||
} | ||
} catch (err) { | ||
// Store the PAT if it is expired. | ||
const errorMessage = err.response?.data?.message?.toLowerCase(); | ||
if (errorMessage === "bad credentials") { | ||
details[pat] = { | ||
status: "expired", | ||
}; | ||
} else if (errorMessage === "sorry. your account was suspended.") { | ||
details[pat] = { | ||
status: "suspended", | ||
}; | ||
} else { | ||
throw err; | ||
} | ||
} | ||
} | ||
|
||
const filterPATsByStatus = (status) => { | ||
return Object.keys(details).filter((pat) => details[pat].status === status); | ||
}; | ||
|
||
const sortedDetails = Object.keys(details) | ||
.sort() | ||
.reduce((obj, key) => { | ||
obj[key] = details[key]; | ||
return obj; | ||
}, {}); | ||
|
||
return { | ||
validPATs: filterPATsByStatus("valid"), | ||
expiredPATs: filterPATsByStatus("expired"), | ||
exhaustedPATs: filterPATsByStatus("exhausted"), | ||
suspendedPATs: filterPATsByStatus("suspended"), | ||
errorPATs: filterPATsByStatus("error"), | ||
details: sortedDetails, | ||
}; | ||
}; | ||
|
||
/** | ||
* Cloud function that returns information about the used PATs. | ||
*/ | ||
export default async (_, res) => { | ||
res.setHeader("Content-Type", "application/json"); | ||
try { | ||
// Add header to prevent abuse. | ||
const PATsInfo = await getPATInfo(uptimeFetcher, {}); | ||
if (PATsInfo) { | ||
res.setHeader( | ||
"Cache-Control", | ||
`max-age=0, s-maxage=${RATE_LIMIT_SECONDS}`, | ||
); | ||
} | ||
res.send(JSON.stringify(PATsInfo, null, 2)); | ||
} catch (err) { | ||
// Throw error if something went wrong. | ||
logger.error(err); | ||
res.setHeader("Cache-Control", "no-store"); | ||
res.send("Something went wrong: " + err.message); | ||
} | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
/** | ||
* @file Contains a simple cloud function that can be used to check if the PATs are still | ||
* functional. | ||
* | ||
* @description This function is currently rate limited to 1 request per 10 minutes. | ||
*/ | ||
|
||
import retryer from "../../src/common/retryer.js"; | ||
import { logger, request } from "../../src/common/utils.js"; | ||
|
||
export const RATE_LIMIT_SECONDS = 60 * 10; // 1 request per 10 minutes | ||
|
||
/** | ||
* Simple uptime check fetcher for the PATs. | ||
* | ||
* @param {import('axios').AxiosRequestHeaders} variables | ||
* @param {string} token | ||
*/ | ||
const uptimeFetcher = (variables, token) => { | ||
return request( | ||
{ | ||
query: ` | ||
query { | ||
rateLimit { | ||
remaining | ||
} | ||
} | ||
`, | ||
variables, | ||
}, | ||
{ | ||
Authorization: `bearer ${token}`, | ||
}, | ||
); | ||
}; | ||
|
||
/** | ||
* Creates Json response that can be used for shields.io dynamic card generation. | ||
* | ||
* @param {*} up Whether the PATs are up or not. | ||
* @returns Dynamic shields.io JSON response object. | ||
* | ||
* @see https://shields.io/endpoint. | ||
*/ | ||
const shieldsUptimeBadge = (up) => { | ||
const schemaVersion = 1; | ||
const isError = true; | ||
const label = "Public Instance"; | ||
const message = up ? "up" : "down"; | ||
const color = up ? "brightgreen" : "red"; | ||
return { | ||
schemaVersion, | ||
label, | ||
message, | ||
color, | ||
isError, | ||
}; | ||
}; | ||
|
||
/** | ||
* Cloud function that returns whether the PATs are still functional. | ||
*/ | ||
export default async (req, res) => { | ||
let { type } = req.query; | ||
type = type ? type.toLowerCase() : "boolean"; | ||
|
||
res.setHeader("Content-Type", "application/json"); | ||
|
||
try { | ||
let PATsValid = true; | ||
try { | ||
await retryer(uptimeFetcher, {}); | ||
} catch (err) { | ||
PATsValid = false; | ||
} | ||
|
||
if (PATsValid) { | ||
res.setHeader( | ||
"Cache-Control", | ||
`max-age=0, s-maxage=${RATE_LIMIT_SECONDS}`, | ||
); | ||
} else { | ||
res.setHeader("Cache-Control", "no-store"); | ||
} | ||
|
||
switch (type) { | ||
case "shields": | ||
res.send(shieldsUptimeBadge(PATsValid)); | ||
break; | ||
case "json": | ||
res.send({ up: PATsValid }); | ||
break; | ||
default: | ||
res.send(PATsValid); | ||
break; | ||
} | ||
} catch (err) { | ||
// Return fail boolean if something went wrong. | ||
logger.error(err); | ||
res.setHeader("Cache-Control", "no-store"); | ||
res.send("Something went wrong: " + err.message); | ||
} | ||
}; |
Check failure
Code scanning / Scorecard
Token-Permissions