From d70cb18ea0cf6cf2ae9b17dfd76c9fc62c63f6f6 Mon Sep 17 00:00:00 2001 From: jochen Date: Mon, 28 Sep 2026 04:31:20 +0200 Subject: [PATCH] The forge watches every repository, not the administrator's own MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit /user/repos lists what the token's user owns, which for the mesh's administrator is nothing — so the forge module watched an empty list and never announced a merge. It reads the forge's whole view through the search endpoint, every page. --- modules/gitea/client.ts | 18 ++++++++++++++++-- modules/gitea/index.ts | 4 ++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/modules/gitea/client.ts b/modules/gitea/client.ts index 09f05d0..5a6e918 100644 --- a/modules/gitea/client.ts +++ b/modules/gitea/client.ts @@ -121,9 +121,23 @@ export class GiteaClient { // ---- Repositories ---- + /** Every repository this token can see, one page. `/user/repos` is only what the token's own + * user owns — for the mesh's administrator that is nothing, which is how the forge watched an + * empty list and announced no merge (2026-09-28). The search endpoint is the forge's whole view. */ async listRepos(page = 1, limit = 20): Promise { - const repos = await this.request(`/user/repos?page=${page}&limit=${limit}`); - return (repos ?? []).map(GiteaClient.mapRepo); + const found = await this.request<{ data?: any[] }>(`/repos/search?page=${page}&limit=${limit}`); + return (found?.data ?? []).map(GiteaClient.mapRepo); + } + + /** Every repository, all pages. */ + async listAllRepos(): Promise { + const all: GiteaRepo[] = []; + for (let page = 1; page < 100; page++) { + const batch = await this.listRepos(page, 50); + all.push(...batch); + if (batch.length < 50) break; + } + return all; } async createRepo(data: { diff --git a/modules/gitea/index.ts b/modules/gitea/index.ts index ccc3ab4..9db8955 100644 --- a/modules/gitea/index.ts +++ b/modules/gitea/index.ts @@ -31,7 +31,7 @@ try { const seen = new Set(); let primed = false; async function pollRepos(client: GiteaClient): Promise { - const repos = await client.listRepos(1, 50); + const repos = await client.listAllRepos(); for (const repo of repos) { if (!seen.has(repo.full_name)) { if (primed) { @@ -77,7 +77,7 @@ function keepAnnounced(): void { renameSync(tmp, mergedRecord); } async function pollMerged(client: GiteaClient): Promise { - const repos = await client.listRepos(1, 50); + const repos = await client.listAllRepos(); let changed = false; for (const repo of repos) { const pulls = await client.listPullRequests(repo.owner, repo.name, { state: "closed", sort: "recentupdate", limit: "20" });