From a5db1f34cb93c3b1560f80912e8c5cad5d9e9c61 Mon Sep 17 00:00:00 2001 From: sebseb7 Date: Mon, 4 Aug 2025 14:30:06 +0200 Subject: [PATCH] feat(api): enhance commit summary with Gitea API integration Add functionality to fetch commit diffs from the Gitea API and incorporate them into the German summary prompt. Update the summarizeMostRecentCommitDE function to handle webhook payloads for improved commit data retrieval. Maintain fallback to local git for compatibility. --- x.js | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 74 insertions(+), 7 deletions(-) diff --git a/x.js b/x.js index f779bca..8d5362a 100644 --- a/x.js +++ b/x.js @@ -8,6 +8,9 @@ const { exec, spawn } = require('child_process'); const fs = require('fs'); const path = require('path'); +// Use built-in fetch (Node.js 18+) or fallback to node-fetch +const fetch = globalThis.fetch || require('node-fetch'); + // --- Helpers: Git log + LLM summarization for Executive Summary (DE) --- // Promise-based exec wrapper with timeout @@ -106,8 +109,46 @@ async function callLLMOpenAICompatible({ baseUrl, apiKey, model, system, user, t } } -// Summarize the most recent commit in German -async function summarizeMostRecentCommitDE() { +// Get commit diff from Gitea API +async function getCommitDiffFromGitea(giteaBaseUrl, repoOwner, repoName, commitHash) { + const giteaToken = process.env.GITEA_TOKEN; + if (!giteaToken) { + logMessage('GITEA_TOKEN not configured; cannot fetch diff from API', 'warn'); + return null; + } + + try { + const apiUrl = `${giteaBaseUrl}/api/v1/repos/${repoOwner}/${repoName}/git/commits/${commitHash}.diff`; + logMessage(`Fetching commit diff from: ${apiUrl}`); + + const response = await fetch(apiUrl, { + headers: { + 'Authorization': `token ${giteaToken}`, + 'Accept': 'text/plain' + }, + timeout: 10000 + }); + + if (!response.ok) { + logMessage(`Gitea API request failed: ${response.status} ${response.statusText}`, 'warn'); + return null; + } + + const diffText = await response.text(); + + if (diffText && diffText.trim()) { + return diffText; + } + + return null; + } catch (e) { + logMessage(`Failed to fetch commit diff from Gitea API: ${e.message}`, 'warn'); + return null; + } +} + +// Summarize the most recent commit in German using webhook payload data +async function summarizeMostRecentCommitDE(webhookPayload = null) { // Determine provider const provider = (process.env.LLM_PROVIDER || 'openrouter').toLowerCase(); const model = process.env.LLM_MODEL || (provider === 'openrouter' ? 'openrouter/anthropic/claude-3.5-sonnet' : 'gpt-4o-mini'); @@ -128,15 +169,41 @@ async function summarizeMostRecentCommitDE() { return null; } - // Pull commits from the current working directory (assumed repo root or subdir) - const commits = await getLastCommits({ count: 10, repoDir: process.cwd() }); + let commits = []; + let diff = ''; + + if (webhookPayload && webhookPayload.commits && webhookPayload.commits.length > 0) { + // Use webhook payload data + commits = webhookPayload.commits.map(commit => ({ + hash: commit.id, + author: commit.author?.name || 'Unknown', + date: commit.timestamp || new Date().toISOString(), + subject: commit.message?.split('\n')[0] || 'No subject', + body: commit.message?.split('\n').slice(1).join('\n') || '' + })); + + // Extract Gitea base URL from webhook payload + const giteaBaseUrl = webhookPayload.repository?.html_url?.match(/^https?:\/\/[^\/]+/)?.[0]; + const repoOwner = webhookPayload.repository?.owner?.login; + const repoName = webhookPayload.repository?.name; + const latestCommitHash = commits[0]?.hash; + + if (giteaBaseUrl && repoOwner && repoName && latestCommitHash) { + diff = await getCommitDiffFromGitea(giteaBaseUrl, repoOwner, repoName, latestCommitHash); + } + } else { + // Fallback to local git (original behavior) + commits = await getLastCommits({ count: 10, repoDir: process.cwd() }); + if (!commits.length) return null; + diff = await getLastCommitDiff({ repoDir: process.cwd(), contextLines: 3 }); + } + if (!commits.length) return null; const prompt = buildMostRecentCommitPromptGerman(commits); if (!prompt) return null; - // Also include the unified diff of the latest commit in the system prompt - const diff = await getLastCommitDiff({ repoDir: process.cwd(), contextLines: 3 }); + // Include the diff in the system prompt const systemWithDiff = `${prompt.system}\n\n` + `Kontext (unified diff der neuesten Änderung):\n` + @@ -322,7 +389,7 @@ function formatCommitMessage(payload) { return (async () => { let summaryBlock = ''; try { - const summary = await summarizeMostRecentCommitDE(); + const summary = await summarizeMostRecentCommitDE(payload); if (summary) { const escapedSummary = escapeMdV2(summary); summaryBlock = `\n\n———————————————\n\n📋 *Executive Summary*\n\n${escapedSummary}\n\n\n`;