feat: Enhance deployment logic for multiple Git providers

- Added support for handling commit normalization across GitHub, GitLab, and Gitea in the deployment API.
- Implemented a new utility function to determine the provider based on request headers.
- Improved deployment path validation to ensure consistency across different source types.
- Cleaned up the code by removing redundant checks and enhancing readability.
This commit is contained in:
Mauricio Siu 2025-03-23 03:55:11 -06:00
parent a067abd3e4
commit 95f79f2afb
5 changed files with 122 additions and 30 deletions

View File

@ -84,6 +84,33 @@ export default async function handler(
res.status(301).json({ message: "Branch Not Match" });
return;
}
const provider = getProviderByHeader(req.headers);
let normalizedCommits: string[] = [];
if (provider === "github") {
normalizedCommits = req.body?.commits?.flatMap(
(commit: any) => commit.modified,
);
} else if (provider === "gitlab") {
normalizedCommits = req.body?.commits?.flatMap(
(commit: any) => commit.modified,
);
} else if (provider === "gitea") {
normalizedCommits = req.body?.commits?.flatMap(
(commit: any) => commit.modified,
);
}
const shouldDeployPaths = shouldDeploy(
application.watchPaths,
normalizedCommits,
);
if (!shouldDeployPaths) {
res.status(301).json({ message: "Watch Paths Not Match" });
return;
}
} else if (sourceType === "gitlab") {
const branchName = extractBranchName(req.headers, req.body);
@ -295,6 +322,26 @@ export const extractBranchName = (headers: any, body: any) => {
return null;
};
export const getProviderByHeader = (headers: any) => {
if (headers["x-github-event"]) {
return "github";
}
if (headers["x-gitea-event"]) {
return "gitea";
}
if (headers["x-gitlab-event"]) {
return "gitlab";
}
if (headers["x-event-key"]?.includes("repo:push")) {
return "bitbucket";
}
return null;
};
export const extractCommitedPaths = async (
body: any,
bitbucketUsername: string | null,

View File

@ -11,6 +11,7 @@ import {
extractCommitMessage,
extractCommitedPaths,
extractHash,
getProviderByHeader,
} from "../[refreshToken]";
export default async function handler(
@ -91,12 +92,6 @@ export default async function handler(
res.status(301).json({ message: "Branch Not Match" });
return;
}
} else if (sourceType === "git") {
const branchName = extractBranchName(req.headers, req.body);
if (!branchName || branchName !== composeResult.customGitBranch) {
res.status(301).json({ message: "Branch Not Match" });
return;
}
const commitedPaths = await extractCommitedPaths(
req.body,
@ -104,6 +99,7 @@ export default async function handler(
composeResult.bitbucket?.appPassword || "",
composeResult.bitbucketRepository || "",
);
const shouldDeployPaths = shouldDeploy(
composeResult.watchPaths,
commitedPaths,
@ -113,6 +109,59 @@ export default async function handler(
res.status(301).json({ message: "Watch Paths Not Match" });
return;
}
} else if (sourceType === "git") {
const branchName = extractBranchName(req.headers, req.body);
if (!branchName || branchName !== composeResult.customGitBranch) {
res.status(301).json({ message: "Branch Not Match" });
return;
}
const provider = getProviderByHeader(req.headers);
let normalizedCommits: string[] = [];
if (provider === "github") {
normalizedCommits = req.body?.commits?.flatMap(
(commit: any) => commit.modified,
);
} else if (provider === "gitlab") {
normalizedCommits = req.body?.commits?.flatMap(
(commit: any) => commit.modified,
);
} else if (provider === "gitea") {
normalizedCommits = req.body?.commits?.flatMap(
(commit: any) => commit.modified,
);
}
const shouldDeployPaths = shouldDeploy(
composeResult.watchPaths,
normalizedCommits,
);
if (!shouldDeployPaths) {
res.status(301).json({ message: "Watch Paths Not Match" });
return;
}
} else if (sourceType === "gitea") {
const branchName = extractBranchName(req.headers, req.body);
const normalizedCommits = req.body?.commits?.flatMap(
(commit: any) => commit.modified,
);
const shouldDeployPaths = shouldDeploy(
composeResult.watchPaths,
normalizedCommits,
);
if (!shouldDeployPaths) {
res.status(301).json({ message: "Watch Paths Not Match" });
return;
}
if (!branchName || branchName !== composeResult.giteaBranch) {
res.status(301).json({ message: "Branch Not Match" });
return;
}
}
try {

View File

@ -73,7 +73,7 @@ export default async function handler(
: null;
try {
const updatedGitea = await updateGitea(gitea.giteaId, {
await updateGitea(gitea.giteaId, {
accessToken: result.access_token,
refreshToken: result.refresh_token,
expiresAt,
@ -82,7 +82,6 @@ export default async function handler(
: {}),
});
console.log("Gitea provider updated successfully:", updatedGitea);
return res.redirect(
307,
"/dashboard/settings/git-providers?connected=true",

View File

@ -1,7 +1,6 @@
import { findGiteaById } from "@dokploy/server";
import type { NextApiResponse } from "next";
// Shared Gitea interface
export interface Gitea {
giteaId: string;
gitProviderId: string;
@ -22,7 +21,6 @@ export interface Gitea {
};
}
// Shared function to find Gitea by ID
export const findGitea = async (giteaId: string): Promise<Gitea | null> => {
try {
const gitea = await findGiteaById(giteaId);
@ -33,7 +31,6 @@ export const findGitea = async (giteaId: string): Promise<Gitea | null> => {
}
};
// Helper for redirecting with error message
export const redirectWithError = (res: NextApiResponse, error: string) => {
return res.redirect(
307,

View File

@ -32,26 +32,26 @@ const { handler, api } = betterAuth({
clientSecret: process.env.GOOGLE_CLIENT_SECRET as string,
},
},
...(!IS_CLOUD && {
async trustedOrigins() {
const admin = await db.query.member.findFirst({
where: eq(schema.member.role, "owner"),
with: {
user: true,
},
});
// ...(!IS_CLOUD && {
// async trustedOrigins() {
// const admin = await db.query.member.findFirst({
// where: eq(schema.member.role, "owner"),
// with: {
// user: true,
// },
// });
if (admin) {
return [
...(admin.user.serverIp
? [`http://${admin.user.serverIp}:3000`]
: []),
...(admin.user.host ? [`https://${admin.user.host}`] : []),
];
}
return [];
},
}),
// if (admin) {
// return [
// ...(admin.user.serverIp
// ? [`http://${admin.user.serverIp}:3000`]
// : []),
// ...(admin.user.host ? [`https://${admin.user.host}`] : []),
// ];
// }
// return [];
// },
// }),
emailVerification: {
sendOnSignUp: true,
autoSignInAfterVerification: true,