import type { Context } from "hono"; import type { IssueEvent, TaskRequest } from "../types.js"; import type { TaskQueue } from "../queue.js"; import type { Config } from "../config.js"; /** * Release ticket opened → tag RC for staging. * Release ticket labeled staging-verified → tag for production. * * Replaces: release-process.json */ export function release(config: Config, queue: TaskQueue) { return async (c: Context) => { const event = await c.req.json(); const labels = event.issue.labels.map((l) => l.name); const [org, repo] = event.repository.full_name.split("/"); const isRelease = event.issue.title.toLowerCase().includes("release") || labels.includes("release"); if (!isRelease) { return c.text("ignored: not a release ticket", 200); } let shouldProcess = false; if (event.action === "opened") { shouldProcess = true; } if ( (event.action === "label_updated" || event.action === "labeled") && labels.includes("staging-verified") && !labels.includes("deployed-to-production") ) { shouldProcess = true; } if (!shouldProcess) { return c.text("ignored: no actionable release event", 200); } const task: TaskRequest = { taskType: "release", issueNumber: event.issue.number, giteaOrg: org, giteaRepo: repo, repoCloneUrl: event.repository.clone_url, giteaToken: config.giteaDevToken, }; const queued = await queue.enqueue(task, { useReviewAccount: false, body: `🤖 Release process started.`, }); return c.json({ ok: true, queued }); }; }