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

fix: Redeploy on var value change #211

Merged
merged 3 commits into from
Nov 11, 2024

Conversation

adityachoudhari26
Copy link
Contributor

@adityachoudhari26 adityachoudhari26 commented Nov 11, 2024

Summary by CodeRabbit

Release Notes

  • New Features

    • Enhanced deployment variable management with new job dispatching capabilities.
    • Introduced a new enum value variable_changed for improved trigger conditions in release jobs.
    • Added filtering by deployment IDs in the release job trigger creation process.
  • Bug Fixes

    • Streamlined logic for handling default values of deployment variables.
  • Documentation

    • Updated journal entries to reflect new changes in the PostgreSQL database structure.

Copy link
Contributor

coderabbitai bot commented Nov 11, 2024

Walkthrough

The pull request introduces enhancements to the deployment variable management system, focusing on the deployment-variable.ts file. Key modifications include new imports for job dispatching functionalities and updates to the update mutation logic, which now integrates the creation of release job triggers based on deployment variable changes. Additionally, a new enum value variable_changed is added to the PostgreSQL enum type and the corresponding schema, facilitating new conditions for job triggers. The changes also extend the ReleaseJobTriggerBuilder class to support filtering by deployment IDs.

Changes

File Path Change Summary
packages/api/src/router/deployment-variable.ts Added imports for job dispatching functions; modified update mutation to handle job trigger creation based on variable updates.
packages/db/drizzle/0034_brave_rogue.sql Updated release_job_trigger_type enum to include new value variable_changed.
packages/db/drizzle/meta/_journal.json Added new entry to the JSON journal for the database with index 34.
packages/db/src/schema/release.ts Added new enum value variable_changed to releaseJobTriggerType enum.
packages/job-dispatch/src/release-job-trigger.ts Introduced deploymentIds property and deployments method in ReleaseJobTriggerBuilder class for filtering by deployment IDs.

Possibly related PRs

Suggested reviewers

  • jsbroks

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.

@adityachoudhari26 adityachoudhari26 merged commit 894ed53 into main Nov 11, 2024
8 of 9 checks passed
@adityachoudhari26 adityachoudhari26 deleted the redeploy-on-var-value-change branch November 11, 2024 22:52
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

🧹 Outside diff range and nitpick comments (4)
packages/job-dispatch/src/release-job-trigger.ts (1)

Line range hint 41-91: Consider documenting the general-purpose nature of deployment filtering

While these changes were introduced to support redeployment on variable changes, the implementation provides a general-purpose deployment filtering capability that could be useful in other scenarios. Consider adding documentation to highlight this reusability aspect.

packages/api/src/router/deployment-variable.ts (3)

Line range hint 86-98: Handle potential null results from database query to prevent runtime errors

The takeFirst method may return undefined if no matching record is found. Destructuring properties from an undefined object will cause a runtime error. Ensure that you handle the case where the result is null or undefined.

Apply this diff to handle potential null values:

-      const { deploymentId, defaultValueId } = await ctx.db
+      const result = await ctx.db
         .select()
         .from(deploymentVariableValue)
         .innerJoin(
           deploymentVariable,
           eq(deploymentVariableValue.variableId, deploymentVariable.id),
         )
         .where(eq(deploymentVariableValue.id, input.id))
-        .then(takeFirst)
-        .then((v) => ({
-          deploymentId: v.deployment_variable.deploymentId,
-          defaultValueId: v.deployment_variable.defaultValueId,
-        }));
+        .then(takeFirstOrNull);
+
+      if (!result) {
+        throw new Error(`Deployment variable value with id ${input.id} not found`);
+      }
+
+      const { deploymentId, defaultValueId } = {
+        deploymentId: result.deployment_variable.deploymentId,
+        defaultValueId: result.deployment_variable.defaultValueId,
+      };

Line range hint 100-126: Ensure updatedValue is not null before proceeding

After updating the deployment variable value, takeFirst may return undefined if the update did not affect any rows. Attempting to use updatedValue when it is undefined could lead to runtime errors.

Apply this diff to handle potential null updatedValue:

       const updatedValue = await ctx.db.transaction((tx) =>
         tx
           .update(deploymentVariableValue)
           .set(input.data)
           .where(eq(deploymentVariableValue.id, input.id))
           .returning()
-          .then(takeFirst)
+          .then(takeFirstOrNull)
           .then(async (updatedValue) => {
+            if (!updatedValue) {
+              throw new Error(`Failed to update deployment variable value with id ${input.id}`);
+            }
+
             if (input.data.default && defaultValueId !== updatedValue.id)
               await tx
                 .update(deploymentVariable)
                 .set({ defaultValueId: updatedValue.id })
                 .where(eq(deploymentVariable.id, updatedValue.variableId));

             if (
               input.data.default === false &&
               defaultValueId === updatedValue.id
             )
               await tx
                 .update(deploymentVariable)
                 .set({ defaultValueId: null })
                 .where(eq(deploymentVariable.id, updatedValue.variableId));

             return updatedValue;
           }),
       );

127-148: Refactor chained promises to async/await for improved readability

The current use of nested .then() callbacks can make the code difficult to read and maintain. Refactoring the code to use async/await will enhance clarity and make error handling more straightforward.

Apply this refactor:

       if (input.data.value != null) {
-        await ctx.db.query.target
-          .findMany({
-            where: targetMatchesMetadata(ctx.db, updatedValue.targetFilter),
-          })
-          .then((targets) =>
-            createReleaseJobTriggers(ctx.db, "variable_changed")
-              .causedById(ctx.session.user.id)
-              .targets(targets.map((t) => t.id))
-              .deployments([deploymentId])
-              .filter(isPassingNoPendingJobsPolicy)
-              .filter(isPassingReleaseStringCheckPolicy)
-              .insert()
-              .then((triggers) =>
-                dispatchReleaseJobTriggers(ctx.db)
-                  .releaseTriggers(triggers)
-                  .filter(isPassingAllPolicies)
-                  .then(cancelOldReleaseJobTriggersOnJobDispatch)
-                  .dispatch(),
-              ),
-          );
+        const targets = await ctx.db.query.target.findMany({
+          where: targetMatchesMetadata(ctx.db, updatedValue.targetFilter),
+        });
+
+        const triggers = await createReleaseJobTriggers(ctx.db, "variable_changed")
+          .causedById(ctx.session.user.id)
+          .targets(targets.map((t) => t.id))
+          .deployments([deploymentId])
+          .filter(isPassingNoPendingJobsPolicy)
+          .filter(isPassingReleaseStringCheckPolicy)
+          .insert();
+
+        await dispatchReleaseJobTriggers(ctx.db)
+          .releaseTriggers(triggers)
+          .filter(isPassingAllPolicies)
+          .then(cancelOldReleaseJobTriggersOnJobDispatch)
+          .dispatch();
       }
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 115a193 and 754cd70.

📒 Files selected for processing (5)
  • packages/api/src/router/deployment-variable.ts (4 hunks)
  • packages/db/drizzle/0034_brave_rogue.sql (1 hunks)
  • packages/db/drizzle/meta/_journal.json (1 hunks)
  • packages/db/src/schema/release.ts (1 hunks)
  • packages/job-dispatch/src/release-job-trigger.ts (3 hunks)
🔇 Additional comments (9)
packages/db/drizzle/0034_brave_rogue.sql (2)

1-1: LGTM! Safe enum extension.

The ALTER TYPE statement correctly adds the new enum value. This is a safe operation that won't impact existing data or require table locks.


1-1: Verify corresponding TypeScript enum updates.

Let's ensure the TypeScript schema is properly synchronized with this enum change.

✅ Verification successful

TypeScript enum is properly synchronized with the new value

The TypeScript enum definition in packages/db/src/schema/release.ts already includes the variable_changed value, matching the SQL migration.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the corresponding TypeScript enum includes the new value
# and check for any constraints using this enum type

# Check TypeScript enum definition
echo "Checking TypeScript enum definition:"
rg -A 10 "releaseJobTriggerType" packages/db/src/schema/

# Check for any constraints or checks using this enum
echo "Checking for constraints using this enum:"
rg -l "release_job_trigger_type" packages/db/drizzle/ | grep -v "0034_brave_rogue.sql"

Length of output: 3476

packages/db/drizzle/meta/_journal.json (1)

242-248: LGTM! Verify the corresponding migration file.

The new journal entry follows the correct format and sequential order.

Let's verify the corresponding migration file exists and contains the expected enum changes:

✅ Verification successful

Migration file verified and contains the expected enum changes

The migration file 0034_brave_rogue.sql exists and correctly adds the new 'variable_changed' value to the release_job_trigger_type enum, which aligns with the journal entry and the intended changes for the deployment variable management system.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the migration file exists and contains the enum changes

# Check if the migration file exists and contains the enum changes
fd -t f "0034_brave_rogue.sql" packages/db/drizzle/ -x cat {} | grep -A 5 "release_job_trigger_type"

Length of output: 168

packages/job-dispatch/src/release-job-trigger.ts (3)

41-41: LGTM: Property follows established patterns

The new deploymentIds property is well-structured and consistent with existing filter properties.


77-80: LGTM: Method follows builder pattern correctly

The deployments method is well-implemented, maintaining consistency with other filter methods and proper method chaining.


91-91: Verify query behavior with deployment filtering

The deployment filter implementation looks correct, but let's verify that it works as expected with different combinations of filters.

Let's analyze the query construction:

✅ Verification successful

Let me analyze the query construction further by checking the base query and other deployment-related filters.


The deployment filter implementation is correctly integrated

The implementation is safe and consistent with the codebase's query construction pattern because:

  1. The deployment table is properly joined in _baseQuery() via innerJoin(deployment, eq(deployment.systemId, environment.systemId))
  2. The new filter follows the same pattern as other filters in the _where() method
  3. No conflicting deployment filters exist in the query chain
  4. The condition is properly guarded with this.deploymentIds && to handle undefined cases
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for potential conflicts or edge cases in deployment filtering

# Look for other places where deployment filtering might be applied
rg -l 'deployment.*id' --type ts

# Check for any existing deployment-related queries that might conflict
ast-grep --pattern 'inArray(deployment.id, $_)'

Length of output: 3853


Script:

#!/bin/bash
# Check the base query and other deployment-related filters in release-job-trigger.ts
rg -A 10 "_baseQuery" packages/job-dispatch/src/release-job-trigger.ts

# Look for other deployment filters in the same file
rg "deployment\." -A 3 packages/job-dispatch/src/release-job-trigger.ts

Length of output: 1858

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

169-169: LGTM! Verify database schema migration.

The new enum value variable_changed follows the existing pattern of change-based triggers and aligns with the PR objective.

Let's verify that this enum value is properly added to the database schema:

✅ Verification successful

Migration verified - enum value properly added to schema

The database schema migration is properly handled:

  • Migration file 0034_brave_rogue.sql adds the variable_changed value to the release_job_trigger_type enum
  • The enum value is also reflected in the corresponding snapshot file meta/0034_snapshot.json
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check if the enum value is added to the database schema migration
# Expected: Find a migration file that adds 'variable_changed' to the release_job_trigger_type enum

# Look for migration files that modify the release_job_trigger_type enum
fd --type f . "packages/db/drizzle" --exec rg -l "release_job_trigger_type"

# Look for the specific enum value addition
rg -A 5 -B 5 "variable_changed" "packages/db/drizzle"

Length of output: 2626

packages/api/src/router/deployment-variable.ts (2)

19-26: Imports are appropriate and correctly utilized

All imported functions from @ctrlplane/job-dispatch are used appropriately within the code. This enhances the deployment variable management functionality as intended.


127-148: Verify that all policies are correctly applied to release job triggers

Ensure that the policies are applied in the correct order and that no necessary policy checks are missing before dispatching the release job triggers.

Run the following script to check the policy application in release-job-trigger.ts:

This script searches for all instances where policies are applied in the release-job-trigger module to confirm that they are properly implemented.

✅ Verification successful

The file path in the previous attempt might have been incorrect. Let's search broadly across the codebase to find where these policies are defined and implemented.


Policies are correctly applied in the expected order

Based on the codebase analysis, the policies in the code snippet are correctly implemented and applied in a proper sequence:

  1. isPassingNoPendingJobsPolicy - Ensures no pending jobs exist
  2. isPassingReleaseStringCheckPolicy - Validates release string format
  3. isPassingAllPolicies - Applies all remaining policies in the correct order:
    • Locking policy
    • Approval policy
    • Criteria policy
    • Concurrency policy
    • Release dependency policy
    • Job rollout policy
    • No active jobs policy
    • Newer than last active policy
    • Release window policy

The implementation in deployment-variable.ts follows the standard pattern used across the codebase for policy application, as seen in other files like release.ts, target.ts, and release-deploy.ts.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that all necessary policies are applied to release job triggers.

# Test: Search for policy applications in 'release-job-trigger.ts'. Expect: All policies are applied.
rg 'isPassing.*Policy' packages/job-dispatch/src/release-job-trigger.ts

Length of output: 73


Script:

#!/bin/bash
# Let's try searching in the entire codebase for policy-related functions
rg -A 2 'isPassing.*Policy|isPassingAllPolicies' 

# Also search for the specific policy functions mentioned in the code
rg -A 2 'isPassingNoPendingJobsPolicy|isPassingReleaseStringCheckPolicy'

# Search for any policy-related type definitions or interfaces
ast-grep --pattern 'interface $_Policy {
  $$$
}'

Length of output: 19485

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