diff --git a/apps/event-worker/src/workers/evaluate-release-target.ts b/apps/event-worker/src/workers/evaluate-release-target.ts index ef1651d80..70dac3536 100644 --- a/apps/event-worker/src/workers/evaluate-release-target.ts +++ b/apps/event-worker/src/workers/evaluate-release-target.ts @@ -19,8 +19,8 @@ const log = logger.child({ }); const createJobForRelease = async (tx: Tx, chosenReleaseId: string) => { - const release = await tx.query.release.findFirst({ - where: eq(schema.release.id, chosenReleaseId), + const release = await tx.query.versionRelease.findFirst({ + where: eq(schema.versionRelease.id, chosenReleaseId), with: { variables: true, version: { with: { deployment: { with: { jobAgent: true } } } }, diff --git a/apps/event-worker/src/workers/job-dispatch/github.ts b/apps/event-worker/src/workers/job-dispatch/github.ts index 0f58317d6..66fd2909d 100644 --- a/apps/event-worker/src/workers/job-dispatch/github.ts +++ b/apps/event-worker/src/workers/job-dispatch/github.ts @@ -75,12 +75,12 @@ const getGithubEntity = async ( .select() .from(SCHEMA.releaseJob) .innerJoin( - SCHEMA.release, - eq(SCHEMA.releaseJob.releaseId, SCHEMA.release.id), + SCHEMA.versionRelease, + eq(SCHEMA.releaseJob.releaseId, SCHEMA.versionRelease.id), ) .innerJoin( SCHEMA.releaseTarget, - eq(SCHEMA.release.releaseTargetId, SCHEMA.releaseTarget.id), + eq(SCHEMA.versionRelease.releaseTargetId, SCHEMA.releaseTarget.id), ) .innerJoin( SCHEMA.resource, diff --git a/packages/db/src/schema/release.ts b/packages/db/src/schema/release.ts index f10606b34..2db8a9712 100644 --- a/packages/db/src/schema/release.ts +++ b/packages/db/src/schema/release.ts @@ -39,7 +39,7 @@ export const releaseTarget = pgTable( }), ); -export const release = pgTable("release", { +export const versionRelease = pgTable("version_release", { id: uuid("id").primaryKey().defaultRandom(), releaseTargetId: uuid("release_target_id") @@ -54,25 +54,38 @@ export const release = pgTable("release", { .defaultNow(), }); -export const releaseVariable = pgTable( - "release_variable", +export const variableRelease = pgTable("variable_release", { + id: uuid("id").primaryKey().defaultRandom(), + releaseTargetId: uuid("release_target_id") + .notNull() + .references(() => releaseTarget.id, { onDelete: "cascade" }), + createdAt: timestamp("created_at", { withTimezone: true }) + .notNull() + .defaultNow(), +}); + +export const variableReleaseValue = pgTable( + "variable_release_value", { id: uuid("id").primaryKey().defaultRandom(), - releaseId: uuid("release_id") + variableReleaseId: uuid("variable_release_id") .notNull() - .references(() => release.id, { onDelete: "cascade" }), + .references(() => variableRelease.id, { onDelete: "cascade" }), key: text("key").notNull(), value: json("value").notNull(), sensitive: boolean("sensitive").notNull().default(false), }, - (t) => ({ uniq: uniqueIndex().on(t.releaseId, t.key) }), + (t) => ({ uniq: uniqueIndex().on(t.variableReleaseId, t.key) }), ); -export const releaseJob = pgTable("release_job", { +export const release = pgTable("release", { id: uuid("id").primaryKey().defaultRandom(), - releaseId: uuid("release_id") + versionReleaseId: uuid("version_release_id") + .notNull() + .references(() => versionRelease.id, { onDelete: "cascade" }), + variableReleaseId: uuid("variable_release_id") .notNull() - .references(() => release.id, { onDelete: "cascade" }), + .references(() => variableRelease.id, { onDelete: "cascade" }), jobId: uuid("job_id") .notNull() .references(() => job.id, { onDelete: "cascade" }), @@ -81,40 +94,7 @@ export const releaseJob = pgTable("release_job", { .defaultNow(), }); -export const releaseRelations = relations(release, ({ one, many }) => ({ - version: one(deploymentVersion, { - fields: [release.versionId], - references: [deploymentVersion.id], - }), - releaseTarget: one(releaseTarget, { - fields: [release.releaseTargetId], - references: [releaseTarget.id], - }), - variables: many(releaseVariable), - jobs: many(releaseJob), -})); - -export const releaseVariableRelations = relations( - releaseVariable, - ({ one }) => ({ - release: one(release, { - fields: [releaseVariable.releaseId], - references: [release.id], - }), - }), -); - -export const releaseJobRelations = relations(releaseJob, ({ one }) => ({ - release: one(release, { - fields: [releaseJob.releaseId], - references: [release.id], - }), - job: one(job, { - fields: [releaseJob.jobId], - references: [job.id], - }), -})); - +/* Relations */ export const releaseTargetRelations = relations( releaseTarget, ({ one, many }) => ({ @@ -135,6 +115,59 @@ export const releaseTargetRelations = relations( references: [resource.id], }), - releases: many(release), + versionReleases: many(versionRelease), + variableReleases: many(variableRelease), + }), +); + +export const versionReleaseRelations = relations( + versionRelease, + ({ one, many }) => ({ + version: one(deploymentVersion, { + fields: [versionRelease.versionId], + references: [deploymentVersion.id], + }), + releaseTarget: one(releaseTarget, { + fields: [versionRelease.releaseTargetId], + references: [releaseTarget.id], + }), + release: many(release), + }), +); + +export const variableReleaseRelations = relations( + variableRelease, + ({ one, many }) => ({ + releaseTarget: one(releaseTarget, { + fields: [variableRelease.releaseTargetId], + references: [releaseTarget.id], + }), + release: many(release), + values: many(variableReleaseValue), }), ); + +export const variableReleaseValueRelations = relations( + variableReleaseValue, + ({ one }) => ({ + variableRelease: one(variableRelease, { + fields: [variableReleaseValue.variableReleaseId], + references: [variableRelease.id], + }), + }), +); + +export const releaseRelations = relations(release, ({ one }) => ({ + versionRelease: one(versionRelease, { + fields: [release.versionReleaseId], + references: [versionRelease.id], + }), + variableRelease: one(variableRelease, { + fields: [release.variableReleaseId], + references: [variableRelease.id], + }), + job: one(job, { + fields: [release.jobId], + references: [job.id], + }), +})); diff --git a/packages/rule-engine/src/repositories/db-release-repository.ts b/packages/rule-engine/src/repositories/db-release-repository.ts index f65dc0f82..be829b441 100644 --- a/packages/rule-engine/src/repositories/db-release-repository.ts +++ b/packages/rule-engine/src/repositories/db-release-repository.ts @@ -133,13 +133,13 @@ export class DatabaseReleaseRepository implements ReleaseRepository { tx: Tx, ): Promise { const dbRelease = await tx - .insert(schema.release) + .insert(schema.versionRelease) .values({ ...release, releaseTargetId: this.releaseTarget.id }) .returning() .then(takeFirst); if (release.variables.length > 0) - await tx.insert(schema.releaseVariable).values( + await tx.insert(schema.variableReleaseValue).values( release.variables.map((v) => ({ releaseId: dbRelease.id, key: v.key, diff --git a/packages/rule-engine/src/repositories/get-releases.ts b/packages/rule-engine/src/repositories/get-releases.ts index 6df10f32b..013fd5e9f 100644 --- a/packages/rule-engine/src/repositories/get-releases.ts +++ b/packages/rule-engine/src/repositories/get-releases.ts @@ -52,17 +52,17 @@ export const findPolicyMatchingReleasesBetweenDeployments = async ( where: exists( db .select() - .from(schema.releaseJob) - .innerJoin(schema.job, eq(schema.releaseJob.jobId, schema.job.id)) + .from(schema.release) + .innerJoin(schema.job, eq(schema.release.jobId, schema.job.id)) .where( and( - sql`${schema.releaseJob.releaseId} = "releaseTarget_releases"."id"`, + sql`${schema.release.releaseId} = "releaseTarget_releases"."id"`, eq(schema.job.status, JobStatus.Successful), ), ) .limit(1), ), - orderBy: desc(schema.release.createdAt), + orderBy: desc(schema.versionRelease.createdAt), }, }, }); @@ -84,25 +84,28 @@ export const findPolicyMatchingReleasesBetweenDeployments = async ( ); } - return db.query.release.findMany({ + return db.query.versionRelease.findMany({ where: and( - eq(schema.release.releaseTargetId, releaseTarget.id), + eq(schema.versionRelease.releaseTargetId, releaseTarget.id), schema.deploymentVersionMatchesCondition( db, policy?.deploymentVersionSelector?.deploymentVersionSelector, ), latestDeployedRelease != null - ? gte(schema.release.createdAt, latestDeployedRelease.createdAt) + ? gte(schema.versionRelease.createdAt, latestDeployedRelease.createdAt) : undefined, releaseTarget.desiredRelease != null - ? lte(schema.release.createdAt, releaseTarget.desiredRelease.createdAt) + ? lte( + schema.versionRelease.createdAt, + releaseTarget.desiredRelease.createdAt, + ) : undefined, ), with: { version: { with: { metadata: true } }, variables: true, }, - orderBy: desc(schema.release.createdAt), + orderBy: desc(schema.versionRelease.createdAt), }); }; @@ -122,23 +125,23 @@ export const findLatestPolicyMatchingRelease = async ( ): Promise => { // If no deployment version selector in policy, return latest release for target if (policy?.deploymentVersionSelector == null) { - return tx.query.release.findFirst({ - where: eq(schema.release.releaseTargetId, releaseTarget.id), - orderBy: desc(schema.release.createdAt), + return tx.query.versionRelease.findFirst({ + where: eq(schema.versionRelease.releaseTargetId, releaseTarget.id), + orderBy: desc(schema.versionRelease.createdAt), with: { variables: true, version: { with: { metadata: true } } }, }); } // Otherwise filter by policy deployment version selector - return tx.query.release.findFirst({ + return tx.query.versionRelease.findFirst({ where: and( - eq(schema.release.releaseTargetId, releaseTarget.id), + eq(schema.versionRelease.releaseTargetId, releaseTarget.id), schema.deploymentVersionMatchesCondition( tx, policy.deploymentVersionSelector.deploymentVersionSelector, ), ), with: { variables: true, version: { with: { metadata: true } } }, - orderBy: desc(schema.release.createdAt), + orderBy: desc(schema.versionRelease.createdAt), }); }; diff --git a/packages/rule-engine/src/repositories/types.ts b/packages/rule-engine/src/repositories/types.ts index 3261c7df7..f85a24e1b 100644 --- a/packages/rule-engine/src/repositories/types.ts +++ b/packages/rule-engine/src/repositories/types.ts @@ -6,7 +6,7 @@ import type { MaybeVariable, Variable } from "./variables/types.js"; /** * Base release type with essential properties from schema */ -export type Release = typeof schema.release.$inferSelect & { +export type Release = typeof schema.versionRelease.$inferSelect & { variables: Variable[]; };