This repository has been archived on 2026-05-11. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
autodeployer-old-version/server/src/services/gitea.js
Giuseppe Raffa 87d698bc5c feat: add Docker and Gitea services, monitoring, queue, and Telegram notification functionalities
- Implemented Docker operations including image building, container management, and resource stats.
- Added Gitea API client for repository management and webhook handling.
- Introduced monitoring service to collect and store container metrics in InfluxDB.
- Created a queue system using BullMQ for managing deployment jobs with real-time log streaming.
- Developed Telegram notification service for deployment status updates.
- Added Traefik label generation for dynamic reverse proxy configuration.
- Implemented WebSocket endpoints for log streaming and terminal access to containers.
- Created an updater sidecar for self-updating the AutoDeployer container.
2026-04-13 23:23:18 +02:00

135 lines
3.3 KiB
JavaScript

import config from '../config.js';
/**
* Gitea API client — uses API token auth
*/
const headers = () => ({
'Content-Type': 'application/json',
'Authorization': `token ${config.giteaToken}`,
});
const apiUrl = (path) => `${config.giteaUrl}/api/v1${path}`;
async function request(path, opts = {}) {
const url = apiUrl(path);
const res = await fetch(url, {
...opts,
headers: { ...headers(), ...opts.headers },
});
if (!res.ok) {
const body = await res.text().catch(() => '');
throw new Error(`Gitea API error: ${res.status} ${res.statusText}${body}`);
}
return res.json();
}
/**
* List all accessible repositories
*/
export async function listRepos(page = 1, limit = 50) {
return request(`/repos/search?page=${page}&limit=${limit}&sort=updated&order=desc`);
}
/**
* Get a repository by owner/name
*/
export async function getRepo(owner, name) {
return request(`/repos/${owner}/${name}`);
}
/**
* List branches for a repository
*/
export async function listBranches(owner, name) {
return request(`/repos/${owner}/${name}/branches`);
}
/**
* Get the latest commit on a branch
*/
export async function getLatestCommit(owner, name, branch = 'main') {
const commits = await request(`/repos/${owner}/${name}/commits?sha=${branch}&limit=1`);
if (commits.length === 0) return null;
return {
sha: commits[0].sha,
message: commits[0].commit?.message || '',
author: commits[0].commit?.author?.name || '',
date: commits[0].commit?.author?.date || '',
};
}
/**
* Create a webhook on a Gitea repository
*/
export async function createWebhook(owner, name, targetUrl, secret) {
return request(`/repos/${owner}/${name}/hooks`, {
method: 'POST',
body: JSON.stringify({
type: 'gitea',
config: {
url: targetUrl,
content_type: 'json',
secret: secret,
},
events: ['push'],
active: true,
}),
});
}
/**
* Delete a webhook from a Gitea repository
*/
export async function deleteWebhook(owner, name, hookId) {
const url = apiUrl(`/repos/${owner}/${name}/hooks/${hookId}`);
const res = await fetch(url, {
method: 'DELETE',
headers: headers(),
});
if (!res.ok && res.status !== 404) {
throw new Error(`Gitea API error: ${res.status}`);
}
}
/**
* List webhooks for a repository
*/
export async function listWebhooks(owner, name) {
return request(`/repos/${owner}/${name}/hooks`);
}
/**
* Get the clone URL (with token embedded for private repos)
*/
export function getCloneUrl(repoUrl) {
// repoUrl is like "http://gitea:3000/owner/repo"
// We need to inject the token for authenticated clone
const url = new URL(repoUrl);
url.username = 'autodeployer';
url.password = config.giteaToken;
return url.toString();
}
/**
* Parse a Gitea repo URL into owner/name
*/
export function parseRepoUrl(repoUrl) {
const url = new URL(repoUrl);
const parts = url.pathname.replace(/^\//, '').replace(/\.git$/, '').split('/');
if (parts.length < 2) throw new Error(`Invalid repo URL: ${repoUrl}`);
return { owner: parts[0], name: parts[1] };
}
/**
* Test the Gitea connection
*/
export async function testConnection() {
try {
const user = await request('/user');
return { ok: true, user: user.login };
} catch (err) {
return { ok: false, error: err.message };
}
}