mirror of
https://github.com/Dokploy/dokploy
synced 2025-06-26 18:27:59 +00:00
Merge pull request #189 from slowlydev/feat/enable-autodeploy-github
Add web hook verification to GitHub Autodeploy
This commit is contained in:
commit
3322fdf937
1
drizzle/0018_careful_killmonger.sql
Normal file
1
drizzle/0018_careful_killmonger.sql
Normal file
@ -0,0 +1 @@
|
||||
ALTER TABLE "admin" ADD COLUMN "githubWebhookSecret" text;
|
2632
drizzle/meta/0018_snapshot.json
Normal file
2632
drizzle/meta/0018_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
@ -127,6 +127,13 @@
|
||||
"when": 1719547174326,
|
||||
"tag": "0017_minor_post",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 18,
|
||||
"version": "6",
|
||||
"when": 1719928377858,
|
||||
"tag": "0018_careful_killmonger",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
@ -36,10 +36,12 @@
|
||||
"@codemirror/lang-yaml": "^6.1.1",
|
||||
"@codemirror/language": "^6.10.1",
|
||||
"@codemirror/legacy-modes": "6.4.0",
|
||||
"@dokploy/trpc-openapi": "0.0.4",
|
||||
"@faker-js/faker": "^8.4.1",
|
||||
"@hookform/resolvers": "^3.3.4",
|
||||
"@lucia-auth/adapter-drizzle": "1.0.7",
|
||||
"@octokit/auth-app": "^6.0.4",
|
||||
"@octokit/webhooks": "^13.2.7",
|
||||
"@radix-ui/react-accordion": "1.1.2",
|
||||
"@radix-ui/react-alert-dialog": "^1.0.5",
|
||||
"@radix-ui/react-avatar": "^1.0.4",
|
||||
@ -113,7 +115,6 @@
|
||||
"tailwind-merge": "^2.2.0",
|
||||
"tailwindcss-animate": "^1.0.7",
|
||||
"tar-fs": "3.0.5",
|
||||
"@dokploy/trpc-openapi": "0.0.4",
|
||||
"use-resize-observer": "9.1.0",
|
||||
"ws": "8.16.0",
|
||||
"xterm-addon-fit": "^0.8.0",
|
||||
|
@ -1,17 +1,39 @@
|
||||
import { and, eq } from "drizzle-orm";
|
||||
import { db } from "@/server/db";
|
||||
import { Webhooks } from "@octokit/webhooks";
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import { applications, compose } from "@/server/db/schema";
|
||||
import { extractCommitMessage, extractHash } from "./[refreshToken]";
|
||||
import type { DeploymentJob } from "@/server/queues/deployments-queue";
|
||||
import { myQueue } from "@/server/queues/queueSetup";
|
||||
|
||||
export default async function handler(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse,
|
||||
) {
|
||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
const admin = await db.query.admins.findFirst({});
|
||||
|
||||
if (!admin) {
|
||||
res.status(200).json({ message: "Could not find admin" });
|
||||
return;
|
||||
}
|
||||
|
||||
if (!admin.githubWebhookSecret) {
|
||||
res.status(200).json({ message: "Github Webhook Secret not set" });
|
||||
return;
|
||||
}
|
||||
|
||||
const webhooks = new Webhooks({
|
||||
secret: admin.githubWebhookSecret,
|
||||
});
|
||||
|
||||
const signature = req.headers["x-hub-signature-256"];
|
||||
const github = req.body;
|
||||
|
||||
const verified = await webhooks.verify(JSON.stringify(github), signature as string);
|
||||
|
||||
if (!verified) {
|
||||
res.status(401).json({ message: "Unauthorized" });
|
||||
return;
|
||||
}
|
||||
|
||||
if (req.headers["x-github-event"] === "ping") {
|
||||
res.status(200).json({ message: "Ping received, webhook is active" });
|
||||
return;
|
||||
@ -33,7 +55,7 @@ export default async function handler(
|
||||
eq(applications.sourceType, "github"),
|
||||
eq(applications.autoDeploy, true),
|
||||
eq(applications.branch, branchName),
|
||||
eq(applications.repository, repository),
|
||||
eq(applications.repository, repository)
|
||||
),
|
||||
});
|
||||
|
||||
@ -51,17 +73,12 @@ export default async function handler(
|
||||
{
|
||||
removeOnComplete: true,
|
||||
removeOnFail: true,
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
const composeApps = await db.query.compose.findMany({
|
||||
where: and(
|
||||
eq(compose.sourceType, "github"),
|
||||
eq(compose.autoDeploy, true),
|
||||
eq(compose.branch, branchName),
|
||||
eq(compose.repository, repository),
|
||||
),
|
||||
where: and(eq(compose.sourceType, "github"), eq(compose.autoDeploy, true), eq(compose.branch, branchName), eq(compose.repository, repository)),
|
||||
});
|
||||
|
||||
for (const composeApp of composeApps) {
|
||||
@ -79,7 +96,7 @@ export default async function handler(
|
||||
{
|
||||
removeOnComplete: true,
|
||||
removeOnFail: true,
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -38,6 +38,7 @@ export default async function handler(
|
||||
githubAppName: data.name,
|
||||
githubClientId: data.client_id,
|
||||
githubClientSecret: data.client_secret,
|
||||
githubWebhookSecret: data.webhook_secret,
|
||||
githubPrivateKey: data.pem,
|
||||
})
|
||||
.where(eq(admins.authId, authId as string))
|
||||
|
13925
pnpm-lock.yaml
13925
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
@ -23,6 +23,7 @@ export const admins = pgTable("admin", {
|
||||
githubClientSecret: text("githubClientSecret"),
|
||||
githubInstallationId: text("githubInstallationId"),
|
||||
githubPrivateKey: text("githubPrivateKey"),
|
||||
githubWebhookSecret: text("githubWebhookSecret"),
|
||||
letsEncryptEmail: text("letsEncryptEmail"),
|
||||
sshPrivateKey: text("sshPrivateKey"),
|
||||
enableDockerCleanup: boolean("enableDockerCleanup").notNull().default(false),
|
||||
|
Loading…
Reference in New Issue
Block a user