// Hilfen für „Release für den Updater veröffentlichen“. // Der Updater (updater.js) vergleicht den Tag des neuesten Releases mit der lokalen Version, sucht das // Installer-Asset und liest die SHA-256-Prüfsumme aus einem Asset „.sha256“ oder aus einer Zeile // im Release-Text, die Dateiname und 64 Hex-Zeichen enthält. Dieses Modul stellt sicher, dass beides stimmt. const SHA256_RE = /\b([a-fA-F0-9]{64})\b/; // '2.2.1' aus 'Git-Manager-GUI-Setup-2.2.1.exe' (oder null) function parseVersionFromFileName(name) { const m = String(name || '').match(/(\d+\.\d+\.\d+)/); return m ? m[1] : null; } // Zerlegt 'v2.10.3' in [2, 10, 3]; ungültige Teile zählen als 0. function versionParts(v) { return String(v || '').replace(/^[^\d]*/, '').split('.').map((p) => parseInt(p, 10) || 0); } function compareVersions(a, b) { const pa = versionParts(a); const pb = versionParts(b); for (let i = 0; i < Math.max(pa.length, pb.length, 3); i++) { const d = (pa[i] || 0) - (pb[i] || 0); if (d !== 0) return d > 0 ? 1 : -1; } return 0; } // Inhalt einer .sha256-Datei (" ") → Hash in Kleinbuchstaben oder null function parseSidecar(text) { const m = String(text || '').match(SHA256_RE); return m ? m[1].toLowerCase() : null; } // Prüft, ob ein neuer Tag zum Updater passt. // releases: vorhandene Releases ({ tag_name }), neueste zuerst oder beliebig. function checkNewTag(tag, releases) { const wanted = String(tag || '').trim(); if (!/^v?\d+\.\d+\.\d+$/i.test(wanted)) { return { ok: false, reason: 'Der Tag muss eine Version wie v2.2.1 sein, sonst erkennt der Updater das Release nicht.' }; } const tags = (releases || []).map((r) => String(r.tag_name || '')).filter(Boolean); if (tags.some((t) => t.toLowerCase() === wanted.toLowerCase())) { return { ok: false, reason: `Den Tag „${wanted}“ gibt es schon.` }; } const newest = tags.filter((t) => /\d+\.\d+\.\d+/.test(t)).sort(compareVersions).pop(); if (newest && compareVersions(wanted, newest) <= 0) { return { ok: false, reason: `Die Version ${wanted} ist nicht neuer als das neueste Release ${newest}. Der Updater würde sie nicht anbieten.` }; } return { ok: true, newest: newest || null }; } // Hängt die Prüfsummen an die Release-Notizen, in dem Format, das der Updater liest. function buildReleaseBody(notes, assets) { const base = String(notes || '').replace(/\s+$/, ''); const lines = (assets || []) .filter((a) => a && a.name && /^[a-fA-F0-9]{64}$/.test(String(a.sha256 || ''))) .map((a) => `- ${a.name}: ${String(a.sha256).toLowerCase()}`); if (lines.length === 0) return base; const block = ['### Prüfsummen (SHA-256)', ...lines].join('\n'); return base ? `${base}\n\n${block}\n` : `${block}\n`; } module.exports = { parseVersionFromFileName, compareVersions, parseSidecar, checkNewTag, buildReleaseBody };