feat(deployments): docker tabanlı proje yönetim ve otomatik deploy sistemi ekle
Docker Compose projeleri için tam kapsamlı yönetim paneli ve otomatik deployment altyapısı eklendi. Sistem özellikleri: - Belirtilen root dizin altındaki docker-compose dosyası içeren projeleri tarama - Git repo bağlantısı ile branch yönetimi ve klonlama/pull işlemleri - Docker compose up/down komutları ile otomatik deploy - Gitea webhook entegrasyonu ile commit bazlı tetikleme - Deploy geçmişi, log kayıtları ve durum takibi (running/success/failed) - Deploy metrikleri ve dashboard görselleştirmesi - Webhook token ve secret yönetimi ile güvenlik - Proje favicon servisi Teknik değişiklikler: - Backend: deploymentProject, deploymentRun ve settings modelleri eklendi - Backend: deploymentService ile git ve docker işlemleri otomatize edildi - Backend: webhook doğrulaması için signature kontrolü eklendi - Docker: docker-cli ve docker-compose bağımlılıkları eklendi - Frontend: deployments ve settings sayfaları eklendi - Frontend: dashboard'a deploy metrikleri ve aktivite akışı eklendi - API: /api/deployments ve /api/settings yolları eklendi
This commit is contained in:
115
frontend/src/api/deployments.ts
Normal file
115
frontend/src/api/deployments.ts
Normal file
@@ -0,0 +1,115 @@
|
||||
import { apiClient } from "./client";
|
||||
|
||||
export type ComposeFile = "docker-compose.yml" | "docker-compose.dev.yml";
|
||||
export type DeploymentStatus = "idle" | "running" | "success" | "failed";
|
||||
export type DeploymentEnv = "dev" | "prod";
|
||||
|
||||
export interface DeploymentProject {
|
||||
_id: string;
|
||||
name: string;
|
||||
rootPath: string;
|
||||
repoUrl: string;
|
||||
branch: string;
|
||||
composeFile: ComposeFile;
|
||||
webhookToken: string;
|
||||
env: DeploymentEnv;
|
||||
port?: number;
|
||||
lastDeployAt?: string;
|
||||
lastStatus: DeploymentStatus;
|
||||
lastMessage?: string;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export interface DeploymentRun {
|
||||
_id: string;
|
||||
project: string;
|
||||
status: "running" | "success" | "failed";
|
||||
message?: string;
|
||||
logs: string[];
|
||||
startedAt: string;
|
||||
finishedAt?: string;
|
||||
durationMs?: number;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export interface DeploymentRunWithProject extends Omit<DeploymentRun, "project"> {
|
||||
project: DeploymentProject;
|
||||
}
|
||||
|
||||
export interface DeploymentDetailResponse {
|
||||
project: DeploymentProject;
|
||||
runs: DeploymentRun[];
|
||||
}
|
||||
|
||||
export interface DeploymentMetrics {
|
||||
dailyStats: Array<{
|
||||
_id: string;
|
||||
total: number;
|
||||
success: number;
|
||||
failed: number;
|
||||
avgDurationMs?: number;
|
||||
}>;
|
||||
recentRuns: DeploymentRunWithProject[];
|
||||
}
|
||||
|
||||
export interface DeploymentCandidate {
|
||||
name: string;
|
||||
rootPath: string;
|
||||
composeFiles: ComposeFile[];
|
||||
}
|
||||
|
||||
export interface DeploymentInput {
|
||||
name: string;
|
||||
rootPath: string;
|
||||
repoUrl: string;
|
||||
branch: string;
|
||||
composeFile: ComposeFile;
|
||||
port?: number;
|
||||
}
|
||||
|
||||
export async function fetchDeployments(): Promise<DeploymentProject[]> {
|
||||
const { data } = await apiClient.get("/deployments");
|
||||
return data as DeploymentProject[];
|
||||
}
|
||||
|
||||
export async function fetchDeploymentBranches(repoUrl: string): Promise<string[]> {
|
||||
const { data } = await apiClient.get("/deployments/branches", {
|
||||
params: { repoUrl }
|
||||
});
|
||||
return (data as { branches: string[] }).branches;
|
||||
}
|
||||
|
||||
export async function scanDeployments(): Promise<DeploymentCandidate[]> {
|
||||
const { data } = await apiClient.get("/deployments/scan");
|
||||
return data as DeploymentCandidate[];
|
||||
}
|
||||
|
||||
export async function createDeployment(payload: DeploymentInput): Promise<DeploymentProject> {
|
||||
const { data } = await apiClient.post("/deployments", payload);
|
||||
return data as DeploymentProject;
|
||||
}
|
||||
|
||||
export async function updateDeployment(id: string, payload: Omit<DeploymentInput, "rootPath">) {
|
||||
const { data } = await apiClient.put(`/deployments/${id}`, payload);
|
||||
return data as DeploymentProject;
|
||||
}
|
||||
|
||||
export async function deleteDeployment(id: string): Promise<void> {
|
||||
await apiClient.delete(`/deployments/${id}`);
|
||||
}
|
||||
|
||||
export async function runDeployment(id: string): Promise<void> {
|
||||
await apiClient.post(`/deployments/${id}/run`);
|
||||
}
|
||||
|
||||
export async function fetchDeployment(id: string): Promise<DeploymentDetailResponse> {
|
||||
const { data } = await apiClient.get(`/deployments/${id}`);
|
||||
return data as DeploymentDetailResponse;
|
||||
}
|
||||
|
||||
export async function fetchDeploymentMetrics(): Promise<DeploymentMetrics> {
|
||||
const { data } = await apiClient.get("/deployments/metrics/summary");
|
||||
return data as DeploymentMetrics;
|
||||
}
|
||||
Reference in New Issue
Block a user