Skip to content

Conversation

@adityachoudhari26
Copy link
Contributor

@adityachoudhari26 adityachoudhari26 commented Jan 14, 2026

Summary by CodeRabbit

  • New Features

    • Policy-driven environment progression now automates deployment advancement across environments. Deployments automatically progress to subsequent environments when specified policy conditions are satisfied.
    • Enables staged and gradual rollout workflows for safer production deployments.
  • Tests

    • Added comprehensive end-to-end test coverage for environment progression scenarios and rollout workflows.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 14, 2026

📝 Walkthrough

Walkthrough

The pull request introduces environment progression functionality by adding an action that evaluates policies restricting target progression between environments, collects matching release targets, and reconciles them through a provided function. The workspace engine is updated to integrate this action with a unified reconciliation pattern, and end-to-end tests validate the policy-driven progression behavior.

Changes

Cohort / File(s) Summary
Core Action Implementation
apps/workspace-engine/pkg/workspace/releasemanager/policy/evaluator/environmentprogression/environment_progression_action.go
New EnvironmentProgressionAction type with Execute method that: evaluates environment progression policies against current environment, collects matching release targets via GetForPolicy, and reconciles each target. Includes helper methods for environment lookup, policy filtering, target aggregation, and error-aware reconciliation. Total 122 lines added.
Release Target Query Support
apps/workspace-engine/pkg/workspace/store/release_targets.go
New GetForPolicy method that iterates all release targets, resolves associated environment/deployment/resource, and evaluates policy match. Returns map of matching targets keyed by target.Key(), skipping targets with resolution errors.
Workspace Integration
apps/workspace-engine/pkg/workspace/workspace.go
Added environmentprogression import and introduced reconcileFn closure for forwarding target reconciliation to release manager. Refactored action registration chain to use unified reconcileFn across deployment dependency and environment progression actions.
End-to-End Tests
apps/workspace-engine/test/e2e/engine_policy_environment_progression_test.go
Two test cases validating progression flow: TestEngine_PolicyEnvironmentProgression_TriggersGradualRollout and TestEngine_PolicyEnvironmentProgression_TriggersGradualRolloutStart. Both verify that completing QA environment triggers PROD job creation via policy-driven progression.

Sequence Diagram

sequenceDiagram
    participant E as Execute
    participant S as Store
    participant P as Policy Evaluator
    participant R as Release Manager

    E->>S: getEnvironment(envId)
    S-->>E: environment
    
    E->>P: getProgressionDependentPolicies(environment)
    P-->>E: policies[]
    
    loop For each policy
        E->>S: GetForPolicy(policy)
        S-->>E: releaseTargets{}
    end
    
    E->>E: Aggregate unique targets
    
    loop For each target
        E->>R: reconcileFn(target)
        R-->>E: result/error
    end
    
    E-->>E: Return aggregated errors
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 Through progression's tunnel, policies light the way,
QA to PROD, each target finds its day,
With reconcileFn magic and targets in hand,
Environment hops bloom across the land! 🌱✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and clearly summarizes the main change: adding a reconciliation hook mechanism for environment progression dependencies, which is the core focus of all modified files.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

🧹 Recent nitpick comments
apps/workspace-engine/pkg/workspace/store/release_targets.go (1)

189-214: Consider removing unused error return or adding error paths.

The method signature returns an error, but no code path ever returns a non-nil error. This differs from GetPolicies (lines 127-158) which returns errors for missing entities. Either:

  1. Remove the error return since it's unused, or
  2. Add error logging/aggregation for skipped targets to aid debugging stale references

The silent skip behavior is acceptable for resilience, but the unused error return is misleading.

apps/workspace-engine/test/e2e/engine_policy_environment_progression_test.go (1)

15-15: Misleading test name: no gradual rollout policy is configured.

This test only configures an environment progression policy (no WithRuleGradualRollout). Consider renaming to TestEngine_PolicyEnvironmentProgression_TriggersProdReconciliation or similar to accurately reflect what's being tested.

The second test (TriggersGradualRolloutStart) correctly tests with both policies.

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 46c00fd and 3d922a6.

📒 Files selected for processing (4)
  • apps/workspace-engine/pkg/workspace/releasemanager/policy/evaluator/environmentprogression/environment_progression_action.go
  • apps/workspace-engine/pkg/workspace/store/release_targets.go
  • apps/workspace-engine/pkg/workspace/workspace.go
  • apps/workspace-engine/test/e2e/engine_policy_environment_progression_test.go
🧰 Additional context used
📓 Path-based instructions (2)
apps/workspace-engine/**/*.go

📄 CodeRabbit inference engine (apps/workspace-engine/CLAUDE.md)

apps/workspace-engine/**/*.go: Do not add extraneous inline comments that state the obvious
Do not add comments that simply restate what the code does
Do not add comments for standard Go patterns (e.g., noting WaitGroup or semaphore usage)
Write comments that explain why, document complex logic/algorithms, provide non-obvious context, include TODO/FIXME, and document exported functions/types/methods

Files:

  • apps/workspace-engine/pkg/workspace/store/release_targets.go
  • apps/workspace-engine/test/e2e/engine_policy_environment_progression_test.go
  • apps/workspace-engine/pkg/workspace/workspace.go
  • apps/workspace-engine/pkg/workspace/releasemanager/policy/evaluator/environmentprogression/environment_progression_action.go
apps/workspace-engine/**/*_test.go

📄 CodeRabbit inference engine (apps/workspace-engine/CLAUDE.md)

Follow the existing test structure used in *_test.go files

Files:

  • apps/workspace-engine/test/e2e/engine_policy_environment_progression_test.go
🧠 Learnings (8)
📓 Common learnings
Learnt from: adityachoudhari26
Repo: ctrlplanedev/ctrlplane PR: 637
File: packages/events/src/kafka/client.ts:10-16
Timestamp: 2025-08-01T04:41:41.345Z
Learning: User adityachoudhari26 prefers not to add null safety checks for required environment variables when they are guaranteed to be present in their deployment configuration, similar to their preference for simplicity over defensive programming in test code.
Learnt from: adityachoudhari26
Repo: ctrlplanedev/ctrlplane PR: 601
File: e2e/tests/api/policies/retry-policy.spec.ts:23-24
Timestamp: 2025-06-24T23:52:50.732Z
Learning: The user adityachoudhari26 prefers not to add null safety checks or defensive programming in test code, particularly in e2e tests, as they prioritize simplicity and focus on the main functionality being tested rather than comprehensive error handling within the test itself.
📚 Learning: 2025-08-12T18:13:54.630Z
Learnt from: CR
Repo: ctrlplanedev/ctrlplane PR: 0
File: apps/workspace-engine/CLAUDE.md:0-0
Timestamp: 2025-08-12T18:13:54.630Z
Learning: Applies to apps/workspace-engine/**/*_test.go : Follow the existing test structure used in *_test.go files

Applied to files:

  • apps/workspace-engine/test/e2e/engine_policy_environment_progression_test.go
  • apps/workspace-engine/pkg/workspace/workspace.go
📚 Learning: 2025-08-12T18:13:54.630Z
Learnt from: CR
Repo: ctrlplanedev/ctrlplane PR: 0
File: apps/workspace-engine/CLAUDE.md:0-0
Timestamp: 2025-08-12T18:13:54.630Z
Learning: Applies to apps/workspace-engine/**/*.go : Write comments that explain why, document complex logic/algorithms, provide non-obvious context, include TODO/FIXME, and document exported functions/types/methods

Applied to files:

  • apps/workspace-engine/test/e2e/engine_policy_environment_progression_test.go
  • apps/workspace-engine/pkg/workspace/workspace.go
📚 Learning: 2025-08-12T18:13:54.630Z
Learnt from: CR
Repo: ctrlplanedev/ctrlplane PR: 0
File: apps/workspace-engine/CLAUDE.md:0-0
Timestamp: 2025-08-12T18:13:54.630Z
Learning: Applies to apps/workspace-engine/pkg/model/selector/**/*_test.go : Write comprehensive, data-driven tests for new condition types

Applied to files:

  • apps/workspace-engine/test/e2e/engine_policy_environment_progression_test.go
📚 Learning: 2025-08-12T18:13:54.630Z
Learnt from: CR
Repo: ctrlplanedev/ctrlplane PR: 0
File: apps/workspace-engine/CLAUDE.md:0-0
Timestamp: 2025-08-12T18:13:54.630Z
Learning: Applies to apps/workspace-engine/pkg/model/selector/**/*_test.go : Use table-driven tests for all condition types

Applied to files:

  • apps/workspace-engine/test/e2e/engine_policy_environment_progression_test.go
📚 Learning: 2025-08-12T18:13:54.630Z
Learnt from: CR
Repo: ctrlplanedev/ctrlplane PR: 0
File: apps/workspace-engine/CLAUDE.md:0-0
Timestamp: 2025-08-12T18:13:54.630Z
Learning: Applies to apps/workspace-engine/pkg/model/selector/**/*_test.go : Test validation and matching logic separately for condition types

Applied to files:

  • apps/workspace-engine/test/e2e/engine_policy_environment_progression_test.go
  • apps/workspace-engine/pkg/workspace/workspace.go
📚 Learning: 2025-08-12T18:13:54.630Z
Learnt from: CR
Repo: ctrlplanedev/ctrlplane PR: 0
File: apps/workspace-engine/CLAUDE.md:0-0
Timestamp: 2025-08-12T18:13:54.630Z
Learning: Applies to apps/workspace-engine/pkg/model/selector/**/*_test.go : Include edge cases in tests (empty values, special characters, unicode) for condition types

Applied to files:

  • apps/workspace-engine/test/e2e/engine_policy_environment_progression_test.go
📚 Learning: 2025-10-24T00:02:29.723Z
Learnt from: adityachoudhari26
Repo: ctrlplanedev/ctrlplane PR: 696
File: apps/workspace-engine/pkg/workspace/releasemanager/deployment/executor.go:63-67
Timestamp: 2025-10-24T00:02:29.723Z
Learning: In workspace-engine replay mode (apps/workspace-engine/pkg/workspace/releasemanager/deployment/executor.go), jobs are created with Pending status even during replay because job updates are still accepted and processed. If a job remains Pending after replay completes, it genuinely is still pending because no updates occurred during replay.

Applied to files:

  • apps/workspace-engine/test/e2e/engine_policy_environment_progression_test.go
  • apps/workspace-engine/pkg/workspace/workspace.go
🧬 Code graph analysis (3)
apps/workspace-engine/pkg/workspace/store/release_targets.go (2)
apps/workspace-engine/pkg/oapi/oapi.gen.go (2)
  • Policy (768-781)
  • ReleaseTarget (911-915)
apps/workspace-engine/pkg/selector/policies.go (2)
  • MatchPolicy (34-57)
  • NewResolvedReleaseTarget (8-14)
apps/workspace-engine/test/e2e/engine_policy_environment_progression_test.go (4)
apps/workspace-engine/test/integration/opts.go (16)
  • WithJobAgent (142-158)
  • JobAgentID (690-694)
  • WithDeployment (324-342)
  • WithEnvironment (344-358)
  • EnvironmentID (512-516)
  • EnvironmentName (492-496)
  • EnvironmentCelResourceSelector (498-504)
  • WithPolicyTargetSelector (729-739)
  • PolicyTargetCelEnvironmentSelector (784-790)
  • PolicyTargetCelDeploymentSelector (776-782)
  • PolicyTargetCelResourceSelector (808-814)
  • WithPolicyRule (741-758)
  • WithRuleEnvironmentProgression (826-839)
  • EnvironmentProgressionDependsOnEnvironmentSelector (974-983)
  • EnvironmentProgressionMinimumSuccessPercentage (1004-1009)
  • WithRuleGradualRollout (853-860)
apps/workspace-engine/test/integration/creators/deployment_version.go (1)
  • NewDeploymentVersion (15-36)
apps/workspace-engine/pkg/workspace/workspace.go (1)
  • Workspace (51-59)
apps/workspace-engine/pkg/oapi/oapi.gen.go (5)
  • JobStatusSuccessful (135-135)
  • JobUpdateEvent (691-698)
  • JobUpdateEventFieldsToUpdate (701-701)
  • JobUpdateEventFieldsToUpdateStatus (150-150)
  • JobUpdateEventFieldsToUpdateCompletedAt (140-140)
apps/workspace-engine/pkg/workspace/releasemanager/policy/evaluator/environmentprogression/environment_progression_action.go (4)
apps/workspace-engine/pkg/workspace/releasemanager/action/action.go (2)
  • ActionTrigger (9-9)
  • ActionContext (20-24)
apps/workspace-engine/pkg/oapi/oapi.gen.go (1)
  • Release (902-908)
apps/workspace-engine/pkg/selector/match.go (1)
  • Match (109-141)
apps/workspace-engine/pkg/workspace/store/release_targets.go (1)
  • ReleaseTargets (28-32)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: workspace-engine-tests
  • GitHub Check: tests
  • GitHub Check: build (linux/amd64)
  • GitHub Check: Typecheck
  • GitHub Check: Lint
🔇 Additional comments (7)
apps/workspace-engine/pkg/workspace/releasemanager/policy/evaluator/environmentprogression/environment_progression_action.go (4)

1-29: LGTM!

Clean type definitions with appropriate dependency injection pattern for the reconcile function.


70-94: Clarify intent: break exits after first EnvironmentProgression rule regardless of match.

The break on line 89 executes after evaluating the first EnvironmentProgression rule in each policy, regardless of whether it matched. If a policy has multiple EnvironmentProgression rules, only the first is evaluated.

If this is intentional (e.g., policies should have at most one progression rule), consider adding a brief comment. Otherwise, the break should be inside the if matched block.


96-122: LGTM!

Target deduplication and fail-fast error handling are appropriate for the reconciliation workflow.


31-40: The review comment is incorrect. The actx.Release field is guaranteed to be non-nil when Execute() is called because the orchestrator validates release existence at line 67-73 of orchestrator.go (release, ok := o.store.Releases.Get(job.ReleaseId)) and returns early if the release is not found. The ActionContext is only constructed and actions are only invoked after this validation succeeds, making the nil check unnecessary regardless of trigger type.

Likely an incorrect or invalid review comment.

apps/workspace-engine/pkg/workspace/workspace.go (1)

37-46: LGTM!

Clean integration with a shared reconcileFn for both deployment dependency and environment progression actions, reducing code duplication.

apps/workspace-engine/test/e2e/engine_policy_environment_progression_test.go (2)

67-113: LGTM!

The test logic correctly exercises the environment progression flow: creates a version, verifies only QA job is created initially (PROD blocked by progression policy), marks QA as successful, and verifies PROD job is then created. Assertions have clear messages.


115-227: LGTM!

This test correctly validates the interaction between environment progression and gradual rollout policies. The setup and assertions properly verify that gradual rollout starts after the progression dependency (QA success) is satisfied.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@adityachoudhari26 adityachoudhari26 merged commit 5f4c823 into main Jan 14, 2026
9 checks passed
@adityachoudhari26 adityachoudhari26 deleted the progression-dependencies-hook branch January 14, 2026 04:17
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.

2 participants