333 Zeilen
8.6 KiB
JavaScript
333 Zeilen
8.6 KiB
JavaScript
/**
|
|
* 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://');
|
|
}
|
|
|
|
/**
|
|
* Repository-Einstellungen aktualisieren (z.B. default_branch ändern)
|
|
*/
|
|
async function updateRepository(owner, repo, options = {}) {
|
|
try {
|
|
const updateData = {};
|
|
if (options.defaultBranch) updateData.default_branch = options.defaultBranch;
|
|
if (options.description !== undefined) updateData.description = options.description;
|
|
if (options.private !== undefined) updateData.private = options.private;
|
|
|
|
const repoData = await giteaFetch(`/repos/${owner}/${repo}`, {
|
|
method: 'PATCH',
|
|
body: JSON.stringify(updateData)
|
|
});
|
|
|
|
logger.info(`Repository ${owner}/${repo} aktualisiert (default_branch: ${repoData.default_branch})`);
|
|
return {
|
|
success: true,
|
|
repository: {
|
|
id: repoData.id,
|
|
name: repoData.name,
|
|
fullName: repoData.full_name,
|
|
defaultBranch: repoData.default_branch
|
|
}
|
|
};
|
|
} catch (error) {
|
|
logger.error(`Fehler beim Aktualisieren des Repositories ${owner}/${repo}:`, error);
|
|
return { success: false, error: error.message };
|
|
}
|
|
}
|
|
|
|
module.exports = {
|
|
listRepositories,
|
|
getRepository,
|
|
getRepositoryBranches,
|
|
getRepositoryCommits,
|
|
createRepository,
|
|
updateRepository,
|
|
deleteRepository,
|
|
getCurrentUser,
|
|
testConnection,
|
|
getAuthenticatedCloneUrl,
|
|
getSafeCloneUrl,
|
|
GITEA_URL,
|
|
GITEA_ORG
|
|
};
|