From b25fcaef0f14293886f020231e169be51bb3da45 Mon Sep 17 00:00:00 2001 From: Shadow Date: Sun, 25 Jan 2026 20:38:44 -0600 Subject: [PATCH] CI: parse labeler without deps --- scripts/sync-labels.ts | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/scripts/sync-labels.ts b/scripts/sync-labels.ts index 0220e911a..297644c1e 100644 --- a/scripts/sync-labels.ts +++ b/scripts/sync-labels.ts @@ -1,9 +1,6 @@ import { execFileSync } from "node:child_process"; import { readFileSync } from "node:fs"; import { resolve } from "node:path"; -import yaml from "yaml"; - -type LabelConfig = Record; type RepoLabel = { name: string; @@ -20,13 +17,12 @@ const COLOR_BY_PREFIX = new Map([ ]); const configPath = resolve(".github/labeler.yml"); -const config = yaml.parse(readFileSync(configPath, "utf8")) as LabelConfig; +const labelNames = extractLabelNames(readFileSync(configPath, "utf8")); -if (!config || typeof config !== "object") { - throw new Error("labeler.yml must be a mapping of label names to globs."); +if (!labelNames.length) { + throw new Error("labeler.yml must declare at least one label."); } -const labelNames = Object.keys(config).filter(Boolean); const repo = resolveRepo(); const existing = fetchExistingLabels(repo); @@ -55,6 +51,26 @@ for (const label of missing) { console.log(`Created label: ${label}`); } +function extractLabelNames(contents: string): string[] { + const labels: string[] = []; + for (const line of contents.split("\n")) { + if (!line.trim() || line.trimStart().startsWith("#")) { + continue; + } + if (/^\s/.test(line)) { + continue; + } + const match = line.match(/^(["'])(.+)\1\s*:/) ?? line.match(/^([^:]+):/); + if (match) { + const name = (match[2] ?? match[1] ?? "").trim(); + if (name) { + labels.push(name); + } + } + } + return labels; +} + function pickColor(label: string): string { const prefix = label.includes(":") ? label.split(":", 1)[0].trim() : label.trim(); return COLOR_BY_PREFIX.get(prefix) ?? "ededed";