import { all, first } from "../db"; import { CAPS } from "../limits"; import { deleteRunnerRow, summarizeRunner } from "./runner-registration"; import type { RunnerRow, RunnerSummary } from "./runner-registration"; /** Owner-wide runners of an account (they serve every repository it owns). */ export async function listOwnerRunners(ownerId: string): Promise { const rows = await all( "SELECT * FROM runners WHERE owner_id = ? ORDER BY name LIMIT ?", ownerId, CAPS.runnersPerScope, ); const busy = await all<{ runner_id: string; count: number }>( `SELECT j.runner_id, COUNT(*) AS count FROM workflow_jobs j JOIN runners r ON r.id = j.runner_id WHERE j.status = 'in_progress' AND r.owner_id = ? GROUP BY j.runner_id`, ownerId, ); const counts = new Map(busy.map((row) => [row.runner_id, row.count])); return rows.map((row) => summarizeRunner(row, counts.get(row.id) ?? 0)); } /** Callers must have checked owner admin. */ export async function removeOwnerRunner(ownerId: string, runnerId: string): Promise { const row = await first<{ id: string }>("SELECT id FROM runners WHERE id = ? AND owner_id = ?", runnerId, ownerId); if (!row) return false; await deleteRunnerRow(runnerId); return true; }