Skip to content

Commit 7ec9096

Browse files
committed
Merge branch 'master' into improve_caching_behavoir
2 parents dcab383 + 98f9045 commit 7ec9096

23 files changed

+150
-52
lines changed

.github/ISSUE_TEMPLATE/bug_report.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: Bug report
2-
description: Create a report to help us improve
2+
description: Create a report to help us improve.
33
labels:
44
- "bug"
55
body:

.github/ISSUE_TEMPLATE/config.yml

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
blank_issues_enabled: true
2+
contact_links:
3+
- name: Question
4+
url: https://github.com/anuraghazra/github-readme-stats/discussions
5+
about: Please ask and answer questions here.
6+
- name: Error
7+
url: https://github.com/anuraghazra/github-readme-stats/issues/1772
8+
about:
9+
Before opening a bug report, please check the 'Common Error Codes' issue.
10+
- name: FAQ
11+
url: https://github.com/anuraghazra/github-readme-stats/discussions/1770
12+
about: Please first check the FAQ before asking a question.

.github/ISSUE_TEMPLATE/feature_request.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: Feature request
2-
description: Suggest an idea for this project
2+
description: Suggest an idea for this project.
33
labels:
44
- "enhancement"
55
body:

.github/workflows/stale-theme-pr-closer.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,5 @@ jobs:
2626

2727
- run: npm run close-stale-theme-prs
2828
env:
29-
STALE_DAYS: 15
29+
STALE_DAYS: 20
3030
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

api/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ export default async (req, res) => {
9494
}),
9595
);
9696
} catch (err) {
97+
res.setHeader("Cache-Control", `no-cache, no-store, must-revalidate`); // Don't cache error responses.
9798
return res.send(renderError(err.message, err.secondaryMessage));
9899
}
99100
};

api/pin.js

+1
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ export default async (req, res) => {
8080
}),
8181
);
8282
} catch (err) {
83+
res.setHeader("Cache-Control", `no-cache, no-store, must-revalidate`); // Don't cache error responses.
8384
return res.send(renderError(err.message, err.secondaryMessage));
8485
}
8586
};

api/top-langs.js

+1
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ export default async (req, res) => {
8181
}),
8282
);
8383
} catch (err) {
84+
res.setHeader("Cache-Control", `no-cache, no-store, must-revalidate`); // Don't cache error responses.
8485
return res.send(renderError(err.message, err.secondaryMessage));
8586
}
8687
};

api/wakatime.js

+1
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ export default async (req, res) => {
8383
}),
8484
);
8585
} catch (err) {
86+
res.setHeader("Cache-Control", `no-cache, no-store, must-revalidate`); // Don't cache error responses.
8687
return res.send(renderError(err.message, err.secondaryMessage));
8788
}
8889
};

package.json

+16-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,23 @@
11
{
22
"name": "github-readme-stats",
33
"version": "1.0.0",
4-
"description": "Dynamically generate stats for your github readmes",
5-
"main": "index.js",
4+
"description": "Dynamically generate stats for your GitHub readme",
5+
"keywords": [
6+
"github-readme-stats",
7+
"readme-stats",
8+
"cards",
9+
"card-generator"
10+
],
11+
"main": "src/index.js",
612
"type": "module",
13+
"homepage": "https://github.com/anuraghazra/github-readme-stats",
14+
"bugs": {
15+
"url": "https://github.com/anuraghazra/github-readme-stats/issues"
16+
},
17+
"repository": {
18+
"type": "git",
19+
"url": "https://github.com/anuraghazra/github-readme-stats.git"
20+
},
721
"scripts": {
822
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js --coverage",
923
"test:watch": "node --experimental-vm-modules node_modules/jest/bin/jest.js --watch",

readme.md

+5
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ Visit <https://indiafightscorona.giveindia.org> and make a small donation to hel
9292
- [Language Card Exclusive Options](#language-card-exclusive-options)
9393
- [Wakatime Card Exclusive Option](#wakatime-card-exclusive-options)
9494
- [Deploy Yourself](#deploy-on-your-own-vercel-instance)
95+
- [Keep your fork up to date](#keep-your-fork-up-to-date)
9596

9697
# GitHub Stats Card
9798

@@ -440,6 +441,10 @@ Since the GitHub API only allows 5k requests per hour, my `https://github-readme
440441

441442
</details>
442443

444+
### Keep your fork up to date
445+
446+
You can keep your fork, and thus your private Vercel instance up to date with the upstream using GitHubs' [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.
447+
443448
## :sparkling_heart: Support the project
444449

445450
I open-source almost everything I can and try to reply to everyone needing help using these projects. Obviously,

scripts/close-stale-theme-prs.js

+20-8
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,28 @@ import github from "@actions/github";
99
import { RequestError } from "@octokit/request-error";
1010
import { getGithubToken, getRepoInfo } from "./helpers.js";
1111

12-
// Script parameters
1312
const CLOSING_COMMENT = `
1413
\rThis PR has been automatically closed due to inactivity. Please feel free to reopen it if you need to continue working on it.\
1514
\rThank you for your contributions.
1615
`;
16+
const REVIEWER = "github-actions[bot]";
17+
18+
/**
19+
* Retrieve the review user.
20+
* @returns {string} review user.
21+
*/
22+
const getReviewer = () => {
23+
return process.env.REVIEWER ? process.env.REVIEWER : REVIEWER;
24+
};
1725

1826
/**
1927
* Fetch open PRs from a given repository.
2028
* @param user The user name of the repository owner.
2129
* @param repo The name of the repository.
30+
* @param reviewer The reviewer to filter by.
2231
* @returns The open PRs.
2332
*/
24-
export const fetchOpenPRs = async (octokit, user, repo) => {
33+
export const fetchOpenPRs = async (octokit, user, repo, reviewer) => {
2534
const openPRs = [];
2635
let hasNextPage = true;
2736
let endCursor;
@@ -49,9 +58,9 @@ export const fetchOpenPRs = async (octokit, user, repo) => {
4958
name
5059
}
5160
}
52-
reviews(first: 1, states: CHANGES_REQUESTED, author: "github-actions[bot]") {
61+
reviews(first: 100, states: CHANGES_REQUESTED, author: "${reviewer}") {
5362
nodes {
54-
updatedAt
63+
submittedAt
5564
}
5665
}
5766
}
@@ -99,11 +108,13 @@ const isStale = (pullRequest, staleDays) => {
99108
pullRequest.commits.nodes[0].commit.pushedDate,
100109
);
101110
if (pullRequest.reviews.nodes[0]) {
102-
const lastReviewDate = new Date(pullRequest.reviews.nodes[0].updatedAt);
111+
const lastReviewDate = new Date(
112+
pullRequest.reviews.nodes.sort((a, b) => (a < b ? 1 : -1))[0].submittedAt,
113+
);
103114
const lastUpdateDate =
104115
lastCommitDate >= lastReviewDate ? lastCommitDate : lastReviewDate;
105116
const now = new Date();
106-
return now - lastUpdateDate > 1000 * 60 * 60 * 24 * staleDays;
117+
return (now - lastUpdateDate) / (1000 * 60 * 60 * 24) >= staleDays;
107118
} else {
108119
return false;
109120
}
@@ -116,14 +127,15 @@ const run = async () => {
116127
try {
117128
// Create octokit client.
118129
const dryRun = process.env.DRY_RUN === "true" || false;
119-
const staleDays = process.env.STALE_DAYS || 15;
130+
const staleDays = process.env.STALE_DAYS || 20;
120131
debug("Creating octokit client...");
121132
const octokit = github.getOctokit(getGithubToken());
122133
const { owner, repo } = getRepoInfo(github.context);
134+
const reviewer = getReviewer();
123135

124136
// Retrieve all theme pull requests.
125137
debug("Retrieving all theme pull requests...");
126-
const prs = await fetchOpenPRs(octokit, owner, repo);
138+
const prs = await fetchOpenPRs(octokit, owner, repo, reviewer);
127139
const themePRs = pullsWithLabel(prs, "themes");
128140
const invalidThemePRs = pullsWithLabel(themePRs, "invalid");
129141
debug("Retrieving stale theme PRs...");

scripts/helpers.js

-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
import { getInput } from "@actions/core";
66

7-
// Script variables.
87
const OWNER = "anuraghazra";
98
const REPO = "github-readme-stats";
109

scripts/preview-theme.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import { isValidHexColor } from "../src/common/utils.js";
1616
import { themes } from "../themes/index.js";
1717
import { getGithubToken, getRepoInfo } from "./helpers.js";
1818

19-
// Script variables.
2019
const COMMENTER = "github-actions[bot]";
2120

2221
const COMMENT_TITLE = "Automated Theme Preview";
@@ -25,7 +24,7 @@ const THEME_PR_SUCCESS_TEXT =
2524
":heavy_check_mark: Theme PR does adhere to our guidelines.";
2625
const FAIL_TEXT = `
2726
\rUnfortunately, your theme PR contains an error or does not adhere to our [theme guidelines](https://github.com/anuraghazra/github-readme-stats/blob/master/CONTRIBUTING.md#themes-contribution). Please fix the issues below, and we will review your\
28-
\r PR again. This pull request will **automatically close in 15 days** if no changes are made. After this time, you must re-open the PR for it to be reviewed.
27+
\r PR again. This pull request will **automatically close in 20 days** if no changes are made. After this time, you must re-open the PR for it to be reviewed.
2928
`;
3029
const THEME_CONTRIB_GUIDELINESS = `
3130
\rHi, thanks for the theme contribution. Please read our theme [contribution guidelines](https://github.com/anuraghazra/github-readme-stats/blob/master/CONTRIBUTING.md#themes-contribution).

src/cards/index.js

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export { renderRepoCard } from "./repo-card.js";
2+
export { renderStatsCard } from "./stats-card.js";
3+
export { renderTopLanguages } from "./top-languages-card.js";
4+
export { renderWakatimeCard } from "./wakatime-card.js";

src/cards/stats-card.js

+1
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => {
170170
"pl",
171171
"de",
172172
"nl",
173+
"zh-tw",
173174
];
174175
const isLongLocale = longLocales.includes(locale) === true;
175176

src/common/index.js

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
export { blacklist } from "./blacklist.js";
2+
export { Card } from "./Card.js";
3+
export { createProgressNode } from "./createProgressNode.js";
4+
export { I18n } from "./I18n.js";
5+
export { icons } from "./icons.js";
6+
export { retryer } from "./retryer.js";
7+
export {
8+
ERROR_CARD_LENGTH,
9+
renderError,
10+
encodeHTML,
11+
kFormatter,
12+
isValidHexColor,
13+
parseBoolean,
14+
parseArray,
15+
clampValue,
16+
isValidGradient,
17+
fallbackColor,
18+
request,
19+
flexLayout,
20+
getCardColors,
21+
wrapTextMultiline,
22+
logger,
23+
CONSTANTS,
24+
CustomError,
25+
MissingParamError,
26+
measureText,
27+
lowercaseTrim,
28+
chunkArray,
29+
parseEmojis,
30+
} from "./utils.js";

src/common/utils.js

+7-6
Original file line numberDiff line numberDiff line change
@@ -414,25 +414,26 @@ function parseEmojis(str) {
414414
}
415415

416416
export {
417+
ERROR_CARD_LENGTH,
417418
renderError,
418-
kFormatter,
419419
encodeHTML,
420+
kFormatter,
420421
isValidHexColor,
421-
request,
422-
parseArray,
423422
parseBoolean,
423+
parseArray,
424+
clampValue,
425+
isValidGradient,
424426
fallbackColor,
427+
request,
425428
flexLayout,
426429
getCardColors,
427-
clampValue,
428430
wrapTextMultiline,
429-
measureText,
430431
logger,
431432
CONSTANTS,
432433
CustomError,
433434
MissingParamError,
435+
measureText,
434436
lowercaseTrim,
435437
chunkArray,
436438
parseEmojis,
437-
ERROR_CARD_LENGTH,
438439
};

src/index.js

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export * from "./common/index.js";
2+
export * from "./cards/index.js";
3+
export { getStyles, getAnimations } from "./getStyles.js";

tests/api.test.js

+10
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,16 @@ describe("Test /api/", () => {
184184
]);
185185
});
186186

187+
it("should not store cache when error", async () => {
188+
const { req, res } = faker({}, error);
189+
await api(req, res);
190+
191+
expect(res.setHeader.mock.calls).toEqual([
192+
["Content-Type", "image/svg+xml"],
193+
["Cache-Control", `no-cache, no-store, must-revalidate`],
194+
]);
195+
});
196+
187197
it("should set proper cache with clamped values", async () => {
188198
{
189199
let { req, res } = faker({ cache_seconds: 200000 }, data);

tests/e2e/e2e.test.js

+5-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import { renderStatsCard } from "../../src/cards/stats-card.js";
1111
import { renderTopLanguages } from "../../src/cards/top-languages-card.js";
1212
import { renderWakatimeCard } from "../../src/cards/wakatime-card.js";
1313

14-
// Script variables
1514
const REPO = "dummy-cra";
1615
const USER = "grsdummy";
1716
const STATS_DATA = {
@@ -26,6 +25,7 @@ const STATS_DATA = {
2625
score: 51.01013099671447,
2726
},
2827
};
28+
2929
const LANGS_DATA = {
3030
TypeScript: {
3131
color: "#3178c6",
@@ -48,6 +48,7 @@ const LANGS_DATA = {
4848
size: 671,
4949
},
5050
};
51+
5152
const WAKATIME_DATA = {
5253
human_readable_range: "last week",
5354
is_already_updating: false,
@@ -64,6 +65,7 @@ const WAKATIME_DATA = {
6465
username: "grsdummy",
6566
writes_only: false,
6667
};
68+
6769
const REPOSITORY_DATA = {
6870
name: "dummy-cra",
6971
nameWithOwner: "grsdummy/dummy-cra",
@@ -82,6 +84,7 @@ const REPOSITORY_DATA = {
8284
forkCount: 0,
8385
starCount: 1,
8486
};
87+
8588
const CACHE_BURST_STRING = `v=${new Date().getTime()}`;
8689

8790
describe("Fetch Cards", () => {
@@ -110,7 +113,7 @@ describe("Fetch Cards", () => {
110113

111114
// Check if stats card from deployment matches the stats card from local.
112115
expect(serverStatsSvg.data).toEqual(localStatsCardSVG);
113-
});
116+
}, 7000);
114117

115118
test("retrieve language card", async () => {
116119
expect(VERCEL_PREVIEW_URL).toBeDefined();

tests/fetchRepo.test.js

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ const data_user = {
2323
organization: null,
2424
},
2525
};
26+
2627
const data_org = {
2728
data: {
2829
user: null,

tests/renderStatsCard.test.js

+10-10
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,17 @@ import "@testing-library/jest-dom";
1010

1111
import { themes } from "../themes/index.js";
1212

13-
describe("Test renderStatsCard", () => {
14-
const stats = {
15-
name: "Anurag Hazra",
16-
totalStars: 100,
17-
totalCommits: 200,
18-
totalIssues: 300,
19-
totalPRs: 400,
20-
contributedTo: 500,
21-
rank: { level: "A+", score: 40 },
22-
};
13+
const stats = {
14+
name: "Anurag Hazra",
15+
totalStars: 100,
16+
totalCommits: 200,
17+
totalIssues: 300,
18+
totalPRs: 400,
19+
contributedTo: 500,
20+
rank: { level: "A+", score: 40 },
21+
};
2322

23+
describe("Test renderStatsCard", () => {
2424
it("should render correctly", () => {
2525
document.body.innerHTML = renderStatsCard(stats);
2626

0 commit comments

Comments
 (0)