diff --git a/tools/publish-update.cjs b/tools/publish-update.cjs index 03e551c..e25435a 100644 --- a/tools/publish-update.cjs +++ b/tools/publish-update.cjs @@ -185,9 +185,24 @@ async function giteaPrune(baseUrl, token, keepFile, keepPrevious = 1) { let files; try { files = JSON.parse(res.body); } catch (_) { return; } if (!Array.isArray(files)) return; + // Rank by the version in the filename, not by created_at: this server returns that field empty, + // which would leave every build "equally old" and quietly retain the OLDEST one as the rollback + // copy instead of the newest. + const verOf = (name) => { + const m = String(name).match(/(\d+(?:\.\d+)+)/); + return m ? m[1].split('.').map(n => parseInt(n, 10) || 0) : []; + }; + const newerFirst = (a, b) => { + const pa = verOf(a.name), pb = verOf(b.name); + for (let i = 0; i < Math.max(pa.length, pb.length); i++) { + const x = pa[i] || 0, y = pb[i] || 0; + if (x !== y) return y - x; + } + return new Date(b.created_at || 0) - new Date(a.created_at || 0); + }; const stale = files .filter(f => f && typeof f.name === 'string' && f.name.toLowerCase().endsWith('.exe') && f.name !== keepFile) - .sort((a, b) => new Date(b.created_at || 0) - new Date(a.created_at || 0)) + .sort(newerFirst) .slice(keepPrevious); for (const f of stale) { const del = await giteaRequest('DELETE', baseUrl.replace(/\/+$/, '') + '/' + encodeURIComponent(f.name), token, null);