diff --git a/apps/dokploy/__test__/deploy/github.test.ts b/apps/dokploy/__test__/deploy/github.test.ts index 46be44883..d2e773dfc 100644 --- a/apps/dokploy/__test__/deploy/github.test.ts +++ b/apps/dokploy/__test__/deploy/github.test.ts @@ -83,6 +83,14 @@ describe("GitHub Webhook Skip CI", () => { { commits: [{ message: "[skip ci] test" }] }, ), ).toBe("[skip ci] test"); + + // Soft Serve + expect( + extractCommitMessage( + { "x-softserve-event": "push" }, + { commits: [{ message: "[skip ci] test" }] }, + ), + ).toBe("[skip ci] test"); }); it("should handle missing commit message", () => { @@ -99,6 +107,9 @@ describe("GitHub Webhook Skip CI", () => { expect(extractCommitMessage({ "x-gitea-event": "push" }, {})).toBe( "NEW COMMIT", ); + expect(extractCommitMessage({ "x-softserve-event": "push" }, {})).toBe( + "NEW COMMIT", + ); }); }); diff --git a/apps/dokploy/__test__/deploy/soft-serve.test.ts b/apps/dokploy/__test__/deploy/soft-serve.test.ts new file mode 100644 index 000000000..609f15dee --- /dev/null +++ b/apps/dokploy/__test__/deploy/soft-serve.test.ts @@ -0,0 +1,49 @@ +import { describe, expect, it } from "vitest"; +import { + extractBranchName, + extractCommitMessage, + extractHash, + getProviderByHeader, +} from "@/pages/api/deploy/[refreshToken]"; + +describe("Soft Serve Webhook", () => { + const mockSoftServeHeaders = { + "x-softserve-event": "push", + }; + + const createMockBody = (message: string, hash: string, branch: string) => ({ + event: "push", + ref: `refs/heads/${branch}`, + after: hash, + commits: [{ message: message }], + }); + const message: string = "feat: add new feature"; + const hash: string = "3c91c24ef9560bddc695bce138bf8a7094ec3df5"; + const branch: string = "feat/add-new"; + const goodWebhook = createMockBody(message, hash, branch); + + it("should properly extract the provider name", () => { + expect(getProviderByHeader(mockSoftServeHeaders)).toBe("soft-serve"); + }); + + it("should properly extract the commit message", () => { + expect(extractCommitMessage(mockSoftServeHeaders, goodWebhook)).toBe( + message, + ); + }); + + it("should properly extract hash", () => { + expect(extractHash(mockSoftServeHeaders, goodWebhook)).toBe(hash); + }); + + it("should properly extract branch name", () => { + expect(extractBranchName(mockSoftServeHeaders, goodWebhook)).toBe(branch); + }); + + it("should gracefully handle invalid webhook", () => { + expect(getProviderByHeader({})).toBeNull(); + expect(extractCommitMessage(mockSoftServeHeaders, {})).toBe("NEW COMMIT"); + expect(extractHash(mockSoftServeHeaders, {})).toBe("NEW COMMIT"); + expect(extractBranchName(mockSoftServeHeaders, {})).toBeNull(); + }); +}); diff --git a/apps/dokploy/pages/api/deploy/[refreshToken].ts b/apps/dokploy/pages/api/deploy/[refreshToken].ts index 1bd911494..0a6059325 100644 --- a/apps/dokploy/pages/api/deploy/[refreshToken].ts +++ b/apps/dokploy/pages/api/deploy/[refreshToken].ts @@ -152,6 +152,10 @@ export default async function handler( normalizedCommits = req.body?.commits?.flatMap( (commit: any) => commit.modified, ); + } else if (provider === "soft-serve") { + normalizedCommits = req.body?.commits?.flatMap( + (commit: any) => commit.modified, + ); } const shouldDeployPaths = shouldDeploy( @@ -439,6 +443,13 @@ export const extractCommitMessage = (headers: any, body: any) => { : "NEW COMMIT"; } + // Soft Serve + if (headers["x-softserve-event"]) { + return body.commits && body.commits.length > 0 + ? body.commits[0].message + : "NEW COMMIT"; + } + if (headers["user-agent"]?.includes("Go-http-client")) { if (body.push_data && body.repository) { return `DockerHub image pushed: ${body.repository.repo_name}:${body.push_data.tag} by ${body.push_data.pusher}`; @@ -476,6 +487,11 @@ export const extractHash = (headers: any, body: any) => { return body.after || "NEW COMMIT"; } + // Soft Serve + if (headers["x-softserve-event"]) { + return body.after || "NEW COMMIT"; + } + return ""; }; @@ -484,7 +500,10 @@ export const extractBranchName = (headers: any, body: any) => { return body?.ref?.replace("refs/heads/", ""); } - if (headers["x-gitlab-event"]) { + if ( + headers["x-gitlab-event"] || + headers["x-softserve-event"]?.includes("push") + ) { return body?.ref ? body?.ref.replace("refs/heads/", "") : null; } @@ -512,6 +531,10 @@ export const getProviderByHeader = (headers: any) => { return "bitbucket"; } + if (headers["x-softserve-event"]) { + return "soft-serve"; + } + return null; };