From 4e724d88aabb38cc58ba0c93056f95391a4276bc Mon Sep 17 00:00:00 2001 From: izayl Date: Thu, 16 Jan 2025 16:26:28 +0800 Subject: [PATCH 1/3] feat: add ci skip check --- apps/dokploy/pages/api/deploy/github.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/apps/dokploy/pages/api/deploy/github.ts b/apps/dokploy/pages/api/deploy/github.ts index 9cefe4cf1..2fa50c46e 100644 --- a/apps/dokploy/pages/api/deploy/github.ts +++ b/apps/dokploy/pages/api/deploy/github.ts @@ -71,6 +71,23 @@ export default async function handler( return; } + // skip workflow runs use keywords + // @link https://docs.github.com/en/actions/managing-workflow-runs-and-deployments/managing-workflow-runs/skipping-workflow-runs + if ( + [ + "[skip ci]", + "[ci skip]", + "[no ci]", + "[skip actions]", + "[actions skip]", + ].find((keyword) => + extractCommitMessage(req.headers, req.body).includes(keyword), + ) + ) { + res.status(200).json({ message: "Deployment skipped" }); + return; + } + if (req.headers["x-github-event"] === "push") { try { const branchName = githubBody?.ref?.replace("refs/heads/", ""); From 0116d995d93796292f2577ac07963e5f3ee4f960 Mon Sep 17 00:00:00 2001 From: izayl Date: Fri, 17 Jan 2025 15:32:36 +0800 Subject: [PATCH 2/3] test: extractCommitMessage --- apps/dokploy/__test__/deploy/github.test.ts | 98 +++++++++++++++++++++ apps/dokploy/__test__/vitest.config.ts | 1 + 2 files changed, 99 insertions(+) create mode 100644 apps/dokploy/__test__/deploy/github.test.ts diff --git a/apps/dokploy/__test__/deploy/github.test.ts b/apps/dokploy/__test__/deploy/github.test.ts new file mode 100644 index 000000000..18d7619ab --- /dev/null +++ b/apps/dokploy/__test__/deploy/github.test.ts @@ -0,0 +1,98 @@ +import { extractCommitMessage } from "@/pages/api/deploy/[refreshToken]"; +import { describe, expect, it } from "vitest"; + +describe("GitHub Webhook Skip CI", () => { + const mockGithubHeaders = { + "x-github-event": "push", + }; + + const createMockBody = (message: string) => ({ + head_commit: { + message, + }, + }); + + const skipKeywords = [ + "[skip ci]", + "[ci skip]", + "[no ci]", + "[skip actions]", + "[actions skip]", + ]; + + it("should detect skip keywords in commit message", () => { + for (const keyword of skipKeywords) { + const message = `feat: add new feature ${keyword}`; + const commitMessage = extractCommitMessage( + mockGithubHeaders, + createMockBody(message), + ); + expect(commitMessage.includes(keyword)).toBe(true); + } + }); + + it("should not detect skip keywords in normal commit message", () => { + const message = "feat: add new feature"; + const commitMessage = extractCommitMessage( + mockGithubHeaders, + createMockBody(message), + ); + for (const keyword of skipKeywords) { + expect(commitMessage.includes(keyword)).toBe(false); + } + }); + + it("should handle different webhook sources", () => { + // GitHub + expect( + extractCommitMessage( + { "x-github-event": "push" }, + { head_commit: { message: "[skip ci] test" } }, + ), + ).toBe("[skip ci] test"); + + // GitLab + expect( + extractCommitMessage( + { "x-gitlab-event": "push" }, + { commits: [{ message: "[skip ci] test" }] }, + ), + ).toBe("[skip ci] test"); + + // Bitbucket + expect( + extractCommitMessage( + { "x-event-key": "repo:push" }, + { + push: { + changes: [{ new: { target: { message: "[skip ci] test" } } }], + }, + }, + ), + ).toBe("[skip ci] test"); + + // Gitea + expect( + extractCommitMessage( + { "x-gitea-event": "push" }, + { commits: [{ message: "[skip ci] test" }] }, + ), + ).toBe("[skip ci] test"); + }); + + it("should handle missing commit message", () => { + expect(extractCommitMessage(mockGithubHeaders, {})).toBe("NEW COMMIT"); + expect(extractCommitMessage({ "x-gitlab-event": "push" }, {})).toBe( + "NEW COMMIT", + ); + expect( + extractCommitMessage( + { "x-event-key": "repo:push" }, + { push: { changes: [] } }, + ), + ).toBe("NEW COMMIT"); + expect(extractCommitMessage({ "x-gitea-event": "push" }, {})).toBe( + "NEW COMMIT", + ); + }); +}); diff --git a/apps/dokploy/__test__/vitest.config.ts b/apps/dokploy/__test__/vitest.config.ts index 14eabf695..ddc84d6ac 100644 --- a/apps/dokploy/__test__/vitest.config.ts +++ b/apps/dokploy/__test__/vitest.config.ts @@ -13,6 +13,7 @@ export default defineConfig({ NODE: "test", }, }, + plugins: [tsconfigPaths()], resolve: { alias: { "@dokploy/server": path.resolve( From e69c602d1cb2abfd02053a3daef38809e61ea48c Mon Sep 17 00:00:00 2001 From: izayl Date: Fri, 17 Jan 2025 15:47:18 +0800 Subject: [PATCH 3/3] chore: enhance deployment skip message to include reason for skipping --- apps/dokploy/pages/api/deploy/github.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/dokploy/pages/api/deploy/github.ts b/apps/dokploy/pages/api/deploy/github.ts index 2fa50c46e..2ee173940 100644 --- a/apps/dokploy/pages/api/deploy/github.ts +++ b/apps/dokploy/pages/api/deploy/github.ts @@ -84,7 +84,9 @@ export default async function handler( extractCommitMessage(req.headers, req.body).includes(keyword), ) ) { - res.status(200).json({ message: "Deployment skipped" }); + res.status(200).json({ + message: "Deployment skipped: commit message contains skip keyword", + }); return; }