// 清理舊版本成品的功能模組。 // 對應原本 entrypoint.sh 的「取得成品資訊」與「刪除舊版本成品」區段。 import { section, info, success, fail, warn } from './logger.js' import { isEmptyOrNull } from './validate.js' /** * 依建立時間由新到舊排序,保留最新的 keepCount 筆,回傳其餘待刪除的成品。 * 純函式,方便單元測試。 * @param {any[]} releases 成品清單 * @param {number} keepCount 要保留的筆數 * @returns {any[]} 需要刪除的成品(較舊者) */ export function selectReleasesToDelete(releases, keepCount) { const sorted = [...releases].sort( (a, b) => new Date(b.created_at) - new Date(a.created_at), ) return sorted.slice(keepCount) } /** * 讀取成品清單,刪除超出保留數量的舊版本成品。 * @param {import('./gitea-client.js').GiteaClient} client * @param {ReturnType} config */ export async function cleanupReleases(client, config) { section('取得成品資訊') info(`GET ${config.releaseApiUrl}`) const releases = await client.fetchAllPages(config.releaseApiUrl) info(`RELEASE_COUNT=${releases.length}`) info(`KEEP_COUNT=${config.keepCount}`) if (releases.length <= config.keepCount) { success('沒有需要清理的舊版本成品') return } section('刪除舊版本成品') const toDelete = selectReleasesToDelete(releases, config.keepCount) for (const release of toDelete) { const { id, tag_name: tag, name } = release if (isEmptyOrNull(id)) { warn(`略過沒有 id 的成品: ${tag} (${name})`) continue } const url = `${config.releaseApiUrl}/${id}` info(`DELETE ${tag} (${name})`) const code = await client.deleteResource(url) if (code === 204) { success(`成功刪除: ${tag} (${name})`) } else { fail(`刪除失敗: ${tag} (${name}), HTTP ${code}`) } } }