Files
DiunaBI/.gitea/scripts/getLatestRunWithArtifacts.js
Michał Zieliński 687f5b2be3 wip release
2025-09-18 08:58:49 +02:00

97 lines
3.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// .gitea/scripts/getLatestRunWithArtifacts.js
// Robust finder: uses only Gitea API (no GUI URLs).
const fs = require("fs");
const path = require("path");
const BASE = process.env.GITEA_BASE_URL; // e.g. https://code.bim-it.pl
const OWNER = process.env.OWNER; // e.g. mz
const REPO = process.env.REPO; // e.g. DiunaBI
const TOKEN = process.env.GITEA_PAT;
const SCAN_LIMIT = Number(process.env.SCAN_LIMIT || "100");
const REQUIRED_ARTIFACTS = (process.env.REQUIRED_ARTIFACTS || "frontend,webapi")
.split(",").map(s => s.trim()).filter(Boolean);
if (!BASE || !OWNER || !REPO) {
console.error("Missing one of: GITEA_BASE_URL, OWNER, REPO"); process.exit(1);
}
if (!TOKEN) {
console.error("Missing GITEA_PAT"); process.exit(1);
}
const cacheDir = path.join(".gitea", ".cache");
fs.mkdirSync(cacheDir, { recursive: true });
async function apiJSON(url) {
const res = await fetch(url, { headers: { Authorization: `token ${TOKEN}` } });
if (!res.ok) {
const t = await res.text().catch(()=>"");
throw new Error(`API ${res.status} for ${url}\n${t}`);
}
return res.json();
}
(async () => {
// 1) Pobierz listę tasków (runs)
const listUrl = `${BASE}/api/v1/repos/${OWNER}/${REPO}/actions/tasks?limit=${SCAN_LIMIT}`;
const resp = await apiJSON(listUrl);
// Gitea 1.24 może zwracać różne kształty normalizujemy:
const raw = Array.isArray(resp)
? resp
: (resp.workflow_runs || resp.tasks || resp.data || []);
if (!Array.isArray(raw) || raw.length === 0) {
console.error("No runs returned by API."); process.exit(1);
}
// 2) Filtrujemy „successful”
const isSuccess = (r) => {
const s = (r.status || "").toLowerCase(); // "success" / "completed"
const c = (r.conclusion || "").toLowerCase(); // "success" (czasem brak)
return s === "success" || (s === "completed" && c === "success");
};
const candidates = raw
.filter(r => r && (r.id != null))
.sort((a, b) => (b.id ?? 0) - (a.id ?? 0))
.filter(isSuccess);
if (candidates.length === 0) {
console.error("No successful runs found."); process.exit(1);
}
console.log(`Scanning ${candidates.length} successful runs for artifacts: ${REQUIRED_ARTIFACTS.join(", ")}`);
// 3) Sprawdź artefakty przez API
let pickedId = null;
for (const r of candidates) {
const runId = r.id;
const artsUrl = `${BASE}/api/v1/repos/${OWNER}/${REPO}/actions/runs/${runId}/artifacts`;
try {
const arts = await apiJSON(artsUrl);
const names = (Array.isArray(arts?.artifacts) ? arts.artifacts : arts || [])
.map(a => a?.name)
.filter(Boolean);
const ok = REQUIRED_ARTIFACTS.every(req => names.includes(req));
if (ok) { pickedId = runId; break; }
console.log(`Run ${runId}: lacks required artifacts (has: ${names.join(", ") || "none"})`);
} catch (e) {
console.log(`Run ${runId}: cannot read artifacts via API -> ${e.message.split("\n")[0]}`);
}
}
if (!pickedId) {
console.error("No run exposes all required artifacts via API.");
process.exit(1);
}
// 4) Zapisz outputy
fs.writeFileSync(path.join(cacheDir, "run_id"), String(pickedId), "utf8");
if (process.env.GITHUB_OUTPUT) {
fs.appendFileSync(process.env.GITHUB_OUTPUT, `run_id=${pickedId}\n`);
}
console.log(`Picked run_id=${pickedId}`);
})().catch(err => {
console.error(err.stack || err.message || String(err));
process.exit(1);
});