Skip to content

Commit

Permalink
fix linting
Browse files Browse the repository at this point in the history
  • Loading branch information
jsbroks committed Oct 3, 2024
1 parent 00c6b2b commit 029a6fd
Show file tree
Hide file tree
Showing 12 changed files with 3,890 additions and 94 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ export const CreateReleaseDialog: React.FC<{
const router = useRouter();
const utils = api.useUtils();
const onSubmit = form.handleSubmit(async (data) => {
const release = await create.mutateAsync(data);
const release = await create.mutateAsync({ ...data, name: data.version });
await utils.release.list.invalidate({ deploymentId: release.deploymentId });

const deployment = deployments.data?.find(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,83 +42,85 @@ export const TargetReleaseTable: React.FC<TargetReleaseTableProps> = ({
{_.chain(releaseJobTriggerQuery.data)
.groupBy((r) => r.environmentId)
.entries()
.map(([envId, jobs]) => (
<Fragment key={envId}>
<TableRow className={cn("sticky bg-neutral-800/40")}>
<TableCell colSpan={6}>
{jobs[0]?.environment != null && (
<div className="flex items-center gap-4">
<div className="flex-grow">
{jobs[0].environment.name}
.map(([envId, jobs]) => {
return (
<Fragment key={envId}>
<TableRow className={cn("sticky bg-neutral-800/40")}>
<TableCell colSpan={6}>
{jobs[0]?.environment != null && (
<div className="flex items-center gap-4">
<div className="flex-grow">
{jobs[0].environment.name}
</div>
</div>
</div>
)}
</TableCell>
</TableRow>
{jobs.map((job, idx) => (
<TableRow
key={job.id}
className={cn(
idx !== jobs.length - 1 && "border-b-neutral-800/50",
)}
>
<TableCell className="hover:bg-neutral-800/55">
<Link
href={`${pathname}?target_id=${job.target?.id}`}
className="block w-full hover:text-blue-300"
>
{job.target?.name}
</Link>
</TableCell>
<TableCell>
<div className="flex items-center gap-1">
<JobTableStatusIcon status={job.job.status} />
{capitalCase(job.job.status)}
</div>
</TableCell>
<TableCell>{job.type}</TableCell>
<TableCell>
{job.job.externalId != null ? (
<code className="font-mono text-xs">
{job.job.externalId}
</code>
) : (
<span className="text-sm text-muted-foreground">
No external ID
</span>
)}
</TableCell>
<TableCell>
{job.job.externalUrl != null ? (
</TableRow>
{jobs.map((job, idx) => (
<TableRow
key={job.id}
className={cn(
idx !== jobs.length - 1 && "border-b-neutral-800/50",
)}
>
<TableCell className="hover:bg-neutral-800/55">
<Link
href={job.job.externalUrl}
rel="nofollow noreferrer"
target="_blank"
href={`${pathname}?target_id=${job.target?.id}`}
className="block w-full hover:text-blue-300"
>
{job.job.externalUrl}
{job.target?.name}
</Link>
) : (
<span className="text-sm text-muted-foreground">
No external URL
</span>
)}
</TableCell>
<TableCell>
<TargetDropdownMenu
release={release}
deploymentName={deploymentName}
target={job.target}
environmentId={job.environmentId}
job={{
id: job.job.id,
status: job.job.status as JobStatus,
}}
/>
</TableCell>
</TableRow>
))}
</Fragment>
))
</TableCell>
<TableCell>
<div className="flex items-center gap-1">
<JobTableStatusIcon status={job.job.status} />
{capitalCase(job.job.status)}
</div>
</TableCell>
<TableCell>{job.type}</TableCell>
<TableCell>
{job.job.externalId != null ? (
<code className="font-mono text-xs">
{job.job.externalId}
</code>
) : (
<span className="text-sm text-muted-foreground">
No external ID
</span>
)}
</TableCell>
<TableCell>
{/* {job.job.externalUrl != null ? (
<Link
href={job.job.externalUrl}
rel="nofollow noreferrer"
target="_blank"
>
{job.job.externalUrl}
</Link>
) : (
<span className="text-sm text-muted-foreground">
No external URL
</span>
)} */}
</TableCell>
<TableCell>
<TargetDropdownMenu
release={release}
deploymentName={deploymentName}
target={job.target}
environmentId={job.environmentId}
job={{
id: job.job.id,
status: job.job.status as JobStatus,
}}
/>
</TableCell>
</TableRow>
))}
</Fragment>
);
})
.value()}
</TableBody>
</Table>
Expand Down
26 changes: 22 additions & 4 deletions apps/webservice/src/app/api/github/webhook/workflow/handler.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { WorkflowRunEvent } from "@octokit/webhooks-types";

import { eq, takeFirstOrNull } from "@ctrlplane/db";
import { and, eq, takeFirstOrNull } from "@ctrlplane/db";
import { db } from "@ctrlplane/db/client";
import * as schema from "@ctrlplane/db/schema";
import { onJobCompletion } from "@ctrlplane/job-dispatch";
Expand Down Expand Up @@ -29,16 +29,14 @@ export const handleWorkflowWebhookEvent = async (event: WorkflowRunEvent) => {
repository,
} = event.workflow_run;

const externalUrl = `https://github.com/${repository.owner.login}/${repository.name}/actions/runs/${id}`;

const status =
conclusion != null
? convertConclusion(conclusion)
: convertStatus(externalStatus);

const job = await db
.update(schema.job)
.set({ status, externalUrl })
.set({ status })
.where(eq(schema.job.externalId, id.toString()))
.returning()
.then(takeFirstOrNull);
Expand All @@ -49,5 +47,25 @@ export const handleWorkflowWebhookEvent = async (event: WorkflowRunEvent) => {
// the first event lacks the run ID, so we skip it and wait for the next event.
if (job == null) return;

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 }]);

if (job.status === JobStatus.Completed) return onJobCompletion(job);
};
20 changes: 17 additions & 3 deletions apps/webservice/src/app/api/v1/releases/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,21 @@ import { Permission } from "@ctrlplane/validators/auth";

import { getUser } from "~/app/api/v1/auth";

const bodySchema = createRelease.and(
z.object({ metadata: z.record(z.string()).optional() }),
);

export const POST = async (req: NextRequest) => {
const user = await getUser(req);
if (!user)
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });

try {
const response = await req.json();
const body = createRelease.safeParse(response);
const body = bodySchema.safeParse(response);
if (!body.success) return NextResponse.json(body.error, { status: 400 });

const { metadata = {}, ...releaseData } = body.data;
const canCreateReleases = await can()
.user(user.id)
.perform(Permission.ReleaseCreate)
Expand All @@ -31,11 +36,20 @@ export const POST = async (req: NextRequest) => {

const release = await db
.insert(schema.release)
.values(body.data)
.values(releaseData)
.returning()
.then(takeFirst);

return NextResponse.json(release, { status: 201 });
if (Object.keys(metadata).length > 0)
await db.insert(schema.releaseMetadata).values(
Object.entries(metadata).map(([key, value]) => ({
releaseId: release.id,
key,
value,
})),
);

return NextResponse.json({ ...release, metadata }, { status: 201 });
} catch (error) {
if (error instanceof z.ZodError)
return NextResponse.json({ error: error.errors }, { status: 400 });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const variableOptions = [
{ key: "workspace.name", description: "Workspace Name" },
{ key: "workspace.id", description: "Workspace ID" },
{ key: "job.id", description: "Job ID" },
{ key: "job.externalRunId", description: "Job External Run ID" },
{ key: "job.externalId", description: "Job Run ID" },
{ key: "job.status", description: "Job Status" },
{ key: "job.message", description: "Job Message" },
];
Expand Down
6 changes: 3 additions & 3 deletions integrations/kubernetes-job-agent/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ const deployManifest = async (
jobId,
updateJobRequest: {
status: "in_progress",
externalRunId: `${namespace}/${name}`,
externalId: `${namespace}/${name}`,
message: "Job created successfully.",
},
});
Expand Down Expand Up @@ -116,11 +116,11 @@ const updateExecutionStatus = async (agentId: string) => {
logger.info(`Found ${jobs.length} running execution(s)`);
await Promise.allSettled(
jobs.map(async (job) => {
const [namespace, name] = job.externalRunId?.split("/") ?? [];
const [namespace, name] = job.externalId?.split("/") ?? [];
if (namespace == null || name == null) {
logger.error("Invalid external run ID", {
jobId: job.id,
externalRunId: job.externalRunId,
externalId: job.externalId,
});
return;
}
Expand Down
52 changes: 52 additions & 0 deletions packages/db/drizzle/0009_flaky_hellfire_club.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
CREATE TABLE IF NOT EXISTS "target_relationship" (
"uuid" uuid,
"source_id" uuid NOT NULL,
"relationship_type" "target_relationship_type" NOT NULL,
"target_id" uuid NOT NULL
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "release_metadata" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"release_id" uuid NOT NULL,
"key" text NOT NULL,
"value" text NOT NULL
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "job_metadata" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"job_id" uuid NOT NULL,
"key" text NOT NULL,
"value" text NOT NULL
);
--> statement-breakpoint
ALTER TABLE "release" RENAME COLUMN "metadata" TO "config";--> statement-breakpoint
ALTER TABLE "release" ADD COLUMN "name" text NOT NULL;--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "target_relationship" ADD CONSTRAINT "target_relationship_source_id_target_id_fk" FOREIGN KEY ("source_id") REFERENCES "public"."target"("id") ON DELETE cascade ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "target_relationship" ADD CONSTRAINT "target_relationship_target_id_target_id_fk" FOREIGN KEY ("target_id") REFERENCES "public"."target"("id") ON DELETE cascade ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "release_metadata" ADD CONSTRAINT "release_metadata_release_id_release_id_fk" FOREIGN KEY ("release_id") REFERENCES "public"."release"("id") ON DELETE cascade ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "job_metadata" ADD CONSTRAINT "job_metadata_job_id_job_id_fk" FOREIGN KEY ("job_id") REFERENCES "public"."job"("id") ON DELETE cascade ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
CREATE UNIQUE INDEX IF NOT EXISTS "target_relationship_target_id_source_id_index" ON "target_relationship" USING btree ("target_id","source_id");--> statement-breakpoint
CREATE UNIQUE INDEX IF NOT EXISTS "release_metadata_key_release_id_index" ON "release_metadata" USING btree ("key","release_id");--> statement-breakpoint
CREATE UNIQUE INDEX IF NOT EXISTS "job_metadata_key_job_id_index" ON "job_metadata" USING btree ("key","job_id");--> statement-breakpoint
ALTER TABLE "release" DROP COLUMN IF EXISTS "notes";--> statement-breakpoint
ALTER TABLE "job" DROP COLUMN IF EXISTS "external_url";
Loading

0 comments on commit 029a6fd

Please sign in to comment.