Skip to content

Commit

Permalink
fix: Deployment retry policy (#248)
Browse files Browse the repository at this point in the history
  • Loading branch information
adityachoudhari26 authored Dec 4, 2024
1 parent 0683c14 commit 161c414
Show file tree
Hide file tree
Showing 15 changed files with 4,838 additions and 229 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ export const CreateDeploymentDialog: React.FC<{
name: "",
slug: "",
description: "",
retryCount: 0,
},
mode: "onSubmit",
});
Expand Down Expand Up @@ -183,6 +184,26 @@ export const CreateDeploymentDialog: React.FC<{
</FormItem>
)}
/>
<FormField
control={form.control}
name="retryCount"
render={({ field: { value, onChange } }) => (
<FormItem>
<FormLabel>Retry Count</FormLabel>
<FormControl>
<Input
type="number"
min={0}
step={1}
value={value}
onChange={(e) => onChange(e.target.valueAsNumber)}
className="w-16"
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormRootError />
<DialogFooter>
<Button type="submit">Create</Button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,25 @@ export const EditDeploymentDialog: React.FC<{
/>
<FormField
control={form.control}
name="retryCount"
render={({ field: { value, onChange } }) => (
<FormItem>
<FormLabel>Retry Count</FormLabel>
<FormControl>
<Input
type="number"
value={value}
onChange={(e) => onChange(e.target.valueAsNumber)}
min={0}
step={1}
className="w-16"
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
name="id"
render={() => (
<FormItem>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,27 @@ export const EditDeploymentSection: React.FC<{
)}
/>

<FormField
control={form.control}
name="retryCount"
render={({ field: { value, onChange } }) => (
<FormItem>
<FormLabel>Retry Count</FormLabel>
<FormControl>
<Input
type="number"
value={value}
onChange={(e) => onChange(e.target.valueAsNumber)}
min={0}
step={1}
className="w-16"
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>

<FormRootError />

<Button
Expand Down
44 changes: 12 additions & 32 deletions apps/webservice/src/app/api/github/webhook/workflow/handler.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import type { WorkflowRunEvent } from "@octokit/webhooks-types";

import { and, eq, takeFirstOrNull } from "@ctrlplane/db";
import { eq, takeFirstOrNull } from "@ctrlplane/db";
import { db } from "@ctrlplane/db/client";
import * as schema from "@ctrlplane/db/schema";
import { onJobCompletion } from "@ctrlplane/job-dispatch";
import { updateJob } from "@ctrlplane/job-dispatch";
import { ReservedMetadataKey } from "@ctrlplane/validators/conditions";
import { JobStatus } from "@ctrlplane/validators/jobs";

type Conclusion = Exclude<WorkflowRunEvent["workflow_run"]["conclusion"], null>;
Expand Down Expand Up @@ -65,34 +66,13 @@ export const handleWorkflowWebhookEvent = async (event: WorkflowRunEvent) => {
: convertStatus(externalStatus);

const externalId = id.toString();
await db
.update(schema.job)
.set({ status, externalId })
.where(eq(schema.job.id, job.id));

const existingUrlMetadata = await db
.select()
.from(schema.jobMetadata)
.where(
and(
eq(schema.jobMetadata.jobId, job.id),
eq(schema.jobMetadata.key, "ctrlplane/links"),
),
)
.then(takeFirstOrNull);

const links = JSON.stringify({
...JSON.parse(existingUrlMetadata?.value ?? "{}"),
GitHub: `https://github.com/${repository.owner.login}/${repository.name}/actions/runs/${id}`,
});

await db
.insert(schema.jobMetadata)
.values([{ jobId: job.id, key: "ctrlplane/links", value: links }])
.onConflictDoUpdate({
target: [schema.jobMetadata.jobId, schema.jobMetadata.key],
set: { value: links },
});

if (job.status === JobStatus.Completed) return onJobCompletion(job);
await updateJob(
job.id,
{ status, externalId },
{
[String(ReservedMetadataKey.Links)]: {
GitHub: `https://github.com/${repository.owner.login}/${repository.name}/actions/runs/${id}`,
},
},
);
};
102 changes: 48 additions & 54 deletions apps/webservice/src/app/api/v1/jobs/[jobId]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,43 +3,31 @@ import { NextResponse } from "next/server";

import { and, eq, isNull, takeFirstOrNull } from "@ctrlplane/db";
import { db } from "@ctrlplane/db/client";
import {
deployment,
environment,
environmentPolicyApproval,
job,
jobVariable,
release,
releaseJobTrigger,
resource,
resourceMetadata,
runbook,
runbookJobTrigger,
updateJob,
user,
} from "@ctrlplane/db/schema";
import { onJobCompletion } from "@ctrlplane/job-dispatch";
import * as schema from "@ctrlplane/db/schema";
import { updateJob } from "@ctrlplane/job-dispatch";
import { variablesAES256 } from "@ctrlplane/secrets";
import { Permission } from "@ctrlplane/validators/auth";
import { JobStatus } from "@ctrlplane/validators/jobs";

import { authn, authz } from "~/app/api/v1/auth";
import { request } from "~/app/api/v1/middleware";

type ApprovalJoinResult = {
environment_policy_approval: typeof environmentPolicyApproval.$inferSelect;
user: typeof user.$inferSelect | null;
environment_policy_approval: typeof schema.environmentPolicyApproval.$inferSelect;
user: typeof schema.user.$inferSelect | null;
};

const getApprovalDetails = async (releaseId: string, policyId: string) =>
db
.select()
.from(environmentPolicyApproval)
.leftJoin(user, eq(environmentPolicyApproval.userId, user.id))
.from(schema.environmentPolicyApproval)
.leftJoin(
schema.user,
eq(schema.environmentPolicyApproval.userId, schema.user.id),
)
.where(
and(
eq(environmentPolicyApproval.releaseId, releaseId),
eq(environmentPolicyApproval.policyId, policyId),
eq(schema.environmentPolicyApproval.releaseId, releaseId),
eq(schema.environmentPolicyApproval.policyId, policyId),
),
)
.then(takeFirstOrNull)
Expand Down Expand Up @@ -72,18 +60,38 @@ export const GET = request()
.handle<object, { params: { jobId: string } }>(async ({ db }, { params }) => {
const row = await db
.select()
.from(job)
.leftJoin(runbookJobTrigger, eq(runbookJobTrigger.jobId, job.id))
.leftJoin(runbook, eq(runbookJobTrigger.runbookId, runbook.id))
.leftJoin(releaseJobTrigger, eq(releaseJobTrigger.jobId, job.id))
.from(schema.job)
.leftJoin(
schema.runbookJobTrigger,
eq(schema.runbookJobTrigger.jobId, schema.job.id),
)
.leftJoin(
schema.runbook,
eq(schema.runbookJobTrigger.runbookId, schema.runbook.id),
)
.leftJoin(
schema.releaseJobTrigger,
eq(schema.releaseJobTrigger.jobId, schema.job.id),
)
.leftJoin(
schema.environment,
eq(schema.releaseJobTrigger.environmentId, schema.environment.id),
)
.leftJoin(
schema.resource,
eq(schema.releaseJobTrigger.resourceId, schema.resource.id),
)
.leftJoin(
schema.release,
eq(schema.releaseJobTrigger.releaseId, schema.release.id),
)
.leftJoin(
environment,
eq(environment.id, releaseJobTrigger.environmentId),
schema.deployment,
eq(schema.release.deploymentId, schema.deployment.id),
)
.where(
and(eq(schema.job.id, params.jobId), isNull(schema.resource.deletedAt)),
)
.leftJoin(resource, eq(resource.id, releaseJobTrigger.resourceId))
.leftJoin(release, eq(release.id, releaseJobTrigger.releaseId))
.leftJoin(deployment, eq(deployment.id, release.deploymentId))
.where(and(eq(job.id, params.jobId), isNull(resource.deletedAt)))
.then(takeFirstOrNull);

if (row == null)
Expand All @@ -110,8 +118,8 @@ export const GET = request()

const jobVariableRows = await db
.select()
.from(jobVariable)
.where(eq(jobVariable.jobId, params.jobId));
.from(schema.jobVariable)
.where(eq(schema.jobVariable.jobId, params.jobId));

const variables = Object.fromEntries(
jobVariableRows.map((v) => {
Expand All @@ -126,8 +134,8 @@ export const GET = request()

const metadata = await db
.select()
.from(resourceMetadata)
.where(eq(resourceMetadata.resourceId, je.resource.id))
.from(schema.resourceMetadata)
.where(eq(schema.resourceMetadata.resourceId, je.resource.id))
.then((rows) => Object.fromEntries(rows.map((m) => [m.key, m.value])));

return NextResponse.json({
Expand All @@ -137,7 +145,7 @@ export const GET = request()
});
});

const bodySchema = updateJob;
const bodySchema = schema.updateJob;

export const PATCH = async (
req: NextRequest,
Expand All @@ -146,21 +154,7 @@ export const PATCH = async (
const response = await req.json();
const body = bodySchema.parse(response);

const je = await db
.update(job)
.set(body)
.where(and(eq(job.id, params.jobId)))
.returning()
.then(takeFirstOrNull);

if (je == null)
return NextResponse.json(
{ error: "Job execution not found" },
{ status: 404 },
);

if (je.status === JobStatus.Completed)
onJobCompletion(je).catch(console.error);
const job = await updateJob(params.jobId, body);

return NextResponse.json(je);
return NextResponse.json(job);
};
Loading

0 comments on commit 161c414

Please sign in to comment.