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

@ -877,6 +877,52 @@ test("deployment is dispatched only by an explicit approved second signal", asyn
} finally { fs.rmSync(dir, { recursive: true, force: true }); }
});
test("Forgejo human merge webhook queues deployment without a second workorder", async () => {
const dir = fs.mkdtempSync(path.join(os.tmpdir(), "lake-lamp-merge-deploy-"));
const secret = "m".repeat(64);
const commit = "b".repeat(40);
const payload = {
action: "closed",
repository: { full_name: "bingshuo/guanghu-ice-heart" },
pull_request: {
number: 7,
merged: true,
merge_commit_sha: commit,
merged_by: { login: "bingshuo" },
base: { ref: "main" },
},
};
const body = JSON.stringify(payload);
const signature = crypto.createHmac("sha256", secret).update(body).digest("hex");
try {
await withServer(async ({ base }) => {
const response = await fetch(`${base}/api/deployment/forgejo-merge`, {
method: "POST",
headers: {
"content-type": "application/json",
"x-forgejo-event": "pull_request",
"x-forgejo-delivery": "delivery-server-test-001",
"x-forgejo-signature": signature,
},
body,
});
assert.equal(response.status, 202);
const result = await response.json();
assert.equal(result.state, "queued_for_resident_agent");
assert.equal(result.queued, 1);
assert.equal(fs.readdirSync(path.join(dir, "queue")).filter(name => name.endsWith(".json")).length, 1);
}, {
forgejoMergeSecret: secret,
forgejoMergeMergers: ["bingshuo"],
deploymentQueueDir: path.join(dir, "queue"),
deploymentRepositories: { "bingshuo/guanghu-ice-heart": {} },
listForgejoPullFiles: async () => [
{ filename: "deployment/requests/HLCC-HUMAN-MERGE-AUTO-DEPLOY-20260806.json", status: "added" },
],
});
} finally { fs.rmSync(dir, { recursive: true, force: true }); }
});
test("request endpoint rejects direct email target switching and unknown actions", async () => {
await withServer(async ({ base }) => {
const common = { method: "POST", headers: { authorization: "Bearer request-only-secret", "content-type": "application/json" } };