2020-08-03 01:17:34 +08:00
|
|
|
const core = require("@actions/core");
|
|
|
|
const github = require("@actions/github");
|
|
|
|
const parse = require("parse-diff");
|
2021-11-05 23:31:46 +08:00
|
|
|
const Hjson = require("hjson");
|
|
|
|
const snakeCase = require("lodash.snakecase");
|
|
|
|
const ColorContrastChecker = require("color-contrast-checker");
|
|
|
|
|
2020-08-03 01:17:34 +08:00
|
|
|
require("dotenv").config();
|
|
|
|
|
2021-11-06 22:35:35 +08:00
|
|
|
const OWNER = "anuraghazra";
|
|
|
|
const REPO = "github-readme-stats";
|
|
|
|
const COMMENT_TITLE = "Automated Theme Preview";
|
|
|
|
|
2020-08-10 22:31:19 +08:00
|
|
|
function getPrNumber() {
|
|
|
|
const pullRequest = github.context.payload.pull_request;
|
|
|
|
if (!pullRequest) {
|
|
|
|
return undefined;
|
2020-08-03 01:17:34 +08:00
|
|
|
}
|
2020-08-10 22:31:19 +08:00
|
|
|
|
|
|
|
return pullRequest.number;
|
|
|
|
}
|
2020-08-03 01:17:34 +08:00
|
|
|
|
2021-11-06 22:35:35 +08:00
|
|
|
function findCommentPredicate(inputs, comment) {
|
|
|
|
return (
|
|
|
|
(inputs.commentAuthor && comment.user
|
|
|
|
? comment.user.login === inputs.commentAuthor
|
|
|
|
: true) &&
|
|
|
|
(inputs.bodyIncludes && comment.body
|
|
|
|
? comment.body.includes(inputs.bodyIncludes)
|
|
|
|
: true)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
async function findComment(octokit, issueNumber) {
|
|
|
|
const parameters = {
|
|
|
|
owner: OWNER,
|
|
|
|
repo: REPO,
|
|
|
|
issue_number: issueNumber,
|
|
|
|
};
|
|
|
|
const inputs = {
|
|
|
|
commentAuthor: OWNER,
|
|
|
|
bodyIncludes: COMMENT_TITLE,
|
|
|
|
};
|
|
|
|
|
|
|
|
for await (const { data: comments } of octokit.paginate.iterator(
|
|
|
|
octokit.rest.issues.listComments,
|
|
|
|
parameters,
|
|
|
|
)) {
|
|
|
|
// Search each page for the comment
|
|
|
|
const comment = comments.find((comment) =>
|
|
|
|
findCommentPredicate(inputs, comment),
|
|
|
|
);
|
|
|
|
if (comment) return comment;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async function upsertComment(octokit, props) {
|
|
|
|
if (props.comment_id !== undefined) {
|
|
|
|
await octokit.issues.updateComment(props);
|
|
|
|
} else {
|
|
|
|
await octokit.issues.createComment(props);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function getWebAimLink(color1, color2) {
|
|
|
|
return `https://webaim.org/resources/contrastchecker/?fcolor=${color1}&bcolor=${color2}`;
|
|
|
|
}
|
|
|
|
|
|
|
|
function getGrsLink(colors) {
|
|
|
|
const url = `https://github-readme-stats.vercel.app/api?username=anuraghazra`;
|
|
|
|
const colorString = Object.keys(colors)
|
|
|
|
.map((colorKey) => `${colorKey}=${colors[colorKey]}`)
|
|
|
|
.join("&");
|
|
|
|
|
|
|
|
return `${url}&${colorString}&show_icons=true`;
|
|
|
|
}
|
|
|
|
|
2021-01-10 15:46:01 +08:00
|
|
|
const themeContribGuidelines = `
|
2021-10-02 04:14:10 +08:00
|
|
|
\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).
|
|
|
|
\rWe are currently only accepting color combinations from any VSCode theme or themes which have good color combination to minimize bloating the themes collection.
|
2021-01-10 15:46:01 +08:00
|
|
|
|
2021-10-02 04:14:10 +08:00
|
|
|
\r> Also note that if this theme is exclusively for your personal use, then instead of adding it to our theme collection you can use card [customization options](https://github.com/anuraghazra/github-readme-stats#customization)
|
2021-01-10 15:46:01 +08:00
|
|
|
`;
|
|
|
|
|
2020-08-03 01:17:34 +08:00
|
|
|
async function run() {
|
|
|
|
try {
|
2021-11-05 23:31:46 +08:00
|
|
|
const ccc = new ColorContrastChecker();
|
|
|
|
const warnings = [];
|
2020-08-06 00:27:11 +08:00
|
|
|
const token = core.getInput("token");
|
|
|
|
const octokit = github.getOctokit(token || process.env.PERSONAL_TOKEN);
|
2020-08-10 22:31:19 +08:00
|
|
|
const pullRequestId = getPrNumber();
|
|
|
|
|
|
|
|
if (!pullRequestId) {
|
|
|
|
console.log("PR not found");
|
|
|
|
return;
|
|
|
|
}
|
2020-08-03 01:17:34 +08:00
|
|
|
|
2021-11-05 23:31:46 +08:00
|
|
|
const res = await octokit.pulls.get({
|
2021-11-06 22:35:35 +08:00
|
|
|
owner: OWNER,
|
|
|
|
repo: REPO,
|
2020-08-03 01:17:34 +08:00
|
|
|
pull_number: pullRequestId,
|
|
|
|
mediaType: {
|
|
|
|
format: "diff",
|
|
|
|
},
|
|
|
|
});
|
2021-11-06 22:35:35 +08:00
|
|
|
const comment = await findComment(octokit, pullRequestId);
|
2020-08-03 01:17:34 +08:00
|
|
|
|
2021-11-05 23:31:46 +08:00
|
|
|
const diff = parse(res.data);
|
|
|
|
const content = diff
|
2020-08-03 01:17:34 +08:00
|
|
|
.find((file) => file.to === "themes/index.js")
|
|
|
|
.chunks[0].changes.filter((c) => c.type === "add")
|
|
|
|
.map((c) => c.content.replace("+", ""))
|
|
|
|
.join("");
|
|
|
|
|
2021-11-05 23:31:46 +08:00
|
|
|
const themeObject = Hjson.parse(content);
|
|
|
|
const themeName = Object.keys(themeObject)[0];
|
|
|
|
const colors = themeObject[themeName];
|
|
|
|
|
|
|
|
if (themeName !== snakeCase(themeName)) {
|
|
|
|
warnings.push("Theme name isn't in snake_case");
|
|
|
|
}
|
2020-08-03 01:17:34 +08:00
|
|
|
|
|
|
|
if (!colors) {
|
2021-11-06 22:35:35 +08:00
|
|
|
await upsertComment({
|
|
|
|
comment_id: comment?.id,
|
|
|
|
owner: OWNER,
|
|
|
|
repo: REPO,
|
|
|
|
issue_number: pullRequestId,
|
2020-08-03 01:17:34 +08:00
|
|
|
body: `
|
2021-11-06 22:35:35 +08:00
|
|
|
\r**${COMMENT_TITLE}**
|
2021-01-10 15:46:01 +08:00
|
|
|
|
|
|
|
\rCannot create theme preview
|
|
|
|
|
|
|
|
${themeContribGuidelines}
|
2020-08-03 01:17:34 +08:00
|
|
|
`,
|
|
|
|
});
|
|
|
|
return;
|
|
|
|
}
|
2021-11-05 23:31:46 +08:00
|
|
|
|
|
|
|
const titleColor = colors.title_color;
|
|
|
|
const iconColor = colors.icon_color;
|
|
|
|
const textColor = colors.text_color;
|
|
|
|
const bgColor = colors.bg_color;
|
2021-11-06 22:35:35 +08:00
|
|
|
const url = getGrsLink(colors);
|
2020-08-03 01:17:34 +08:00
|
|
|
|
2021-11-05 23:31:46 +08:00
|
|
|
const colorPairs = {
|
|
|
|
title_color: [titleColor, bgColor],
|
|
|
|
icon_color: [iconColor, bgColor],
|
|
|
|
text_color: [textColor, bgColor],
|
|
|
|
};
|
|
|
|
|
|
|
|
// check color contrast
|
|
|
|
Object.keys(colorPairs).forEach((key) => {
|
|
|
|
const color1 = colorPairs[key][0];
|
|
|
|
const color2 = colorPairs[key][1];
|
|
|
|
if (!ccc.isLevelAA(`#${color1}`, `#${color2}`)) {
|
2021-11-06 22:35:35 +08:00
|
|
|
const permalink = getWebAimLink(color1, color2);
|
2021-11-05 23:31:46 +08:00
|
|
|
warnings.push(
|
|
|
|
`\`${key}\` does not passes [AA contrast ratio](${permalink})`,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2021-11-06 22:35:35 +08:00
|
|
|
await upsertComment(octokit, {
|
|
|
|
comment_id: comment?.id,
|
|
|
|
issue_number: pullRequestId,
|
|
|
|
owner: OWNER,
|
|
|
|
repo: REPO,
|
2020-08-03 01:17:34 +08:00
|
|
|
body: `
|
2021-11-06 22:35:35 +08:00
|
|
|
\r**${COMMENT_TITLE}**
|
2020-08-14 23:57:45 +08:00
|
|
|
|
2021-11-05 23:31:46 +08:00
|
|
|
\r${warnings.map((warning) => `- :warning: ${warning}\n`).join("")}
|
|
|
|
|
2021-01-10 16:08:11 +08:00
|
|
|
\ntitle_color: <code>#${titleColor}</code> | icon_color: <code>#${iconColor}</code> | text_color: <code>#${textColor}</code> | bg_color: <code>#${bgColor}</code>
|
2020-08-14 23:31:33 +08:00
|
|
|
|
2021-09-26 23:46:20 +08:00
|
|
|
\r[Preview Link](${url})
|
2021-01-10 15:46:01 +08:00
|
|
|
|
2020-08-14 23:31:33 +08:00
|
|
|
\r[![](${url})](${url})
|
2021-01-10 15:46:01 +08:00
|
|
|
|
|
|
|
${themeContribGuidelines}
|
2020-08-03 01:17:34 +08:00
|
|
|
`,
|
|
|
|
});
|
|
|
|
} catch (error) {
|
2020-08-14 23:25:54 +08:00
|
|
|
console.log(error);
|
2020-08-03 01:17:34 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
run();
|