fix: handle Gitea 409 on project create by linking to existing repo
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -3,7 +3,7 @@ import { getServerSession } from 'next-auth';
|
|||||||
import { authOptions } from '@/lib/auth/authOptions';
|
import { authOptions } from '@/lib/auth/authOptions';
|
||||||
import { query } from '@/lib/db-postgres';
|
import { query } from '@/lib/db-postgres';
|
||||||
import { randomUUID } from 'crypto';
|
import { randomUUID } from 'crypto';
|
||||||
import { createRepo, createWebhook, GITEA_ADMIN_USER_EXPORT } from '@/lib/gitea';
|
import { createRepo, createWebhook, getRepo, listWebhooks, GITEA_ADMIN_USER_EXPORT } from '@/lib/gitea';
|
||||||
import { provisionTheiaWorkspace } from '@/lib/cloud-run-workspace';
|
import { provisionTheiaWorkspace } from '@/lib/cloud-run-workspace';
|
||||||
import type { ProjectPhaseData, ProjectPhaseScores } from '@/lib/types/project-artifacts';
|
import type { ProjectPhaseData, ProjectPhaseScores } from '@/lib/types/project-artifacts';
|
||||||
|
|
||||||
@@ -67,23 +67,45 @@ export async function POST(request: Request) {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const repoName = slug; // e.g. "taskmaster"
|
const repoName = slug; // e.g. "taskmaster"
|
||||||
const repo = await createRepo(repoName, {
|
let repo;
|
||||||
description: `${projectName} — managed by Vibn`,
|
|
||||||
private: true,
|
try {
|
||||||
auto_init: true,
|
repo = await createRepo(repoName, {
|
||||||
});
|
description: `${projectName} — managed by Vibn`,
|
||||||
|
private: true,
|
||||||
|
auto_init: true,
|
||||||
|
});
|
||||||
|
console.log(`[API] Gitea repo created: ${GITEA_ADMIN_USER}/${repoName}`);
|
||||||
|
} catch (createErr) {
|
||||||
|
const msg = createErr instanceof Error ? createErr.message : String(createErr);
|
||||||
|
// 409 = repo already exists — link to it instead of failing
|
||||||
|
if (msg.includes('409')) {
|
||||||
|
console.log(`[API] Gitea repo already exists, linking to ${GITEA_ADMIN_USER}/${repoName}`);
|
||||||
|
repo = await getRepo(GITEA_ADMIN_USER, repoName);
|
||||||
|
if (!repo) throw new Error(`Repo ${repoName} exists but could not be fetched`);
|
||||||
|
} else {
|
||||||
|
throw createErr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
giteaRepo = repo.full_name; // e.g. "mark/taskmaster"
|
giteaRepo = repo.full_name; // e.g. "mark/taskmaster"
|
||||||
giteaRepoUrl = repo.html_url; // e.g. "https://git.vibnai.com/mark/taskmaster"
|
giteaRepoUrl = repo.html_url; // e.g. "https://git.vibnai.com/mark/taskmaster"
|
||||||
giteaCloneUrl = repo.clone_url;
|
giteaCloneUrl = repo.clone_url;
|
||||||
giteaSshUrl = repo.ssh_url;
|
giteaSshUrl = repo.ssh_url;
|
||||||
|
|
||||||
// 2. Register webhook on the repo pointing back to Vibn
|
// Register webhook — skip if one already points to this project
|
||||||
const webhookUrl = `${APP_URL}/api/webhooks/gitea?projectId=${projectId}`;
|
const webhookUrl = `${APP_URL}/api/webhooks/gitea?projectId=${projectId}`;
|
||||||
const hook = await createWebhook(GITEA_ADMIN_USER, repoName, webhookUrl, GITEA_WEBHOOK_SECRET);
|
const existingHooks = await listWebhooks(GITEA_ADMIN_USER, repoName).catch(() => []);
|
||||||
giteaWebhookId = hook.id;
|
const alreadyHooked = existingHooks.some(h => h.config.url.includes(projectId));
|
||||||
|
|
||||||
console.log(`[API] Gitea repo created: ${giteaRepo}, webhook: ${giteaWebhookId}`);
|
if (!alreadyHooked) {
|
||||||
|
const hook = await createWebhook(GITEA_ADMIN_USER, repoName, webhookUrl, GITEA_WEBHOOK_SECRET);
|
||||||
|
giteaWebhookId = hook.id;
|
||||||
|
console.log(`[API] Webhook registered: ${giteaRepo}, id: ${giteaWebhookId}`);
|
||||||
|
} else {
|
||||||
|
giteaWebhookId = existingHooks.find(h => h.config.url.includes(projectId))?.id ?? null;
|
||||||
|
console.log(`[API] Webhook already exists for ${giteaRepo}`);
|
||||||
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// Non-fatal — log and continue. Project is still created.
|
// Non-fatal — log and continue. Project is still created.
|
||||||
giteaError = err instanceof Error ? err.message : String(err);
|
giteaError = err instanceof Error ? err.message : String(err);
|
||||||
|
|||||||
Reference in New Issue
Block a user