Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

release channels policy #178

Closed
wants to merge 4 commits into from
Closed

release channels policy #178

wants to merge 4 commits into from

Conversation

jsbroks
Copy link
Member

@jsbroks jsbroks commented Oct 27, 2024

Summary by CodeRabbit

  • New Features

    • Introduced a new release_channel table for managing release-related data.
    • Added a new environment_policy_release_channel table to enhance deployment policy management with release channels.
    • Expanded existing tables with new fields for better data handling related to environment policies.
  • Bug Fixes

    • Updated import statements to include new dependencies for improved functionality.

These changes enhance the application's ability to manage deployment policies and release channels effectively.

Copy link
Contributor

coderabbitai bot commented Oct 27, 2024

Warning

Rate limit exceeded

@jsbroks has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 1 minutes and 51 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Files that changed from the base of the PR and between f089d03 and 6ae504a.

Walkthrough

The changes in this pull request involve the addition of new database table definitions in the environment.ts and release.ts files. A new table, environment_policy_release_channel, is introduced in environment.ts, which establishes relationships with existing tables. Additionally, a new table, release_channel, is defined in release.ts, expanding the schema to accommodate additional release-related data. The modifications primarily focus on enhancing the database structure without altering existing functionalities.

Changes

File Path Change Summary
packages/db/src/schema/environment.ts - Added new table environment_policy_release_channel with fields id, policyId, and channelId.
- Added fields ephemeralDuration and hasCustomPolicy to existing tables.
- Updated import statements to include deployment and releaseChannel.
packages/db/src/schema/release.ts - Added new table release_channel with fields id, name, description, deploymentId, and releaseFilter.

Possibly related PRs

  • fix: Remove semver and regex release filter #160: The changes in this PR involve the handling of the releaseFilter field, which is directly related to the new releaseFilter added in the main PR's environment.ts file. Both PRs modify how release conditions are managed, indicating a strong connection at the code level.

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 07dce71 and 1a583a9.

📒 Files selected for processing (2)
  • packages/db/src/schema/environment.ts (2 hunks)
  • packages/db/src/schema/release.ts (1 hunks)
🔇 Additional comments (5)
packages/db/src/schema/environment.ts (3)

23-23: LGTM: Import statement correctly updated

The addition of releaseChannel to the import statement is appropriate for the new table relationship being established.


112-124: LGTM: Well-structured junction table

The table definition follows best practices with:

  • Clear naming convention
  • Proper primary key
  • Appropriate foreign key relationships
  • Unique constraint preventing duplicates

116-121: Verify cascade delete behavior

Both foreign key relationships are set to onDelete: "cascade". This means that when either a policy or a channel is deleted, all corresponding entries in this table will be automatically removed. Please confirm if this aggressive cascade behavior is intended, as it could lead to silent data removal.

Consider these scenarios:

  1. When a policy is deleted, should all its channel associations be removed?
  2. When a channel is deleted, should all its policy associations be removed?

Let's check if there are any existing cascade delete patterns in related tables:

✅ Verification successful

Cascade delete behavior is consistent with the codebase patterns

The cascade delete behavior in this table aligns with the established patterns across the codebase. The search results show consistent use of onDelete: "cascade" in similar parent-child relationships:

  • Environment-related cascades: The codebase shows that environments and their associated entities (policies, channels, variables) consistently use cascade deletes
  • Similar patterns in workspace -> system -> environment hierarchy
  • Release and deployment relationships also follow cascade patterns

The aggressive cascade behavior is intentional and follows the application's data integrity model where:

  1. When a policy is deleted, removing its channel associations is correct as they're no longer valid without the policy
  2. When a channel is deleted, removing its policy associations is appropriate as the relationship becomes invalid

This maintains referential integrity and prevents orphaned records, which is the established pattern throughout the schema definitions.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check cascade delete patterns in related tables
# Expected: Find similar cascade patterns to validate consistency

# Search for cascade delete patterns in schema files
rg -B 2 -A 2 'onDelete: "cascade"' packages/db/src/schema/

Length of output: 17581

packages/db/src/schema/release.ts (2)

58-60: LGTM! Good integration with existing filtering system.

The releaseFilter field properly integrates with the existing release filtering infrastructure, reusing the ReleaseCondition type and compatible with existing filter processing functions.


51-61: Verify the environment policy deployment channel relationship.

Let's verify that the relationship between release channels and environment policies is properly set up.

✅ Verification successful

The environment policy deployment release channel relationship is properly configured

The verification confirms that:

  • The environment_policy_deployment_release_channel table exists with proper foreign key constraints
  • It has a channelId column that references releaseChannel.id with cascade delete
  • A unique index is set on the combination of policyId and channelId
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check if the environment policy deployment release channel table is properly set up
# with correct foreign key constraints.

# Test: Search for the table definition and its relationships
rg -A 10 "environment_policy_deployment_release_channel"

# Test: Verify the foreign key constraint to release_channel
ast-grep --pattern 'references(() => releaseChannel.id'

Length of output: 946

Comment on lines +51 to +61
export const releaseChannel = pgTable("release_channel", {
id: uuid("id").primaryKey().defaultRandom(),
name: text("name").notNull(),
description: text("description").default(""),
deploymentId: uuid("deployment_id")
.notNull()
.references(() => deployment.id, { onDelete: "cascade" }),
releaseFilter: jsonb("release_filter")
.$type<ReleaseCondition | null>()
.default(sql`NULL`),
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider adding uniqueness constraint for channel names within a deployment.

The current schema allows duplicate channel names within the same deployment, which could lead to confusion. Consider adding a unique index on (deploymentId, name).

 export const releaseChannel = pgTable("release_channel", {
   id: uuid("id").primaryKey().defaultRandom(),
   name: text("name").notNull(),
   description: text("description").default(""),
   deploymentId: uuid("deployment_id")
     .notNull()
     .references(() => deployment.id, { onDelete: "cascade" }),
   releaseFilter: jsonb("release_filter")
     .$type<ReleaseCondition | null>()
     .default(sql`NULL`),
- });
+ }, (t) => ({
+   unq: uniqueIndex().on(t.deploymentId, t.name)
+ }));
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export const releaseChannel = pgTable("release_channel", {
id: uuid("id").primaryKey().defaultRandom(),
name: text("name").notNull(),
description: text("description").default(""),
deploymentId: uuid("deployment_id")
.notNull()
.references(() => deployment.id, { onDelete: "cascade" }),
releaseFilter: jsonb("release_filter")
.$type<ReleaseCondition | null>()
.default(sql`NULL`),
});
export const releaseChannel = pgTable("release_channel", {
id: uuid("id").primaryKey().defaultRandom(),
name: text("name").notNull(),
description: text("description").default(""),
deploymentId: uuid("deployment_id")
.notNull()
.references(() => deployment.id, { onDelete: "cascade" }),
releaseFilter: jsonb("release_filter")
.$type<ReleaseCondition | null>()
.default(sql`NULL`),
}, (t) => ({
unq: uniqueIndex().on(t.deploymentId, t.name)
}));

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Outside diff range and nitpick comments (1)
packages/db/src/schema/environment.ts (1)

24-25: Ensure consistent import statement ordering

The import statements mix default imports and named imports. For better readability and maintenance, consider grouping and ordering imports consistently, e.g., third-party imports first, followed by local imports, and keep similar import styles together.

Apply this diff to reorder the imports:

 import { relations, sql } from "drizzle-orm";
 import {
   bigint,
   boolean,
   integer,
   jsonb,
   pgEnum,
   pgTable,
   text,
   timestamp,
   uniqueIndex,
   uuid,
 } from "drizzle-orm/pg-core";
 import { createInsertSchema } from "drizzle-zod";

+import { deployment } from "./deployment.js";
+import { release, releaseChannel } from "./release.js";
 import { releaseCondition } from "@ctrlplane/validators/releases";
 import { targetCondition } from "@ctrlplane/validators/targets";
 import { user } from "./auth.js";
-import { deployment } from "./deployment.js";
-import { release, releaseChannel } from "./release.js";
 import { system } from "./system.js";
 import { variableSetEnvironment } from "./variable-sets.js";
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 1a583a9 and f089d03.

📒 Files selected for processing (1)
  • packages/db/src/schema/environment.ts (6 hunks)
🔇 Additional comments (5)
packages/db/src/schema/environment.ts (5)

39-41: Confirm deletedAt and expiresAt fields allow null values

The fields deletedAt and expiresAt are defined without notNull() constraints, which means they can accept NULL values. Confirm that this is the intended behavior. If these fields should always have a timestamp, consider adding .notNull() and providing default values.


104-106: Validate default value for ephemeralDuration

The field ephemeralDuration in the environmentPolicy table has a default value of 0. Ensure that a duration of zero is acceptable within the application's logic and won't lead to unintended behavior, such as policies expiring immediately.


181-181: Consider adding .notNull() to hasCustomPolicy field

The field hasCustomPolicy is defined with .notNull(). Since it has a default value of false, this ensures data integrity. Confirm that all instances where environmentPolicyDeployment is inserted without specifying hasCustomPolicy will correctly default to false.


39-41: Clarify the purpose of the createdAt field

The createdAt field is added to the environment table with .defaultNow(), which records when the environment was created. Ensure that this field is used consistently across the application for tracking purposes.


117-136: Verify the SQL expression in deploymentUniq unique index

The unique index deploymentUniq uses a subquery in the on clause to reference the deployment.id from the releaseChannel table. Ensure that this SQL expression is valid and functions correctly within the ORM context, as complex expressions in index definitions may lead to SQL errors or unexpected behavior.

Run the following script to check for syntax issues in index definitions:

✅ Verification successful

Based on the search results, I can now provide a definitive response about the SQL subquery in the unique index:

The SQL subquery in the unique index is valid and correctly implemented

The subquery SELECT ${deployment.id} FROM ${releaseChannel} WHERE id = ${t.channelId} is used to enforce a unique constraint that prevents duplicate policy-deployment combinations through release channels. This is a valid SQL pattern and is correctly implemented because:

  1. The releaseChannel table has a direct foreign key relationship to deployment (shown in the table definition)
  2. The subquery is used within a unique index to enforce a compound uniqueness constraint
  3. The SQL template literals are properly constructed using DrizzleORM's sql`` tag
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Search for index definitions with subqueries to verify their correctness.

# Test: Find index definitions that include subqueries.
# Expect: Ensure that the syntax is accepted by the database.

rg 'uniqueIndex\(\).*sql`.*SELECT' -A 5

Length of output: 41


Script:

#!/bin/bash
# Let's try a broader search to understand the context better

# 1. Find all references to releaseChannel and deployment tables
rg "releaseChannel|deployment" --type ts -A 5

# 2. Search for all unique index definitions to understand the pattern
rg "uniqueIndex\(\)" --type ts -A 5

# 3. Look for SQL template literal usage
rg "sql`" --type ts -A 5

Length of output: 337358


Script:

#!/bin/bash
# Let's search for the releaseChannel table definition and its relationships to understand the SQL subquery better

# 1. Find releaseChannel table definition
ast-grep --pattern 'export const releaseChannel = pgTable($$$)'

# 2. Look for references to releaseChannel and deployment tables together
rg "releaseChannel.*deployment|deployment.*releaseChannel" --type ts -A 5

# 3. Search for similar unique index patterns with subqueries
rg "uniqueIndex\(\).*SELECT.*FROM" --type ts -A 5

Length of output: 1400

Comment on lines +181 to +188
hasCustomPolicy: boolean("has_custom_policy").notNull().default(false),
},
(t) => ({ uniq: uniqueIndex().on(t.policyId, t.environmentId) }),
(t) => ({
customPolicyUniq: uniqueIndex()
.on(t.environmentId)
.where(sql`is_own_policy = true`),
uniq: uniqueIndex().on(t.policyId, t.environmentId),
}),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix incorrect field reference in unique index customPolicyUniq

The unique index customPolicyUniq references is_own_policy, which is not defined in the environmentPolicyDeployment table. The correct field is hasCustomPolicy. Update the WHERE clause to use hasCustomPolicy instead to ensure the index functions as intended.

Apply this diff to correct the field reference:

 (t) => ({
   customPolicyUniq: uniqueIndex()
     .on(t.environmentId)
-    .where(sql`is_own_policy = true`),
+    .where(sql`has_custom_policy = true`),
   uniq: uniqueIndex().on(t.policyId, t.environmentId),
 }),
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
hasCustomPolicy: boolean("has_custom_policy").notNull().default(false),
},
(t) => ({ uniq: uniqueIndex().on(t.policyId, t.environmentId) }),
(t) => ({
customPolicyUniq: uniqueIndex()
.on(t.environmentId)
.where(sql`is_own_policy = true`),
uniq: uniqueIndex().on(t.policyId, t.environmentId),
}),
hasCustomPolicy: boolean("has_custom_policy").notNull().default(false),
},
(t) => ({
customPolicyUniq: uniqueIndex()
.on(t.environmentId)
.where(sql`has_custom_policy = true`),
uniq: uniqueIndex().on(t.policyId, t.environmentId),
}),

@jsbroks jsbroks closed this Oct 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant