Files

76 lines
2.0 KiB
TypeScript

import { incidentToFilename, renderMarkdown } from "./markdown";
import type { Incident } from "@/types/incident";
export interface GiteaConfig {
url: string;
token: string;
owner: string;
repo: string;
}
export interface PushResult {
success: boolean;
url?: string;
error?: string;
}
export async function pushIncidentToGitea(
incident: Incident,
config: GiteaConfig,
markdownTemplate?: string
): Promise<PushResult> {
const filepath = incidentToFilename(incident);
const content = renderMarkdown(incident, markdownTemplate);
const base64Content = btoa(unescape(encodeURIComponent(content)));
const apiBase = config.url.replace(/\/$/, "");
const endpoint = `${apiBase}/api/v1/repos/${config.owner}/${config.repo}/contents/${filepath}`;
try {
// Check if file already exists to get its SHA (required for updates)
const existingResponse = await fetch(endpoint, {
headers: {
Authorization: `Bearer ${config.token}`,
"Content-Type": "application/json",
},
});
let sha: string | undefined;
if (existingResponse.ok) {
const existing = await existingResponse.json() as { sha?: string };
sha = existing.sha;
}
const body: Record<string, string> = {
message: `incident: ${incident.title}`,
content: base64Content,
};
if (sha) body.sha = sha;
const response = await fetch(endpoint, {
method: "POST",
headers: {
Authorization: `Bearer ${config.token}`,
"Content-Type": "application/json",
},
body: JSON.stringify(body),
});
if (!response.ok) {
const err = await response.text();
return { success: false, error: `HTTP ${response.status}: ${err}` };
}
const data = await response.json() as { content?: { html_url?: string } };
return {
success: true,
url: data.content?.html_url,
};
} catch (e) {
return {
success: false,
error: e instanceof Error ? e.message : String(e),
};
}
}