The forge watches every repository, not the administrator's own #125

Merged
mesh-admin merged 1 commits from fix/the-forge-watches-every-repository into main 2026-09-28 02:31:26 +00:00
2 changed files with 18 additions and 4 deletions
+16 -2
View File
@@ -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<GiteaRepo[]> {
const repos = await this.request<any[]>(`/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<GiteaRepo[]> {
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: {
+2 -2
View File
@@ -31,7 +31,7 @@ try {
const seen = new Set<string>();
let primed = false;
async function pollRepos(client: GiteaClient): Promise<void> {
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<void> {
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" });