import { existsSync, promises as fsPromises } from "node:fs";import path from "node:path";import { paths } from "@dokploy/server/constants";import { db } from "@dokploy/server/db";import { type apiCreateDeployment, type apiCreateDeploymentBackup, type apiCreateDeploymentCompose, type apiCreateDeploymentPreview, type apiCreateDeploymentSchedule, type apiCreateDeploymentServer, type apiCreateDeploymentVolumeBackup, applications, compose, deployments, environments, projects,} from "@dokploy/server/db/schema";import { removeDirectoryIfExistsContent } from "@dokploy/server/utils/filesystem/directory";import { execAsync, execAsyncRemote,} from "@dokploy/server/utils/process/execAsync";import { TRPCError } from "@trpc/server";import { format } from "date-fns";import { and, desc, eq, inArray, or, sql } from "drizzle-orm";import type { z } from "zod";import { type Application, findApplicationById, updateApplicationStatus,} from "./application";import { findBackupById } from "./backup";import { type Compose, findComposeById, updateCompose } from "./compose";import { findPreviewDeploymentById, type PreviewDeployment, updatePreviewDeployment,} from "./preview-deployment";import { removeRollbackById } from "./rollbacks";import { findScheduleById } from "./schedule";import { findServerById, type Server } from "./server";import { findVolumeBackupById } from "./volume-backups"; export type ServicePath = { href: string | null; label: string }; export async function resolveServicePath( orgId: string, data: Record<string, unknown>,): Promise<ServicePath> { try { const applicationId = data?.applicationId as string | undefined; const composeId = data?.composeId as string | undefined; if (applicationId) { const app = await findApplicationById(applicationId); if (app.environment.project.organizationId !== orgId) { return { href: null, label: "Application" }; } return { href: `/dashboard/project/${app.environment.project.projectId}/environment/${app.environment.environmentId}/services/application/${app.applicationId}`, label: "Application", }; } if (composeId) { const comp = await findComposeById(composeId); if (comp.environment.project.organizationId !== orgId) { return { href: null, label: "Compose" }; } return { href: `/dashboard/project/${comp.environment.project.projectId}/environment/${comp.environment.environmentId}/services/compose/${comp.composeId}`, label: "Compose", }; } } catch { // not found or unauthorized } return { href: null, label: "—" };} export type Deployment = typeof deployments.$inferSelect; export const findDeploymentById = async (deploymentId: string) => { const deployment = await db.query.deployments.findFirst({ where: eq(deployments.deploymentId, deploymentId), with: { application: true, compose: true, schedule: true, }, }); if (!deployment) { throw new TRPCError({ code: "NOT_FOUND", message: "Deployment not found", }); } return deployment;}; export const findDeploymentByApplicationId = async (applicationId: string) => { const deployment = await db.query.deployments.findFirst({ where: eq(deployments.applicationId, applicationId), }); if (!deployment) { throw new TRPCError({ code: "NOT_FOUND", message: "Deployment not found", }); } return deployment;}; export const createDeployment = async ( deployment: Omit< z.infer<typeof apiCreateDeployment>, "deploymentId" | "createdAt" | "status" | "logPath" >,) => { const application = await findApplicationById(deployment.applicationId); await removeLastTenDeployments( deployment.applicationId, "application", application.serverId, ); try { const serverId = application.buildServerId || application.serverId; const { LOGS_PATH } = paths(!!serverId); const formattedDateTime = format(new Date(), "yyyy-MM-dd:HH:mm:ss"); const fileName = `${application.appName}-${formattedDateTime}.log`; const logFilePath = path.join(LOGS_PATH, application.appName, fileName); if (serverId) { const server = await findServerById(serverId); const command = ` mkdir -p ${LOGS_PATH}/${application.appName}; echo "Initializing deployment" >> ${logFilePath}; echo "Building on ${serverId ? "Build Server" : "Dokploy Server"}" >> ${logFilePath}; `; await execAsyncRemote(server.serverId, command); } else { await fsPromises.mkdir(path.join(LOGS_PATH, application.appName), { recursive: true, }); await fsPromises.writeFile(logFilePath, "Initializing deployment\n"); } const deploymentCreate = await db .insert(deployments) .values({ applicationId: deployment.applicationId, title: deployment.title || "Deployment", status: "running", logPath: logFilePath, description: deployment.description || "", startedAt: new Date().toISOString(), ...(application.buildServerId && { buildServerId: application.buildServerId, }), }) .returning(); if (deploymentCreate.length === 0 || !deploymentCreate[0]) { throw new TRPCError({ code: "BAD_REQUEST", message: "Error creating the deployment", }); } return deploymentCreate[0]; } catch (error) { await db .insert(deployments) .values({ applicationId: deployment.applicationId, title: deployment.title || "Deployment", status: "error", logPath: "", description: deployment.description || "", errorMessage: `An error have occurred: ${error instanceof Error ? error.message : error}`, startedAt: new Date().toISOString(), finishedAt: new Date().toISOString(), }) .returning(); await updateApplicationStatus(application.applicationId, "error"); console.log(error); throw new TRPCError({ code: "BAD_REQUEST", message: "Error creating the deployment", }); }}; export const createDeploymentPreview = async ( deployment: Omit< z.infer<typeof apiCreateDeploymentPreview>, "deploymentId" | "createdAt" | "status" | "logPath" >,) => { const previewDeployment = await findPreviewDeploymentById( deployment.previewDeploymentId, ); await removeLastTenDeployments( deployment.previewDeploymentId, "previewDeployment", previewDeployment?.application?.serverId, ); try { const appName = `${previewDeployment.appName}`; const { LOGS_PATH } = paths(!!previewDeployment?.application?.serverId); const formattedDateTime = format(new Date(), "yyyy-MM-dd:HH:mm:ss"); const fileName = `${appName}-${formattedDateTime}.log`; const logFilePath = path.join(LOGS_PATH, appName, fileName); if (previewDeployment?.application?.serverId) { const server = await findServerById( previewDeployment?.application?.serverId, ); const command = ` mkdir -p ${LOGS_PATH}/${appName}; echo "Initializing deployment" >> ${logFilePath}; `; await execAsyncRemote(server.serverId, command); } else { await fsPromises.mkdir(path.join(LOGS_PATH, appName), { recursive: true, }); await fsPromises.writeFile(logFilePath, "Initializing deployment"); } const deploymentCreate = await db .insert(deployments) .values({ title: deployment.title || "Deployment", status: "running", logPath: logFilePath, description: deployment.description || "", previewDeploymentId: deployment.previewDeploymentId, startedAt: new Date().toISOString(), }) .returning(); if (deploymentCreate.length === 0 || !deploymentCreate[0]) { throw new TRPCError({ code: "BAD_REQUEST", message: "Error creating the deployment", }); } return deploymentCreate[0]; } catch (error) { await db .insert(deployments) .values({ previewDeploymentId: deployment.previewDeploymentId, title: deployment.title || "Deployment", status: "error", logPath: "", description: deployment.description || "", errorMessage: `An error have occurred: ${error instanceof Error ? error.message : error}`, startedAt: new Date().toISOString(), finishedAt: new Date().toISOString(), }) .returning(); await updatePreviewDeployment(deployment.previewDeploymentId, { previewStatus: "error", }); console.log(error); throw new TRPCError({ code: "BAD_REQUEST", message: "Error creating the deployment", }); }}; export const createDeploymentCompose = async ( deployment: Omit< z.infer<typeof apiCreateDeploymentCompose>, "deploymentId" | "createdAt" | "status" | "logPath" >,) => { const compose = await findComposeById(deployment.composeId); await removeLastTenDeployments( deployment.composeId, "compose", compose.serverId, ); try { const { LOGS_PATH } = paths(!!compose.serverId); const formattedDateTime = format(new Date(), "yyyy-MM-dd:HH:mm:ss"); const fileName = `${compose.appName}-${formattedDateTime}.log`; const logFilePath = path.join(LOGS_PATH, compose.appName, fileName); if (compose.serverId) { const server = await findServerById(compose.serverId); const command = `mkdir -p ${LOGS_PATH}/${compose.appName};echo "Initializing deployment\n" >> ${logFilePath};`; await execAsyncRemote(server.serverId, command); } else { await fsPromises.mkdir(path.join(LOGS_PATH, compose.appName), { recursive: true, }); await fsPromises.writeFile(logFilePath, "Initializing deployment\n"); } const deploymentCreate = await db .insert(deployments) .values({ composeId: deployment.composeId, title: deployment.title || "Deployment", description: deployment.description || "", status: "running", logPath: logFilePath, startedAt: new Date().toISOString(), }) .returning(); if (deploymentCreate.length === 0 || !deploymentCreate[0]) { throw new TRPCError({ code: "BAD_REQUEST", message: "Error creating the deployment", }); } return deploymentCreate[0]; } catch (error) { await db .insert(deployments) .values({ composeId: deployment.composeId, title: deployment.title || "Deployment", status: "error", logPath: "", description: deployment.description || "", errorMessage: `An error have occurred: ${error instanceof Error ? error.message : error}`, startedAt: new Date().toISOString(), finishedAt: new Date().toISOString(), }) .returning(); await updateCompose(compose.composeId, { composeStatus: "error", }); console.log(error); throw new TRPCError({ code: "BAD_REQUEST", message: "Error creating the deployment", }); }}; export const createDeploymentBackup = async ( deployment: Omit< z.infer<typeof apiCreateDeploymentBackup>, "deploymentId" | "createdAt" | "status" | "logPath" >,) => { const backup = await findBackupById(deployment.backupId); let serverId: string | null | undefined; if (backup.backupType === "database") { serverId = backup.postgres?.serverId || backup.mariadb?.serverId || backup.mysql?.serverId || backup.mongo?.serverId; } else if (backup.backupType === "compose") { serverId = backup.compose?.serverId; } await removeLastTenDeployments(deployment.backupId, "backup", serverId); try { const { LOGS_PATH } = paths(!!serverId); const formattedDateTime = format(new Date(), "yyyy-MM-dd:HH:mm:ss"); const fileName = `${backup.appName}-${formattedDateTime}.log`; const logFilePath = path.join(LOGS_PATH, backup.appName, fileName); if (serverId) { const server = await findServerById(serverId); const command = `mkdir -p ${LOGS_PATH}/${backup.appName};echo "Initializing backup\n" >> ${logFilePath};`; await execAsyncRemote(server.serverId, command); } else { await fsPromises.mkdir(path.join(LOGS_PATH, backup.appName), { recursive: true, }); await fsPromises.writeFile(logFilePath, "Initializing backup\n"); } const deploymentCreate = await db .insert(deployments) .values({ backupId: deployment.backupId, title: deployment.title || "Backup", description: deployment.description || "", status: "running", logPath: logFilePath, startedAt: new Date().toISOString(), }) .returning(); if (deploymentCreate.length === 0 || !deploymentCreate[0]) { throw new TRPCError({ code: "BAD_REQUEST", message: "Error creating the backup", }); } return deploymentCreate[0]; } catch (error) { await db .insert(deployments) .values({ backupId: deployment.backupId, title: deployment.title || "Backup", status: "error", logPath: "", description: deployment.description || "", errorMessage: `An error have occurred: ${error instanceof Error ? error.message : error}`, startedAt: new Date().toISOString(), finishedAt: new Date().toISOString(), }) .returning(); throw new TRPCError({ code: "BAD_REQUEST", message: "Error creating the backup", }); }}; export const createDeploymentSchedule = async ( deployment: Omit< z.infer<typeof apiCreateDeploymentSchedule>, "deploymentId" | "createdAt" | "status" | "logPath" >,) => { const schedule = await findScheduleById(deployment.scheduleId); const serverId = schedule.application?.serverId || schedule.compose?.serverId || schedule.server?.serverId; await removeLastTenDeployments(deployment.scheduleId, "schedule", serverId); try { const { SCHEDULES_PATH } = paths(!!serverId); const formattedDateTime = format(new Date(), "yyyy-MM-dd:HH:mm:ss"); const fileName = `${schedule.appName}-${formattedDateTime}.log`; const logFilePath = path.join(SCHEDULES_PATH, schedule.appName, fileName); if (serverId) { const server = await findServerById(serverId); const command = ` mkdir -p ${SCHEDULES_PATH}/${schedule.appName}; echo "Initializing schedule" >> ${logFilePath}; `; await execAsyncRemote(server.serverId, command); } else { await fsPromises.mkdir(path.join(SCHEDULES_PATH, schedule.appName), { recursive: true, }); await fsPromises.writeFile(logFilePath, "Initializing schedule\n"); } const deploymentCreate = await db .insert(deployments) .values({ scheduleId: deployment.scheduleId, title: deployment.title || "Deployment", status: "running", logPath: logFilePath, description: deployment.description || "", startedAt: new Date().toISOString(), }) .returning(); if (deploymentCreate.length === 0 || !deploymentCreate[0]) { throw new TRPCError({ code: "BAD_REQUEST", message: "Error creating the deployment", }); } return deploymentCreate[0]; } catch (error) { console.log(error); await db .insert(deployments) .values({ scheduleId: deployment.scheduleId, title: deployment.title || "Deployment", status: "error", logPath: "", description: deployment.description || "", errorMessage: `An error have occurred: ${error instanceof Error ? error.message : error}`, startedAt: new Date().toISOString(), finishedAt: new Date().toISOString(), })Lines 1–500 of 1052. Load more
import { existsSync, promises as fsPromises } from "node:fs"; import path from "node:path"; import { paths } from "@dokploy/server/constants"; import { db } from "@dokploy/server/db"; import { type apiCreateDeployment, type apiCreateDeploymentBackup, type apiCreateDeploymentCompose, type apiCreateDeploymentPreview, type apiCreateDeploymentSchedule, type apiCreateDeploymentServer, type apiCreateDeploymentVolumeBackup, applications, compose, deployments, environments, projects, } from "@dokploy/server/db/schema"; import { removeDirectoryIfExistsContent } from "@dokploy/server/utils/filesystem/directory"; import { execAsync, execAsyncRemote, } from "@dokploy/server/utils/process/execAsync"; import { TRPCError } from "@trpc/server"; import { format } from "date-fns"; import { and, desc, eq, inArray, or, sql } from "drizzle-orm"; import type { z } from "zod"; import { type Application, findApplicationById, updateApplicationStatus, } from "./application"; import { findBackupById } from "./backup"; import { type Compose, findComposeById, updateCompose } from "./compose"; import { findPreviewDeploymentById, type PreviewDeployment, updatePreviewDeployment, } from "./preview-deployment"; import { removeRollbackById } from "./rollbacks"; import { findScheduleById } from "./schedule"; import { findServerById, type Server } from "./server"; import { findVolumeBackupById } from "./volume-backups"; export type ServicePath = { href: string | null; label: string }; export async function resolveServicePath( orgId: string, data: Record<string, unknown>, ): Promise<ServicePath> { try { const applicationId = data?.applicationId as string | undefined; const composeId = data?.composeId as string | undefined; if (applicationId) { const app = await findApplicationById(applicationId); if (app.environment.project.organizationId !== orgId) { return { href: null, label: "Application" }; } return { href: `/dashboard/project/${app.environment.project.projectId}/environment/${app.environment.environmentId}/services/application/${app.applicationId}`, label: "Application", }; } if (composeId) { const comp = await findComposeById(composeId); if (comp.environment.project.organizationId !== orgId) { return { href: null, label: "Compose" }; } return { href: `/dashboard/project/${comp.environment.project.projectId}/environment/${comp.environment.environmentId}/services/compose/${comp.composeId}`, label: "Compose", }; } } catch { // not found or unauthorized } return { href: null, label: "—" }; } export type Deployment = typeof deployments.$inferSelect; export const findDeploymentById = async (deploymentId: string) => { const deployment = await db.query.deployments.findFirst({ where: eq(deployments.deploymentId, deploymentId), with: { application: true, compose: true, schedule: true, }, }); if (!deployment) { throw new TRPCError({ code: "NOT_FOUND", message: "Deployment not found", }); } return deployment; }; export const findDeploymentByApplicationId = async (applicationId: string) => { const deployment = await db.query.deployments.findFirst({ where: eq(deployments.applicationId, applicationId), }); if (!deployment) { throw new TRPCError({ code: "NOT_FOUND", message: "Deployment not found", }); } return deployment; }; export const createDeployment = async ( deployment: Omit< z.infer<typeof apiCreateDeployment>, "deploymentId" | "createdAt" | "status" | "logPath" >, ) => { const application = await findApplicationById(deployment.applicationId); await removeLastTenDeployments( deployment.applicationId, "application", application.serverId, ); try { const serverId = application.buildServerId || application.serverId; const { LOGS_PATH } = paths(!!serverId); const formattedDateTime = format(new Date(), "yyyy-MM-dd:HH:mm:ss"); const fileName = `${application.appName}-${formattedDateTime}.log`; const logFilePath = path.join(LOGS_PATH, application.appName, fileName); if (serverId) { const server = await findServerById(serverId); const command = ` mkdir -p ${LOGS_PATH}/${application.appName}; echo "Initializing deployment" >> ${logFilePath}; echo "Building on ${serverId ? "Build Server" : "Dokploy Server"}" >> ${logFilePath}; `; await execAsyncRemote(server.serverId, command); } else { await fsPromises.mkdir(path.join(LOGS_PATH, application.appName), { recursive: true, }); await fsPromises.writeFile(logFilePath, "Initializing deployment\n"); } const deploymentCreate = await db .insert(deployments) .values({ applicationId: deployment.applicationId, title: deployment.title || "Deployment", status: "running", logPath: logFilePath, description: deployment.description || "", startedAt: new Date().toISOString(), ...(application.buildServerId && { buildServerId: application.buildServerId, }), }) .returning(); if (deploymentCreate.length === 0 || !deploymentCreate[0]) { throw new TRPCError({ code: "BAD_REQUEST", message: "Error creating the deployment", }); } return deploymentCreate[0]; } catch (error) { await db .insert(deployments) .values({ applicationId: deployment.applicationId, title: deployment.title || "Deployment", status: "error", logPath: "", description: deployment.description || "", errorMessage: `An error have occurred: ${error instanceof Error ? error.message : error}`, startedAt: new Date().toISOString(), finishedAt: new Date().toISOString(), }) .returning(); await updateApplicationStatus(application.applicationId, "error"); console.log(error); throw new TRPCError({ code: "BAD_REQUEST", message: "Error creating the deployment", }); } }; export const createDeploymentPreview = async ( deployment: Omit< z.infer<typeof apiCreateDeploymentPreview>, "deploymentId" | "createdAt" | "status" | "logPath" >, ) => { const previewDeployment = await findPreviewDeploymentById( deployment.previewDeploymentId, ); await removeLastTenDeployments( deployment.previewDeploymentId, "previewDeployment", previewDeployment?.application?.serverId, ); try { const appName = `${previewDeployment.appName}`; const { LOGS_PATH } = paths(!!previewDeployment?.application?.serverId); const formattedDateTime = format(new Date(), "yyyy-MM-dd:HH:mm:ss"); const fileName = `${appName}-${formattedDateTime}.log`; const logFilePath = path.join(LOGS_PATH, appName, fileName); if (previewDeployment?.application?.serverId) { const server = await findServerById( previewDeployment?.application?.serverId, ); const command = ` mkdir -p ${LOGS_PATH}/${appName}; echo "Initializing deployment" >> ${logFilePath}; `; await execAsyncRemote(server.serverId, command); } else { await fsPromises.mkdir(path.join(LOGS_PATH, appName), { recursive: true, }); await fsPromises.writeFile(logFilePath, "Initializing deployment"); } const deploymentCreate = await db .insert(deployments) .values({ title: deployment.title || "Deployment", status: "running", logPath: logFilePath, description: deployment.description || "", previewDeploymentId: deployment.previewDeploymentId, startedAt: new Date().toISOString(), }) .returning(); if (deploymentCreate.length === 0 || !deploymentCreate[0]) { throw new TRPCError({ code: "BAD_REQUEST", message: "Error creating the deployment", }); } return deploymentCreate[0]; } catch (error) { await db .insert(deployments) .values({ previewDeploymentId: deployment.previewDeploymentId, title: deployment.title || "Deployment", status: "error", logPath: "", description: deployment.description || "", errorMessage: `An error have occurred: ${error instanceof Error ? error.message : error}`, startedAt: new Date().toISOString(), finishedAt: new Date().toISOString(), }) .returning(); await updatePreviewDeployment(deployment.previewDeploymentId, { previewStatus: "error", }); console.log(error); throw new TRPCError({ code: "BAD_REQUEST", message: "Error creating the deployment", }); } }; export const createDeploymentCompose = async ( deployment: Omit< z.infer<typeof apiCreateDeploymentCompose>, "deploymentId" | "createdAt" | "status" | "logPath" >, ) => { const compose = await findComposeById(deployment.composeId); await removeLastTenDeployments( deployment.composeId, "compose", compose.serverId, ); try { const { LOGS_PATH } = paths(!!compose.serverId); const formattedDateTime = format(new Date(), "yyyy-MM-dd:HH:mm:ss"); const fileName = `${compose.appName}-${formattedDateTime}.log`; const logFilePath = path.join(LOGS_PATH, compose.appName, fileName); if (compose.serverId) { const server = await findServerById(compose.serverId); const command = ` mkdir -p ${LOGS_PATH}/${compose.appName}; echo "Initializing deployment\n" >> ${logFilePath}; `; await execAsyncRemote(server.serverId, command); } else { await fsPromises.mkdir(path.join(LOGS_PATH, compose.appName), { recursive: true, }); await fsPromises.writeFile(logFilePath, "Initializing deployment\n"); } const deploymentCreate = await db .insert(deployments) .values({ composeId: deployment.composeId, title: deployment.title || "Deployment", description: deployment.description || "", status: "running", logPath: logFilePath, startedAt: new Date().toISOString(), }) .returning(); if (deploymentCreate.length === 0 || !deploymentCreate[0]) { throw new TRPCError({ code: "BAD_REQUEST", message: "Error creating the deployment", }); } return deploymentCreate[0]; } catch (error) { await db .insert(deployments) .values({ composeId: deployment.composeId, title: deployment.title || "Deployment", status: "error", logPath: "", description: deployment.description || "", errorMessage: `An error have occurred: ${error instanceof Error ? error.message : error}`, startedAt: new Date().toISOString(), finishedAt: new Date().toISOString(), }) .returning(); await updateCompose(compose.composeId, { composeStatus: "error", }); console.log(error); throw new TRPCError({ code: "BAD_REQUEST", message: "Error creating the deployment", }); } }; export const createDeploymentBackup = async ( deployment: Omit< z.infer<typeof apiCreateDeploymentBackup>, "deploymentId" | "createdAt" | "status" | "logPath" >, ) => { const backup = await findBackupById(deployment.backupId); let serverId: string | null | undefined; if (backup.backupType === "database") { serverId = backup.postgres?.serverId || backup.mariadb?.serverId || backup.mysql?.serverId || backup.mongo?.serverId; } else if (backup.backupType === "compose") { serverId = backup.compose?.serverId; } await removeLastTenDeployments(deployment.backupId, "backup", serverId); try { const { LOGS_PATH } = paths(!!serverId); const formattedDateTime = format(new Date(), "yyyy-MM-dd:HH:mm:ss"); const fileName = `${backup.appName}-${formattedDateTime}.log`; const logFilePath = path.join(LOGS_PATH, backup.appName, fileName); if (serverId) { const server = await findServerById(serverId); const command = ` mkdir -p ${LOGS_PATH}/${backup.appName}; echo "Initializing backup\n" >> ${logFilePath}; `; await execAsyncRemote(server.serverId, command); } else { await fsPromises.mkdir(path.join(LOGS_PATH, backup.appName), { recursive: true, }); await fsPromises.writeFile(logFilePath, "Initializing backup\n"); } const deploymentCreate = await db .insert(deployments) .values({ backupId: deployment.backupId, title: deployment.title || "Backup", description: deployment.description || "", status: "running", logPath: logFilePath, startedAt: new Date().toISOString(), }) .returning(); if (deploymentCreate.length === 0 || !deploymentCreate[0]) { throw new TRPCError({ code: "BAD_REQUEST", message: "Error creating the backup", }); } return deploymentCreate[0]; } catch (error) { await db .insert(deployments) .values({ backupId: deployment.backupId, title: deployment.title || "Backup", status: "error", logPath: "", description: deployment.description || "", errorMessage: `An error have occurred: ${error instanceof Error ? error.message : error}`, startedAt: new Date().toISOString(), finishedAt: new Date().toISOString(), }) .returning(); throw new TRPCError({ code: "BAD_REQUEST", message: "Error creating the backup", }); } }; export const createDeploymentSchedule = async ( deployment: Omit< z.infer<typeof apiCreateDeploymentSchedule>, "deploymentId" | "createdAt" | "status" | "logPath" >, ) => { const schedule = await findScheduleById(deployment.scheduleId); const serverId = schedule.application?.serverId || schedule.compose?.serverId || schedule.server?.serverId; await removeLastTenDeployments(deployment.scheduleId, "schedule", serverId); try { const { SCHEDULES_PATH } = paths(!!serverId); const formattedDateTime = format(new Date(), "yyyy-MM-dd:HH:mm:ss"); const fileName = `${schedule.appName}-${formattedDateTime}.log`; const logFilePath = path.join(SCHEDULES_PATH, schedule.appName, fileName); if (serverId) { const server = await findServerById(serverId); const command = ` mkdir -p ${SCHEDULES_PATH}/${schedule.appName}; echo "Initializing schedule" >> ${logFilePath}; `; await execAsyncRemote(server.serverId, command); } else { await fsPromises.mkdir(path.join(SCHEDULES_PATH, schedule.appName), { recursive: true, }); await fsPromises.writeFile(logFilePath, "Initializing schedule\n"); } const deploymentCreate = await db .insert(deployments) .values({ scheduleId: deployment.scheduleId, title: deployment.title || "Deployment", status: "running", logPath: logFilePath, description: deployment.description || "", startedAt: new Date().toISOString(), }) .returning(); if (deploymentCreate.length === 0 || !deploymentCreate[0]) { throw new TRPCError({ code: "BAD_REQUEST", message: "Error creating the deployment", }); } return deploymentCreate[0]; } catch (error) { console.log(error); await db .insert(deployments) .values({ scheduleId: deployment.scheduleId, title: deployment.title || "Deployment", status: "error", logPath: "", description: deployment.description || "", errorMessage: `An error have occurred: ${error instanceof Error ? error.message : error}`, startedAt: new Date().toISOString(), finishedAt: new Date().toISOString(), })