mirror of
https://github.com/Dokploy/dokploy
synced 2025-06-26 18:27:59 +00:00
Update drizzle-zod dependency and enhance deployment tracking features
- Downgraded the drizzle-zod package from version 0.7.1 to 0.5.1 for compatibility. - Added new fields `startedAt` and `finishedAt` to the deployment schema to track deployment timing. - Enhanced deployment creation logic to set `startedAt` and `finishedAt` timestamps during deployment processes. - Improved the ShowDeployments and ShowSchedulesLogs components to display deployment duration using a new Badge component. - Refactored deployment removal logic to streamline the process of cleaning up old deployments.
This commit is contained in:
@@ -9,12 +9,13 @@ import {
|
|||||||
CardTitle,
|
CardTitle,
|
||||||
} from "@/components/ui/card";
|
} from "@/components/ui/card";
|
||||||
import { type RouterOutputs, api } from "@/utils/api";
|
import { type RouterOutputs, api } from "@/utils/api";
|
||||||
import { RocketIcon } from "lucide-react";
|
import { RocketIcon, Clock } from "lucide-react";
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { CancelQueues } from "./cancel-queues";
|
import { CancelQueues } from "./cancel-queues";
|
||||||
import { RefreshToken } from "./refresh-token";
|
import { RefreshToken } from "./refresh-token";
|
||||||
import { ShowDeployment } from "./show-deployment";
|
import { ShowDeployment } from "./show-deployment";
|
||||||
|
import { Badge } from "@/components/ui/badge";
|
||||||
|
import { formatDuration } from "../schedules/show-schedules-logs";
|
||||||
interface Props {
|
interface Props {
|
||||||
applicationId: string;
|
applicationId: string;
|
||||||
}
|
}
|
||||||
@@ -96,8 +97,23 @@ export const ShowDeployments = ({ applicationId }: Props) => {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col items-end gap-2">
|
<div className="flex flex-col items-end gap-2">
|
||||||
<div className="text-sm capitalize text-muted-foreground">
|
<div className="text-sm capitalize text-muted-foreground flex items-center gap-2">
|
||||||
<DateTooltip date={deployment.createdAt} />
|
<DateTooltip date={deployment.createdAt} />
|
||||||
|
{deployment.startedAt && deployment.finishedAt && (
|
||||||
|
<Badge
|
||||||
|
variant="outline"
|
||||||
|
className="text-[10px] gap-1 flex items-center"
|
||||||
|
>
|
||||||
|
<Clock className="size-3" />
|
||||||
|
{formatDuration(
|
||||||
|
Math.floor(
|
||||||
|
(new Date(deployment.finishedAt).getTime() -
|
||||||
|
new Date(deployment.startedAt).getTime()) /
|
||||||
|
1000,
|
||||||
|
),
|
||||||
|
)}
|
||||||
|
</Badge>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
@@ -13,7 +13,8 @@ import {
|
|||||||
import type { RouterOutputs } from "@/utils/api";
|
import type { RouterOutputs } from "@/utils/api";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { ShowDeployment } from "../deployments/show-deployment";
|
import { ShowDeployment } from "../deployments/show-deployment";
|
||||||
import { ClipboardList } from "lucide-react";
|
import { ClipboardList, Clock } from "lucide-react";
|
||||||
|
import { Badge } from "@/components/ui/badge";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
deployments: RouterOutputs["deployment"]["all"];
|
deployments: RouterOutputs["deployment"]["all"];
|
||||||
@@ -21,6 +22,13 @@ interface Props {
|
|||||||
children?: React.ReactNode;
|
children?: React.ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const formatDuration = (seconds: number) => {
|
||||||
|
if (seconds < 60) return `${seconds}s`;
|
||||||
|
const minutes = Math.floor(seconds / 60);
|
||||||
|
const remainingSeconds = seconds % 60;
|
||||||
|
return `${minutes}m ${remainingSeconds}s`;
|
||||||
|
};
|
||||||
|
|
||||||
export const ShowSchedulesLogs = ({
|
export const ShowSchedulesLogs = ({
|
||||||
deployments,
|
deployments,
|
||||||
serverId,
|
serverId,
|
||||||
@@ -73,8 +81,23 @@ export const ShowSchedulesLogs = ({
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col items-end gap-2">
|
<div className="flex flex-col items-end gap-2">
|
||||||
<div className="text-sm capitalize text-muted-foreground">
|
<div className="flex items-center gap-2 text-sm text-muted-foreground">
|
||||||
<DateTooltip date={deployment.createdAt} />
|
<DateTooltip date={deployment.createdAt} />
|
||||||
|
{deployment.startedAt && deployment.finishedAt && (
|
||||||
|
<Badge
|
||||||
|
variant="outline"
|
||||||
|
className="text-[10px] gap-1 flex items-center"
|
||||||
|
>
|
||||||
|
<Clock className="size-3" />
|
||||||
|
{formatDuration(
|
||||||
|
Math.floor(
|
||||||
|
(new Date(deployment.finishedAt).getTime() -
|
||||||
|
new Date(deployment.startedAt).getTime()) /
|
||||||
|
1000,
|
||||||
|
),
|
||||||
|
)}
|
||||||
|
</Badge>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
@@ -9,12 +9,13 @@ import {
|
|||||||
CardTitle,
|
CardTitle,
|
||||||
} from "@/components/ui/card";
|
} from "@/components/ui/card";
|
||||||
import { type RouterOutputs, api } from "@/utils/api";
|
import { type RouterOutputs, api } from "@/utils/api";
|
||||||
import { RocketIcon } from "lucide-react";
|
import { RocketIcon, Clock } from "lucide-react";
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { CancelQueuesCompose } from "./cancel-queues-compose";
|
import { CancelQueuesCompose } from "./cancel-queues-compose";
|
||||||
import { RefreshTokenCompose } from "./refresh-token-compose";
|
import { RefreshTokenCompose } from "./refresh-token-compose";
|
||||||
import { ShowDeploymentCompose } from "./show-deployment-compose";
|
import { ShowDeploymentCompose } from "./show-deployment-compose";
|
||||||
|
import { Badge } from "@/components/ui/badge";
|
||||||
|
import { formatDuration } from "@/components/dashboard/application/schedules/show-schedules-logs";
|
||||||
interface Props {
|
interface Props {
|
||||||
composeId: string;
|
composeId: string;
|
||||||
}
|
}
|
||||||
@@ -96,8 +97,23 @@ export const ShowDeploymentsCompose = ({ composeId }: Props) => {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col items-end gap-2">
|
<div className="flex flex-col items-end gap-2">
|
||||||
<div className="text-sm capitalize text-muted-foreground">
|
<div className="text-sm capitalize text-muted-foreground flex items-center gap-2">
|
||||||
<DateTooltip date={deployment.createdAt} />
|
<DateTooltip date={deployment.createdAt} />
|
||||||
|
{deployment.startedAt && deployment.finishedAt && (
|
||||||
|
<Badge
|
||||||
|
variant="outline"
|
||||||
|
className="text-[10px] gap-1 flex items-center"
|
||||||
|
>
|
||||||
|
<Clock className="size-3" />
|
||||||
|
{formatDuration(
|
||||||
|
Math.floor(
|
||||||
|
(new Date(deployment.finishedAt).getTime() -
|
||||||
|
new Date(deployment.startedAt).getTime()) /
|
||||||
|
1000,
|
||||||
|
),
|
||||||
|
)}
|
||||||
|
</Badge>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
2
apps/dokploy/drizzle/0096_special_may_parker.sql
Normal file
2
apps/dokploy/drizzle/0096_special_may_parker.sql
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
ALTER TABLE "deployment" ADD COLUMN "startedAt" text;--> statement-breakpoint
|
||||||
|
ALTER TABLE "deployment" ADD COLUMN "finishedAt" text;
|
||||||
5617
apps/dokploy/drizzle/meta/0096_snapshot.json
Normal file
5617
apps/dokploy/drizzle/meta/0096_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -673,6 +673,13 @@
|
|||||||
"when": 1746232483345,
|
"when": 1746232483345,
|
||||||
"tag": "0095_friendly_cobalt_man",
|
"tag": "0095_friendly_cobalt_man",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idx": 96,
|
||||||
|
"version": "7",
|
||||||
|
"when": 1746252086587,
|
||||||
|
"tag": "0096_special_may_parker",
|
||||||
|
"breakpoints": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -104,7 +104,7 @@
|
|||||||
"dockerode": "4.0.2",
|
"dockerode": "4.0.2",
|
||||||
"dotenv": "16.4.5",
|
"dotenv": "16.4.5",
|
||||||
"drizzle-orm": "^0.39.1",
|
"drizzle-orm": "^0.39.1",
|
||||||
"drizzle-zod": "0.7.1",
|
"drizzle-zod": "0.5.1",
|
||||||
"fancy-ansi": "^0.1.3",
|
"fancy-ansi": "^0.1.3",
|
||||||
"hi-base32": "^0.5.1",
|
"hi-base32": "^0.5.1",
|
||||||
"i18next": "^23.16.4",
|
"i18next": "^23.16.4",
|
||||||
|
|||||||
@@ -54,7 +54,7 @@
|
|||||||
"dockerode": "4.0.2",
|
"dockerode": "4.0.2",
|
||||||
"dotenv": "16.4.5",
|
"dotenv": "16.4.5",
|
||||||
"drizzle-orm": "^0.39.1",
|
"drizzle-orm": "^0.39.1",
|
||||||
"drizzle-zod": "0.7.1",
|
"drizzle-zod": "0.5.1",
|
||||||
"hi-base32": "^0.5.1",
|
"hi-base32": "^0.5.1",
|
||||||
"js-yaml": "4.1.0",
|
"js-yaml": "4.1.0",
|
||||||
"lodash": "4.17.21",
|
"lodash": "4.17.21",
|
||||||
|
|||||||
@@ -47,6 +47,8 @@ export const deployments = pgTable("deployment", {
|
|||||||
createdAt: text("createdAt")
|
createdAt: text("createdAt")
|
||||||
.notNull()
|
.notNull()
|
||||||
.$defaultFn(() => new Date().toISOString()),
|
.$defaultFn(() => new Date().toISOString()),
|
||||||
|
startedAt: text("startedAt"),
|
||||||
|
finishedAt: text("finishedAt"),
|
||||||
errorMessage: text("errorMessage"),
|
errorMessage: text("errorMessage"),
|
||||||
scheduleId: text("scheduleId").references(
|
scheduleId: text("scheduleId").references(
|
||||||
(): AnyPgColumn => schedules.scheduleId,
|
(): AnyPgColumn => schedules.scheduleId,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { relations } from "drizzle-orm";
|
import { relations } from "drizzle-orm";
|
||||||
import { boolean, pgEnum, pgTable, text } from "drizzle-orm/pg-core";
|
import { boolean, pgEnum, pgTable, text } from "drizzle-orm/pg-core";
|
||||||
import { createInsertSchema, createUpdateSchema } from "drizzle-zod";
|
import { createInsertSchema } from "drizzle-zod";
|
||||||
import { nanoid } from "nanoid";
|
import { nanoid } from "nanoid";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { applications } from "./application";
|
import { applications } from "./application";
|
||||||
@@ -78,6 +78,6 @@ export const schedulesRelations = relations(schedules, ({ one, many }) => ({
|
|||||||
|
|
||||||
export const createScheduleSchema = createInsertSchema(schedules);
|
export const createScheduleSchema = createInsertSchema(schedules);
|
||||||
|
|
||||||
export const updateScheduleSchema = createUpdateSchema(schedules).extend({
|
export const updateScheduleSchema = createScheduleSchema.extend({
|
||||||
scheduleId: z.string().min(1),
|
scheduleId: z.string().min(1),
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ export const createDeployment = async (
|
|||||||
try {
|
try {
|
||||||
await removeLastTenDeployments(
|
await removeLastTenDeployments(
|
||||||
deployment.applicationId,
|
deployment.applicationId,
|
||||||
|
"application",
|
||||||
application.serverId,
|
application.serverId,
|
||||||
);
|
);
|
||||||
const { LOGS_PATH } = paths(!!application.serverId);
|
const { LOGS_PATH } = paths(!!application.serverId);
|
||||||
@@ -90,6 +91,7 @@ export const createDeployment = async (
|
|||||||
status: "running",
|
status: "running",
|
||||||
logPath: logFilePath,
|
logPath: logFilePath,
|
||||||
description: deployment.description || "",
|
description: deployment.description || "",
|
||||||
|
startedAt: new Date().toISOString(),
|
||||||
})
|
})
|
||||||
.returning();
|
.returning();
|
||||||
if (deploymentCreate.length === 0 || !deploymentCreate[0]) {
|
if (deploymentCreate.length === 0 || !deploymentCreate[0]) {
|
||||||
@@ -109,6 +111,8 @@ export const createDeployment = async (
|
|||||||
logPath: "",
|
logPath: "",
|
||||||
description: deployment.description || "",
|
description: deployment.description || "",
|
||||||
errorMessage: `An error have occured: ${error instanceof Error ? error.message : error}`,
|
errorMessage: `An error have occured: ${error instanceof Error ? error.message : error}`,
|
||||||
|
startedAt: new Date().toISOString(),
|
||||||
|
finishedAt: new Date().toISOString(),
|
||||||
})
|
})
|
||||||
.returning();
|
.returning();
|
||||||
await updateApplicationStatus(application.applicationId, "error");
|
await updateApplicationStatus(application.applicationId, "error");
|
||||||
@@ -130,8 +134,9 @@ export const createDeploymentPreview = async (
|
|||||||
deployment.previewDeploymentId,
|
deployment.previewDeploymentId,
|
||||||
);
|
);
|
||||||
try {
|
try {
|
||||||
await removeLastTenPreviewDeploymenById(
|
await removeLastTenDeployments(
|
||||||
deployment.previewDeploymentId,
|
deployment.previewDeploymentId,
|
||||||
|
"previewDeployment",
|
||||||
previewDeployment?.application?.serverId,
|
previewDeployment?.application?.serverId,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -167,6 +172,7 @@ export const createDeploymentPreview = async (
|
|||||||
logPath: logFilePath,
|
logPath: logFilePath,
|
||||||
description: deployment.description || "",
|
description: deployment.description || "",
|
||||||
previewDeploymentId: deployment.previewDeploymentId,
|
previewDeploymentId: deployment.previewDeploymentId,
|
||||||
|
startedAt: new Date().toISOString(),
|
||||||
})
|
})
|
||||||
.returning();
|
.returning();
|
||||||
if (deploymentCreate.length === 0 || !deploymentCreate[0]) {
|
if (deploymentCreate.length === 0 || !deploymentCreate[0]) {
|
||||||
@@ -186,6 +192,8 @@ export const createDeploymentPreview = async (
|
|||||||
logPath: "",
|
logPath: "",
|
||||||
description: deployment.description || "",
|
description: deployment.description || "",
|
||||||
errorMessage: `An error have occured: ${error instanceof Error ? error.message : error}`,
|
errorMessage: `An error have occured: ${error instanceof Error ? error.message : error}`,
|
||||||
|
startedAt: new Date().toISOString(),
|
||||||
|
finishedAt: new Date().toISOString(),
|
||||||
})
|
})
|
||||||
.returning();
|
.returning();
|
||||||
await updatePreviewDeployment(deployment.previewDeploymentId, {
|
await updatePreviewDeployment(deployment.previewDeploymentId, {
|
||||||
@@ -207,8 +215,9 @@ export const createDeploymentCompose = async (
|
|||||||
) => {
|
) => {
|
||||||
const compose = await findComposeById(deployment.composeId);
|
const compose = await findComposeById(deployment.composeId);
|
||||||
try {
|
try {
|
||||||
await removeLastTenComposeDeployments(
|
await removeLastTenDeployments(
|
||||||
deployment.composeId,
|
deployment.composeId,
|
||||||
|
"compose",
|
||||||
compose.serverId,
|
compose.serverId,
|
||||||
);
|
);
|
||||||
const { LOGS_PATH } = paths(!!compose.serverId);
|
const { LOGS_PATH } = paths(!!compose.serverId);
|
||||||
@@ -240,6 +249,7 @@ echo "Initializing deployment" >> ${logFilePath};
|
|||||||
description: deployment.description || "",
|
description: deployment.description || "",
|
||||||
status: "running",
|
status: "running",
|
||||||
logPath: logFilePath,
|
logPath: logFilePath,
|
||||||
|
startedAt: new Date().toISOString(),
|
||||||
})
|
})
|
||||||
.returning();
|
.returning();
|
||||||
if (deploymentCreate.length === 0 || !deploymentCreate[0]) {
|
if (deploymentCreate.length === 0 || !deploymentCreate[0]) {
|
||||||
@@ -259,6 +269,8 @@ echo "Initializing deployment" >> ${logFilePath};
|
|||||||
logPath: "",
|
logPath: "",
|
||||||
description: deployment.description || "",
|
description: deployment.description || "",
|
||||||
errorMessage: `An error have occured: ${error instanceof Error ? error.message : error}`,
|
errorMessage: `An error have occured: ${error instanceof Error ? error.message : error}`,
|
||||||
|
startedAt: new Date().toISOString(),
|
||||||
|
finishedAt: new Date().toISOString(),
|
||||||
})
|
})
|
||||||
.returning();
|
.returning();
|
||||||
await updateCompose(compose.composeId, {
|
await updateCompose(compose.composeId, {
|
||||||
@@ -285,14 +297,13 @@ export const createDeploymentSchedule = async (
|
|||||||
schedule.application?.serverId ||
|
schedule.application?.serverId ||
|
||||||
schedule.compose?.serverId ||
|
schedule.compose?.serverId ||
|
||||||
schedule.server?.serverId;
|
schedule.server?.serverId;
|
||||||
await removeDeploymentsSchedule(deployment.scheduleId, serverId);
|
await removeLastTenDeployments(deployment.scheduleId, "schedule", serverId);
|
||||||
const { SCHEDULES_PATH } = paths(!!serverId);
|
const { SCHEDULES_PATH } = paths(!!serverId);
|
||||||
const formattedDateTime = format(new Date(), "yyyy-MM-dd:HH:mm:ss");
|
const formattedDateTime = format(new Date(), "yyyy-MM-dd:HH:mm:ss");
|
||||||
const fileName = `${schedule.appName}-${formattedDateTime}.log`;
|
const fileName = `${schedule.appName}-${formattedDateTime}.log`;
|
||||||
const logFilePath = path.join(SCHEDULES_PATH, schedule.appName, fileName);
|
const logFilePath = path.join(SCHEDULES_PATH, schedule.appName, fileName);
|
||||||
|
|
||||||
if (serverId) {
|
if (serverId) {
|
||||||
console.log("serverId", serverId);
|
|
||||||
const server = await findServerById(serverId);
|
const server = await findServerById(serverId);
|
||||||
|
|
||||||
const command = `
|
const command = `
|
||||||
@@ -316,6 +327,7 @@ export const createDeploymentSchedule = async (
|
|||||||
status: "running",
|
status: "running",
|
||||||
logPath: logFilePath,
|
logPath: logFilePath,
|
||||||
description: deployment.description || "",
|
description: deployment.description || "",
|
||||||
|
startedAt: new Date().toISOString(),
|
||||||
})
|
})
|
||||||
.returning();
|
.returning();
|
||||||
if (deploymentCreate.length === 0 || !deploymentCreate[0]) {
|
if (deploymentCreate.length === 0 || !deploymentCreate[0]) {
|
||||||
@@ -336,6 +348,8 @@ export const createDeploymentSchedule = async (
|
|||||||
logPath: "",
|
logPath: "",
|
||||||
description: deployment.description || "",
|
description: deployment.description || "",
|
||||||
errorMessage: `An error have occured: ${error instanceof Error ? error.message : error}`,
|
errorMessage: `An error have occured: ${error instanceof Error ? error.message : error}`,
|
||||||
|
startedAt: new Date().toISOString(),
|
||||||
|
finishedAt: new Date().toISOString(),
|
||||||
})
|
})
|
||||||
.returning();
|
.returning();
|
||||||
|
|
||||||
@@ -372,144 +386,15 @@ export const removeDeploymentsByApplicationId = async (
|
|||||||
.returning();
|
.returning();
|
||||||
};
|
};
|
||||||
|
|
||||||
const removeLastTenDeployments = async (
|
const getDeploymentsByType = async (
|
||||||
applicationId: string,
|
id: string,
|
||||||
serverId: string | null,
|
type: "application" | "compose" | "server" | "schedule" | "previewDeployment",
|
||||||
) => {
|
) => {
|
||||||
const deploymentList = await db.query.deployments.findMany({
|
const deploymentList = await db.query.deployments.findMany({
|
||||||
where: eq(deployments.applicationId, applicationId),
|
where: eq(deployments[`${type}Id`], id),
|
||||||
orderBy: desc(deployments.createdAt),
|
orderBy: desc(deployments.createdAt),
|
||||||
});
|
});
|
||||||
|
return deploymentList;
|
||||||
if (deploymentList.length > 10) {
|
|
||||||
const deploymentsToDelete = deploymentList.slice(9);
|
|
||||||
if (serverId) {
|
|
||||||
let command = "";
|
|
||||||
for (const oldDeployment of deploymentsToDelete) {
|
|
||||||
const logPath = path.join(oldDeployment.logPath);
|
|
||||||
|
|
||||||
command += `
|
|
||||||
rm -rf ${logPath};
|
|
||||||
`;
|
|
||||||
await removeDeployment(oldDeployment.deploymentId);
|
|
||||||
}
|
|
||||||
|
|
||||||
await execAsyncRemote(serverId, command);
|
|
||||||
} else {
|
|
||||||
for (const oldDeployment of deploymentsToDelete) {
|
|
||||||
const logPath = path.join(oldDeployment.logPath);
|
|
||||||
if (existsSync(logPath)) {
|
|
||||||
await fsPromises.unlink(logPath);
|
|
||||||
}
|
|
||||||
await removeDeployment(oldDeployment.deploymentId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const removeLastTenComposeDeployments = async (
|
|
||||||
composeId: string,
|
|
||||||
serverId: string | null,
|
|
||||||
) => {
|
|
||||||
const deploymentList = await db.query.deployments.findMany({
|
|
||||||
where: eq(deployments.composeId, composeId),
|
|
||||||
orderBy: desc(deployments.createdAt),
|
|
||||||
});
|
|
||||||
if (deploymentList.length > 10) {
|
|
||||||
if (serverId) {
|
|
||||||
let command = "";
|
|
||||||
const deploymentsToDelete = deploymentList.slice(9);
|
|
||||||
for (const oldDeployment of deploymentsToDelete) {
|
|
||||||
const logPath = path.join(oldDeployment.logPath);
|
|
||||||
|
|
||||||
command += `
|
|
||||||
rm -rf ${logPath};
|
|
||||||
`;
|
|
||||||
await removeDeployment(oldDeployment.deploymentId);
|
|
||||||
}
|
|
||||||
|
|
||||||
await execAsyncRemote(serverId, command);
|
|
||||||
} else {
|
|
||||||
const deploymentsToDelete = deploymentList.slice(9);
|
|
||||||
for (const oldDeployment of deploymentsToDelete) {
|
|
||||||
const logPath = path.join(oldDeployment.logPath);
|
|
||||||
if (existsSync(logPath)) {
|
|
||||||
await fsPromises.unlink(logPath);
|
|
||||||
}
|
|
||||||
await removeDeployment(oldDeployment.deploymentId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const removeLastTenPreviewDeploymenById = async (
|
|
||||||
previewDeploymentId: string,
|
|
||||||
serverId: string | null,
|
|
||||||
) => {
|
|
||||||
const deploymentList = await db.query.deployments.findMany({
|
|
||||||
where: eq(deployments.previewDeploymentId, previewDeploymentId),
|
|
||||||
orderBy: desc(deployments.createdAt),
|
|
||||||
});
|
|
||||||
|
|
||||||
if (deploymentList.length > 10) {
|
|
||||||
const deploymentsToDelete = deploymentList.slice(9);
|
|
||||||
if (serverId) {
|
|
||||||
let command = "";
|
|
||||||
for (const oldDeployment of deploymentsToDelete) {
|
|
||||||
const logPath = path.join(oldDeployment.logPath);
|
|
||||||
|
|
||||||
command += `
|
|
||||||
rm -rf ${logPath};
|
|
||||||
`;
|
|
||||||
await removeDeployment(oldDeployment.deploymentId);
|
|
||||||
}
|
|
||||||
|
|
||||||
await execAsyncRemote(serverId, command);
|
|
||||||
} else {
|
|
||||||
for (const oldDeployment of deploymentsToDelete) {
|
|
||||||
const logPath = path.join(oldDeployment.logPath);
|
|
||||||
if (existsSync(logPath)) {
|
|
||||||
await fsPromises.unlink(logPath);
|
|
||||||
}
|
|
||||||
await removeDeployment(oldDeployment.deploymentId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const removeDeploymentsSchedule = async (
|
|
||||||
scheduleId: string,
|
|
||||||
serverId?: string | null,
|
|
||||||
) => {
|
|
||||||
const deploymentList = await db.query.deployments.findMany({
|
|
||||||
where: eq(deployments.scheduleId, scheduleId),
|
|
||||||
orderBy: desc(deployments.createdAt),
|
|
||||||
});
|
|
||||||
|
|
||||||
if (deploymentList.length > 10) {
|
|
||||||
const deploymentsToDelete = deploymentList.slice(9);
|
|
||||||
if (serverId) {
|
|
||||||
let command = "";
|
|
||||||
for (const oldDeployment of deploymentsToDelete) {
|
|
||||||
const logPath = path.join(oldDeployment.logPath);
|
|
||||||
|
|
||||||
command += `
|
|
||||||
rm -rf ${logPath};
|
|
||||||
`;
|
|
||||||
await removeDeployment(oldDeployment.deploymentId);
|
|
||||||
}
|
|
||||||
|
|
||||||
await execAsyncRemote(serverId, command);
|
|
||||||
} else {
|
|
||||||
for (const oldDeployment of deploymentsToDelete) {
|
|
||||||
const logPath = path.join(oldDeployment.logPath);
|
|
||||||
if (existsSync(logPath)) {
|
|
||||||
await fsPromises.unlink(logPath);
|
|
||||||
}
|
|
||||||
await removeDeployment(oldDeployment.deploymentId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const removeDeployments = async (application: Application) => {
|
export const removeDeployments = async (application: Application) => {
|
||||||
@@ -524,6 +409,38 @@ export const removeDeployments = async (application: Application) => {
|
|||||||
await removeDeploymentsByApplicationId(applicationId);
|
await removeDeploymentsByApplicationId(applicationId);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const removeLastTenDeployments = async (
|
||||||
|
id: string,
|
||||||
|
type: "application" | "compose" | "server" | "schedule" | "previewDeployment",
|
||||||
|
serverId?: string | null,
|
||||||
|
) => {
|
||||||
|
const deploymentList = await getDeploymentsByType(id, type);
|
||||||
|
if (deploymentList.length > 10) {
|
||||||
|
const deploymentsToDelete = deploymentList.slice(10);
|
||||||
|
if (serverId) {
|
||||||
|
let command = "";
|
||||||
|
for (const oldDeployment of deploymentsToDelete) {
|
||||||
|
const logPath = path.join(oldDeployment.logPath);
|
||||||
|
|
||||||
|
command += `
|
||||||
|
rm -rf ${logPath};
|
||||||
|
`;
|
||||||
|
await removeDeployment(oldDeployment.deploymentId);
|
||||||
|
}
|
||||||
|
|
||||||
|
await execAsyncRemote(serverId, command);
|
||||||
|
} else {
|
||||||
|
for (const oldDeployment of deploymentsToDelete) {
|
||||||
|
const logPath = path.join(oldDeployment.logPath);
|
||||||
|
if (existsSync(logPath)) {
|
||||||
|
await fsPromises.unlink(logPath);
|
||||||
|
}
|
||||||
|
await removeDeployment(oldDeployment.deploymentId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
export const removeDeploymentsByPreviewDeploymentId = async (
|
export const removeDeploymentsByPreviewDeploymentId = async (
|
||||||
previewDeployment: PreviewDeployment,
|
previewDeployment: PreviewDeployment,
|
||||||
serverId: string | null,
|
serverId: string | null,
|
||||||
@@ -605,6 +522,10 @@ export const updateDeploymentStatus = async (
|
|||||||
.update(deployments)
|
.update(deployments)
|
||||||
.set({
|
.set({
|
||||||
status: deploymentStatus,
|
status: deploymentStatus,
|
||||||
|
finishedAt:
|
||||||
|
deploymentStatus === "done" || deploymentStatus === "error"
|
||||||
|
? new Date().toISOString()
|
||||||
|
: null,
|
||||||
})
|
})
|
||||||
.where(eq(deployments.deploymentId, deploymentId))
|
.where(eq(deployments.deploymentId, deploymentId))
|
||||||
.returning();
|
.returning();
|
||||||
|
|||||||
18
pnpm-lock.yaml
generated
18
pnpm-lock.yaml
generated
@@ -302,8 +302,8 @@ importers:
|
|||||||
specifier: ^0.39.1
|
specifier: ^0.39.1
|
||||||
version: 0.39.1(@opentelemetry/api@1.9.0)(@types/react@18.3.5)(kysely@0.27.6)(postgres@3.4.4)(react@18.2.0)(sqlite3@5.1.7)
|
version: 0.39.1(@opentelemetry/api@1.9.0)(@types/react@18.3.5)(kysely@0.27.6)(postgres@3.4.4)(react@18.2.0)(sqlite3@5.1.7)
|
||||||
drizzle-zod:
|
drizzle-zod:
|
||||||
specifier: 0.7.1
|
specifier: 0.5.1
|
||||||
version: 0.7.1(drizzle-orm@0.39.1(@opentelemetry/api@1.9.0)(@types/react@18.3.5)(kysely@0.27.6)(postgres@3.4.4)(react@18.2.0)(sqlite3@5.1.7))(zod@3.23.8)
|
version: 0.5.1(drizzle-orm@0.39.1(@opentelemetry/api@1.9.0)(@types/react@18.3.5)(kysely@0.27.6)(postgres@3.4.4)(react@18.2.0)(sqlite3@5.1.7))(zod@3.23.8)
|
||||||
fancy-ansi:
|
fancy-ansi:
|
||||||
specifier: ^0.1.3
|
specifier: ^0.1.3
|
||||||
version: 0.1.3
|
version: 0.1.3
|
||||||
@@ -664,8 +664,8 @@ importers:
|
|||||||
specifier: ^0.39.1
|
specifier: ^0.39.1
|
||||||
version: 0.39.1(@opentelemetry/api@1.9.0)(@types/react@18.3.5)(kysely@0.27.6)(postgres@3.4.4)(react@18.2.0)(sqlite3@5.1.7)
|
version: 0.39.1(@opentelemetry/api@1.9.0)(@types/react@18.3.5)(kysely@0.27.6)(postgres@3.4.4)(react@18.2.0)(sqlite3@5.1.7)
|
||||||
drizzle-zod:
|
drizzle-zod:
|
||||||
specifier: 0.7.1
|
specifier: 0.5.1
|
||||||
version: 0.7.1(drizzle-orm@0.39.1(@opentelemetry/api@1.9.0)(@types/react@18.3.5)(kysely@0.27.6)(postgres@3.4.4)(react@18.2.0)(sqlite3@5.1.7))(zod@3.23.8)
|
version: 0.5.1(drizzle-orm@0.39.1(@opentelemetry/api@1.9.0)(@types/react@18.3.5)(kysely@0.27.6)(postgres@3.4.4)(react@18.2.0)(sqlite3@5.1.7))(zod@3.23.8)
|
||||||
hi-base32:
|
hi-base32:
|
||||||
specifier: ^0.5.1
|
specifier: ^0.5.1
|
||||||
version: 0.5.1
|
version: 0.5.1
|
||||||
@@ -4549,11 +4549,11 @@ packages:
|
|||||||
sqlite3:
|
sqlite3:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
drizzle-zod@0.7.1:
|
drizzle-zod@0.5.1:
|
||||||
resolution: {integrity: sha512-nZzALOdz44/AL2U005UlmMqaQ1qe5JfanvLujiTHiiT8+vZJTBFhj3pY4Vk+L6UWyKFfNmLhk602Hn4kCTynKQ==}
|
resolution: {integrity: sha512-C/8bvzUH/zSnVfwdSibOgFjLhtDtbKYmkbPbUCq46QZyZCH6kODIMSOgZ8R7rVjoI+tCj3k06MRJMDqsIeoS4A==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
drizzle-orm: '>=0.36.0'
|
drizzle-orm: '>=0.23.13'
|
||||||
zod: '>=3.0.0'
|
zod: '*'
|
||||||
|
|
||||||
eastasianwidth@0.2.0:
|
eastasianwidth@0.2.0:
|
||||||
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
|
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
|
||||||
@@ -11191,7 +11191,7 @@ snapshots:
|
|||||||
react: 18.2.0
|
react: 18.2.0
|
||||||
sqlite3: 5.1.7
|
sqlite3: 5.1.7
|
||||||
|
|
||||||
drizzle-zod@0.7.1(drizzle-orm@0.39.1(@opentelemetry/api@1.9.0)(@types/react@18.3.5)(kysely@0.27.6)(postgres@3.4.4)(react@18.2.0)(sqlite3@5.1.7))(zod@3.23.8):
|
drizzle-zod@0.5.1(drizzle-orm@0.39.1(@opentelemetry/api@1.9.0)(@types/react@18.3.5)(kysely@0.27.6)(postgres@3.4.4)(react@18.2.0)(sqlite3@5.1.7))(zod@3.23.8):
|
||||||
dependencies:
|
dependencies:
|
||||||
drizzle-orm: 0.39.1(@opentelemetry/api@1.9.0)(@types/react@18.3.5)(kysely@0.27.6)(postgres@3.4.4)(react@18.2.0)(sqlite3@5.1.7)
|
drizzle-orm: 0.39.1(@opentelemetry/api@1.9.0)(@types/react@18.3.5)(kysely@0.27.6)(postgres@3.4.4)(react@18.2.0)(sqlite3@5.1.7)
|
||||||
zod: 3.23.8
|
zod: 3.23.8
|
||||||
|
|||||||
Reference in New Issue
Block a user