Files
sdlc-orchestrator/src/handlers/issue-comment.ts
T
Daniel SamsonandClaude Opus 4.6 13e96e9356
Publish Image / publish (push) Successful in 36s
Migrate task queue from in-memory to BullMQ + Redis
Replace the volatile in-memory Map/Set queue with BullMQ backed by Redis
for persistence across restarts, automatic retry with exponential backoff,
and non-blocking workspace cleanup.

- Two queues: workspace-create (concurrency-limited) and workspace-cleanup
  (with polling instead of sleep-based stop→delete)
- Active workspaces tracked in Redis hash for dedup across restarts
- Stale sweep every 10 minutes catches orphaned workspaces
- Graceful shutdown on SIGTERM/SIGINT
- Replace node-cron with BullMQ repeatable jobs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-12 15:40:12 +01:00

51 lines
1.5 KiB
TypeScript

import type { Context } from "hono";
import type { IssueCommentEvent, TaskRequest } from "../types.js";
import type { TaskQueue } from "../queue.js";
import type { Config } from "../config.js";
/**
* Issue comment created or edited → re-trigger analyst if still in analysis.
*
* Replaces: issue-comment-reply.json
*/
export function issueComment(config: Config, queue: TaskQueue) {
return async (c: Context) => {
const event = await c.req.json<IssueCommentEvent>();
if (event.action !== "created" && event.action !== "edited") {
return c.text("ignored: not a created or edited event", 200);
}
const commenter = event.comment.user.login;
const botUsernames = [config.botDevUsername, config.botReviewUsername];
if (botUsernames.includes(commenter)) {
return c.text("ignored: bot comment", 200);
}
const labels = event.issue.labels.map((l) => l.name);
const pastAnalysis =
labels.includes("ready-for-architecture") ||
labels.includes("ready-for-development");
if (pastAnalysis) {
return c.text("ignored: issue past analysis stage", 200);
}
const [org, repo] = event.repository.full_name.split("/");
const task: TaskRequest = {
taskType: "analyse",
issueNumber: event.issue.number,
giteaOrg: org,
giteaRepo: repo,
repoCloneUrl: event.repository.clone_url,
giteaToken: config.giteaDevToken,
};
const queued = await queue.enqueue(task);
return c.json({ ok: true, queued });
};
}