feat(deploy): trigger JD agent after human merge

This commit is contained in:
冰朔 2026-08-06 13:35:10 +08:00
commit 564859b1ce
9 changed files with 517 additions and 8 deletions

View file

@ -11,9 +11,30 @@ function enqueueDeploymentEvent(intent, push, queueDir, context = {}) {
const invalid = validateIntent(intent, push, context);
if (invalid) return { state: "rejected", diagnostic_code: invalid };
fs.mkdirSync(queueDir, { recursive: true, mode: 0o750 });
const requestedEventId = String(context.event_id || "");
if (requestedEventId && !/^[0-9a-f]{8}-[0-9a-f]{4}-[45][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(requestedEventId)) {
return { state: "rejected", diagnostic_code: "deployment_event_id_invalid" };
}
const eventId = requestedEventId || crypto.randomUUID();
const dedupeKey = String(context.dedupe_key || "");
let marker = "";
if (dedupeKey) {
const dedupeDir = path.join(queueDir, ".dedupe");
fs.mkdirSync(dedupeDir, { recursive: true, mode: 0o750 });
marker = path.join(dedupeDir, `${crypto.createHash("sha256").update(dedupeKey).digest("hex")}.json`);
try {
fs.writeFileSync(marker, JSON.stringify({ event_id: eventId, state: "reserved" }), { mode: 0o640, flag: "wx" });
} catch (error) {
if (error.code === "EEXIST") {
const prior = JSON.parse(fs.readFileSync(marker, "utf8"));
return { state: "duplicate", event_id: String(prior.event_id || eventId) };
}
throw error;
}
}
const event = {
schema: "guanghu.deployment-event/v1",
event_id: crypto.randomUUID(),
event_id: eventId,
created_at: Date.now() / 1000,
state: "queued_for_resident_agent",
repo: push.repo, branch: push.branch, commit_sha: push.commit_sha,
@ -28,8 +49,21 @@ function enqueueDeploymentEvent(intent, push, queueDir, context = {}) {
};
const target = path.join(queueDir, `${event.created_at}-${event.event_id}.json`);
const temporary = `${target}.${process.pid}.tmp`;
fs.writeFileSync(temporary, JSON.stringify(event), { mode: 0o640 });
fs.renameSync(temporary, target);
try {
fs.writeFileSync(temporary, JSON.stringify(event), { mode: 0o640, flag: "wx" });
fs.renameSync(temporary, target);
if (marker) {
const markerTemporary = `${marker}.${process.pid}.tmp`;
fs.writeFileSync(markerTemporary, JSON.stringify({ event_id: eventId, state: "queued", queued_at: event.created_at }), { mode: 0o640, flag: "wx" });
fs.renameSync(markerTemporary, marker);
}
} catch (error) {
try { fs.unlinkSync(temporary); } catch {}
if (marker) {
try { fs.unlinkSync(marker); } catch {}
}
throw error;
}
return { state: event.state, event_id: event.event_id };
}
function validateIntent(intent, push, context = {}) {