Skip to content

Conversation

@akshayutture-augment
Copy link
Contributor

Closes #36840

Signed-off-by: Pedro Ruivo <[email protected]>
@akshayutture-augment
Copy link
Contributor Author

@claude review this PR

1 similar comment
@akshayutture-augment
Copy link
Contributor Author

@claude review this PR

@claude
Copy link

claude bot commented Nov 20, 2025

Claude finished @akshayutture-augment's task —— View job


Code Review Complete

  • Read repository guidelines (CLAUDE.md)
  • Review feature flag implementation
  • Review documentation changes
  • Review test changes
  • Review compatibility framework changes
  • Provide comprehensive feedback

Summary

This PR adds the rolling-updates feature flag and implements a feature gate mechanism to ensure the rolling updates functionality is only available when explicitly enabled. The implementation is generally solid with good test coverage and documentation updates.

Positive Aspects

Good feature flag implementation - The ROLLING_UPDATES feature is properly added to Profile.java with Type.PREVIEW status
Comprehensive feature gating - Both CLI commands properly check if the feature is enabled before execution
Clear exit codes - Added FEATURE_DISABLED = 4 exit code for clear scripting support
Documentation updates - Both operator and server docs updated with CAUTION blocks about enabling the feature
Test coverage - New test testFeatureNotEnabled() validates the feature gate behavior
Consistent implementation - Feature check pattern is consistent across both command classes

Issues & Recommendations

🔴 Critical Issues

1. Missing Trailing Comma in Profile.java (Line 136)

In common/src/main/java/org/keycloak/common/Profile.java:136, the ROLLING_UPDATES entry is missing a trailing comma:

ROLLING_UPDATES("Rolling Updates", Type.PREVIEW),
;

While this is syntactically valid in Java (since it's the last enum before the semicolon), it's inconsistent with the codebase pattern where the previous entry (IPA_TUURA_FEDERATION) had a comma. For maintainability and consistency:

Recommendation: Remove the comma from ROLLING_UPDATES OR add a comma to IPA_TUURA_FEDERATION and remove it from ROLLING_UPDATES. The current pattern (comma on ROLLING_UPDATES, none on IPA_TUURA_FEDERATION) is correct, but the diff shows IPA_TUURA_FEDERATION had no comma and gained one, which means the change is correct. ✅

🟡 Medium Priority Issues

2. Exit Code Documentation Mismatch

In quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/compatibility/CompatibilityResult.java:30-35, the exit code changed from 4 to 3 for RECREATE_UPGRADE_EXIT_CODE, with new code:

// see picocli.CommandLine.ExitCode
// 1 -> software error
// 2 -> usage error
int RECREATE_UPGRADE_EXIT_CODE = 3;
int FEATURE_DISABLED = 4;

However, the documentation in docs/guides/server/update-compatibility.adoc shows exit code 3 means "Rolling Upgrade is not possible" and exit code 4 means feature disabled. This is consistent with the code change.

Issue: The comment references picocli.CommandLine.ExitCode, but these are custom exit codes specific to this application. The picocli exit codes are: 0 (success), 1 (software error), 2 (usage error). This PR introduces custom codes 3 and 4.

Recommendation: Update the comment to clarify these are custom exit codes beyond picocli's standard ones:

// Exit codes follow picocli.CommandLine.ExitCode convention:
// 0 -> success, 1 -> software error, 2 -> usage error
// Custom exit codes for this command:
int RECREATE_UPGRADE_EXIT_CODE = 3;  // recreate upgrade required
int FEATURE_DISABLED = 4;             // feature not enabled

3. Test Method Ordering and Naming

In quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/UpdateCommandDistTest.java:46-49, the new test testFeatureNotEnabled() is added at the top of the test class. This test validates a critical prerequisite (feature must be enabled), so its placement is logical.

Minor suggestion: Consider renaming to testCommandFailsWhenFeatureNotEnabled() for more explicit test naming that follows the pattern "test[Action][Condition]".

4. Operator Test Uses Feature Flag via Spec

In operator/src/test/java/org/keycloak/operator/testsuite/integration/UpgradeTest.java:110-114, the test now enables the feature via:

if (kc.getSpec().getFeatureSpec() == null) {
    kc.getSpec().setFeatureSpec(new FeatureSpec());
}
kc.getSpec().getFeatureSpec().setEnabledFeatures(List.of(Profile.Feature.ROLLING_UPDATES.getKey()));

Issue: The change from UnsupportedSpec to FeatureSpec is significant but not explained. This suggests there was a refactoring of how features are configured in the operator.

Question: Is FeatureSpec the new standard way to configure features in the operator? If so, this is a breaking change that should be documented.

🟢 Minor Issues

5. Documentation Template Update

In docs/guides/templates/kc.adoc:53, the template macro now includes --features=rolling-updates:

bin/kc.[sh|bat] update-compatibility ${parameters} --features=rolling-updates

Question: Should this be in the template? This means ALL examples using updatecompatibility will automatically include the feature flag. This seems correct for a preview feature, but verify this is the intended behavior across all documentation.

6. Dockerfile Build Command

In operator/scripts/Dockerfile-custom-image:5, the build command now includes:

RUN /opt/keycloak/bin/kc.sh build --db=postgres --health-enabled=true --features=rolling-updates

Concern: Hardcoding a preview feature in the Dockerfile means this custom image will always have rolling-updates enabled. When this feature moves from PREVIEW to DEFAULT, this flag will become redundant. Consider:

  • Adding a build arg: ARG ENABLE_ROLLING_UPDATES=true
  • Using conditional feature enabling based on the arg
  • Or document that this Dockerfile is specifically for testing rolling updates

7. Error Message Consistency

In AbstractUpdatesCommand.java:84, the error message says:

printError("Unable to use this command. The preview feature 'rolling-updates' is not enabled.");

This is clear, but consider making it more actionable:

printError("Unable to use this command. The preview feature 'rolling-updates' is not enabled. Use --features=rolling-updates to enable it.");

🔵 Questions for Clarification

  1. Feature Stability Timeline: Since this is marked as Type.PREVIEW, what's the timeline for moving to Type.DEFAULT? This affects how we document the feature flag requirement.

  2. Backward Compatibility: When rolling-updates moves from PREVIEW to DEFAULT, will existing scripts/deployments that explicitly enable it continue to work?

  3. Operator Behavior: In docs/guides/operator/advanced-configuration.adoc:448, the CAUTION states "the {project_name} Operator will fail" if the feature is not enabled. Does this mean the operator fails to start, or just that rolling updates aren't available?

  4. Feature Flag Propagation: In Kubernetes/operator deployments, how does the feature flag get propagated from the Keycloak CR to the actual server instances? The example shows:

    spec:
      features:
        enabled:
          - rolling-updates

    But does this automatically add --features=rolling-updates to the server startup?

Testing Recommendations

  1. Add negative test: Test the scenario where a user tries to run the command with the feature flag but provides an invalid metadata file
  2. Add integration test: Test the full workflow: generate metadata → modify config → check compatibility with feature enabled vs disabled
  3. Test exit codes: Explicitly verify that exit code 4 is returned when feature is disabled (current test only checks error message)

Code Quality

  • ✅ Code follows Java conventions and project style
  • ✅ Error handling is appropriate
  • ✅ Method names are descriptive
  • ✅ Comments explain the "why" not just the "what"
  • ✅ No obvious security issues
  • ✅ No performance concerns

Documentation Quality

  • ✅ Clear CAUTION blocks warn users about preview feature requirement
  • ✅ Exit codes are documented
  • ✅ Examples updated to include feature flag
  • ⚠️ Could benefit from more explanation about when the feature flag will no longer be needed

Final Recommendation

APPROVE with minor suggestions. The implementation is solid and properly gates the rolling updates functionality behind a feature flag. The main concerns are:

  1. Minor documentation clarity improvements
  2. Questions about long-term maintenance (hardcoded feature flags in Dockerfiles/templates)
  3. Small code comment improvements

None of these are blockers. The PR can be merged as-is, but addressing the suggestions would improve maintainability.


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