mirror of
https://github.com/Dokploy/dokploy.git
synced 2026-06-19 14:15:21 +02:00
Compare commits
6 Commits
v0.24.1
...
1365-creat
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
80d5313dd8 | ||
|
|
3f3ff9670b | ||
|
|
7fb902551e | ||
|
|
a201b3f979 | ||
|
|
01d78e50fc | ||
|
|
da0e726326 |
@@ -48,7 +48,7 @@ export const ShowTraefikConfig = ({ applicationId }: Props) => {
|
|||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="flex flex-col pt-2 relative">
|
<div className="flex flex-col pt-2 relative">
|
||||||
<div className="flex flex-col gap-6 max-h-[35rem] min-h-[10rem]">
|
<div className="flex flex-col gap-6 max-h-[35rem] min-h-[10rem] overflow-y-auto">
|
||||||
<CodeEditor
|
<CodeEditor
|
||||||
lineWrapping
|
lineWrapping
|
||||||
value={data || "Empty"}
|
value={data || "Empty"}
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ export const ShowDeployment = ({
|
|||||||
<div
|
<div
|
||||||
ref={scrollRef}
|
ref={scrollRef}
|
||||||
onScroll={handleScroll}
|
onScroll={handleScroll}
|
||||||
className="h-[720px] space-y-0 border p-4 bg-[#fafafa] dark:bg-[#050506] rounded custom-logs-scrollbar"
|
className="h-[720px] overflow-y-auto space-y-0 border p-4 bg-[#fafafa] dark:bg-[#050506] rounded custom-logs-scrollbar"
|
||||||
>
|
>
|
||||||
{" "}
|
{" "}
|
||||||
{filteredLogs.length > 0 ? (
|
{filteredLogs.length > 0 ? (
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ export const ShowContainerConfig = ({ containerId, serverId }: Props) => {
|
|||||||
See in detail the config of this container
|
See in detail the config of this container
|
||||||
</DialogDescription>
|
</DialogDescription>
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
<div className="text-wrap rounded-lg border p-4 text-sm bg-card max-h-[80vh]">
|
<div className="text-wrap rounded-lg border p-4 overflow-y-auto text-sm bg-card max-h-[80vh]">
|
||||||
<code>
|
<code>
|
||||||
<pre className="whitespace-pre-wrap break-words">
|
<pre className="whitespace-pre-wrap break-words">
|
||||||
<CodeEditor
|
<CodeEditor
|
||||||
|
|||||||
@@ -274,7 +274,7 @@ export const DockerLogsId: React.FC<Props> = ({
|
|||||||
<div
|
<div
|
||||||
ref={scrollRef}
|
ref={scrollRef}
|
||||||
onScroll={handleScroll}
|
onScroll={handleScroll}
|
||||||
className="h-[720px] space-y-0 border p-4 bg-[#fafafa] dark:bg-[#050506] rounded custom-logs-scrollbar"
|
className="h-[720px] overflow-y-auto space-y-0 border p-4 bg-[#fafafa] dark:bg-[#050506] rounded custom-logs-scrollbar"
|
||||||
>
|
>
|
||||||
{filteredLogs.length > 0 ? (
|
{filteredLogs.length > 0 ? (
|
||||||
filteredLogs.map((filteredLog: LogLine, index: number) => (
|
filteredLogs.map((filteredLog: LogLine, index: number) => (
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ export function LineCountFilter({
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<CommandPrimitive.List className="max-h-[300px] overflow-x-hidden">
|
<CommandPrimitive.List className="max-h-[300px] overflow-y-auto overflow-x-hidden">
|
||||||
<CommandPrimitive.Group className="px-2 py-1.5">
|
<CommandPrimitive.Group className="px-2 py-1.5">
|
||||||
{lineCountOptions.map((option) => {
|
{lineCountOptions.map((option) => {
|
||||||
const isSelected = value === option.value;
|
const isSelected = value === option.value;
|
||||||
|
|||||||
@@ -167,7 +167,7 @@ export const DuplicateProject = ({
|
|||||||
|
|
||||||
<div className="grid gap-2">
|
<div className="grid gap-2">
|
||||||
<Label>Selected services to duplicate</Label>
|
<Label>Selected services to duplicate</Label>
|
||||||
<div className="space-y-2 max-h-[200px] border rounded-md p-4">
|
<div className="space-y-2 max-h-[200px] overflow-y-auto border rounded-md p-4">
|
||||||
{selectedServices.map((service) => (
|
{selectedServices.map((service) => (
|
||||||
<div key={service.id} className="flex items-center space-x-2">
|
<div key={service.id} className="flex items-center space-x-2">
|
||||||
<span className="text-sm">
|
<span className="text-sm">
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ export const ShowProjects = () => {
|
|||||||
</Button>
|
</Button>
|
||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
<DropdownMenuContent
|
<DropdownMenuContent
|
||||||
className="w-[200px] space-y-2 max-h-[400px]"
|
className="w-[200px] space-y-2 overflow-y-auto max-h-[400px]"
|
||||||
onClick={(e) => e.stopPropagation()}
|
onClick={(e) => e.stopPropagation()}
|
||||||
>
|
>
|
||||||
{project.applications.length > 0 && (
|
{project.applications.length > 0 && (
|
||||||
@@ -265,7 +265,7 @@ export const ShowProjects = () => {
|
|||||||
</Button>
|
</Button>
|
||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
<DropdownMenuContent
|
<DropdownMenuContent
|
||||||
className="w-[200px] space-y-2 max-h-[280px]"
|
className="w-[200px] space-y-2 overflow-y-auto max-h-[280px]"
|
||||||
onClick={(e) => e.stopPropagation()}
|
onClick={(e) => e.stopPropagation()}
|
||||||
>
|
>
|
||||||
<DropdownMenuLabel className="font-normal">
|
<DropdownMenuLabel className="font-normal">
|
||||||
|
|||||||
@@ -147,7 +147,7 @@ export const SetupServer = ({ serverId }: Props) => {
|
|||||||
<li>2. Add The SSH Key to Server Manually</li>
|
<li>2. Add The SSH Key to Server Manually</li>
|
||||||
</ul>
|
</ul>
|
||||||
<div className="flex flex-col gap-4 w-full overflow-auto">
|
<div className="flex flex-col gap-4 w-full overflow-auto">
|
||||||
<div className="flex relative flex-col gap-2">
|
<div className="flex relative flex-col gap-2 overflow-y-auto">
|
||||||
<div className="text-sm text-primary flex flex-row gap-2 items-center">
|
<div className="text-sm text-primary flex flex-row gap-2 items-center">
|
||||||
Copy Public Key ({server?.sshKey?.name})
|
Copy Public Key ({server?.sshKey?.name})
|
||||||
<button
|
<button
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ export const CreateSSHKey = () => {
|
|||||||
Option 2
|
Option 2
|
||||||
</span>
|
</span>
|
||||||
<div className="flex flex-col gap-4 w-full overflow-auto">
|
<div className="flex flex-col gap-4 w-full overflow-auto">
|
||||||
<div className="flex relative flex-col gap-2">
|
<div className="flex relative flex-col gap-2 overflow-y-auto">
|
||||||
<div className="text-sm text-primary flex flex-row gap-2 items-center">
|
<div className="text-sm text-primary flex flex-row gap-2 items-center">
|
||||||
Copy Public Key
|
Copy Public Key
|
||||||
<button
|
<button
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ export default function SwarmMonitorCard({ serverId }: Props) {
|
|||||||
</div>
|
</div>
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
<TooltipContent>
|
<TooltipContent>
|
||||||
<div className="max-h-48">
|
<div className="max-h-48 overflow-y-auto">
|
||||||
{activeNodes.map((node) => (
|
{activeNodes.map((node) => (
|
||||||
<div key={node.ID} className="flex items-center gap-2">
|
<div key={node.ID} className="flex items-center gap-2">
|
||||||
{node.Hostname}
|
{node.Hostname}
|
||||||
@@ -162,7 +162,7 @@ export default function SwarmMonitorCard({ serverId }: Props) {
|
|||||||
</div>
|
</div>
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
<TooltipContent>
|
<TooltipContent>
|
||||||
<div className="max-h-48">
|
<div className="max-h-48 overflow-y-auto">
|
||||||
{managerNodes.map((node) => (
|
{managerNodes.map((node) => (
|
||||||
<div key={node.ID} className="flex items-center gap-2">
|
<div key={node.ID} className="flex items-center gap-2">
|
||||||
{node.Hostname}
|
{node.Hostname}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "dokploy",
|
"name": "dokploy",
|
||||||
"version": "v0.24.1",
|
"version": "v0.24.2",
|
||||||
"private": true,
|
"private": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|||||||
@@ -1,13 +1,23 @@
|
|||||||
import { apiFindAllByApplication } from "@/server/db/schema";
|
import { db } from "@/server/db";
|
||||||
|
import { apiFindAllByApplication, applications } from "@/server/db/schema";
|
||||||
import {
|
import {
|
||||||
|
createPreviewDeployment,
|
||||||
findApplicationById,
|
findApplicationById,
|
||||||
|
findPreviewDeploymentByApplicationId,
|
||||||
findPreviewDeploymentById,
|
findPreviewDeploymentById,
|
||||||
findPreviewDeploymentsByApplicationId,
|
findPreviewDeploymentsByApplicationId,
|
||||||
|
findPreviewDeploymentsByPullRequestId,
|
||||||
|
IS_CLOUD,
|
||||||
removePreviewDeployment,
|
removePreviewDeployment,
|
||||||
} from "@dokploy/server";
|
} from "@dokploy/server";
|
||||||
import { TRPCError } from "@trpc/server";
|
import { TRPCError } from "@trpc/server";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { createTRPCRouter, protectedProcedure } from "../trpc";
|
import { createTRPCRouter, protectedProcedure } from "../trpc";
|
||||||
|
import { eq } from "drizzle-orm";
|
||||||
|
import { and } from "drizzle-orm";
|
||||||
|
import { myQueue } from "@/server/queues/queueSetup";
|
||||||
|
import { deploy } from "@/server/utils/deploy";
|
||||||
|
import type { DeploymentJob } from "@/server/queues/queue-types";
|
||||||
|
|
||||||
export const previewDeploymentRouter = createTRPCRouter({
|
export const previewDeploymentRouter = createTRPCRouter({
|
||||||
all: protectedProcedure
|
all: protectedProcedure
|
||||||
@@ -59,4 +69,142 @@ export const previewDeploymentRouter = createTRPCRouter({
|
|||||||
}
|
}
|
||||||
return previewDeployment;
|
return previewDeployment;
|
||||||
}),
|
}),
|
||||||
|
create: protectedProcedure
|
||||||
|
.input(
|
||||||
|
z.object({
|
||||||
|
action: z.enum(["opened", "synchronize", "reopened", "closed"]),
|
||||||
|
pullRequestId: z.string(),
|
||||||
|
repository: z.string(),
|
||||||
|
owner: z.string(),
|
||||||
|
branch: z.string(),
|
||||||
|
deploymentHash: z.string(),
|
||||||
|
prBranch: z.string(),
|
||||||
|
prNumber: z.any(),
|
||||||
|
prTitle: z.string(),
|
||||||
|
prURL: z.string(),
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.mutation(async ({ input, ctx }) => {
|
||||||
|
const organizationId = ctx.session.activeOrganizationId;
|
||||||
|
const action = input.action;
|
||||||
|
const prId = input.pullRequestId;
|
||||||
|
|
||||||
|
if (action === "closed") {
|
||||||
|
const previewDeploymentResult =
|
||||||
|
await findPreviewDeploymentsByPullRequestId(prId);
|
||||||
|
|
||||||
|
const filteredPreviewDeploymentResult = previewDeploymentResult.filter(
|
||||||
|
(previewDeployment) =>
|
||||||
|
previewDeployment.application.project.organizationId ===
|
||||||
|
organizationId,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (filteredPreviewDeploymentResult.length > 0) {
|
||||||
|
for (const previewDeployment of filteredPreviewDeploymentResult) {
|
||||||
|
try {
|
||||||
|
await removePreviewDeployment(
|
||||||
|
previewDeployment.previewDeploymentId,
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
message: "Preview Deployments Closed",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
action === "opened" ||
|
||||||
|
action === "synchronize" ||
|
||||||
|
action === "reopened"
|
||||||
|
) {
|
||||||
|
const deploymentHash = input.deploymentHash;
|
||||||
|
|
||||||
|
const prBranch = input.prBranch;
|
||||||
|
const prNumber = input.prNumber;
|
||||||
|
const prTitle = input.prTitle;
|
||||||
|
const prURL = input.prURL;
|
||||||
|
const apps = await db.query.applications.findMany({
|
||||||
|
where: and(
|
||||||
|
eq(applications.sourceType, "github"),
|
||||||
|
eq(applications.repository, input.repository),
|
||||||
|
eq(applications.branch, input.branch),
|
||||||
|
eq(applications.isPreviewDeploymentsActive, true),
|
||||||
|
eq(applications.owner, input.owner),
|
||||||
|
),
|
||||||
|
with: {
|
||||||
|
previewDeployments: true,
|
||||||
|
project: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const filteredApps = apps.filter(
|
||||||
|
(app) => app.project.organizationId === organizationId,
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log(filteredApps);
|
||||||
|
|
||||||
|
for (const app of filteredApps) {
|
||||||
|
const previewLimit = app?.previewLimit || 0;
|
||||||
|
if (app?.previewDeployments?.length > previewLimit) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const previewDeploymentResult =
|
||||||
|
await findPreviewDeploymentByApplicationId(app.applicationId, prId);
|
||||||
|
|
||||||
|
let previewDeploymentId =
|
||||||
|
previewDeploymentResult?.previewDeploymentId || "";
|
||||||
|
|
||||||
|
if (!previewDeploymentResult) {
|
||||||
|
try {
|
||||||
|
const previewDeployment = await createPreviewDeployment({
|
||||||
|
applicationId: app.applicationId as string,
|
||||||
|
branch: prBranch,
|
||||||
|
pullRequestId: prId,
|
||||||
|
pullRequestNumber: prNumber,
|
||||||
|
pullRequestTitle: prTitle,
|
||||||
|
pullRequestURL: prURL,
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(previewDeployment);
|
||||||
|
previewDeploymentId = previewDeployment.previewDeploymentId;
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const jobData: DeploymentJob = {
|
||||||
|
applicationId: app.applicationId as string,
|
||||||
|
titleLog: "Preview Deployment",
|
||||||
|
descriptionLog: `Hash: ${deploymentHash}`,
|
||||||
|
type: "deploy",
|
||||||
|
applicationType: "application-preview",
|
||||||
|
server: !!app.serverId,
|
||||||
|
previewDeploymentId,
|
||||||
|
isExternal: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (IS_CLOUD && app.serverId) {
|
||||||
|
jobData.serverId = app.serverId;
|
||||||
|
await deploy(jobData);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
await myQueue.add(
|
||||||
|
"deployments",
|
||||||
|
{ ...jobData },
|
||||||
|
{
|
||||||
|
removeOnComplete: true,
|
||||||
|
removeOnFail: true,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
message: "Preview Deployments Created",
|
||||||
|
};
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -641,16 +641,10 @@ export const settingsRouter = createTRPCRouter({
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
.input(
|
.input(
|
||||||
z
|
z.object({
|
||||||
.object({
|
start: z.string().optional(),
|
||||||
dateRange: z
|
end: z.string().optional(),
|
||||||
.object({
|
}),
|
||||||
start: z.string().optional(),
|
|
||||||
end: z.string().optional(),
|
|
||||||
})
|
|
||||||
.optional(),
|
|
||||||
})
|
|
||||||
.optional(),
|
|
||||||
)
|
)
|
||||||
.query(async ({ input }) => {
|
.query(async ({ input }) => {
|
||||||
if (IS_CLOUD) {
|
if (IS_CLOUD) {
|
||||||
|
|||||||
@@ -98,6 +98,7 @@ export const deploymentWorker = new Worker(
|
|||||||
titleLog: job.data.titleLog,
|
titleLog: job.data.titleLog,
|
||||||
descriptionLog: job.data.descriptionLog,
|
descriptionLog: job.data.descriptionLog,
|
||||||
previewDeploymentId: job.data.previewDeploymentId,
|
previewDeploymentId: job.data.previewDeploymentId,
|
||||||
|
isExternal: job.data.isExternal,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -107,6 +108,7 @@ export const deploymentWorker = new Worker(
|
|||||||
titleLog: job.data.titleLog,
|
titleLog: job.data.titleLog,
|
||||||
descriptionLog: job.data.descriptionLog,
|
descriptionLog: job.data.descriptionLog,
|
||||||
previewDeploymentId: job.data.previewDeploymentId,
|
previewDeploymentId: job.data.previewDeploymentId,
|
||||||
|
isExternal: job.data.isExternal,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ type DeployJob =
|
|||||||
applicationType: "application-preview";
|
applicationType: "application-preview";
|
||||||
previewDeploymentId: string;
|
previewDeploymentId: string;
|
||||||
serverId?: string;
|
serverId?: string;
|
||||||
|
isExternal?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type DeploymentJob = DeployJob;
|
export type DeploymentJob = DeployJob;
|
||||||
|
|||||||
@@ -404,11 +404,13 @@ export const deployPreviewApplication = async ({
|
|||||||
titleLog = "Preview Deployment",
|
titleLog = "Preview Deployment",
|
||||||
descriptionLog = "",
|
descriptionLog = "",
|
||||||
previewDeploymentId,
|
previewDeploymentId,
|
||||||
|
isExternal = false,
|
||||||
}: {
|
}: {
|
||||||
applicationId: string;
|
applicationId: string;
|
||||||
titleLog: string;
|
titleLog: string;
|
||||||
descriptionLog: string;
|
descriptionLog: string;
|
||||||
previewDeploymentId: string;
|
previewDeploymentId: string;
|
||||||
|
isExternal?: boolean;
|
||||||
}) => {
|
}) => {
|
||||||
const application = await findApplicationById(applicationId);
|
const application = await findApplicationById(applicationId);
|
||||||
|
|
||||||
@@ -434,36 +436,39 @@ export const deployPreviewApplication = async ({
|
|||||||
githubId: application?.githubId || "",
|
githubId: application?.githubId || "",
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
const commentExists = await issueCommentExists({
|
if (!isExternal) {
|
||||||
...issueParams,
|
const commentExists = await issueCommentExists({
|
||||||
});
|
|
||||||
if (!commentExists) {
|
|
||||||
const result = await createPreviewDeploymentComment({
|
|
||||||
...issueParams,
|
...issueParams,
|
||||||
previewDomain,
|
|
||||||
appName: previewDeployment.appName,
|
|
||||||
githubId: application?.githubId || "",
|
|
||||||
previewDeploymentId,
|
|
||||||
});
|
});
|
||||||
|
if (!commentExists) {
|
||||||
if (!result) {
|
const result = await createPreviewDeploymentComment({
|
||||||
throw new TRPCError({
|
...issueParams,
|
||||||
code: "NOT_FOUND",
|
previewDomain,
|
||||||
message: "Pull request comment not found",
|
appName: previewDeployment.appName,
|
||||||
|
githubId: application?.githubId || "",
|
||||||
|
previewDeploymentId,
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
issueParams.comment_id = Number.parseInt(result?.pullRequestCommentId);
|
if (!result) {
|
||||||
|
throw new TRPCError({
|
||||||
|
code: "NOT_FOUND",
|
||||||
|
message: "Pull request comment not found",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
issueParams.comment_id = Number.parseInt(result?.pullRequestCommentId);
|
||||||
|
}
|
||||||
|
const buildingComment = getIssueComment(
|
||||||
|
application.name,
|
||||||
|
"running",
|
||||||
|
previewDomain,
|
||||||
|
);
|
||||||
|
await updateIssueComment({
|
||||||
|
...issueParams,
|
||||||
|
body: `### Dokploy Preview Deployment\n\n${buildingComment}`,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
const buildingComment = getIssueComment(
|
|
||||||
application.name,
|
|
||||||
"running",
|
|
||||||
previewDomain,
|
|
||||||
);
|
|
||||||
await updateIssueComment({
|
|
||||||
...issueParams,
|
|
||||||
body: `### Dokploy Preview Deployment\n\n${buildingComment}`,
|
|
||||||
});
|
|
||||||
application.appName = previewDeployment.appName;
|
application.appName = previewDeployment.appName;
|
||||||
application.env = `${application.previewEnv}\nDOKPLOY_DEPLOY_URL=${previewDeployment?.domain?.host}`;
|
application.env = `${application.previewEnv}\nDOKPLOY_DEPLOY_URL=${previewDeployment?.domain?.host}`;
|
||||||
application.buildArgs = application.previewBuildArgs;
|
application.buildArgs = application.previewBuildArgs;
|
||||||
@@ -477,25 +482,31 @@ export const deployPreviewApplication = async ({
|
|||||||
});
|
});
|
||||||
await buildApplication(application, deployment.logPath);
|
await buildApplication(application, deployment.logPath);
|
||||||
}
|
}
|
||||||
const successComment = getIssueComment(
|
|
||||||
application.name,
|
if (!isExternal) {
|
||||||
"success",
|
const successComment = getIssueComment(
|
||||||
previewDomain,
|
application.name,
|
||||||
);
|
"success",
|
||||||
await updateIssueComment({
|
previewDomain,
|
||||||
...issueParams,
|
);
|
||||||
body: `### Dokploy Preview Deployment\n\n${successComment}`,
|
await updateIssueComment({
|
||||||
});
|
...issueParams,
|
||||||
|
body: `### Dokploy Preview Deployment\n\n${successComment}`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
await updateDeploymentStatus(deployment.deploymentId, "done");
|
await updateDeploymentStatus(deployment.deploymentId, "done");
|
||||||
await updatePreviewDeployment(previewDeploymentId, {
|
await updatePreviewDeployment(previewDeploymentId, {
|
||||||
previewStatus: "done",
|
previewStatus: "done",
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const comment = getIssueComment(application.name, "error", previewDomain);
|
if (!isExternal) {
|
||||||
await updateIssueComment({
|
const comment = getIssueComment(application.name, "error", previewDomain);
|
||||||
...issueParams,
|
await updateIssueComment({
|
||||||
body: `### Dokploy Preview Deployment\n\n${comment}`,
|
...issueParams,
|
||||||
});
|
body: `### Dokploy Preview Deployment\n\n${comment}`,
|
||||||
|
});
|
||||||
|
}
|
||||||
await updateDeploymentStatus(deployment.deploymentId, "error");
|
await updateDeploymentStatus(deployment.deploymentId, "error");
|
||||||
await updatePreviewDeployment(previewDeploymentId, {
|
await updatePreviewDeployment(previewDeploymentId, {
|
||||||
previewStatus: "error",
|
previewStatus: "error",
|
||||||
@@ -511,11 +522,13 @@ export const deployRemotePreviewApplication = async ({
|
|||||||
titleLog = "Preview Deployment",
|
titleLog = "Preview Deployment",
|
||||||
descriptionLog = "",
|
descriptionLog = "",
|
||||||
previewDeploymentId,
|
previewDeploymentId,
|
||||||
|
isExternal = false,
|
||||||
}: {
|
}: {
|
||||||
applicationId: string;
|
applicationId: string;
|
||||||
titleLog: string;
|
titleLog: string;
|
||||||
descriptionLog: string;
|
descriptionLog: string;
|
||||||
previewDeploymentId: string;
|
previewDeploymentId: string;
|
||||||
|
isExternal?: boolean;
|
||||||
}) => {
|
}) => {
|
||||||
const application = await findApplicationById(applicationId);
|
const application = await findApplicationById(applicationId);
|
||||||
|
|
||||||
@@ -541,36 +554,39 @@ export const deployRemotePreviewApplication = async ({
|
|||||||
githubId: application?.githubId || "",
|
githubId: application?.githubId || "",
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
const commentExists = await issueCommentExists({
|
if (!isExternal) {
|
||||||
...issueParams,
|
const commentExists = await issueCommentExists({
|
||||||
});
|
|
||||||
if (!commentExists) {
|
|
||||||
const result = await createPreviewDeploymentComment({
|
|
||||||
...issueParams,
|
...issueParams,
|
||||||
previewDomain,
|
|
||||||
appName: previewDeployment.appName,
|
|
||||||
githubId: application?.githubId || "",
|
|
||||||
previewDeploymentId,
|
|
||||||
});
|
});
|
||||||
|
if (!commentExists) {
|
||||||
if (!result) {
|
const result = await createPreviewDeploymentComment({
|
||||||
throw new TRPCError({
|
...issueParams,
|
||||||
code: "NOT_FOUND",
|
previewDomain,
|
||||||
message: "Pull request comment not found",
|
appName: previewDeployment.appName,
|
||||||
|
githubId: application?.githubId || "",
|
||||||
|
previewDeploymentId,
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
issueParams.comment_id = Number.parseInt(result?.pullRequestCommentId);
|
if (!result) {
|
||||||
|
throw new TRPCError({
|
||||||
|
code: "NOT_FOUND",
|
||||||
|
message: "Pull request comment not found",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
issueParams.comment_id = Number.parseInt(result?.pullRequestCommentId);
|
||||||
|
}
|
||||||
|
const buildingComment = getIssueComment(
|
||||||
|
application.name,
|
||||||
|
"running",
|
||||||
|
previewDomain,
|
||||||
|
);
|
||||||
|
await updateIssueComment({
|
||||||
|
...issueParams,
|
||||||
|
body: `### Dokploy Preview Deployment\n\n${buildingComment}`,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
const buildingComment = getIssueComment(
|
|
||||||
application.name,
|
|
||||||
"running",
|
|
||||||
previewDomain,
|
|
||||||
);
|
|
||||||
await updateIssueComment({
|
|
||||||
...issueParams,
|
|
||||||
body: `### Dokploy Preview Deployment\n\n${buildingComment}`,
|
|
||||||
});
|
|
||||||
application.appName = previewDeployment.appName;
|
application.appName = previewDeployment.appName;
|
||||||
application.env = `${application.previewEnv}\nDOKPLOY_DEPLOY_URL=${previewDeployment?.domain?.host}`;
|
application.env = `${application.previewEnv}\nDOKPLOY_DEPLOY_URL=${previewDeployment?.domain?.host}`;
|
||||||
application.buildArgs = application.previewBuildArgs;
|
application.buildArgs = application.previewBuildArgs;
|
||||||
@@ -592,25 +608,29 @@ export const deployRemotePreviewApplication = async ({
|
|||||||
await mechanizeDockerContainer(application);
|
await mechanizeDockerContainer(application);
|
||||||
}
|
}
|
||||||
|
|
||||||
const successComment = getIssueComment(
|
if (!isExternal) {
|
||||||
application.name,
|
const successComment = getIssueComment(
|
||||||
"success",
|
application.name,
|
||||||
previewDomain,
|
"success",
|
||||||
);
|
previewDomain,
|
||||||
await updateIssueComment({
|
);
|
||||||
...issueParams,
|
await updateIssueComment({
|
||||||
body: `### Dokploy Preview Deployment\n\n${successComment}`,
|
...issueParams,
|
||||||
});
|
body: `### Dokploy Preview Deployment\n\n${successComment}`,
|
||||||
|
});
|
||||||
|
}
|
||||||
await updateDeploymentStatus(deployment.deploymentId, "done");
|
await updateDeploymentStatus(deployment.deploymentId, "done");
|
||||||
await updatePreviewDeployment(previewDeploymentId, {
|
await updatePreviewDeployment(previewDeploymentId, {
|
||||||
previewStatus: "done",
|
previewStatus: "done",
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const comment = getIssueComment(application.name, "error", previewDomain);
|
if (!isExternal) {
|
||||||
await updateIssueComment({
|
const comment = getIssueComment(application.name, "error", previewDomain);
|
||||||
...issueParams,
|
await updateIssueComment({
|
||||||
body: `### Dokploy Preview Deployment\n\n${comment}`,
|
...issueParams,
|
||||||
});
|
body: `### Dokploy Preview Deployment\n\n${comment}`,
|
||||||
|
});
|
||||||
|
}
|
||||||
await updateDeploymentStatus(deployment.deploymentId, "error");
|
await updateDeploymentStatus(deployment.deploymentId, "error");
|
||||||
await updatePreviewDeployment(previewDeploymentId, {
|
await updatePreviewDeployment(previewDeploymentId, {
|
||||||
previewStatus: "error",
|
previewStatus: "error",
|
||||||
|
|||||||
@@ -152,6 +152,7 @@ export const findPreviewDeploymentsByApplicationId = async (
|
|||||||
|
|
||||||
export const createPreviewDeployment = async (
|
export const createPreviewDeployment = async (
|
||||||
schema: typeof apiCreatePreviewDeployment._type,
|
schema: typeof apiCreatePreviewDeployment._type,
|
||||||
|
isExternal = false,
|
||||||
) => {
|
) => {
|
||||||
const application = await findApplicationById(schema.applicationId);
|
const application = await findApplicationById(schema.applicationId);
|
||||||
const appName = `preview-${application.appName}-${generatePassword(6)}`;
|
const appName = `preview-${application.appName}-${generatePassword(6)}`;
|
||||||
@@ -166,27 +167,32 @@ export const createPreviewDeployment = async (
|
|||||||
org?.ownerId || "",
|
org?.ownerId || "",
|
||||||
);
|
);
|
||||||
|
|
||||||
const octokit = authGithub(application?.github as Github);
|
let issueId = "";
|
||||||
|
if (!isExternal) {
|
||||||
|
const octokit = authGithub(application?.github as Github);
|
||||||
|
|
||||||
const runningComment = getIssueComment(
|
const runningComment = getIssueComment(
|
||||||
application.name,
|
application.name,
|
||||||
"initializing",
|
"initializing",
|
||||||
`${application.previewHttps ? "https" : "http"}://${generateDomain}`,
|
`${application.previewHttps ? "https" : "http"}://${generateDomain}`,
|
||||||
);
|
);
|
||||||
|
|
||||||
const issue = await octokit.rest.issues.createComment({
|
const issue = await octokit.rest.issues.createComment({
|
||||||
owner: application?.owner || "",
|
owner: application?.owner || "",
|
||||||
repo: application?.repository || "",
|
repo: application?.repository || "",
|
||||||
issue_number: Number.parseInt(schema.pullRequestNumber),
|
issue_number: Number.parseInt(schema.pullRequestNumber),
|
||||||
body: `### Dokploy Preview Deployment\n\n${runningComment}`,
|
body: `### Dokploy Preview Deployment\n\n${runningComment}`,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
issueId = `${issue.data.id}`;
|
||||||
|
}
|
||||||
|
|
||||||
const previewDeployment = await db
|
const previewDeployment = await db
|
||||||
.insert(previewDeployments)
|
.insert(previewDeployments)
|
||||||
.values({
|
.values({
|
||||||
...schema,
|
...schema,
|
||||||
appName: appName,
|
appName: appName,
|
||||||
pullRequestCommentId: `${issue.data.id}`,
|
pullRequestCommentId: issueId,
|
||||||
})
|
})
|
||||||
.returning()
|
.returning()
|
||||||
.then((value) => value[0]);
|
.then((value) => value[0]);
|
||||||
@@ -233,6 +239,13 @@ export const findPreviewDeploymentsByPullRequestId = async (
|
|||||||
) => {
|
) => {
|
||||||
const previewDeploymentResult = await db.query.previewDeployments.findMany({
|
const previewDeploymentResult = await db.query.previewDeployments.findMany({
|
||||||
where: eq(previewDeployments.pullRequestId, pullRequestId),
|
where: eq(previewDeployments.pullRequestId, pullRequestId),
|
||||||
|
with: {
|
||||||
|
application: {
|
||||||
|
with: {
|
||||||
|
project: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
return previewDeploymentResult;
|
return previewDeploymentResult;
|
||||||
|
|||||||
Reference in New Issue
Block a user