diff --git a/modules/gitea/index.ts b/modules/gitea/index.ts index 947086f..fcb437d 100644 --- a/modules/gitea/index.ts +++ b/modules/gitea/index.ts @@ -3,12 +3,12 @@ // // Emits (novox/hq ADR 0041/0042): // module.gitea.repo.created — a repository appeared, however it was made (push, web UI, or tool) +// module.gitea.pull.merged — a pull request was merged, however it was merged (web UI, API, or tool) // -// issue.opened and pull.merged are emitted from the tools (tools/index.ts), at the instant the mesh -// takes that action — the natural point, and one process only. repo.created belongs here instead: -// a repository is usually born from a `git push` or the web UI, which no tool sees, so polling the -// repo list is the only way to catch every path — and keeping it out of the create-repo tool means -// the fact is never announced twice from two processes. +// issue.opened is emitted from its tool (tools/index.ts). repo.created and pull.merged belong here: a +// repository or a merge is as often made by the web UI or a plain API call, which no tool sees, so +// polling is the only way to catch every path — and the only emitter, so a fact is never announced +// twice. The merge tool announced too until novox/hq issue 250, and every merge it made was heard twice. // // The polling is deliberately unhurried: an event a minute late is still an event, whereas hammering // the forge for an immediacy nobody asked for is not. diff --git a/modules/gitea/tools/index.ts b/modules/gitea/tools/index.ts index 51932f8..5c4cabe 100644 --- a/modules/gitea/tools/index.ts +++ b/modules/gitea/tools/index.ts @@ -1,12 +1,12 @@ // gitea's tools — moved here from the shared sdk (novox/hq ADR 0039), importing gitea's own client. // They return structured data; the mesh serves them through the sdk's tool harness. // -// Two tools emit an event at the natural point of the action they take (novox/hq ADR 0041/0042): -// create-issue emits issue.opened, merge-pull-request emits pull.merged — the mesh's own hand on -// the forge, announced the instant it moves. repo.created is deliberately NOT emitted here: repos -// are far more often born from a `git push` or the web UI than from this tool, so the events -// entrypoint (index.ts) owns that one by polling, which catches every path without this tool and -// the poll double-announcing the same repo from two processes. +// One tool emits an event at the natural point of the action it takes (novox/hq ADR 0041/0042): +// create-issue emits issue.opened. pull.merged and repo.created are deliberately NOT emitted here: a +// merge or a repository is as often made in the web UI or by a plain API call as by these tools, so the +// events entrypoint (index.ts) owns both by polling, which catches every path. Announcing a merge here +// as well announced every merge made through this tool twice — the tool's at once, the poll's moments +// later (novox/hq issue 250). import { registerModuleTools, type ToolDefinition } from "@novox/mesh-sdk/tools"; import { emit } from "@novox/mesh-sdk/events"; @@ -228,29 +228,11 @@ export function getGiteaTools(gitea: GiteaClient): ToolDefinition[] { const number = Number(args.number); const method = args.method ? String(args.method) : "merge"; const deleteBranch = args.delete_branch === undefined ? true : Boolean(args.delete_branch); - // Read the PR first, so the merged event carries a title and branches, not just a number. - const pull = await gitea.getPullRequest(owner, repo, number); await gitea.mergePullRequest(owner, repo, number, method, deleteBranch); - // Read it again: the merge commit only exists now, and it is what a build is made from. + // The merge commit only exists now; answered so the caller can follow what is built from it. + // pull.merged is the events entrypoint's to announce (index.ts), once, within its poll. const merged = await gitea.getPullRequest(owner, repo, number); - // And what it changed, so the mesh rebuilds the modules whose own files moved rather than - // every module built from the repository (novox/hq 04-ISSUES/131). - const changed = await gitea.listPullFiles(owner, repo, number); - await emit("pull.merged", { - owner, - repo, - number, - title: pull.title, - head: pull.head, - base: pull.base, - merge_commit_sha: merged.merge_commit_sha, - merged_at: merged.merged_at, - method, - html_url: pull.html_url, - paths: changed.paths, - paths_truncated: changed.truncated, - }); - return { merged: true, number, method, deleted_branch: deleteBranch }; + return { merged: true, number, method, deleted_branch: deleteBranch, merge_commit_sha: merged.merge_commit_sha }; }, },