delqhi/sin-github-issues
0
1import { runCommand, runJsonCommand } from './command.js';2 3type IssueRow = { number: number; title: string; url: string; state: string };4 5export async function ensureIssue(input: {6 repo: string;7 title: string;8 body: string;9 labels?: string[];10}) {11 const rows = await runJsonCommand<IssueRow[]>('gh', ['issue', 'list', '--repo', input.repo, '--state', 'all', '--limit', '200', '--json', 'number,title,url,state']);12 const existing = rows.find((row) => row.title.trim().toLowerCase() === input.title.trim().toLowerCase());13 if (existing) {14 await runCommand('gh', ['issue', 'edit', String(existing.number), '--repo', input.repo, '--body', input.body], undefined);15 for (const label of input.labels || []) {16 try {17 await runCommand('gh', ['issue', 'edit', String(existing.number), '--repo', input.repo, '--add-label', label], undefined);18 } catch {19 }20 }21 return { created: false, issue: existing, issueNumber: existing.number, issueUrl: existing.url };22 }23 let created;24 try {25 created = await runCommand('gh', ['issue', 'create', '--repo', input.repo, '--title', input.title, '--body', input.body, ...(input.labels || []).flatMap((label) => ['--label', label])], undefined);26 } catch {27 created = await runCommand('gh', ['issue', 'create', '--repo', input.repo, '--title', input.title, '--body', input.body], undefined);28 }29 const url = created.stdout.trim();30 const issueNumber = Number.parseInt(url.split('/').pop() || '', 10);31 return { created: true, issueUrl: url, issueNumber };32}33 34export async function commentIssue(repo: string, issueNumber: number, body: string) {35 await runCommand('gh', ['issue', 'comment', String(issueNumber), '--repo', repo, '--body', body], undefined);36 return { ok: true, repo, issueNumber };37}38 39export async function closeIssue(repo: string, issueNumber: number, comment?: string) {40 const args = ['issue', 'close', String(issueNumber), '--repo', repo];41 if (comment) args.push('--comment', comment);42 await runCommand('gh', args, undefined);43 return { ok: true, repo, issueNumber };44}45 