ci: automatically sync labels with userstyles (#143)

This commit is contained in:
Hamothy 2023-08-09 18:51:15 +01:00 committed by GitHub
parent 5f5a744a95
commit 4f83ac4607
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 164 additions and 38 deletions

109
.github/labels.yml vendored Normal file
View File

@ -0,0 +1,109 @@
# THIS FILE IS AUTOGENERATED. DO NOT EDIT IT BY HAND.
- name: advent-of-code
description: Advent Of Code
color: "#8aadf4"
- name: anilist
description: AniList,AniChart
color: "#8aadf4"
- name: brave-search
description: Brave Search
color: "#8aadf4"
- name: canvas-lms
description: Canvas LMS
color: "#8aadf4"
- name: chatgpt
description: ChatGPT
color: "#8aadf4"
- name: chess.com
description: Chess.com
color: "#8aadf4"
- name: cinny
description: Cinny
color: "#8aadf4"
- name: codeberg
description: Codeberg
color: "#8aadf4"
- name: crowdin
description: Crowdin
color: "#8aadf4"
- name: deepl
description: DeepL
color: "#8aadf4"
- name: ecosia
description: Ecosia
color: "#8aadf4"
- name: elk
description: Elk
color: "#8aadf4"
- name: github
description: GitHub
color: "#8aadf4"
- name: hacker-news
description: Hacker News
color: "#8aadf4"
- name: homepage
description: homepage
color: "#8aadf4"
- name: ichi.moe
description: ichi.moe
color: "#8aadf4"
- name: invidious
description: Invidious
color: "#8aadf4"
- name: invokeai
description: InvokeAI
color: "#8aadf4"
- name: lastfm
description: Last.fm
color: "#8aadf4"
- name: libreddit
description: Libreddit
color: "#8aadf4"
- name: mastodon
description: Mastodon
color: "#8aadf4"
- name: modrinth
description: Modrinth
color: "#8aadf4"
- name: nitter
description: Nitter
color: "#8aadf4"
- name: nixos-search
description: NixOS Search
color: "#8aadf4"
- name: paste.rs
description: paste.rs
color: "#8aadf4"
- name: proton
description: Proton
color: "#8aadf4"
- name: quizlet
description: Quizlet
color: "#8aadf4"
- name: reddit
description: Reddit
color: "#8aadf4"
- name: searxng
description: SearXNG
color: "#8aadf4"
- name: substack
description: Substack
color: "#8aadf4"
- name: tutanota
description: Tutanota
color: "#8aadf4"
- name: twitch
description: Twitch
color: "#8aadf4"
- name: vercel
description: Vercel
color: "#8aadf4"
- name: whatsapp-web
description: WhatsApp Web
color: "#8aadf4"
- name: wikiwand
description: WikiWand
color: "#8aadf4"
- name: youtube
description: YouTube
color: "#8aadf4"

18
.github/workflows/sync-labels.yml vendored Normal file
View File

@ -0,0 +1,18 @@
name: Sync Labels
on:
workflow_dispatch:
push:
branches: [main]
paths:
- ".github/labels.yml"
jobs:
update:
name: Update
runs-on: ubuntu-latest
steps:
- uses: r7kamura/github-label-sync-action@v0
if: ${{ github.repository == 'catppuccin/userstyles' }}
with:
allow_added_labels: "true"

View File

@ -4,9 +4,7 @@ import Ajv from "npm:ajv@8.12.0";
import * as path from "https://deno.land/std@0.181.0/path/mod.ts"; import * as path from "https://deno.land/std@0.181.0/path/mod.ts";
import { walkSync } from "https://deno.land/std@0.181.0/fs/walk.ts"; import { walkSync } from "https://deno.land/std@0.181.0/fs/walk.ts";
import schema from "../userstyles.schema.json" assert { type: "json" }; import schema from "../userstyles.schema.json" assert { type: "json" };
import portsSchema from "https://raw.githubusercontent.com/catppuccin/catppuccin/main/resources/ports.schema.json" assert { import portsSchema from "https://raw.githubusercontent.com/catppuccin/catppuccin/main/resources/ports.schema.json" assert { type: "json" };
type: "json",
};
export type { Categories as PortCategories } from "https://raw.githubusercontent.com/catppuccin/catppuccin/main/resources/generate/types.d.ts"; export type { Categories as PortCategories } from "https://raw.githubusercontent.com/catppuccin/catppuccin/main/resources/generate/types.d.ts";
export { Ajv, path, portsSchema, schema, walkSync }; export { Ajv, path, portsSchema, schema, walkSync };

View File

@ -42,7 +42,7 @@ const validate = ajv.compile<Metadata>(schema);
const validatePorts = ajv.compile<PortMetadata>(portsSchema); const validatePorts = ajv.compile<PortMetadata>(portsSchema);
const userstylesYaml = Deno.readTextFileSync( const userstylesYaml = Deno.readTextFileSync(
path.join(ROOT, "../userstyles.yml"), path.join(ROOT, "../userstyles.yml")
); );
const userstylesData = parseYaml(userstylesYaml); const userstylesData = parseYaml(userstylesYaml);
if (!validate(userstylesData)) { if (!validate(userstylesData)) {
@ -51,7 +51,7 @@ if (!validate(userstylesData)) {
} }
const portsYaml = await fetch( const portsYaml = await fetch(
"https://raw.githubusercontent.com/catppuccin/catppuccin/main/resources/ports.yml", "https://raw.githubusercontent.com/catppuccin/catppuccin/main/resources/ports.yml"
); );
const portsData = parseYaml(await portsYaml.text()); const portsData = parseYaml(await portsYaml.text());
if (!validatePorts(portsData)) { if (!validatePorts(portsData)) {
@ -70,7 +70,7 @@ const categorized = Object.entries(userstylesData.userstyles).reduce(
}); });
return acc; return acc;
}, },
{} as Record<string, MappedPort[]>, {} as Record<string, MappedPort[]>
); );
const portListData = portsData.categories const portListData = portsData.categories
@ -88,18 +88,14 @@ const portContent = portListData
`<details open> `<details open>
<summary>${data.meta.emoji} ${data.meta.name}</summary> <summary>${data.meta.emoji} ${data.meta.name}</summary>
${ ${data.ports
data.ports
.map((port) => { .map((port) => {
const name = Array.isArray(port.name) const name = Array.isArray(port.name) ? port.name.join(", ") : port.name;
? port.name.join(", ")
: port.name;
return `- [${name}](${port.path})`; return `- [${name}](${port.path})`;
}) })
.join("\n") .join("\n")}
}
</details>`, </details>`
) )
.join("\n"); .join("\n");
@ -155,6 +151,17 @@ const pullRequestLabelerContent = Object.entries(userstylesData.userstyles)
.join("\n"); .join("\n");
updateFile(pullRequestLabelerPath, pullRequestLabelerContent); updateFile(pullRequestLabelerPath, pullRequestLabelerContent);
const syncLabels = path.join(REPO_ROOT, ".github/labels.yml");
const syncLabelsContent = Object.entries(userstylesData.userstyles)
.map(
([key, style]) =>
`- name: ${key}
description: ${style.name}
color: "#8aadf4"`
)
.join("\n");
updateFile(syncLabels, syncLabelsContent);
const issuesLabelerPath = path.join(REPO_ROOT, ".github/issue-labeler.yml"); const issuesLabelerPath = path.join(REPO_ROOT, ".github/issue-labeler.yml");
const issuesLabelerContent = Object.entries(userstylesData.userstyles) const issuesLabelerContent = Object.entries(userstylesData.userstyles)
.map(([key]) => `${key}: ['(${ISSUE_PREFIX + key})']`) .map(([key]) => `${key}: ['(${ISSUE_PREFIX + key})']`)
@ -176,15 +183,13 @@ const userstyleIssuePath = path.join(ROOT, "templates/userstyle-issue.yml");
const userstyleIssueContent = Deno.readTextFileSync(userstyleIssuePath); const userstyleIssueContent = Deno.readTextFileSync(userstyleIssuePath);
const replacedUserstyleIssueContent = userstyleIssueContent.replace( const replacedUserstyleIssueContent = userstyleIssueContent.replace(
"$PORTS", "$PORTS",
`${ `${Object.entries(userstylesData.userstyles)
Object.entries(userstylesData.userstyles)
.map(([key]) => `'${ISSUE_PREFIX + key}'`) .map(([key]) => `'${ISSUE_PREFIX + key}'`)
.join(", ") .join(", ")}`
}`,
); );
Deno.writeTextFileSync( Deno.writeTextFileSync(
path.join(REPO_ROOT, ".github/ISSUE_TEMPLATE/userstyle.yml"), path.join(REPO_ROOT, ".github/ISSUE_TEMPLATE/userstyle.yml"),
replacedUserstyleIssueContent, replacedUserstyleIssueContent
); );
const heading = (name: Name, link: ApplicationLink) => { const heading = (name: Name, link: ApplicationLink) => {
@ -193,15 +198,13 @@ const heading = (name: Name, link: ApplicationLink) => {
if (nameArray.length !== linkArray.length) { if (nameArray.length !== linkArray.length) {
throw new Error( throw new Error(
'The "name" and "app-link" arrays must have the same length', 'The "name" and "app-link" arrays must have the same length'
); );
} }
return `Catppuccin for ${ return `Catppuccin for ${nameArray
nameArray
.map((name, index) => `<a href="${linkArray[index]}">${name}</a>`) .map((name, index) => `<a href="${linkArray[index]}">${name}</a>`)
.join(", ") .join(", ")}`;
}`;
}; };
const usageContent = (usage?: Usage) => { const usageContent = (usage?: Usage) => {
@ -213,11 +216,9 @@ const faqContent = (faq?: FAQ) => {
return ""; return "";
} }
return `## 🙋 FAQ return `## 🙋 FAQ
${ ${faq
faq
.map(({ question, answer }) => `- Q: ${question} \n\tA: ${answer}`) .map(({ question, answer }) => `- Q: ${question} \n\tA: ${answer}`)
.join("\n") .join("\n")}`;
}`;
}; };
const collaboratorsContent = (allCollaborators: CollaboratorsData[]) => { const collaboratorsContent = (allCollaborators: CollaboratorsData[]) => {
@ -235,7 +236,7 @@ const collaboratorsContent = (allCollaborators: CollaboratorsData[]) => {
const updateStylesReadmeContent = ( const updateStylesReadmeContent = (
readme: string, readme: string,
key: string, key: string,
userstyle: Userstyle, userstyle: Userstyle
) => { ) => {
return readme return readme
.replace("$TITLE", heading(userstyle.name, userstyle.readme["app-link"])) .replace("$TITLE", heading(userstyle.name, userstyle.readme["app-link"]))
@ -253,7 +254,7 @@ const updateStylesReadmeContent = (
collaborators: userstyle.readme["past-maintainers"], collaborators: userstyle.readme["past-maintainers"],
heading: "## 💖 Past Maintainer(s)", heading: "## 💖 Past Maintainer(s)",
}, },
]), ])
); );
}; };
@ -265,11 +266,11 @@ for (const [key, userstyle] of Object.entries(userstylesData.userstyles)) {
readmeContent = updateStylesReadmeContent( readmeContent = updateStylesReadmeContent(
stylesReadmeContent, stylesReadmeContent,
key, key,
userstyle, userstyle
); );
Deno.writeTextFileSync( Deno.writeTextFileSync(
path.join(REPO_ROOT, "styles", key, "README.md"), path.join(REPO_ROOT, "styles", key, "README.md"),
readmeContent, readmeContent
); );
} catch (e) { } catch (e) {
console.log(`Failed to update ${userstyle} README:`, e); console.log(`Failed to update ${userstyle} README:`, e);