Dieser Commit ist enthalten in:
Claude Project Manager
2025-12-28 21:36:45 +00:00
Commit ab1e5be9a9
146 geänderte Dateien mit 65525 neuen und 0 gelöschten Zeilen

Datei anzeigen

@ -0,0 +1,300 @@
/**
* TASKMATE - Gitea Service
* =========================
* Integration mit Gitea API
*/
const logger = require('../utils/logger');
const GITEA_URL = process.env.GITEA_URL || 'https://gitea-undso.aegis-sight.de';
const GITEA_TOKEN = process.env.GITEA_TOKEN;
const GITEA_ORG = process.env.GITEA_ORG || 'AegisSight'; // Standard-Organisation für neue Repos
/**
* Basis-Fetch für Gitea API
*/
async function giteaFetch(endpoint, options = {}) {
if (!GITEA_TOKEN) {
throw new Error('Gitea-Token nicht konfiguriert');
}
const url = `${GITEA_URL}/api/v1${endpoint}`;
const response = await fetch(url, {
...options,
headers: {
'Authorization': `token ${GITEA_TOKEN}`,
'Content-Type': 'application/json',
'Accept': 'application/json',
...options.headers
}
});
if (!response.ok) {
const errorText = await response.text();
logger.error(`Gitea API Fehler: ${response.status} - ${errorText}`);
throw new Error(`Gitea API Fehler: ${response.status}`);
}
return response.json();
}
/**
* Alle Repositories der Organisation abrufen
*/
async function listRepositories(options = {}) {
try {
const page = options.page || 1;
const limit = options.limit || 50;
// Repositories der Organisation abrufen
const repos = await giteaFetch(`/orgs/${GITEA_ORG}/repos?page=${page}&limit=${limit}`);
return {
success: true,
repositories: repos.map(repo => ({
id: repo.id,
name: repo.name,
fullName: repo.full_name,
owner: repo.owner.login,
description: repo.description || '',
cloneUrl: repo.clone_url,
htmlUrl: repo.html_url,
defaultBranch: repo.default_branch,
private: repo.private,
fork: repo.fork,
stars: repo.stars_count,
forks: repo.forks_count,
updatedAt: repo.updated_at,
createdAt: repo.created_at
}))
};
} catch (error) {
logger.error('Fehler beim Abrufen der Repositories:', error);
return { success: false, error: error.message };
}
}
/**
* Repository-Details abrufen
*/
async function getRepository(owner, repo) {
try {
const repoData = await giteaFetch(`/repos/${owner}/${repo}`);
return {
success: true,
repository: {
id: repoData.id,
name: repoData.name,
fullName: repoData.full_name,
owner: repoData.owner.login,
description: repoData.description || '',
cloneUrl: repoData.clone_url,
htmlUrl: repoData.html_url,
defaultBranch: repoData.default_branch,
private: repoData.private,
fork: repoData.fork,
stars: repoData.stars_count,
forks: repoData.forks_count,
size: repoData.size,
updatedAt: repoData.updated_at,
createdAt: repoData.created_at
}
};
} catch (error) {
logger.error(`Fehler beim Abrufen des Repositories ${owner}/${repo}:`, error);
return { success: false, error: error.message };
}
}
/**
* Branches eines Repositories abrufen
*/
async function getRepositoryBranches(owner, repo) {
try {
const branches = await giteaFetch(`/repos/${owner}/${repo}/branches`);
return {
success: true,
branches: branches.map(branch => ({
name: branch.name,
commit: branch.commit?.id,
protected: branch.protected
}))
};
} catch (error) {
logger.error(`Fehler beim Abrufen der Branches für ${owner}/${repo}:`, error);
return { success: false, error: error.message };
}
}
/**
* Commits eines Repositories abrufen
*/
async function getRepositoryCommits(owner, repo, options = {}) {
try {
const page = options.page || 1;
const limit = options.limit || 20;
const branch = options.branch || '';
let endpoint = `/repos/${owner}/${repo}/commits?page=${page}&limit=${limit}`;
if (branch) {
endpoint += `&sha=${branch}`;
}
const commits = await giteaFetch(endpoint);
return {
success: true,
commits: commits.map(commit => ({
sha: commit.sha,
shortSha: commit.sha.substring(0, 7),
message: commit.commit.message,
author: commit.commit.author.name,
email: commit.commit.author.email,
date: commit.commit.author.date,
htmlUrl: commit.html_url
}))
};
} catch (error) {
logger.error(`Fehler beim Abrufen der Commits für ${owner}/${repo}:`, error);
return { success: false, error: error.message };
}
}
/**
* Neues Repository in der Organisation erstellen
*/
async function createRepository(name, options = {}) {
try {
// Repository unter der Organisation erstellen
const repoData = await giteaFetch(`/orgs/${GITEA_ORG}/repos`, {
method: 'POST',
body: JSON.stringify({
name,
description: options.description || '',
private: options.private !== false,
auto_init: options.autoInit !== false,
default_branch: options.defaultBranch || 'main',
readme: options.readme || 'Default'
})
});
logger.info(`Repository in Organisation ${GITEA_ORG} erstellt: ${repoData.full_name}`);
return {
success: true,
repository: {
id: repoData.id,
name: repoData.name,
fullName: repoData.full_name,
owner: repoData.owner.login,
cloneUrl: repoData.clone_url,
htmlUrl: repoData.html_url,
defaultBranch: repoData.default_branch
}
};
} catch (error) {
logger.error('Fehler beim Erstellen des Repositories:', error);
return { success: false, error: error.message };
}
}
/**
* Repository löschen
*/
async function deleteRepository(owner, repo) {
try {
await giteaFetch(`/repos/${owner}/${repo}`, {
method: 'DELETE'
});
logger.info(`Repository gelöscht: ${owner}/${repo}`);
return { success: true };
} catch (error) {
logger.error(`Fehler beim Löschen des Repositories ${owner}/${repo}:`, error);
return { success: false, error: error.message };
}
}
/**
* Authentifizierten Benutzer abrufen
*/
async function getCurrentUser() {
try {
const user = await giteaFetch('/user');
return {
success: true,
user: {
id: user.id,
login: user.login,
fullName: user.full_name,
email: user.email,
avatarUrl: user.avatar_url
}
};
} catch (error) {
logger.error('Fehler beim Abrufen des aktuellen Benutzers:', error);
return { success: false, error: error.message };
}
}
/**
* Prüft ob die Gitea-Verbindung funktioniert
*/
async function testConnection() {
try {
const result = await getCurrentUser();
return {
success: result.success,
connected: result.success,
user: result.user,
giteaUrl: GITEA_URL,
organization: GITEA_ORG
};
} catch (error) {
return {
success: false,
connected: false,
error: error.message,
giteaUrl: GITEA_URL,
organization: GITEA_ORG
};
}
}
/**
* Clone-URL mit Token für private Repos
*/
function getAuthenticatedCloneUrl(cloneUrl) {
if (!GITEA_TOKEN) {
return cloneUrl;
}
// Füge Token zur URL hinzu
return cloneUrl.replace('https://', `https://${GITEA_TOKEN}@`);
}
/**
* Gitea-URL ohne Token (für Anzeige)
*/
function getSafeCloneUrl(cloneUrl) {
// Entferne Token aus URL falls vorhanden
return cloneUrl.replace(/https:\/\/[^@]+@/, 'https://');
}
module.exports = {
listRepositories,
getRepository,
getRepositoryBranches,
getRepositoryCommits,
createRepository,
deleteRepository,
getCurrentUser,
testConnection,
getAuthenticatedCloneUrl,
getSafeCloneUrl,
GITEA_URL,
GITEA_ORG
};