- 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.
135 lines
3.3 KiB
JavaScript
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 };
|
|
}
|
|
}
|