[autofix.ci] apply automated fixes

This commit is contained in:
autofix-ci[bot]
2026-02-17 06:04:26 +00:00
committed by GitHub
parent 0fc043d0ad
commit 752f90c330
10 changed files with 21293 additions and 22887 deletions

View File

@@ -1,4 +1,3 @@
import { existsSync } from "node:fs";
import path from "node:path";
import type { ApplicationNested } from "@dokploy/server";
@@ -80,9 +79,8 @@ vi.mock("@dokploy/server/services/rollbacks", () => ({
}));
vi.mock("@dokploy/server/services/patch", async (importOriginal) => {
const actual = await importOriginal<
typeof import("@dokploy/server/services/patch")
>();
const actual =
await importOriginal<typeof import("@dokploy/server/services/patch")>();
return {
...actual,
findPatchesByApplicationId: vi.fn().mockResolvedValue([]),
@@ -507,7 +505,8 @@ describe(
// 1. Setup local temporary git repo
const tempRepo = await mkdtemp(join(tmpdir(), "real-patch-repo-"));
// Helper for local git commands
const execLocal = async (cmd: string) => execAsync(cmd, { cwd: tempRepo });
const execLocal = async (cmd: string) =>
execAsync(cmd, { cwd: tempRepo });
await execLocal("git init");
await execLocal("git config user.email 'test@dokploy.com'");
@@ -518,7 +517,7 @@ describe(
await writeFile(join(tempRepo, "app.py"), "print('Original App')\n");
await writeFile(
join(tempRepo, "Dockerfile"),
"FROM python:3.9-slim\nCOPY app.py .\nCMD [\"python\", \"app.py\"]\n",
'FROM python:3.9-slim\nCOPY app.py .\nCMD ["python", "app.py"]\n',
);
await execLocal("git add .");

View File

@@ -1,4 +1,3 @@
import { generatePatch } from "@dokploy/server/services/patch";
import { describe, expect, it, afterEach } from "vitest";
import { mkdtemp, rm, writeFile, readFile } from "node:fs/promises";
@@ -23,16 +22,18 @@ describe("Patch System Integration", () => {
tempDir = await mkdtemp(join(tmpdir(), "dokploy-patch-test-"));
const fileName = "test.txt";
const filePath = join(tempDir, fileName);
await execAsyncLocal("git init", { cwd: tempDir });
await execAsyncLocal("git config user.email 'test@test.com'", { cwd: tempDir });
await execAsyncLocal("git config user.email 'test@test.com'", {
cwd: tempDir,
});
await execAsyncLocal("git config user.name 'Test'", { cwd: tempDir });
// Original content
await writeFile(filePath, "line1\nline2\n");
await execAsyncLocal(`git add ${fileName}`, { cwd: tempDir });
await execAsyncLocal("git commit -m 'init'", { cwd: tempDir });
// Generate patch (modify content)
const newContent = "line1\nline2\nline3\n";
const patchContent = await generatePatch({
@@ -41,7 +42,7 @@ describe("Patch System Integration", () => {
newContent,
serverId: null,
});
// Verify patch format
expect(patchContent.endsWith("\n")).toBe(true);
@@ -49,20 +50,22 @@ describe("Patch System Integration", () => {
await execAsyncLocal("git checkout .", { cwd: tempDir });
const savedContent = await readFile(filePath, "utf-8");
expect(savedContent).toBe("line1\nline2\n");
// Apply patch verification
// We simulate what Deployment Service does: write patch to file and run git apply
const patchFile = join(tempDir, "changes.patch");
await writeFile(patchFile, patchContent);
try {
await execAsyncLocal(`git apply --whitespace=fix ${patchFile}`, { cwd: tempDir });
await execAsyncLocal(`git apply --whitespace=fix ${patchFile}`, {
cwd: tempDir,
});
} catch (e: any) {
console.error("Git apply failed:", e.message);
console.log("Patch content:", JSON.stringify(patchContent));
throw e;
}
const appliedContent = await readFile(filePath, "utf-8");
expect(appliedContent).toBe(newContent);
});
@@ -72,17 +75,19 @@ describe("Patch System Integration", () => {
tempDir = await mkdtemp(join(tmpdir(), "dokploy-patch-test-noline-"));
const fileName = "noline.txt";
const filePath = join(tempDir, fileName);
await execAsyncLocal("git init", { cwd: tempDir });
await execAsyncLocal("git config user.email 'test@test.com'", { cwd: tempDir });
await execAsyncLocal("git config user.email 'test@test.com'", {
cwd: tempDir,
});
await execAsyncLocal("git config user.name 'Test'", { cwd: tempDir });
// Original content WITHOUT newline
await writeFile(filePath, "line1");
await execAsyncLocal(`git add ${fileName}`, { cwd: tempDir });
await execAsyncLocal("git commit -m 'init'", { cwd: tempDir });
// Generate patch
// Generate patch
const newContent = "line1\nline2";
const patchContent = await generatePatch({
codePath: tempDir,
@@ -93,13 +98,15 @@ describe("Patch System Integration", () => {
// Verify patch format
expect(patchContent.endsWith("\n")).toBe(true);
// Apply patch
const patchFile = join(tempDir, "changes.patch");
await writeFile(patchFile, patchContent);
await execAsyncLocal(`git apply --whitespace=fix ${patchFile}`, { cwd: tempDir });
await execAsyncLocal(`git apply --whitespace=fix ${patchFile}`, {
cwd: tempDir,
});
const appliedContent = await readFile(filePath, "utf-8");
expect(appliedContent).toBe(newContent);
});

View File

@@ -1,9 +1,22 @@
import { ArrowLeft, ChevronRight, File, Folder, Loader2, Save } from "lucide-react";
import {
ArrowLeft,
ChevronRight,
File,
Folder,
Loader2,
Save,
} from "lucide-react";
import { useCallback, useState } from "react";
import { toast } from "sonner";
import { CodeEditor } from "@/components/shared/code-editor";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { ScrollArea } from "@/components/ui/scroll-area";
import { api } from "@/utils/api";
import type { RouterOutputs } from "@/utils/api";
@@ -31,7 +44,9 @@ export const PatchEditor = ({
const [selectedFile, setSelectedFile] = useState<string | null>(null);
const [fileContent, setFileContent] = useState<string>("");
const [originalContent, setOriginalContent] = useState<string>("");
const [expandedFolders, setExpandedFolders] = useState<Set<string>>(new Set());
const [expandedFolders, setExpandedFolders] = useState<Set<string>>(
new Set(),
);
const [isSaving, setIsSaving] = useState(false);
// Fetch directory tree

View File

@@ -1,9 +1,23 @@
import { AlertCircle, ChevronRight, File, Folder, Loader2, Power, Trash2 } from "lucide-react";
import {
AlertCircle,
ChevronRight,
File,
Folder,
Loader2,
Power,
Trash2,
} from "lucide-react";
import { useState } from "react";
import { toast } from "sonner";
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { Switch } from "@/components/ui/switch";
import {
Table,
@@ -136,8 +150,8 @@ export const ShowPatches = ({ applicationId, composeId }: Props) => {
<div>
<CardTitle>Patches</CardTitle>
<CardDescription>
Apply code patches to your repository during build. Patches are applied after
cloning the repository and before building.
Apply code patches to your repository during build. Patches are
applied after cloning the repository and before building.
</CardDescription>
</div>
<Button onClick={handleOpenEditor} disabled={isLoadingRepo}>
@@ -155,8 +169,8 @@ export const ShowPatches = ({ applicationId, composeId }: Props) => {
<AlertCircle className="h-4 w-4" />
<AlertTitle>No patches</AlertTitle>
<AlertDescription>
No patches have been created for this application yet. Click "Create Patch"
to add modifications to your code during build.
No patches have been created for this application yet. Click
"Create Patch" to add modifications to your code during build.
</AlertDescription>
</Alert>
) : (

View File

@@ -33,7 +33,9 @@ import {
} from "@/server/db/schema";
// Helper to get git config from application
const getApplicationGitConfig = (app: Awaited<ReturnType<typeof findApplicationById>>) => {
const getApplicationGitConfig = (
app: Awaited<ReturnType<typeof findApplicationById>>,
) => {
switch (app.sourceType) {
case "github":
return {
@@ -73,7 +75,9 @@ const getApplicationGitConfig = (app: Awaited<ReturnType<typeof findApplicationB
};
// Helper to get git config from compose
const getComposeGitConfig = (compose: Awaited<ReturnType<typeof findComposeById>>) => {
const getComposeGitConfig = (
compose: Awaited<ReturnType<typeof findComposeById>>,
) => {
switch (compose.sourceType) {
case "github":
return {
@@ -153,11 +157,9 @@ export const patchRouter = createTRPCRouter({
return await createPatch(input);
}),
one: protectedProcedure
.input(apiFindPatch)
.query(async ({ input }) => {
return await findPatchById(input.patchId);
}),
one: protectedProcedure.input(apiFindPatch).query(async ({ input }) => {
return await findPatchById(input.patchId);
}),
byApplicationId: protectedProcedure
.input(apiFindPatchesByApplicationId)

44030
openapi.json

File diff suppressed because it is too large Load Diff

View File

@@ -208,8 +208,10 @@ export const deployApplication = async ({
// Apply patches after cloning (for non-docker sources only)
if (application.sourceType !== "docker") {
const patches = await findPatchesByApplicationId(application.applicationId);
const enabledPatches = patches.filter(p => p.enabled);
const patches = await findPatchesByApplicationId(
application.applicationId,
);
const enabledPatches = patches.filter((p) => p.enabled);
if (enabledPatches.length > 0) {
command += generateApplyPatchesCommand({
appName: application.appName,

View File

@@ -40,10 +40,7 @@ import {
updateDeployment,
updateDeploymentStatus,
} from "./deployment";
import {
findPatchesByComposeId,
generateApplyPatchesCommand,
} from "./patch";
import { findPatchesByComposeId, generateApplyPatchesCommand } from "./patch";
import { validUniqueServerAppName } from "./project";
export type Compose = typeof compose.$inferSelect;
@@ -255,7 +252,7 @@ export const deployCompose = async ({
// Apply patches after cloning (for non-raw sources only)
if (compose.sourceType !== "raw") {
const patches = await findPatchesByComposeId(compose.composeId);
const enabledPatches = patches.filter(p => p.enabled);
const enabledPatches = patches.filter((p) => p.enabled);
if (enabledPatches.length > 0) {
const patchCommand = generateApplyPatchesCommand({
appName: compose.appName,

View File

@@ -76,7 +76,7 @@ echo "Repository cloned successfully";
});
}
} else {
// Repo exists - check if on correct branch and update
// Repo exists - check if on correct branch and update
const updateCommand = `
set -e;
cd "${repoPath}";
@@ -161,7 +161,7 @@ export const readPatchRepoDirectory = async (
for (let i = 0; i < parts.length; i++) {
const part = parts[i];
if (!part) continue;
const isFile = i === parts.length - 1;
const parentPath = currentPath;
currentPath = currentPath ? `${currentPath}/${part}` : part;
@@ -295,7 +295,9 @@ rm -rf "${tempDir}";
/**
* Clean all patch repos
*/
export const cleanPatchRepos = async (serverId?: string | null): Promise<void> => {
export const cleanPatchRepos = async (
serverId?: string | null,
): Promise<void> => {
const { PATCH_REPOS_PATH } = paths(!!serverId);
const command = `rm -rf "${PATCH_REPOS_PATH}"/* 2>/dev/null || true`;

View File

@@ -1,10 +1,7 @@
import { join } from "node:path";
import { paths } from "@dokploy/server/constants";
import { db } from "@dokploy/server/db";
import {
type apiCreatePatch,
patch,
} from "@dokploy/server/db/schema";
import { type apiCreatePatch, patch } from "@dokploy/server/db/schema";
import {
execAsync,
execAsyncRemote,
@@ -98,10 +95,7 @@ export const findPatchByFilePath = async (
return null;
};
export const updatePatch = async (
patchId: string,
data: Partial<Patch>,
) => {
export const updatePatch = async (patchId: string, data: Partial<Patch>) => {
const result = await db
.update(patch)
.set({