Skip to content

Conversation

@jsbroks
Copy link
Member

@jsbroks jsbroks commented Mar 31, 2025

Summary by CodeRabbit

  • New Features
    • Enhanced release evaluation by dynamically retrieving release data for improved accuracy.
    • Expanded policy capabilities with a new deployment version selection feature to support more flexible management.
    • Introduced a new function to merge deployment version selectors for improved policy handling.
    • Added new relationships and exports for better resource management.
  • Bug Fixes
    • Improved error handling in the evaluation process to manage cases with no valid policy.
  • Chores
    • Added new dependencies for better integration and type support.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 31, 2025

Walkthrough

This PR introduces a new asynchronous mechanism for retrieving releases. The event worker now uses a dynamically queried list of releases via the getReleases function instead of a static array. In parallel, the schema is extended with a new table and corresponding type to manage deployment version selectors for policies. The evaluate function in the rule engine has been updated to be asynchronous and utilize the new release retrieval process, while an import path has been adjusted in the release manager.

Changes

File(s) Summary
apps/event-worker/.../evaluate/index.ts Added async getReleases function using DB queries; updated evaluate call to use getReleases; enhanced error handling.
packages/db/src/schema/policy.ts &
packages/rule-engine/src/types.ts
Introduced the policyDeploymentVersionSelector table and its inferred type; updated the Policy type to include deploymentVersionSelector.
packages/release-manager/src/variables/types.ts Updated the import path for ReleaseIdentifier from "src/types" to "../types.js".
packages/rule-engine/src/evaluate.ts Modified the function to async; replaced the releases parameter with a getReleases function; added a check to return a fail-safe result when no policy exists.
packages/db/src/schema/policy-relations.ts Added new relationship deploymentVersionSelector referencing policyDeploymentVersionSelector.
packages/rule-engine/src/db/get-applicable-policies.ts Updated query to include deploymentVersionSelector in the getApplicablePolicies function.
packages/rule-engine/src/utils/merge-policies.ts Introduced mergeVersionSelectors function to handle merging of deploymentVersionSelector properties in policies.
apps/event-worker/package.json Added dependency "@ctrlplane/release-manager": "workspace:*" in package.json.
packages/rule-engine/package.json Added dependencies "@ctrlplane/logger": "workspace:*" and "@types/lodash": "catalog:" in package.json.
packages/rule-engine/src/db/create-ctx.ts Updated import source for and and eq functions from drizzle-orm to @ctrlplane/db.
packages/rule-engine/src/index.ts Added export for all entities from ./utils/get-releases.js.
packages/rule-engine/src/utils/get-releases.ts Introduced getReleases function to retrieve release information based on specific criteria.

Sequence Diagram(s)

sequenceDiagram
    participant Worker as Release Worker
    participant Evaluate as Evaluate Function
    participant DB as Database Service
    Worker->>Evaluate: execute(policy, getReleases, context)
    Evaluate-->>Evaluate: merge policies
    alt mergedPolicy is null
        Evaluate->>Worker: Return {allowed: false, release: undefined}
    else
        Evaluate->>DB: getReleases(mergedPolicy)
        DB-->>Evaluate: releases array
        Evaluate->>Worker: Continue with evaluation using releases
    end
Loading

Possibly related PRs

  • fix: Create jobs for latest valid releases on env create #197: The changes in the main PR, specifically the introduction of the getReleasesWithContext function and modifications to the evaluate function, are related to the changes in the retrieved PR, which also involves the handling of releases in the context of environment creation and job triggers.
  • fix: Optimize release list query and use lazy loading for release cells #269: The changes in the main PR, which involve modifying the evaluate function and introducing the getReleasesWithContext function, are related to the changes in the retrieved PR, specifically regarding the handling of release data and the introduction of new querying mechanisms.
  • fix: Deployment version metadata router #376: The changes in the main PR, which involve modifying the evaluate function to use a new getReleasesWithContext function and enhancing error handling, are related to the changes in the retrieved PR that also focus on handling deployment version metadata.

Poem

I’m a coding rabbit on a joyful spree,
Leaping through functions as nimble as can be.
Dynamic releases now hop into view,
With policies and queries all fresh and new.
In a garden of code, I nibble on each change,
Hoppy days ahead in our tech-savvy range!

✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 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 generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai plan to trigger planning for file edits and PR creation.
  • @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

🧹 Nitpick comments (3)
packages/db/src/schema/policy.ts (1)

76-256: Consider adding insert/update schemas for the new table.

Unlike the other tables in this file, there are no corresponding insert/update schemas defined for the new policyDeploymentVersionSelector table. Consider adding these for consistency.

You could add schemas similar to how the other tables are handled, for example:

const policyDeploymentVersionSelectorInsertSchema = createInsertSchema(
  policyDeploymentVersionSelector,
  {
    policyId: z.string().uuid(),
    name: z.string().min(1, "Name is required"),
    description: z.string().optional(),
    deploymentVersionSelector: z.any(), // You might want to create a proper schema for this
  }
).omit({ id: true });

export const createPolicyDeploymentVersionSelector = policyDeploymentVersionSelectorInsertSchema;
export type CreatePolicyDeploymentVersionSelector = z.infer<typeof createPolicyDeploymentVersionSelector>;

export const updatePolicyDeploymentVersionSelector = policyDeploymentVersionSelectorInsertSchema.partial();
export type UpdatePolicyDeploymentVersionSelector = z.infer<typeof updatePolicyDeploymentVersionSelector>;
apps/event-worker/src/releases/evaluate/index.ts (2)

43-64: Consider using the Policy parameter.

The function accepts a Policy parameter but doesn't use it. Based on the comments, this parameter is intended to be used for filtering releases based on policy conditions.

Once the TODOs are addressed, ensure that the Policy parameter is properly utilized to filter releases based on the deployment version selector.


43-64: Add error handling for database operations.

There's no error handling for the database query. Consider adding try/catch blocks to handle potential database errors gracefully.

const getReleases = async (_: Policy) => {
+  try {
    return await db.query.release.findMany({
      where: and(
        eq(schema.release.deploymentId, ctx.deploymentId),
        eq(schema.release.resourceId, ctx.resourceId),
        eq(schema.release.environmentId, ctx.environmentId),
      ),
      with: {
        version: true,
        variables: true,
      },
      orderBy: desc(schema.release.createdAt),
    });
+  } catch (error) {
+    console.error("Error fetching releases:", error);
+    return [];
+  }
};
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 35fcafb and 15933c6.

📒 Files selected for processing (5)
  • apps/event-worker/src/releases/evaluate/index.ts (2 hunks)
  • packages/db/src/schema/policy.ts (3 hunks)
  • packages/release-manager/src/variables/types.ts (1 hunks)
  • packages/rule-engine/src/evaluate.ts (1 hunks)
  • packages/rule-engine/src/types.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
`**/*.{ts,tsx}`: **Note on Error Handling:** Avoid strict enforcement of try/catch blocks. Code may use early returns, Promise chains (.then().catch()), or other patterns for error...

**/*.{ts,tsx}: Note on Error Handling:
Avoid strict enforcement of try/catch blocks. Code may use early returns, Promise chains (.then().catch()), or other patterns for error handling. These are acceptable as long as they maintain clarity and predictability.

  • packages/db/src/schema/policy.ts
  • packages/release-manager/src/variables/types.ts
  • packages/rule-engine/src/types.ts
  • apps/event-worker/src/releases/evaluate/index.ts
  • packages/rule-engine/src/evaluate.ts
🧬 Code Definitions (2)
packages/rule-engine/src/types.ts (1)
packages/db/src/schema/policy.ts (1)
  • PolicyDeploymentVersionSelector (254-256)
packages/rule-engine/src/evaluate.ts (2)
packages/db/src/schema/policy.ts (2)
  • policy (24-40)
  • Policy (249-249)
packages/rule-engine/src/types.ts (3)
  • Policy (66-69)
  • Release (7-17)
  • DeploymentResourceContext (37-42)
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: Typecheck
  • GitHub Check: Lint
  • GitHub Check: build (linux/amd64)
🔇 Additional comments (10)
packages/release-manager/src/variables/types.ts (1)

1-1: Import path update looks good.

The updated import path uses a relative path with a .js extension which is a good practice in TypeScript projects using ESM.

packages/rule-engine/src/types.ts (1)

68-68: Type extension for Policy looks good.

Adding deploymentVersionSelector to the Policy type properly extends it to support the new capability being introduced. The type is correctly defined as schema.PolicyDeploymentVersionSelector | null.

packages/db/src/schema/policy.ts (3)

3-3: LGTM - Import added for DeploymentVersionCondition.

The import is correctly added to support the new table definition.


76-95: Table definition is well-structured.

The new policyDeploymentVersionSelector table is defined with appropriate constraints:

  • Primary key for the ID
  • Foreign key relationship to the policy table
  • Unique constraint on policyId ensuring one-to-one relationship
  • Required fields marked as notNull

254-256: Type export is consistent with schema pattern.

The PolicyDeploymentVersionSelector type correctly uses InferSelectModel to generate the type from the table definition.

apps/event-worker/src/releases/evaluate/index.ts (2)

1-9: Import statements look good.

All required imports are properly added to support the new functionality.


66-66: Updated evaluate call looks good.

The evaluate function is now correctly called with the new getReleases function as a parameter.

packages/rule-engine/src/evaluate.ts (3)

24-27: Good function signature update to support asynchronous release retrieval.

The change from accepting a static array of releases to using a function parameter that can asynchronously fetch releases is a good architectural improvement. This allows for more flexibility in how releases are obtained and makes the evaluation process more dynamic.


33-38: Good defensive programming with explicit handling of null merged policy.

Adding this early return when no valid policy is available improves error handling and makes the behavior more predictable. It correctly prevents further processing when there's no policy to evaluate against.


41-41: Correct implementation of async release retrieval.

The code properly awaits the result of getReleases(mergedPolicy), ensuring that releases are available before proceeding with evaluation. This correctly handles both synchronous and asynchronous release retrieval functions.

@jsbroks jsbroks merged commit b27aadd into main Mar 31, 2025
2 of 9 checks passed
@jsbroks jsbroks deleted the filter-rule branch March 31, 2025 22:20
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: 0

🧹 Nitpick comments (2)
packages/rule-engine/src/utils/get-releases.ts (1)

16-28: Utilize consistent logging practices.

The logger child object is created for the rule-engine/getReleases scope, which is good for isolating logs. Consider adding context fields (e.g. deploymentId, resourceId) to enhance debugging if there are future issues with date bounds validation.

packages/rule-engine/src/evaluate.ts (1)

49-49: Consider capturing potential errors from getReleases.

While the call to await getReleases(mergedPolicy) is appropriate, any internal errors will bubble up directly. Verify that the caller or higher-level logic can handle these failures properly if necessary.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3a09b6a and 96f85d3.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (8)
  • apps/event-worker/src/releases/evaluate/index.ts (2 hunks)
  • packages/db/src/schema/resource.ts (1 hunks)
  • packages/release-manager/package.json (1 hunks)
  • packages/rule-engine/package.json (2 hunks)
  • packages/rule-engine/src/db/create-ctx.ts (1 hunks)
  • packages/rule-engine/src/evaluate.ts (1 hunks)
  • packages/rule-engine/src/index.ts (1 hunks)
  • packages/rule-engine/src/utils/get-releases.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/event-worker/src/releases/evaluate/index.ts
🧰 Additional context used
📓 Path-based instructions (1)
`**/*.{ts,tsx}`: **Note on Error Handling:** Avoid strict enforcement of try/catch blocks. Code may use early returns, Promise chains (.then().catch()), or other patterns for error...

**/*.{ts,tsx}: Note on Error Handling:
Avoid strict enforcement of try/catch blocks. Code may use early returns, Promise chains (.then().catch()), or other patterns for error handling. These are acceptable as long as they maintain clarity and predictability.

  • packages/rule-engine/src/index.ts
  • packages/rule-engine/src/db/create-ctx.ts
  • packages/rule-engine/src/evaluate.ts
  • packages/db/src/schema/resource.ts
  • packages/rule-engine/src/utils/get-releases.ts
🧬 Code Definitions (2)
packages/db/src/schema/resource.ts (3)
packages/db/src/schema/release.ts (1)
  • release (18-37)
packages/db/src/schema/deployment.ts (1)
  • deployment (66-90)
packages/db/src/schema/environment.ts (1)
  • environment (57-82)
packages/rule-engine/src/utils/get-releases.ts (1)
packages/db/src/schema/resource.ts (1)
  • resourceRelease (91-120)
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Lint
  • GitHub Check: build (linux/amd64)
🔇 Additional comments (11)
packages/rule-engine/src/index.ts (1)

7-7: Added export for the new get-releases module

The new export statement correctly makes all entities from the ./utils/get-releases.js module available for external importing. This aligns with the PR objective of introducing a new asynchronous mechanism for retrieving releases.

packages/release-manager/package.json (1)

32-32: Added TypeScript type definitions for lodash

Adding @types/lodash as a dev dependency is appropriate since lodash is already listed as a main dependency. This improves type safety and developer experience when using lodash in TypeScript files.

packages/rule-engine/src/db/create-ctx.ts (1)

3-3: Updated import source for database utilities

The import for and and eq functions has been updated to source from @ctrlplane/db instead of directly from drizzle-orm. This is a good practice that centralizes database utilities and creates a more consistent API across the project.

packages/rule-engine/package.json (2)

28-28: Added logger dependency

The addition of @ctrlplane/logger as a workspace dependency is appropriate for the new asynchronous operations that may require logging capabilities, especially for error handling in the updated evaluate function mentioned in the PR summary.


41-41: Added TypeScript type definitions for lodash

The addition of @types/lodash as a dev dependency improves type safety and developer experience when using lodash in TypeScript files. This change is consistent with the same addition in the release-manager package.

packages/db/src/schema/resource.ts (1)

122-142: Looks good!

These newly introduced relations properly define one-to-one mappings for each related table field. The syntax and references appear consistent with the existing schema conventions.

packages/rule-engine/src/utils/get-releases.ts (2)

1-14: Imports and type definitions look appropriate.

No concerns about importing Tx from @ctrlplane/db or isAfter from date-fns. The Policy type definition is clear, and the usage of typed properties (e.g., denyWindows) is consistent with the rest of the codebase.


30-119:

❓ Verification inconclusive

Ensure error handling aligns with best practices.

The function getReleases utilizes two database queries but does not implement an explicit error or exception handling flow. Should either query fail (e.g., a connection issue or an invalid schema operation), it may reject or produce an unhandled rejection. While your guidelines do not strictly require try/catch, consider ensuring upstream error handling is robust and logs or short-circuits gracefully when these queries fail.

Is an upstream mechanism in place for handling any errors thrown by these queries (e.g., your request pipeline or a standard error boundary)? If not, we can create a follow-up script to trace all getReleases invocations to ensure that the potential rejections are handled properly.


🏁 Script executed:

#!/bin/bash
# Searching for all getReleases invocations to verify error handling in the rule engine or upper layers
rg -A 3 "getReleases("

Length of output: 99


Below is a new shell script that uses proper escaping to search for all invocations of getReleases( in the codebase. This will help verify whether upstream error handling is in place for potential rejections from those database queries. Please run the script and share the output if available.

Once we have the correct output, we can determine if there's an upstream error handling mechanism or if further action is required.


🏁 Script executed:

#!/bin/bash
# Correctly search for all invocations of getReleases in the repository using escaped parenthesis
rg -A 3 "getReleases\("

Length of output: 802


Action Required: Verify Upstream Error Handling for Database Query Failures

It appears that the getReleases function (in packages/rule-engine/src/utils/get-releases.ts, lines 30–119) does not include explicit error or exception handling around its two database queries. Our search of its invocations revealed that:

  • In packages/rule-engine/src/evaluate.ts, the call is made via await getReleases(mergedPolicy) without any local try/catch.
  • In apps/event-worker/src/releases/evaluate/index.ts, the function is similarly invoked without explicit error handling.

Please verify that a robust, upstream error handling mechanism (such as a global error boundary or middleware) exists to catch and appropriately handle rejections from these queries. If not, consider implementing dedicated try/catch blocks within these contexts to ensure graceful failure handling.

packages/rule-engine/src/evaluate.ts (3)

25-26: Accurate JSDoc comments.

Documenting getReleases as a function returning a list of releases for the given policy clarifies usage for other contributors.


32-34: Async function signature is properly declared.

Converting evaluate into an async function is consistent with the new getReleases usage. No issues noted.


41-45: Clear null check for mergedPolicy.

Returning { allowed: false, release: undefined } when mergedPolicy is null is a logical safeguard, ensuring no further steps proceed with an undefined policy.

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.

3 participants