gitea: the tools' token carries write:admin, and a kept token is re-minted when it lacks a scope

The forge's own users are the mesh's to settle — making the builder's login
a site admin so private repos build (hq 229) — and the tools' token had no
write:admin. A token kept from before a scope was added lacks it, so the
client now treats the forge's 403 "required scope" like a 401: the source
re-mints by name with the whole list and retries once. The fake forge in the
tests learns /repos/search, which the client has used since 2026-09-28 and
which had left 9 of the 11 token tests failing on main.
This commit is contained in:
2026-09-30 21:05:52 +02:00
parent ac7a9f2ca8
commit d58ed21367
3 changed files with 82 additions and 5 deletions
+7
View File
@@ -95,6 +95,13 @@ export class GiteaClient {
if (res.status === 401) {
token = await this.tokens.renew(token);
res = await this.send(path, options, token);
} else if (res.status === 403) {
// A kept token minted before a scope was added lacks it. The forge says so; the source
// re-mints with the whole list and the call is retried once. Any other 403 stays a 403.
const text = await res.text();
if (!MintedToken.lacksScope(res.status, text)) throw new Error(`Gitea API ${path}: 403 ${text}`);
token = await this.tokens.renew(token);
res = await this.send(path, options, token);
}
if (!res.ok) throw new Error(`Gitea API ${path}: ${res.status} ${await res.text()}`);
if (res.status === 204) return null as T;