feat(#147): add hash commit when deploying

This commit is contained in:
Mauricio Siu
2024-06-27 21:53:26 -06:00
parent 817fa91173
commit 3cfc2d6cd8
9 changed files with 71 additions and 2 deletions

View File

@@ -86,6 +86,11 @@ export const ShowDeployments = ({ applicationId }: Props) => {
<span className="text-sm text-muted-foreground"> <span className="text-sm text-muted-foreground">
{deployment.title} {deployment.title}
</span> </span>
{deployment.description && (
<span className="text-sm text-muted-foreground">
{deployment.description}
</span>
)}
</div> </div>
<div className="flex flex-col items-end gap-2"> <div className="flex flex-col items-end gap-2">
<div className="text-sm capitalize text-muted-foreground"> <div className="text-sm capitalize text-muted-foreground">

View File

@@ -33,6 +33,7 @@ export default async function handler(
} }
const deploymentTitle = extractCommitMessage(req.headers, req.body); const deploymentTitle = extractCommitMessage(req.headers, req.body);
const deploymentHash = extractHash(req.headers, req.body);
const sourceType = application.sourceType; const sourceType = application.sourceType;
@@ -75,6 +76,7 @@ export default async function handler(
const jobData: DeploymentJob = { const jobData: DeploymentJob = {
applicationId: application.applicationId as string, applicationId: application.applicationId as string,
titleLog: deploymentTitle, titleLog: deploymentTitle,
descriptionLog: `Hash: ${deploymentHash}`,
type: "deploy", type: "deploy",
applicationType: "application", applicationType: "application",
}; };
@@ -166,6 +168,37 @@ export const extractCommitMessage = (headers: any, body: any) => {
return "NEW CHANGES"; return "NEW CHANGES";
}; };
export const extractHash = (headers: any, body: any) => {
// GitHub
if (headers["x-github-event"]) {
return body.head_commit ? body.head_commit.id : "";
}
// GitLab
if (headers["x-gitlab-event"]) {
return (
body.checkout_sha ||
(body.commits && body.commits.length > 0
? body.commits[0].id
: "NEW COMMIT")
);
}
// Bitbucket
if (headers["x-event-key"]?.includes("repo:push")) {
return body.push.changes && body.push.changes.length > 0
? body.push.changes[0].new.target.hash
: "NEW COMMIT";
}
// Gitea
if (headers["x-gitea-event"]) {
return body.after || "NEW COMMIT";
}
return "";
};
export const extractBranchName = (headers: any, body: any) => { export const extractBranchName = (headers: any, body: any) => {
if (headers["x-github-event"] || headers["x-gitea-event"]) { if (headers["x-github-event"] || headers["x-gitea-event"]) {
return body?.ref?.replace("refs/heads/", ""); return body?.ref?.replace("refs/heads/", "");

View File

@@ -4,7 +4,11 @@ import type { DeploymentJob } from "@/server/queues/deployments-queue";
import { myQueue } from "@/server/queues/queueSetup"; import { myQueue } from "@/server/queues/queueSetup";
import { eq } from "drizzle-orm"; import { eq } from "drizzle-orm";
import type { NextApiRequest, NextApiResponse } from "next"; import type { NextApiRequest, NextApiResponse } from "next";
import { extractBranchName, extractCommitMessage } from "../[refreshToken]"; import {
extractBranchName,
extractCommitMessage,
extractHash,
} from "../[refreshToken]";
import { updateCompose } from "@/server/api/services/compose"; import { updateCompose } from "@/server/api/services/compose";
export default async function handler( export default async function handler(
@@ -34,7 +38,7 @@ export default async function handler(
} }
const deploymentTitle = extractCommitMessage(req.headers, req.body); const deploymentTitle = extractCommitMessage(req.headers, req.body);
const deploymentHash = extractHash(req.headers, req.body);
const sourceType = composeResult.sourceType; const sourceType = composeResult.sourceType;
if (sourceType === "github") { if (sourceType === "github") {
@@ -61,6 +65,7 @@ export default async function handler(
titleLog: deploymentTitle, titleLog: deploymentTitle,
type: "deploy", type: "deploy",
applicationType: "compose", applicationType: "compose",
descriptionLog: `Hash: ${deploymentHash}`,
}; };
await myQueue.add( await myQueue.add(
"deployments", "deployments",

View File

@@ -162,6 +162,7 @@ export const applicationRouter = createTRPCRouter({
const jobData: DeploymentJob = { const jobData: DeploymentJob = {
applicationId: input.applicationId, applicationId: input.applicationId,
titleLog: "Rebuild deployment", titleLog: "Rebuild deployment",
descriptionLog: "",
type: "redeploy", type: "redeploy",
applicationType: "application", applicationType: "application",
}; };
@@ -294,6 +295,7 @@ export const applicationRouter = createTRPCRouter({
const jobData: DeploymentJob = { const jobData: DeploymentJob = {
applicationId: input.applicationId, applicationId: input.applicationId,
titleLog: "Manual deployment", titleLog: "Manual deployment",
descriptionLog: "",
type: "deploy", type: "deploy",
applicationType: "application", applicationType: "application",
}; };

View File

@@ -130,15 +130,18 @@ export const updateApplicationStatus = async (
export const deployApplication = async ({ export const deployApplication = async ({
applicationId, applicationId,
titleLog = "Manual deployment", titleLog = "Manual deployment",
descriptionLog = "",
}: { }: {
applicationId: string; applicationId: string;
titleLog: string; titleLog: string;
descriptionLog: string;
}) => { }) => {
const application = await findApplicationById(applicationId); const application = await findApplicationById(applicationId);
const admin = await findAdmin(); const admin = await findAdmin();
const deployment = await createDeployment({ const deployment = await createDeployment({
applicationId: applicationId, applicationId: applicationId,
title: titleLog, title: titleLog,
description: descriptionLog,
}); });
try { try {
@@ -173,14 +176,17 @@ export const deployApplication = async ({
export const rebuildApplication = async ({ export const rebuildApplication = async ({
applicationId, applicationId,
titleLog = "Rebuild deployment", titleLog = "Rebuild deployment",
descriptionLog = "",
}: { }: {
applicationId: string; applicationId: string;
titleLog: string; titleLog: string;
descriptionLog: string;
}) => { }) => {
const application = await findApplicationById(applicationId); const application = await findApplicationById(applicationId);
const deployment = await createDeployment({ const deployment = await createDeployment({
applicationId: applicationId, applicationId: applicationId,
title: titleLog, title: titleLog,
description: descriptionLog,
}); });
try { try {

View File

@@ -134,15 +134,18 @@ export const updateCompose = async (
export const deployCompose = async ({ export const deployCompose = async ({
composeId, composeId,
titleLog = "Manual deployment", titleLog = "Manual deployment",
descriptionLog = "",
}: { }: {
composeId: string; composeId: string;
titleLog: string; titleLog: string;
descriptionLog: string;
}) => { }) => {
const compose = await findComposeById(composeId); const compose = await findComposeById(composeId);
const admin = await findAdmin(); const admin = await findAdmin();
const deployment = await createDeploymentCompose({ const deployment = await createDeploymentCompose({
composeId: composeId, composeId: composeId,
title: titleLog, title: titleLog,
description: descriptionLog,
}); });
try { try {
@@ -170,14 +173,17 @@ export const deployCompose = async ({
export const rebuildCompose = async ({ export const rebuildCompose = async ({
composeId, composeId,
titleLog = "Rebuild deployment", titleLog = "Rebuild deployment",
descriptionLog = "",
}: { }: {
composeId: string; composeId: string;
titleLog: string; titleLog: string;
descriptionLog: string;
}) => { }) => {
const compose = await findComposeById(composeId); const compose = await findComposeById(composeId);
const deployment = await createDeploymentCompose({ const deployment = await createDeploymentCompose({
composeId: composeId, composeId: composeId,
title: titleLog, title: titleLog,
description: descriptionLog,
}); });
try { try {

View File

@@ -60,6 +60,7 @@ export const createDeployment = async (
title: deployment.title || "Deployment", title: deployment.title || "Deployment",
status: "running", status: "running",
logPath: logFilePath, logPath: logFilePath,
description: deployment.description || "",
}) })
.returning(); .returning();
if (deploymentCreate.length === 0 || !deploymentCreate[0]) { if (deploymentCreate.length === 0 || !deploymentCreate[0]) {
@@ -100,6 +101,7 @@ export const createDeploymentCompose = async (
.values({ .values({
composeId: deployment.composeId, composeId: deployment.composeId,
title: deployment.title || "Deployment", title: deployment.title || "Deployment",
description: deployment.description || "",
status: "running", status: "running",
logPath: logFilePath, logPath: logFilePath,
}) })

View File

@@ -18,6 +18,7 @@ export const deployments = pgTable("deployment", {
.primaryKey() .primaryKey()
.$defaultFn(() => nanoid()), .$defaultFn(() => nanoid()),
title: text("title").notNull(), title: text("title").notNull(),
description: text("description"),
status: deploymentStatus("status").default("running"), status: deploymentStatus("status").default("running"),
logPath: text("logPath").notNull(), logPath: text("logPath").notNull(),
applicationId: text("applicationId").references( applicationId: text("applicationId").references(
@@ -49,6 +50,7 @@ const schema = createInsertSchema(deployments, {
logPath: z.string().min(1), logPath: z.string().min(1),
applicationId: z.string(), applicationId: z.string(),
composeId: z.string(), composeId: z.string(),
description: z.string().optional(),
}); });
export const apiCreateDeployment = schema export const apiCreateDeployment = schema
@@ -57,6 +59,7 @@ export const apiCreateDeployment = schema
status: true, status: true,
logPath: true, logPath: true,
applicationId: true, applicationId: true,
description: true,
}) })
.extend({ .extend({
applicationId: z.string().min(1), applicationId: z.string().min(1),
@@ -68,6 +71,7 @@ export const apiCreateDeploymentCompose = schema
status: true, status: true,
logPath: true, logPath: true,
composeId: true, composeId: true,
description: true,
}) })
.extend({ .extend({
composeId: z.string().min(1), composeId: z.string().min(1),

View File

@@ -10,12 +10,14 @@ type DeployJob =
| { | {
applicationId: string; applicationId: string;
titleLog: string; titleLog: string;
descriptionLog: string;
type: "deploy" | "redeploy"; type: "deploy" | "redeploy";
applicationType: "application"; applicationType: "application";
} }
| { | {
composeId: string; composeId: string;
titleLog: string; titleLog: string;
descriptionLog: string;
type: "deploy" | "redeploy"; type: "deploy" | "redeploy";
applicationType: "compose"; applicationType: "compose";
}; };
@@ -31,11 +33,13 @@ export const deploymentWorker = new Worker(
await rebuildApplication({ await rebuildApplication({
applicationId: job.data.applicationId, applicationId: job.data.applicationId,
titleLog: job.data.titleLog, titleLog: job.data.titleLog,
descriptionLog: job.data.descriptionLog,
}); });
} else if (job.data.type === "deploy") { } else if (job.data.type === "deploy") {
await deployApplication({ await deployApplication({
applicationId: job.data.applicationId, applicationId: job.data.applicationId,
titleLog: job.data.titleLog, titleLog: job.data.titleLog,
descriptionLog: job.data.descriptionLog,
}); });
} }
} else if (job.data.applicationType === "compose") { } else if (job.data.applicationType === "compose") {
@@ -43,11 +47,13 @@ export const deploymentWorker = new Worker(
await deployCompose({ await deployCompose({
composeId: job.data.composeId, composeId: job.data.composeId,
titleLog: job.data.titleLog, titleLog: job.data.titleLog,
descriptionLog: job.data.descriptionLog,
}); });
} else if (job.data.type === "redeploy") { } else if (job.data.type === "redeploy") {
await rebuildCompose({ await rebuildCompose({
composeId: job.data.composeId, composeId: job.data.composeId,
titleLog: job.data.titleLog, titleLog: job.data.titleLog,
descriptionLog: job.data.descriptionLog,
}); });
} }
} }