ci: automatically sync labels with userstyles (#143)
This commit is contained in:
parent
5f5a744a95
commit
4f83ac4607
109
.github/labels.yml
vendored
Normal file
109
.github/labels.yml
vendored
Normal 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
18
.github/workflows/sync-labels.yml
vendored
Normal 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"
|
@ -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 };
|
||||||
|
@ -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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user