102 lines
3.6 KiB
JavaScript
102 lines
3.6 KiB
JavaScript
#!/usr/bin/env node
|
||
/**
|
||
* seed-gitea-labels — crée les labels attendus (idempotent)
|
||
*
|
||
* Usage:
|
||
* FORGE_TOKEN=... FORGE_API=http://192.168.1.20:3000 node scripts/seed-gitea-labels.mjs
|
||
* (ou FORGE_BASE=https://gitea... si pas de FORGE_API)
|
||
*
|
||
* Optionnel:
|
||
* GITEA_OWNER / GITEA_REPO (sinon auto-détecté via git remote origin)
|
||
*/
|
||
|
||
import { spawnSync } from "node:child_process";
|
||
|
||
function getEnv(name, fallback = "") {
|
||
return (process.env[name] ?? fallback).trim();
|
||
}
|
||
|
||
function inferOwnerRepoFromGit() {
|
||
const r = spawnSync("git", ["remote", "get-url", "origin"], { encoding: "utf-8" });
|
||
if (r.status !== 0) return null;
|
||
const u = (r.stdout || "").trim();
|
||
const m = u.match(/[:/](?<owner>[^/]+)\/(?<repo>[^/]+?)(?:\.git)?$/);
|
||
if (!m?.groups) return null;
|
||
return { owner: m.groups.owner, repo: m.groups.repo };
|
||
}
|
||
|
||
async function apiReq(base, token, method, path, payload = null) {
|
||
const url = `${base.replace(/\/+$/, "")}/api/v1${path}`;
|
||
const headers = {
|
||
Authorization: `token ${token}`,
|
||
Accept: "application/json",
|
||
"User-Agent": "archicratie-seed-labels/1.0",
|
||
};
|
||
const init = { method, headers };
|
||
|
||
if (payload != null) {
|
||
init.headers["Content-Type"] = "application/json";
|
||
init.body = JSON.stringify(payload);
|
||
}
|
||
|
||
const res = await fetch(url, init);
|
||
const text = await res.text().catch(() => "");
|
||
let json = null;
|
||
try { json = text ? JSON.parse(text) : null; } catch {}
|
||
if (!res.ok) throw new Error(`HTTP ${res.status} ${method} ${url}\n${text}`);
|
||
return json;
|
||
}
|
||
|
||
async function main() {
|
||
const token = getEnv("FORGE_TOKEN");
|
||
if (!token) throw new Error("FORGE_TOKEN manquant");
|
||
|
||
const inferred = inferOwnerRepoFromGit() || {};
|
||
const owner = getEnv("GITEA_OWNER", inferred.owner || "");
|
||
const repo = getEnv("GITEA_REPO", inferred.repo || "");
|
||
if (!owner || !repo) throw new Error("Impossible de déterminer owner/repo (GITEA_OWNER/GITEA_REPO ou git remote)");
|
||
|
||
const base = getEnv("FORGE_API") || getEnv("FORGE_BASE");
|
||
if (!base) throw new Error("FORGE_API ou FORGE_BASE manquant");
|
||
|
||
const wanted = [
|
||
// type/*
|
||
{ name: "type/comment", color: "1d76db", description: "Commentaire éditorial (site)" },
|
||
{ name: "type/media", color: "1d76db", description: "Media à intégrer (image/audio/video)" },
|
||
{ name: "type/correction", color: "1d76db", description: "Correction proposée" },
|
||
{ name: "type/fact-check", color: "1d76db", description: "Vérification / sourçage" },
|
||
|
||
// state/*
|
||
{ name: "state/a-trier", color: "0e8a16", description: "À trier" },
|
||
{ name: "state/recevable", color: "0e8a16", description: "Recevable" },
|
||
{ name: "state/a-sourcer", color: "0e8a16", description: "À sourcer" },
|
||
|
||
// scope/*
|
||
{ name: "scope/readers", color: "5319e7", description: "Signalé par lecteur" },
|
||
{ name: "scope/editors", color: "5319e7", description: "Signalé par éditeur" },
|
||
];
|
||
|
||
const labels = (await apiReq(base, token, "GET", `/repos/${owner}/${repo}/labels?limit=1000`)) || [];
|
||
const existing = new Set(labels.map((x) => x?.name).filter(Boolean));
|
||
|
||
let created = 0;
|
||
for (const L of wanted) {
|
||
if (existing.has(L.name)) continue;
|
||
await apiReq(base, token, "POST", `/repos/${owner}/${repo}/labels`, {
|
||
name: L.name,
|
||
color: L.color,
|
||
description: L.description,
|
||
});
|
||
created++;
|
||
console.log("✅ created:", L.name);
|
||
}
|
||
|
||
if (created === 0) console.log("ℹ️ seed: nothing to do (all labels already exist)");
|
||
else console.log(`✅ seed done: created=${created}`);
|
||
}
|
||
|
||
main().catch((e) => {
|
||
console.error("💥 seed-gitea-labels:", e?.message || e);
|
||
process.exit(1);
|
||
});
|