// forgejo doesn't have a built-in way to clear old actions logs, so we have to do it manually // https://github.com/go-gitea/gitea/issues/24256, didnt find a separate issue for forgejo import * as fs from 'fs' import * as path from 'path' const LOGS_DIR = '/srv/forgejo/data/data/actions_log' const RETENTION = 30 * 24 * 60 * 60 * 1000 // 30 days function handleLogsDir(dir) { // the actions_log dir structure is something like this: // actions_log/owner/repo/job-id-hex/job-id.log.zst // (todo: verify this is the case) let found = false const subdirs = fs.readdirSync(dir, { withFileTypes: true }) for (const subdir of subdirs) { if (!subdir.isDirectory()) continue const fullPath = path.join(dir, subdir.name) // validate that the structure is how we expect it const jobId = parseInt(subdir.name, 16) if (isNaN(jobId)) { console.error(`invalid job id at: ${fullPath}`) process.exit(1) } const children = fs.readdirSync(fullPath, { withFileTypes: true }) if (children.length !== 1 || !children[0].isFile() || children[0].name !== `${jobId}.log.zst`) { console.error(`Invalid actions_log dir: ${dir}`) process.exit(1) } const stat = fs.statSync(fullPath) if (stat.mtimeMs < Date.now() - RETENTION) { console.log(`deleting old (${new Date(stat.mtimeMs).toISOString()}) actions log: ${fullPath}`) fs.rmSync(fullPath, { recursive: true }) found = true } } } for (const owner of fs.readdirSync(LOGS_DIR)) { for (const repo of fs.readdirSync(path.join(LOGS_DIR, owner))) { handleLogsDir(path.join(LOGS_DIR, owner, repo)) } }