feat(tasks): Aufgabe als Git-Issue anlegen, Zustand wandert mit
Die Zuordnung stand im Schema laengst – sourceIssue, sourceUrl und sourceRepositoryId samt Eindeutigkeit je Repository, gefuellt von der Uebernahme aus Issues seit v0.9.0. Es fehlte die Gegenrichtung. Ein Knopf im Aufgabendialog legt das Issue an; Nummer und Adresse landen in denselben Feldern, der Dublettenschutz gilt also fuer beide Wege. In den Rumpf kommt ein Rueckverweis auf das Projekt. Ausdruecklich per Knopf und nie nebenbei: was in ein fremdes System geschrieben wird, soll jemand gewollt haben. Ist die Aufgabe erst verknuepft, wandert der Zustand allerdings mit – erledigt schliesst das Issue, ein Zurueckziehen oeffnet es wieder. Fehlertolerant: ein nicht erreichbares Git-System darf das Abhaken nicht verhindern. Die Zustaende passen nicht aufeinander, und das bleibt so. Nebula kennt vier, ein Issue zwei; nach aussen geht nur die Grenze um ERLEDIGT. Ein Rundlauf verliert damit IN ARBEIT und BLOCKIERT. Labels waeren die Alternative, wuerden aber den Issue-Tracker mit Zustaenden fuellen, die dort niemand pflegt. Kein Widerspruch zu "keine eigenen Git-Operationen": Issues laufen ueber die HTTP-API der Provider. Dafuer gibt es jetzt sendJson neben getJson – durch dieselbe SSRF-Schleuse, aber ohne Umleitungen zu folgen. Ein 307 auf eine interne Adresse naehme den Rumpf und den Token im Header mit. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+28
-1
@@ -1,4 +1,4 @@
|
||||
import { getJson, getJsonSafe, normalizeBaseUrl, shortSha, toIso } from "./http";
|
||||
import { getJson, getJsonSafe, normalizeBaseUrl, sendJson, shortSha, toIso } from "./http";
|
||||
import {
|
||||
CALENDAR_PAGE_SIZE,
|
||||
calendarByPaging,
|
||||
@@ -12,6 +12,7 @@ import type {
|
||||
CiState,
|
||||
CommitInfo,
|
||||
ConnectionCheck,
|
||||
CreatedIssue,
|
||||
GitClient,
|
||||
ProviderConfig,
|
||||
ReleaseInfo,
|
||||
@@ -44,6 +45,32 @@ export class GiteaClient implements GitClient {
|
||||
return headers;
|
||||
}
|
||||
|
||||
private repoBase(ref: RepoRef): string {
|
||||
return `${this.apiBase}/repos/${encodeURIComponent(ref.owner)}/${encodeURIComponent(ref.name)}`;
|
||||
}
|
||||
|
||||
async createIssue(
|
||||
ref: RepoRef,
|
||||
issue: { title: string; body?: string | null },
|
||||
): Promise<CreatedIssue> {
|
||||
const angelegt = await sendJson<{ number: number; html_url?: string }>(
|
||||
`${this.repoBase(ref)}/issues`,
|
||||
"POST",
|
||||
{ title: issue.title, body: issue.body ?? "" },
|
||||
{ headers: this.headers() },
|
||||
);
|
||||
return { number: angelegt.number, url: angelegt.html_url ?? null };
|
||||
}
|
||||
|
||||
async setIssueState(ref: RepoRef, number: number, open: boolean): Promise<void> {
|
||||
await sendJson(
|
||||
`${this.repoBase(ref)}/issues/${number}`,
|
||||
"PATCH",
|
||||
{ state: open ? "open" : "closed" },
|
||||
{ headers: this.headers() },
|
||||
);
|
||||
}
|
||||
|
||||
async check(): Promise<ConnectionCheck> {
|
||||
try {
|
||||
const version = await getJsonSafe<{ version?: string }>(
|
||||
|
||||
Reference in New Issue
Block a user