Conversation
WalkthroughThis pull request introduces Kubernetes Gateway API support to the WSO2 all-in-one Helm deployment. Six new template files define Gateway, HTTPRoute, and BackendTLSPolicy resources for routing API traffic across management, gateway, WebSocket, and WebSub endpoints. A corresponding values.yaml configuration section enables feature flags and customization parameters. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 1 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. 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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 7
🤖 Fix all issues with AI agents
In `@all-in-one/templates/am/wso2am-gateway-api-backend-tls-policy.yaml`:
- Around line 24-27: The BackendTLSPolicy template currently renders an empty
caCertificateRefs entry when
.Values.kubernetes.gatewayAPI.backendTLSPolicy.caCertificateSecret is an empty
string; add validation so that when .Values.kubernetes.gatewayAPI.enabled and
.Values.kubernetes.gatewayAPI.backendTLSPolicy.enabled are true you call
required (or otherwise assert) on
.Values.kubernetes.gatewayAPI.backendTLSPolicy.caCertificateSecret to fail the
render with a clear error message, and only render the caCertificateRefs block
if that required value is present; reference the variables
.Values.kubernetes.gatewayAPI.backendTLSPolicy.caCertificateSecret and the
template logic that builds caCertificateRefs to implement this check.
In `@all-in-one/templates/am/wso2am-gateway-api-management-httproute.yaml`:
- Around line 36-39: The filters block is mis-indented causing it not to align
with sibling fields (matches, backendRefs); update the template that renders {{
toYaml .Values.kubernetes.gatewayAPI.management.filters }} so it uses indent 6
instead of indent 4 (i.e., change the indent call for the filters block in the
HTTPRoute template) so the filters field becomes a proper sibling of matches and
backendRefs.
In `@all-in-one/templates/am/wso2am-gateway-api-websocket-httproute.yaml`:
- Around line 36-39: The filters block in the WebSocket HTTPRoute template uses
the wrong indentation; update the template code that checks
.Values.kubernetes.gatewayAPI.websocket.filters and renders "filters:" with the
subsequent YAML produced by toYaml
.Values.kubernetes.gatewayAPI.websocket.filters to use indent 6 instead of
indent 4 so the "filters" field aligns consistently with other HTTPRoute
templates.
- Around line 12-35: The HTTPRoute for websocket is fine but the backend Service
must declare an appProtocol for WebSocket; update the Service named "{{ template
\"am-all-in-one.fullname\" . }}-am-service" (the Service that exposes port 8099)
to add appProtocol: kubernetes.io/ws (or kubernetes.io/wss if TLS) on the port
definition so Gateway API v1.2+ can perform WebSocket upgrades; ensure the port
entry that references 8099 includes the appProtocol field and keep the port
name/number consistent with the HTTPRoute backendRef.
In `@all-in-one/templates/am/wso2am-gateway-api-websub-httproute.yaml`:
- Around line 36-39: The filters block is currently nested under backendRefs;
move the entire filters block (the "filters:" line and the templated content
from .Values.kubernetes.gatewayAPI.websub.filters) out of the backendRefs scope
so it is a sibling of "matches" and "backendRefs" within the rule, and adjust
the template indentation (change the indent pipe argument as needed) so the
"filters:" key and its contents align exactly with the "matches:" and
"backendRefs:" keys.
🧹 Nitpick comments (1)
all-in-one/templates/am/wso2am-gateway-api-gw-httproute.yaml (1)
12-21: Consider adding labels support for consistency with the Gateway resource.The Gateway resource template supports both
annotationsandlabelsin metadata, but this HTTPRoute template only includesannotations. For consistency and flexibility, consider adding labels support.Suggested change to add labels support
{{- if .Values.kubernetes.gatewayAPI.gateway.annotations }} annotations: {{ toYaml .Values.kubernetes.gatewayAPI.gateway.annotations | indent 4 }} {{- end }} +{{- if .Values.kubernetes.gatewayAPI.gateway.labels }} + labels: +{{ toYaml .Values.kubernetes.gatewayAPI.gateway.labels | indent 4 }} +{{- end }}Note: The YAMLlint error at line 12 is a false positive—static analyzers don't recognize Helm templating syntax.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
all-in-one/templates/am/wso2am-gateway-api-backend-tls-policy.yamlall-in-one/templates/am/wso2am-gateway-api-gateway.yamlall-in-one/templates/am/wso2am-gateway-api-gw-httproute.yamlall-in-one/templates/am/wso2am-gateway-api-management-httproute.yamlall-in-one/templates/am/wso2am-gateway-api-websocket-httproute.yamlall-in-one/templates/am/wso2am-gateway-api-websub-httproute.yamlall-in-one/values.yaml
🧰 Additional context used
🪛 YAMLlint (1.37.1)
all-in-one/templates/am/wso2am-gateway-api-websub-httproute.yaml
[error] 12-12: syntax error: expected the node content, but found '-'
(syntax)
all-in-one/templates/am/wso2am-gateway-api-management-httproute.yaml
[error] 12-12: syntax error: expected the node content, but found '-'
(syntax)
all-in-one/templates/am/wso2am-gateway-api-gateway.yaml
[error] 12-12: syntax error: expected the node content, but found '-'
(syntax)
all-in-one/templates/am/wso2am-gateway-api-gw-httproute.yaml
[error] 12-12: syntax error: expected the node content, but found '-'
(syntax)
all-in-one/templates/am/wso2am-gateway-api-backend-tls-policy.yaml
[error] 12-12: syntax error: expected the node content, but found '-'
(syntax)
all-in-one/templates/am/wso2am-gateway-api-websocket-httproute.yaml
[error] 12-12: syntax error: expected the node content, but found '-'
(syntax)
🔇 Additional comments (5)
all-in-one/templates/am/wso2am-gateway-api-backend-tls-policy.yaml (1)
12-29: BackendTLSPolicy structure looks correct for alpha API.The resource structure follows the Gateway API v1alpha3 BackendTLSPolicy spec correctly with proper targetRefs and validation configuration.
all-in-one/templates/am/wso2am-gateway-api-management-httproute.yaml (1)
12-35: HTTPRoute structure for management endpoint is correct.The template properly gates rendering on both
gatewayAPI.enabledandmanagement.enabled, correctly references the gateway parent withsectionName: management-https, and targets the appropriate backend port 9443.all-in-one/templates/am/wso2am-gateway-api-websub-httproute.yaml (1)
23-25: Gateway listener "websub-https" is correctly defined.The HTTPRoute's parentRefs sectionName "websub-https" matches the listener defined in the Gateway template (wso2am-gateway-api-gateway.yaml:72). The alignment is correct and no changes are needed.
all-in-one/templates/am/wso2am-gateway-api-gateway.yaml (1)
29-84: Listener definitions are well-structured.The conditional rendering of each listener and TLS configuration follows Gateway API conventions. The YAMLlint error at line 12 is a false positive—static analyzers don't recognize Helm templating syntax (
{{-), but the rendered YAML will be valid.all-in-one/templates/am/wso2am-gateway-api-gw-httproute.yaml (1)
22-39: HTTPRoute spec is correctly structured.The
parentRefscorrectly references the Gateway with the matchingsectionName, and the routing rule with path prefix/will route all traffic to the backend service. The conditionalfiltersblock withindent 4produces correct YAML indentation.
✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.
| caCertificateRefs: | ||
| - name: {{ .Values.kubernetes.gatewayAPI.backendTLSPolicy.caCertificateSecret }} | ||
| group: "" | ||
| kind: Secret |
There was a problem hiding this comment.
Empty caCertificateSecret will create invalid BackendTLSPolicy.
If backendTLSPolicy.enabled is true but caCertificateSecret is not set (empty string), the rendered manifest will have an empty secret name, causing deployment failures.
Proposed fix - add validation
-{{- if and .Values.kubernetes.gatewayAPI.enabled .Values.kubernetes.gatewayAPI.backendTLSPolicy.enabled }}
+{{- if and .Values.kubernetes.gatewayAPI.enabled .Values.kubernetes.gatewayAPI.backendTLSPolicy.enabled .Values.kubernetes.gatewayAPI.backendTLSPolicy.caCertificateSecret }}
apiVersion: gateway.networking.k8s.io/v1alpha3
kind: BackendTLSPolicyAlternatively, use required function to provide a clear error message:
{{- if and .Values.kubernetes.gatewayAPI.enabled .Values.kubernetes.gatewayAPI.backendTLSPolicy.enabled }}
{{- $caCertSecret := required "kubernetes.gatewayAPI.backendTLSPolicy.caCertificateSecret is required when backendTLSPolicy is enabled" .Values.kubernetes.gatewayAPI.backendTLSPolicy.caCertificateSecret }}🤖 Prompt for AI Agents
In `@all-in-one/templates/am/wso2am-gateway-api-backend-tls-policy.yaml` around
lines 24 - 27, The BackendTLSPolicy template currently renders an empty
caCertificateRefs entry when
.Values.kubernetes.gatewayAPI.backendTLSPolicy.caCertificateSecret is an empty
string; add validation so that when .Values.kubernetes.gatewayAPI.enabled and
.Values.kubernetes.gatewayAPI.backendTLSPolicy.enabled are true you call
required (or otherwise assert) on
.Values.kubernetes.gatewayAPI.backendTLSPolicy.caCertificateSecret to fail the
render with a clear error message, and only render the caCertificateRefs block
if that required value is present; reference the variables
.Values.kubernetes.gatewayAPI.backendTLSPolicy.caCertificateSecret and the
template logic that builds caCertificateRefs to implement this check.
| {{- if .Values.kubernetes.gatewayAPI.enabled }} | ||
| apiVersion: gateway.networking.k8s.io/v1 | ||
| kind: Gateway | ||
| metadata: | ||
| name: {{ template "am-all-in-one.fullname" . }}-gateway | ||
| namespace: {{ .Release.Namespace }} | ||
| {{- if .Values.kubernetes.gatewayAPI.annotations }} | ||
| annotations: | ||
| {{ toYaml .Values.kubernetes.gatewayAPI.annotations | indent 4 }} | ||
| {{- end }} | ||
| {{- if .Values.kubernetes.gatewayAPI.labels }} | ||
| labels: | ||
| {{ toYaml .Values.kubernetes.gatewayAPI.labels | indent 4 }} | ||
| {{- end }} | ||
| spec: | ||
| gatewayClassName: {{ .Values.kubernetes.gatewayAPI.gatewayClassName }} | ||
| listeners: |
There was a problem hiding this comment.
Gateway may render with empty listeners array causing validation failure.
If kubernetes.gatewayAPI.enabled is true but all four listener flags (management.enabled, gateway.enabled, websocket.enabled, websub.enabled) are false, the Gateway resource will be created with an empty listeners: array. The Gateway API specification requires at least one listener, and Kubernetes will reject this resource.
Consider adding a validation check or requiring at least one listener to be enabled when the Gateway API feature is enabled.
Suggested approach: Add a validation guard
-{{- if .Values.kubernetes.gatewayAPI.enabled }}
+{{- if and .Values.kubernetes.gatewayAPI.enabled (or .Values.kubernetes.gatewayAPI.management.enabled .Values.kubernetes.gatewayAPI.gateway.enabled .Values.kubernetes.gatewayAPI.websocket.enabled .Values.kubernetes.gatewayAPI.websub.enabled) }}Alternatively, add a fail template function to provide a clear error message when the configuration is invalid.
🧰 Tools
🪛 YAMLlint (1.37.1)
[error] 12-12: syntax error: expected the node content, but found '-'
(syntax)
| {{- if .Values.kubernetes.gatewayAPI.management.filters }} | ||
| filters: | ||
| {{ toYaml .Values.kubernetes.gatewayAPI.management.filters | indent 4 }} | ||
| {{- end }} |
There was a problem hiding this comment.
Same incorrect indentation for filters block.
The filters field has the same indentation issue as other HTTPRoute templates. It should use indent 6 to be properly aligned as a sibling of matches and backendRefs.
Proposed fix
{{- if .Values.kubernetes.gatewayAPI.management.filters }}
filters:
-{{ toYaml .Values.kubernetes.gatewayAPI.management.filters | indent 4 }}
+{{ toYaml .Values.kubernetes.gatewayAPI.management.filters | indent 6 }}
{{- end }}🤖 Prompt for AI Agents
In `@all-in-one/templates/am/wso2am-gateway-api-management-httproute.yaml` around
lines 36 - 39, The filters block is mis-indented causing it not to align with
sibling fields (matches, backendRefs); update the template that renders {{
toYaml .Values.kubernetes.gatewayAPI.management.filters }} so it uses indent 6
instead of indent 4 (i.e., change the indent call for the filters block in the
HTTPRoute template) so the filters field becomes a proper sibling of matches and
backendRefs.
| {{- if and .Values.kubernetes.gatewayAPI.enabled .Values.kubernetes.gatewayAPI.websocket.enabled }} | ||
| apiVersion: gateway.networking.k8s.io/v1 | ||
| kind: HTTPRoute | ||
| metadata: | ||
| name: {{ template "am-all-in-one.fullname" . }}-websocket-httproute | ||
| namespace: {{ .Release.Namespace }} | ||
| {{- if .Values.kubernetes.gatewayAPI.websocket.annotations }} | ||
| annotations: | ||
| {{ toYaml .Values.kubernetes.gatewayAPI.websocket.annotations | indent 4 }} | ||
| {{- end }} | ||
| spec: | ||
| parentRefs: | ||
| - name: {{ template "am-all-in-one.fullname" . }}-gateway | ||
| sectionName: websocket-https | ||
| hostnames: | ||
| - {{ .Values.kubernetes.gatewayAPI.websocket.hostname }} | ||
| rules: | ||
| - matches: | ||
| - path: | ||
| type: PathPrefix | ||
| value: / | ||
| backendRefs: | ||
| - name: {{ template "am-all-in-one.fullname" . }}-am-service | ||
| port: 8099 |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
Kubernetes Gateway API HTTPRoute WebSocket support upgrade
💡 Result:
Short answer: Gateway API supports WebSocket upgrades when the backend Service port signals WebSocket via appProtocol (kubernetes.io/ws or kubernetes.io/wss). If an HTTPRoute backendRef points to a Service port with that appProtocol, implementations conformant with Gateway API v1.2+ will automatically perform the Upgrade to WebSocket. [1][2]
Example (Service port indicates ws):
apiVersion: v1
kind: Service
spec:
ports:
- name: http
port: 80
appProtocol: kubernetes.io/ws
Then an HTTPRoute referencing that Service backend will be upgraded to WebSocket by conformant controllers. [1]
References:
[1] Kubernetes Blog — Gateway API v1.2 (WebSockets support).
[2] Kubernetes docs/blog (Gateway API v1.2 release notes / v1.2 docs).
WebSocket HTTPRoute requires Service port appProtocol configuration.
The HTTPRoute structure itself is correct, but WebSocket support in Gateway API v1.2+ depends critically on the backend Service port declaring appProtocol: kubernetes.io/ws or kubernetes.io/wss. Without this, Gateway API implementations will not upgrade HTTP connections to WebSocket, and WebSocket traffic will fail.
Verify that the am-service Service port (8099) includes the appropriate appProtocol field:
apiVersion: v1
kind: Service
spec:
ports:
- name: http
port: 8099
appProtocol: kubernetes.io/ws # or kubernetes.io/wss if TLSWithout this Service configuration, the HTTPRoute alone cannot enable WebSocket upgrades.
🧰 Tools
🪛 YAMLlint (1.37.1)
[error] 12-12: syntax error: expected the node content, but found '-'
(syntax)
🤖 Prompt for AI Agents
In `@all-in-one/templates/am/wso2am-gateway-api-websocket-httproute.yaml` around
lines 12 - 35, The HTTPRoute for websocket is fine but the backend Service must
declare an appProtocol for WebSocket; update the Service named "{{ template
\"am-all-in-one.fullname\" . }}-am-service" (the Service that exposes port 8099)
to add appProtocol: kubernetes.io/ws (or kubernetes.io/wss if TLS) on the port
definition so Gateway API v1.2+ can perform WebSocket upgrades; ensure the port
entry that references 8099 includes the appProtocol field and keep the port
name/number consistent with the HTTPRoute backendRef.
| {{- if .Values.kubernetes.gatewayAPI.websocket.filters }} | ||
| filters: | ||
| {{ toYaml .Values.kubernetes.gatewayAPI.websocket.filters | indent 4 }} | ||
| {{- end }} |
There was a problem hiding this comment.
Same incorrect indentation for filters block.
Consistent with other HTTPRoute templates, the filters field needs indent 6 instead of indent 4.
Proposed fix
{{- if .Values.kubernetes.gatewayAPI.websocket.filters }}
filters:
-{{ toYaml .Values.kubernetes.gatewayAPI.websocket.filters | indent 4 }}
+{{ toYaml .Values.kubernetes.gatewayAPI.websocket.filters | indent 6 }}
{{- end }}📝 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.
| {{- if .Values.kubernetes.gatewayAPI.websocket.filters }} | |
| filters: | |
| {{ toYaml .Values.kubernetes.gatewayAPI.websocket.filters | indent 4 }} | |
| {{- end }} | |
| {{- if .Values.kubernetes.gatewayAPI.websocket.filters }} | |
| filters: | |
| {{ toYaml .Values.kubernetes.gatewayAPI.websocket.filters | indent 6 }} | |
| {{- end }} |
🤖 Prompt for AI Agents
In `@all-in-one/templates/am/wso2am-gateway-api-websocket-httproute.yaml` around
lines 36 - 39, The filters block in the WebSocket HTTPRoute template uses the
wrong indentation; update the template code that checks
.Values.kubernetes.gatewayAPI.websocket.filters and renders "filters:" with the
subsequent YAML produced by toYaml
.Values.kubernetes.gatewayAPI.websocket.filters to use indent 6 instead of
indent 4 so the "filters" field aligns consistently with other HTTPRoute
templates.
| {{- if .Values.kubernetes.gatewayAPI.websub.filters }} | ||
| filters: | ||
| {{ toYaml .Values.kubernetes.gatewayAPI.websub.filters | indent 4 }} | ||
| {{- end }} |
There was a problem hiding this comment.
Incorrect indentation for filters block.
The filters field should be a sibling of matches and backendRefs under the rule, not nested under backendRefs. The current indent 4 places it at the wrong YAML level.
Proposed fix
backendRefs:
- name: {{ template "am-all-in-one.fullname" . }}-am-service
port: 8021
{{- if .Values.kubernetes.gatewayAPI.websub.filters }}
filters:
-{{ toYaml .Values.kubernetes.gatewayAPI.websub.filters | indent 4 }}
+{{ toYaml .Values.kubernetes.gatewayAPI.websub.filters | indent 6 }}
{{- end }}📝 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.
| {{- if .Values.kubernetes.gatewayAPI.websub.filters }} | |
| filters: | |
| {{ toYaml .Values.kubernetes.gatewayAPI.websub.filters | indent 4 }} | |
| {{- end }} | |
| {{- if .Values.kubernetes.gatewayAPI.websub.filters }} | |
| filters: | |
| {{ toYaml .Values.kubernetes.gatewayAPI.websub.filters | indent 6 }} | |
| {{- end }} |
🤖 Prompt for AI Agents
In `@all-in-one/templates/am/wso2am-gateway-api-websub-httproute.yaml` around
lines 36 - 39, The filters block is currently nested under backendRefs; move the
entire filters block (the "filters:" line and the templated content from
.Values.kubernetes.gatewayAPI.websub.filters) out of the backendRefs scope so it
is a sibling of "matches" and "backendRefs" within the rule, and adjust the
template indentation (change the indent pipe argument as needed) so the
"filters:" key and its contents align exactly with the "matches:" and
"backendRefs:" keys.
| # -- Kubernetes Gateway API configurations (alternative to Ingress) | ||
| # Requires Gateway API CRDs to be installed in the cluster | ||
| # https://gateway-api.sigs.k8s.io/ | ||
| gatewayAPI: | ||
| # -- Enable Gateway API resources | ||
| enabled: false | ||
| # -- Gateway class name (e.g., istio, nginx, contour, envoy-gateway, gke-l7-global-external-managed) | ||
| gatewayClassName: "istio" | ||
| # -- Kubernetes secret created for Gateway TLS | ||
| tlsSecret: "" | ||
| # -- Gateway annotations | ||
| annotations: {} | ||
| # -- Gateway labels | ||
| labels: {} | ||
| management: | ||
| # -- Enable HTTPRoute for Management Console, Publisher, DevPortal and Admin Portal | ||
| enabled: true | ||
| # -- Hostname for API Manager Management interfaces | ||
| hostname: "am.wso2.com" | ||
| # -- HTTPRoute annotations | ||
| annotations: {} | ||
| # -- HTTPRoute filters (optional) | ||
| # filters: | ||
| # - type: RequestHeaderModifier | ||
| # requestHeaderModifier: | ||
| # add: | ||
| # - name: X-Custom-Header | ||
| # value: "custom-value" | ||
| filters: [] | ||
| gateway: | ||
| # -- Enable HTTPRoute for Gateway pass-through | ||
| enabled: true | ||
| # -- Hostname for Gateway pass-through | ||
| hostname: "gw.wso2.com" | ||
| # -- HTTPRoute annotations | ||
| annotations: {} | ||
| # -- HTTPRoute filters (optional) | ||
| filters: [] | ||
| websocket: | ||
| # -- Enable HTTPRoute for Websocket | ||
| enabled: true | ||
| # -- Hostname for Websocket | ||
| hostname: "websocket.wso2.com" | ||
| # -- HTTPRoute annotations | ||
| annotations: {} | ||
| # -- HTTPRoute filters (optional) | ||
| filters: [] | ||
| websub: | ||
| # -- Enable HTTPRoute for Websub | ||
| enabled: true | ||
| # -- Hostname for Websub | ||
| hostname: "websub.wso2.com" | ||
| # -- HTTPRoute annotations | ||
| annotations: {} | ||
| # -- HTTPRoute filters (optional) | ||
| filters: [] | ||
| # -- Backend TLS Policy for HTTPS backend connections (alpha feature) | ||
| backendTLSPolicy: | ||
| # -- Enable BackendTLSPolicy | ||
| enabled: false | ||
| # -- CA certificate secret name for backend TLS verification | ||
| caCertificateSecret: "" | ||
| # -- Backend hostname for TLS verification | ||
| hostname: "localhost" |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, verify the exact content at lines 220-283 in the values.yaml file
sed -n '220,283p' all-in-one/values.yamlRepository: wso2/helm-apim
Length of output: 2216
🏁 Script executed:
# Check if there's any validation logic in templates for required fields
rg -n "required|fail|error" all-in-one/templates/ --type yaml -C 2 | head -100Repository: wso2/helm-apim
Length of output: 5879
🏁 Script executed:
# Search for how backendTLSPolicy is used in templates
rg -n "backendTLSPolicy" all-in-one/templates/ -C 3Repository: wso2/helm-apim
Length of output: 1717
🏁 Script executed:
# Check for any validation or conditional logic around caCertificateSecret
rg -n "caCertificateSecret" all-in-one/templates/ -C 3Repository: wso2/helm-apim
Length of output: 865
Add validation for required backendTLSPolicy field.
The configuration is well-structured and aligns with existing patterns. However, there's a gap in validation:
If backendTLSPolicy.enabled is set to true without providing a caCertificateSecret, the template renders an invalid Kubernetes resource with an empty secret name reference (line 25 in wso2am-gateway-api-backend-tls-policy.yaml).
Similar to the validation patterns already present in route templates (which use fail directives), add a validation check in the template to ensure caCertificateSecret is not empty when backendTLSPolicy.enabled is true. Alternatively, document this as a required field.
Purpose
Support Gateway API
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.