Skip to content

v0.3.7 patch release#369

Open
thomasmaas wants to merge 11 commits intorelease-v0.3from
patch-v0.3.7
Open

v0.3.7 patch release#369
thomasmaas wants to merge 11 commits intorelease-v0.3from
patch-v0.3.7

Conversation

@thomasmaas
Copy link
Copy Markdown
Contributor

@thomasmaas thomasmaas commented Apr 15, 2026

Summary

Patch release v0.3.7 — cherry-picked fixes from main onto release-v0.3 (branched from v0.3.6).

Once merged, tag v0.3.7 from release-v0.3.

Bug fixes

Security

Platform support

Cherry-pick conflict resolutions

  • Fix metrics #329: kuadrant-dev-setup/ files (from kuadrant dev setup #330) don't exist on the release branch — removed from cherry-pick
  • Gh 298 #352: Two KuadrantOverviewPage.tsx hunks — took incoming watchNamespace + emptyResourceName typo fix over #ALL_NS# + emtpyResourceName

Not included (deferred to v0.4.0)

Test plan

  • Verify console plugin loads correctly on OCP 4.20 and 4.21
  • Verify overview page renders in both cluster-scoped and namespace-scoped modes
  • Verify policies page does not auto-refresh every 20 seconds
  • Verify metrics/observability section loads correctly
  • Verify navigation works without useHistory deprecation warnings
  • Verify i18n keys resolve for all UI strings
  • Run e2e tests against the built image

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

New Features

  • Namespace-scoped overview page with intelligent redirect for namespace-scoped users
  • Namespace picker to switch between cluster-wide and namespace-specific views
  • Configurable Topology and Prometheus metrics for gateway traffic monitoring

Chores

  • Version bump to 0.3.7
  • Multi-architecture support added (amd64, arm64, s390x)
  • Dependency updates for security
  • Documentation links updated for Connectivity Link integration

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 15, 2026

📝 Walkthrough

Walkthrough

This PR introduces namespace-scoped Overview page functionality with smart RBAC-based routing, refactors CI/CD pipelines to use Docker multi-platform builds, adds configuration and metrics query utilities, and migrates React Router navigation patterns to v5-compat, with comprehensive e2e test coverage for namespace-aware access patterns.

Changes

Cohort / File(s) Summary
CI/CD Pipeline Modernisation
.github/workflows/dev-build.yaml, .github/workflows/release-build.yaml
Replaced Buildah matrix-based build with Docker multi-platform build-push actions; added s390x architecture support alongside existing amd64/arm64; refactored registry authentication and image tagging via Docker's login and metadata actions.
Configuration Management
charts/openshift-console-plugin/values.yaml, charts/openshift-console-plugin/templates/deployment.yaml, kuadrant-dev-setup/cluster-monitoring.yaml, install.yaml, entrypoint.sh
Added three new runtime configuration variables (TOPOLOGY_CONFIGMAP_NAME, TOPOLOGY_CONFIGMAP_NAMESPACE, METRICS_WORKLOAD_SUFFIX) to Helm values, Deployment templates, and entry point defaults; introduced cluster-monitoring-config ConfigMap for user workload monitoring enablement.
Configuration & Metrics Utilities
src/utils/configLoader.ts, src/utils/metricsQueries.ts, src/utils/topology/configLoader.ts
Consolidated configuration loading into new configLoader.ts with KuadrantConfig interface; added PromQL query builders (buildTotalRequestsQuery, buildErrorRequestQuery, buildErrorsByCodeQuery) with namespace filtering support; removed duplicate legacy topology/configLoader.ts.
Routing & Navigation Updates
src/components/DropdownWithKebab.tsx, src/components/KuadrantDNSPolicyCreatePage.tsx, src/components/KuadrantTLSCreatePage.tsx, src/components/dnspolicy/useDNSPolicyActions.tsx, src/components/tlspolicy/useTLSPolicyActions.tsx, src/utils/cancel.tsx
Migrated from React Router v5 useHistory/history.push() to v5-compat useNavigate/navigate() for consistent navigation patterns; updated handleCancel to use navigate(-1) instead of history.goBack().
React Router Import Updates
src/components/GatewayPoliciesPage.tsx, src/components/HTTPRoutePoliciesPage.tsx, src/components/PolicyTopologyPage.tsx
Changed useLocation imports from react-router-dom to react-router-dom-v5-compat for compatibility consistency.
Namespace-Scoped Overview Page
src/components/KuadrantOverviewPage.tsx
Implemented smart default RBAC-based redirect from /kuadrant/overview to /kuadrant/ns/<namespace>/overview for namespace-scoped users; added dynamic watchNamespace derivation from URL parameters; integrated configuration and metrics utilities with namespace filtering; added NamespaceBar component for namespace selection; updated resource watches to use filtered namespace; added cluster version detection for operator link generation.
Policy Page Context & Refactoring
src/components/KuadrantPoliciesPage.tsx, src/components/KuadrantCreateUpdate.tsx
Introduced PolicyPageContext for shared tab component data; refactored per-tab inline definitions to stable components; improved error handling with typed exceptions; updated from template strings to interpolated i18n keys for policy-type-dependent messages; migrated to useNavigate pattern.
Status Alert & Localisation
src/components/KuadrantStatusAlert.tsx, locales/en/plugin__kuadrant-console-plugin.json
Removed unnecessary i18n translation of runtime Kubernetes data in tooltips; added new i18n keys for dynamic policy-type strings with {{policyType}} interpolation.
Operator Link Versioning
src/constants/links.ts
Enhanced certManagerOperator function to accept clusterVersion parameter and generate version-specific operator hub URLs (pre-4.20 vs 4.20+).
Route Configuration
console-extensions.json
Added new namespace-scoped route mapping /kuadrant/ns/:ns/overview to KuadrantOverviewPage component.
Package & Version Updates
package.json, downstream.js
Bumped plugin version from 0.3.6 to 0.3.7; updated lodash resolution to 4.18.0 and pinned immutable to 3.8.3; updated Red Hat Connectivity Link documentation URL mappings.
Documentation & Design
CLAUDE.md, docs/designs/2026-03-27-namespace-scoped-overview-design.md
Added configuration section documenting topology and metrics support with environment variable examples; introduced comprehensive design document specifying namespace-scoped overview routing, RBAC flows, namespace-change handling, metrics filtering, and UX scenarios.
E2E Test Coverage
e2e/tests/rbac.spec.ts
Expanded test suite to verify cluster-wide vs namespace-scoped routing behaviour; added namespace-specific access tests for test-viewer and test-devops personas; verified redirect flows for namespace-scoped users and namespace picker integration.

Sequence Diagram(s)

sequenceDiagram
    actor User as Namespace-Scoped User
    participant Browser
    participant Component as KuadrantOverviewPage
    participant K8sAPI as Kubernetes API
    participant AuthChecker as Access Checker
    participant Config as Config Loader
    participant Prometheus
    
    User->>Browser: Navigate to /kuadrant/overview
    Browser->>Component: Mount component
    Component->>Config: fetchConfig()
    Config-->>Component: KuadrantConfig (namespace, metrics suffix)
    Component->>AuthChecker: checkAccess(gateways/list, undefined)
    AuthChecker->>K8sAPI: Check cluster-wide permission
    K8sAPI-->>AuthChecker: Permission denied
    AuthChecker-->>Component: isAllowed = false
    Component->>Browser: navigate(/kuadrant/ns/default/overview)
    Browser->>Component: Re-mount with ns param
    Component->>Component: watchNamespace = 'default'
    Component->>K8sAPI: Watch Gateways in 'default' namespace
    K8sAPI-->>Component: Gateway resources (scoped)
    Component->>Prometheus: buildTotalRequestsQuery('default')
    Prometheus-->>Component: Metrics data (filtered)
    Component->>Browser: Render overview (namespace-scoped)
    User->>Browser: Select different namespace (kuadrant-test)
    Browser->>Component: handleNamespaceChange('kuadrant-test')
    Component->>Browser: navigate(/kuadrant/ns/kuadrant-test/overview)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

  • Gh 298 #352: Overlapping changes to console routing logic, namespace-scoped overview implementation, metrics query utilities, and related e2e RBAC test patterns.

Suggested reviewers

  • eguzki
  • R-Lawton

🐰 A namespace-scoped warren, where each burrow now knows its place,
Smart redirects hop users to their rightful space,
Metrics filter by den, and permissions check fast,
React Router hops onward—v5-compat at last! 🌿✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately summarises the primary purpose: a patch release (v0.3.7) with version bump and multiple bug fixes. It is clear, concise, and directly reflects the main objective.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch patch-v0.3.7

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.

@thomasmaas
Copy link
Copy Markdown
Contributor Author

I think this might be the first cherry picked release of console plugin, at least since 0.3, every v0.3.x release was tagged directly on main. Looking at how kuadrant-operator does it: one branch per minor (release-v1.4), and patch releases are PRs into that branch. So I created a release-v0.3 branch, meant to be the long-lived branch for all 0.3.x patches.

Let me know if that makes sense and if you agree.

jasonmadigan and others added 11 commits April 16, 2026 09:54
Bump ajv from 6.12.6 to 6.14.0

Signed-off-by: Thomas Maas <thomas@webtypes.com>
Compatible Navigation with OpenShift Console plugin

Signed-off-by: Thomas Maas <thomas@webtypes.com>
…-the-connectivity-link-release-notes-and-cert-manager-operator-pages-under-getting-started-resources-are-not-found

324 on ocp versions 420 and 421 the connectivity link release notes and cert manager operator pages under getting started resources are not found

Signed-off-by: Thomas Maas <thomas@webtypes.com>
dev image build: latest and git sha tag sharing digest

Signed-off-by: Thomas Maas <thomas@webtypes.com>
…ility

image build add s390x to dev and release multi arch builds

Signed-off-by: Thomas Maas <thomas@webtypes.com>
Fix metrics

Signed-off-by: Thomas Maas <thomas@webtypes.com>
🔨 🔧 KuadrantPoliciesPage.tsx: fix page refresh

Signed-off-by: Thomas Maas <thomas@webtypes.com>
missing i18n keys

Signed-off-by: Thomas Maas <thomas@webtypes.com>
chore(deps): fix CVE-2026-4800 (lodash) and CVE-2026-29063 (immutable)

Signed-off-by: Thomas Maas <thomas@webtypes.com>
Gh 298

Signed-off-by: Thomas Maas <thomas@webtypes.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Thomas Maas <thomas@webtypes.com>
@eguzki
Copy link
Copy Markdown
Collaborator

eguzki commented Apr 16, 2026

there is a little technical issue here. You cherry-picked "Merge pull request" commits to the patch branch and those are not signed off, so the DCO check is failing.

@eguzki
Copy link
Copy Markdown
Collaborator

eguzki commented Apr 16, 2026

I think this might be the first cherry picked release of console plugin, at least since 0.3, every v0.3.x release was tagged directly on main. Looking at how kuadrant-operator does it: one branch per minor (release-v1.4), and patch releases are PRs into that branch. So I created a release-v0.3 branch, meant to be the long-lived branch for all 0.3.x patches.

Let me know if that makes sense and if you agree.

I am more in favor of moving forward to the next minor release (v0.4.0) than keeping the release-v0.3 branch for the console plugin. The kuadrant operator represents a full product and should maintain minor release branches. However, for dependencies, like the console plugin, moving forward seems easier to manage. Anyway, it's not a big deal to me. You are cherry-picking, which is fine and the next minor release will contain those fixes as well.

Copy link
Copy Markdown
Contributor Author

@thomasmaas thomasmaas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cherry-pick conflict resolutions

Two cherry-picks had merge conflicts. Here's how they were resolved:

1. PR #329 (Fix metrics) — kuadrant-dev-setup/ files

Three files (kuadrant-dev-setup/Makefile, kuadrant-dev-setup/kuadrant/kuadrant-instance.yaml, kuadrant-dev-setup/kuadrant/subscription.yaml) were modified by #329 but don't exist on the release branch — they were introduced by #330 (kuadrant dev setup), which is not included in this patch. Resolution: removed the conflicting files. The kuadrant-dev-setup/cluster-monitoring.yaml file from #329 was kept as it's a new file.

2. PR #352 (Namespace-scoped overview) — src/components/KuadrantOverviewPage.tsx

Two identical conflicts at the ResourceList components for Gateways (line ~993) and HTTPRoutes (line ~1143):

  • HEAD had: namespace="#ALL_NS#" and emtpyResourceName (typo)
  • Incoming had: namespace={watchNamespace} and emptyResourceName (typo fixed)

Resolution: took the incoming version in both cases — watchNamespace is the whole point of #352 (namespace scoping), and emptyResourceName is the correct spelling.

@thomasmaas
Copy link
Copy Markdown
Contributor Author

thomasmaas commented Apr 16, 2026

@eguzki I see how for a single active minor, tagging from main is simpler but we're moving to a place where we will need to do patch releases on multiple minors. Eg once kuadrant-operator v1.5.0 ships with console-plugin v0.4.x, any CVE or bug fix needed in v1.4.x requires a console-plugin v0.3.x patch. Plus it would be nice to have all repo's behave the same when it comes to releases; less surprises.

@thomasmaas
Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 16, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown

@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: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
src/components/dnspolicy/useDNSPolicyActions.tsx (1)

86-86: ⚠️ Potential issue | 🔴 Critical

Replace undefined history with navigate in dependencies.

Line 86 references history in the dependency array, but history is not imported. The component uses navigate from the useNavigate hook (line 18) for route navigation (lines 71–73), so navigate should be in the dependencies instead.

Fix
-  }, [history, obj, dnsPolicyModel, launchAnnotationsModal, launchDeleteModal, launchLabelsModal]);
+  }, [navigate, obj, dnsPolicyModel, launchAnnotationsModal, launchDeleteModal, launchLabelsModal]);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/dnspolicy/useDNSPolicyActions.tsx` at line 86, The dependency
array for the hook includes an undefined symbol `history`; replace it with the
`navigate` function returned by `useNavigate` so React correctly tracks changes
— locate the hook whose dependency array contains `history` (in
src/components/dnspolicy/useDNSPolicyActions.tsx) and update the dependencies to
include `navigate` (the value from `useNavigate`) instead of `history`; ensure
any references inside the effect/callback use the `navigate` identifier so
ESLint/react-hooks no longer warn.
src/components/tlspolicy/useTLSPolicyActions.tsx (1)

86-86: ⚠️ Potential issue | 🔴 Critical

Replace undefined history dependency with navigate.

Line 86 references history in the dependency array, but this variable is never imported or defined. The function uses navigate (from useNavigate hook) at lines 71–73, so navigate must be included in the dependencies instead.

Proposed fix
-  }, [history, obj, tlsPolicyModel, launchAnnotationsModal, launchDeleteModal, launchLabelsModal]);
+  }, [navigate, obj, tlsPolicyModel, launchAnnotationsModal, launchDeleteModal, launchLabelsModal]);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/tlspolicy/useTLSPolicyActions.tsx` at line 86, The dependency
array for the effect in useTLSPolicyActions incorrectly lists an undefined
symbol history; replace history with the actual navigate function from the
useNavigate hook: update the dependency array in the effect that references
navigate (in useTLSPolicyActions) to include navigate instead of history,
ensuring the effect lists navigate, obj, tlsPolicyModel, launchAnnotationsModal,
launchDeleteModal, and launchLabelsModal so React's hook dependencies are
accurate.
src/components/KuadrantPoliciesPage.tsx (1)

399-402: ⚠️ Potential issue | 🟠 Major

Hooks called inside a loop – Rules of Hooks violation.

useResourceRBAC calls useAccessReview at the top level, but useResourceRBAC itself is invoked inside a reduce callback at lines 399–402. React hooks cannot be called from within callbacks, loops, or conditions. Although policyKinds is currently stable (derived from a constant RESOURCES registry), this pattern violates React's Rules of Hooks and is fragile. If code changes in the future to alter the number of policy kinds dynamically, this will cause runtime errors.

Call useResourceRBAC at the component's top level for each known policy kind, or refactor to extract the hook calls into a separate custom hook that doesn't depend on a dynamic array length.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/KuadrantPoliciesPage.tsx` around lines 399 - 402, The current
implementation calls useResourceRBAC inside a reduce over policyKinds which
violates the Rules of Hooks (useResourceRBAC calls useAccessReview), so refactor
so hook calls are at the component top level: either explicitly call
useResourceRBAC once per known policy kind (e.g., call
useResourceRBAC(PolicyKindA, nsForCheck), useResourceRBAC(PolicyKindB,
nsForCheck), etc.) and assemble resourceRBAC from those results, or create a new
custom hook (e.g., useResourceRBACMap) that internally calls useAccessReview a
fixed number of times for each known entry in RESOURCES and returns the RBACMap;
ensure the number and order of hook calls is constant and no hooks are invoked
inside loops or callbacks.
🧹 Nitpick comments (4)
src/utils/configLoader.ts (1)

32-34: Acknowledge static analysis warning — trusted source context.

The static analysis flagged the innerHTML assignment as a potential XSS vector. In this case, the script is fetched from /api/plugins/kuadrant-console-plugin/config.js, which is a same-origin, deployment-controlled resource generated by entrypoint.sh from environment variables—not user input.

While the current implementation is safe given the trusted source, consider using a safer alternative for future maintainability:

🔧 Optional: Use script.src instead of innerHTML
-    const script = await response.text();
-
-    const configScript = document.createElement('script');
-    configScript.innerHTML = script;
-    document.head.appendChild(configScript);
+    // Create script element with src attribute instead of innerHTML
+    const configScript = document.createElement('script');
+    configScript.src = '/api/plugins/kuadrant-console-plugin/config.js';
+    
+    await new Promise<void>((resolve, reject) => {
+      configScript.onload = () => resolve();
+      configScript.onerror = () => reject(new Error('Failed to load config.js'));
+      document.head.appendChild(configScript);
+    });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/utils/configLoader.ts` around lines 32 - 34, The static analyzer warns
about assigning to configScript.innerHTML (created via
document.createElement('script')) as a potential XSS; since the script comes
from a trusted same‑origin endpoint, you can eliminate the warning and be safer
for future changes by loading it via a src URL instead of injecting raw HTML:
replace the configScript.innerHTML = script assignment with setting
configScript.src to the trusted endpoint
('/api/plugins/kuadrant-console-plugin/config.js'), attach onload/onerror
handlers if needed, and then document.head.appendChild(configScript) (adjust any
code that currently relies on the inline string).
e2e/tests/rbac.spec.ts (2)

500-504: Fixed timeout for stability check may be unnecessary.

The second URL assertion with waitForTimeout(2000) to verify "URL doesn't revert" could be replaced with a more targeted check or removed if the first assertion is sufficient.

♻️ Suggested improvement

If verifying URL stability is important, consider using page.waitForLoadState('networkidle') instead of a fixed timeout:

-    // verify URL doesn't revert back to cluster-wide view
-    await page.waitForTimeout(2000);
+    // verify URL remains stable after any async operations
+    await page.waitForLoadState('networkidle');
     await expect(page).toHaveURL('/kuadrant/ns/kuadrant-test/overview', {
       timeout: 5_000,
     });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@e2e/tests/rbac.spec.ts` around lines 500 - 504, The fixed 2s pause using
page.waitForTimeout(2000) followed by
expect(page).toHaveURL('/kuadrant/ns/kuadrant-test/overview') is unnecessary and
brittle; either remove the second stability check if the initial
expect(page).toHaveURL(...) already asserts the target URL, or replace the
waitForTimeout call with a targeted wait such as await
page.waitForLoadState('networkidle') before calling expect(page).toHaveURL to
ensure network/activity quiescence; update the code around page.waitForTimeout
and expect(page).toHaveURL accordingly.

470-493: Consider replacing waitForTimeout with explicit waits.

Using fixed timeouts (waitForTimeout(1000), waitForTimeout(2000)) can lead to flaky tests. Prefer waiting for specific conditions.

♻️ Suggested improvement
     // click to open dropdown
     await namespaceButton.click();
-    await page.waitForTimeout(1000);
+    // Wait for dropdown to be visible
+    await page.waitForSelector('[role="listbox"], [role="menu"], .pf-v6-c-menu', { state: 'visible' });

     // ... select namespace ...

     await namespaceOption.click();
-    await page.waitForTimeout(2000);
+    // Wait for navigation to complete
+    await page.waitForURL('/kuadrant/ns/kuadrant-test/overview', { timeout: 15_000 });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@e2e/tests/rbac.spec.ts` around lines 470 - 493, Replace the fixed sleeps
around namespace selection with explicit waits: after clicking namespaceButton,
wait for the dropdown/options to appear using a selector from
namespaceOptionSelectors via page.waitForSelector or await
page.locator(selector).waitFor({ state: 'visible' }); and before clicking
namespaceOption, wait for that specific locator's visibility or be enabled
(e.g., await namespaceOption.waitFor({ state: 'visible' }) or
waitForElementState('stable') ) instead of page.waitForTimeout(1000/2000); keep
the existing namespaceButton, namespaceOptionSelectors, namespaceOption
identifiers so the logic of choosing the first visible option remains the same.
src/components/KuadrantPoliciesPage.tsx (1)

481-485: Consider memoizing the context value.

The contextValue object is recreated on every render, which could cause unnecessary re-renders of context consumers. Consider using useMemo to stabilise the reference.

♻️ Suggested improvement
-  const contextValue = {
-    activeNamespace,
-    defaultColumns,
-    resourceRBAC,
-  };
+  const contextValue = React.useMemo(
+    () => ({
+      activeNamespace,
+      defaultColumns,
+      resourceRBAC,
+    }),
+    [activeNamespace, defaultColumns, resourceRBAC]
+  );
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/KuadrantPoliciesPage.tsx` around lines 481 - 485, The
contextValue object in KuadrantPoliciesPage (currently built from
activeNamespace, defaultColumns, resourceRBAC) is recreated every render causing
unnecessary context consumer updates; wrap its creation in React.useMemo and
return a memoized object keyed on [activeNamespace, defaultColumns,
resourceRBAC] so the reference is stable across renders—update the code that
declares contextValue to use useMemo inside the KuadrantPoliciesPage component.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/dev-build.yaml:
- Around line 27-32: The "Login to container registry" step currently uses
docker/login-action@v2 and runs unconditionally; change it to use
docker/login-action@v3 (or v4) and add the same guard as the build/push step
(if: github.repository_owner == 'kuadrant') so the login only runs for the
kuadrant repository and avoids failing on forks without registry secrets; update
the step reference (the step name "Login to container registry" and the action
reference docker/login-action@v2) accordingly.

In `@CLAUDE.md`:
- Line 96: Fix the minor typo in the sentence containing "Topology
andPrometheus" by inserting a space so it reads "Topology and Prometheus";
locate the sentence phrase "Topology andPrometheus metrics for gateway traffic
monitoring" and update it to "Topology and Prometheus metrics for gateway
traffic monitoring".

In `@entrypoint.sh`:
- Line 8: The fallback value for METRICS_WORKLOAD_SUFFIX is missing the leading
hyphen, causing inconsistent defaults; update the environment variable
assignment for METRICS_WORKLOAD_SUFFIX so its default value is
"-openshift-default" instead of "openshift-default" (i.e., change the assignment
that sets METRICS_WORKLOAD_SUFFIX:
'${METRICS_WORKLOAD_SUFFIX:-openshift-default}' to use the hyphen-prefixed
default), ensuring all runtime code that expects the "-openshift-default" suffix
receives the correct value.

In `@src/components/KuadrantOverviewPage.tsx`:
- Around line 973-975: The tooltip strings in KuadrantOverviewPage are
hard-coded (e.g. the Tooltip content "You do not have permission to create a
Gateway" used alongside resourceRBAC['Gateway']?.create and the similar strings
around the create Button with class kuadrant-overview-create-button); update the
component to use the useTranslation hook and replace those literal strings with
t('...') calls using new i18n keys (e.g. gateway.permission.create.tooltip),
then add the corresponding keys/translations to your i18n resource files so the
tooltips are localisable.
- Around line 551-566: The helpers getTotalRequests, getSuccessfulRequests and
getErrorRate treat 0 as missing because they rely on falsy checks; change them
to use explicit nullish handling: for getTotalRequests use const total =
totalRequestsByGateway[key]?.total ?? 0 and return Math.round(total); for
getSuccessfulRequests read const total = totalRequestsByGateway[key]?.total;
const errors = totalRequestsByGateway[key]?.errors ?? 0 and if total == null
return 0 (or preserve existing missing-vs-zero behavior by returning 0 when
total is null?), otherwise compute success = Math.round((total ?? 0) - errors);
for getErrorRate read const total = totalRequestsByGateway[key]?.total; const
errors = totalRequestsByGateway[key]?.errors; if total == null return '-';
otherwise compute rate = total === 0 ? 0 : (errors ?? 0) / total * 100 and
return rate.toFixed(1); apply the same nullish-based fixes to the corresponding
helpers/cells referenced around lines 688-707.

---

Outside diff comments:
In `@src/components/dnspolicy/useDNSPolicyActions.tsx`:
- Line 86: The dependency array for the hook includes an undefined symbol
`history`; replace it with the `navigate` function returned by `useNavigate` so
React correctly tracks changes — locate the hook whose dependency array contains
`history` (in src/components/dnspolicy/useDNSPolicyActions.tsx) and update the
dependencies to include `navigate` (the value from `useNavigate`) instead of
`history`; ensure any references inside the effect/callback use the `navigate`
identifier so ESLint/react-hooks no longer warn.

In `@src/components/KuadrantPoliciesPage.tsx`:
- Around line 399-402: The current implementation calls useResourceRBAC inside a
reduce over policyKinds which violates the Rules of Hooks (useResourceRBAC calls
useAccessReview), so refactor so hook calls are at the component top level:
either explicitly call useResourceRBAC once per known policy kind (e.g., call
useResourceRBAC(PolicyKindA, nsForCheck), useResourceRBAC(PolicyKindB,
nsForCheck), etc.) and assemble resourceRBAC from those results, or create a new
custom hook (e.g., useResourceRBACMap) that internally calls useAccessReview a
fixed number of times for each known entry in RESOURCES and returns the RBACMap;
ensure the number and order of hook calls is constant and no hooks are invoked
inside loops or callbacks.

In `@src/components/tlspolicy/useTLSPolicyActions.tsx`:
- Line 86: The dependency array for the effect in useTLSPolicyActions
incorrectly lists an undefined symbol history; replace history with the actual
navigate function from the useNavigate hook: update the dependency array in the
effect that references navigate (in useTLSPolicyActions) to include navigate
instead of history, ensuring the effect lists navigate, obj, tlsPolicyModel,
launchAnnotationsModal, launchDeleteModal, and launchLabelsModal so React's hook
dependencies are accurate.

---

Nitpick comments:
In `@e2e/tests/rbac.spec.ts`:
- Around line 500-504: The fixed 2s pause using page.waitForTimeout(2000)
followed by expect(page).toHaveURL('/kuadrant/ns/kuadrant-test/overview') is
unnecessary and brittle; either remove the second stability check if the initial
expect(page).toHaveURL(...) already asserts the target URL, or replace the
waitForTimeout call with a targeted wait such as await
page.waitForLoadState('networkidle') before calling expect(page).toHaveURL to
ensure network/activity quiescence; update the code around page.waitForTimeout
and expect(page).toHaveURL accordingly.
- Around line 470-493: Replace the fixed sleeps around namespace selection with
explicit waits: after clicking namespaceButton, wait for the dropdown/options to
appear using a selector from namespaceOptionSelectors via page.waitForSelector
or await page.locator(selector).waitFor({ state: 'visible' }); and before
clicking namespaceOption, wait for that specific locator's visibility or be
enabled (e.g., await namespaceOption.waitFor({ state: 'visible' }) or
waitForElementState('stable') ) instead of page.waitForTimeout(1000/2000); keep
the existing namespaceButton, namespaceOptionSelectors, namespaceOption
identifiers so the logic of choosing the first visible option remains the same.

In `@src/components/KuadrantPoliciesPage.tsx`:
- Around line 481-485: The contextValue object in KuadrantPoliciesPage
(currently built from activeNamespace, defaultColumns, resourceRBAC) is
recreated every render causing unnecessary context consumer updates; wrap its
creation in React.useMemo and return a memoized object keyed on
[activeNamespace, defaultColumns, resourceRBAC] so the reference is stable
across renders—update the code that declares contextValue to use useMemo inside
the KuadrantPoliciesPage component.

In `@src/utils/configLoader.ts`:
- Around line 32-34: The static analyzer warns about assigning to
configScript.innerHTML (created via document.createElement('script')) as a
potential XSS; since the script comes from a trusted same‑origin endpoint, you
can eliminate the warning and be safer for future changes by loading it via a
src URL instead of injecting raw HTML: replace the configScript.innerHTML =
script assignment with setting configScript.src to the trusted endpoint
('/api/plugins/kuadrant-console-plugin/config.js'), attach onload/onerror
handlers if needed, and then document.head.appendChild(configScript) (adjust any
code that currently relies on the inline string).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a2a6e885-b6b9-479c-9c8a-2c5a16c58a97

📥 Commits

Reviewing files that changed from the base of the PR and between a7468dc and 6abed8e.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (31)
  • .github/workflows/dev-build.yaml
  • .github/workflows/release-build.yaml
  • CLAUDE.md
  • charts/openshift-console-plugin/templates/deployment.yaml
  • charts/openshift-console-plugin/values.yaml
  • console-extensions.json
  • docs/designs/2026-03-27-namespace-scoped-overview-design.md
  • downstream.js
  • e2e/tests/rbac.spec.ts
  • entrypoint.sh
  • install.yaml
  • kuadrant-dev-setup/cluster-monitoring.yaml
  • locales/en/plugin__kuadrant-console-plugin.json
  • package.json
  • src/components/DropdownWithKebab.tsx
  • src/components/GatewayPoliciesPage.tsx
  • src/components/HTTPRoutePoliciesPage.tsx
  • src/components/KuadrantCreateUpdate.tsx
  • src/components/KuadrantDNSPolicyCreatePage.tsx
  • src/components/KuadrantOverviewPage.tsx
  • src/components/KuadrantPoliciesPage.tsx
  • src/components/KuadrantStatusAlert.tsx
  • src/components/KuadrantTLSCreatePage.tsx
  • src/components/PolicyTopologyPage.tsx
  • src/components/dnspolicy/useDNSPolicyActions.tsx
  • src/components/tlspolicy/useTLSPolicyActions.tsx
  • src/constants/links.ts
  • src/utils/cancel.tsx
  • src/utils/configLoader.ts
  • src/utils/metricsQueries.ts
  • src/utils/topology/configLoader.ts
💤 Files with no reviewable changes (1)
  • src/utils/topology/configLoader.ts

Comment on lines +27 to +32
- name: Login to container registry
uses: docker/login-action@v2
with:
image: ${{ env.REGISTRY }}/${{ env.IMAGE_BASE_NAME }}
tags: latest-${{ matrix.arch }}
archs: ${{ matrix.arch }}
containerfiles: |
./Dockerfile

- name: Push Architecture-Specific Image
uses: redhat-actions/push-to-registry@v2
username: ${{ secrets.IMG_REGISTRY_USERNAME }}
password: ${{ secrets.IMG_REGISTRY_TOKEN }}
registry: ${{ env.IMG_REGISTRY_HOST }}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

find . -name "dev-build.yaml" -type f

Repository: Kuadrant/kuadrant-console-plugin

Length of output: 110


🏁 Script executed:

cat -n .github/workflows/dev-build.yaml | head -60

Repository: Kuadrant/kuadrant-console-plugin

Length of output: 2260


🌐 Web query:

docker/login-action@v2 GitHub Actions compatibility current runners 2024 2025

💡 Result:

docker/login-action@v2 is compatible with current GitHub Actions hosted runners as of April 2026, but it is outdated and runs on Node.js 16, which has been deprecated since 2023-2024. Current runners (v2.33x+) support Node 20 (default until June 2026) and Node 24. Node 16 actions like v2 will continue to run with opt-out env vars (ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION=true), but may fail post-September 2026 when Node 20 is fully removed. Official docs and examples use v4.1.0 (Node 24, requires runner v2.327.1+). Upgrade to v3+ (Node 20, runner v2.308+) or v4+ for full compatibility without warnings or future breakage. In 2024-early 2025, v2 worked fine; by 2025-2026, Dependabot recommends upgrades in projects like actions/runner.

Citations:


🌐 Web query:

actionlint docker/login-action version compatibility warnings

💡 Result:

No specific version compatibility warnings or issues were found between actionlint and docker/login-action. Actionlint performs comprehensive static analysis on GitHub Actions workflows, including checks for popular actions like docker/login-action such as input validation at 'with:', outdated versions at 'uses:', and general syntax/type checks. Docker/login-action is actively maintained with recent releases up to v4.1.0 (as of 2026-04-02), and major version bumps (e.g., v2 to v3, v3 to v4) are handled via Dependabot without actionlint-related complaints in searched issues/PRs. Use the latest versions: actionlint v1.7.12+ and docker/login-action@v4 for optimal compatibility. To verify workflows, run actionlint locally or in CI.

Citations:


Guard this login step and bump docker/login-action to v3 or later.

This login step (line 28) runs unconditionally whilst the build/push step (line 46) is guarded by if: github.repository_owner == 'kuadrant'. For non-Kuadrant forks triggered via workflow_dispatch, the login step will attempt to execute before being skipped, causing failure due to missing registry credentials. Additionally, docker/login-action@v2 runs on Node.js 16, which is deprecated. Upgrade to v3 (Node 20, supported through June 2026) or v4 for forward compatibility.

Suggested patch
       - name: Login to container registry
+        if: github.repository_owner == 'kuadrant'
-        uses: docker/login-action@v2
+        uses: docker/login-action@v3
         with:
           username: ${{ secrets.IMG_REGISTRY_USERNAME }}
           password: ${{ secrets.IMG_REGISTRY_TOKEN }}
           registry: ${{ env.IMG_REGISTRY_HOST }}
🧰 Tools
🪛 actionlint (1.7.12)

[error] 28-28: the runner of "docker/login-action@v2" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/dev-build.yaml around lines 27 - 32, The "Login to
container registry" step currently uses docker/login-action@v2 and runs
unconditionally; change it to use docker/login-action@v3 (or v4) and add the
same guard as the build/push step (if: github.repository_owner == 'kuadrant') so
the login only runs for the kuadrant repository and avoids failing on forks
without registry secrets; update the step reference (the step name "Login to
container registry" and the action reference docker/login-action@v2)
accordingly.

Comment thread CLAUDE.md

### 5. Configuration

The plugin supports configurable Topology andPrometheus metrics for gateway traffic monitoring. This allows the console to work with different Gateway API implementations (OpenShift 4.19+, OSSM, etc.).
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Minor typo: missing space.

There's a missing space between "and" and "Prometheus".

📝 Suggested fix
-The plugin supports configurable Topology andPrometheus metrics for gateway traffic monitoring. This allows the console to work with different Gateway API implementations (OpenShift 4.19+, OSSM, etc.).
+The plugin supports configurable Topology and Prometheus metrics for gateway traffic monitoring. This allows the console to work with different Gateway API implementations (OpenShift 4.19+, OSSM, etc.).
📝 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.

Suggested change
The plugin supports configurable Topology andPrometheus metrics for gateway traffic monitoring. This allows the console to work with different Gateway API implementations (OpenShift 4.19+, OSSM, etc.).
The plugin supports configurable Topology and Prometheus metrics for gateway traffic monitoring. This allows the console to work with different Gateway API implementations (OpenShift 4.19+, OSSM, etc.).
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@CLAUDE.md` at line 96, Fix the minor typo in the sentence containing
"Topology andPrometheus" by inserting a space so it reads "Topology and
Prometheus"; locate the sentence phrase "Topology andPrometheus metrics for
gateway traffic monitoring" and update it to "Topology and Prometheus metrics
for gateway traffic monitoring".

Comment thread entrypoint.sh
TOPOLOGY_CONFIGMAP_NAMESPACE: '${TOPOLOGY_CONFIGMAP_NAMESPACE}'
TOPOLOGY_CONFIGMAP_NAME: '${TOPOLOGY_CONFIGMAP_NAME:-topology}',
TOPOLOGY_CONFIGMAP_NAMESPACE: '${TOPOLOGY_CONFIGMAP_NAMESPACE:-kuadrant-system}',
METRICS_WORKLOAD_SUFFIX: '${METRICS_WORKLOAD_SUFFIX:-openshift-default}'
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Fallback value mismatch for METRICS_WORKLOAD_SUFFIX.

Line 8 uses openshift-default, but the rest of the codebase expects -openshift-default. This causes inconsistent runtime config when the env var is not set.

💡 Proposed fix
-  METRICS_WORKLOAD_SUFFIX: '${METRICS_WORKLOAD_SUFFIX:-openshift-default}'
+  METRICS_WORKLOAD_SUFFIX: '${METRICS_WORKLOAD_SUFFIX:--openshift-default}'
📝 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.

Suggested change
METRICS_WORKLOAD_SUFFIX: '${METRICS_WORKLOAD_SUFFIX:-openshift-default}'
METRICS_WORKLOAD_SUFFIX: '${METRICS_WORKLOAD_SUFFIX:--openshift-default}'
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@entrypoint.sh` at line 8, The fallback value for METRICS_WORKLOAD_SUFFIX is
missing the leading hyphen, causing inconsistent defaults; update the
environment variable assignment for METRICS_WORKLOAD_SUFFIX so its default value
is "-openshift-default" instead of "openshift-default" (i.e., change the
assignment that sets METRICS_WORKLOAD_SUFFIX:
'${METRICS_WORKLOAD_SUFFIX:-openshift-default}' to use the hyphen-prefixed
default), ensuring all runtime code that expects the "-openshift-default" suffix
receives the correct value.

Comment on lines 551 to 566
const getTotalRequests = (obj: { metadata: { namespace: string; name: string } }): number => {
const key = `${obj.metadata.namespace}/${obj.metadata.name}-istio`;
const key = buildGatewayKey(obj.metadata.namespace, obj.metadata.name, metricsWorkloadSuffix);
const total = totalRequestsByGateway[key]?.total;
return Number.isFinite(total) ? Math.round(total) : 0;
};
const getSuccessfulRequests = (obj: {
metadata: { namespace: string; name: string };
}): number => {
const key = `${obj.metadata.namespace}/${obj.metadata.name}-istio`;
const key = buildGatewayKey(obj.metadata.namespace, obj.metadata.name, metricsWorkloadSuffix);
const success = totalRequestsByGateway[key]?.total - totalRequestsByGateway[key]?.errors;
return Number.isFinite(success) ? Math.round(success) : 0;
};
const getErrorRate = (obj: { metadata: { namespace: string; name: string } }): string => {
const key = `${obj.metadata.namespace}/${obj.metadata.name}-istio`;
const key = buildGatewayKey(obj.metadata.namespace, obj.metadata.name, metricsWorkloadSuffix);
const rate = (totalRequestsByGateway[key]?.errors / totalRequestsByGateway[key]?.total) * 100;
return Number.isFinite(rate) ? rate.toFixed(1) : '-';
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Keep zero-traffic gateways distinct from missing metrics.

The current fallbacks treat valid 0 values as empty, so a quiet gateway renders - for totals/successes and -% for error rate. Please switch these helpers/cells to explicit nullish handling instead of falsy checks.

💡 Possible fix
-  const getTotalRequests = (obj: { metadata: { namespace: string; name: string } }): number => {
+  const getTotalRequests = (
+    obj: { metadata: { namespace: string; name: string } },
+  ): number | undefined => {
     const key = buildGatewayKey(obj.metadata.namespace, obj.metadata.name, metricsWorkloadSuffix);
     const total = totalRequestsByGateway[key]?.total;
-    return Number.isFinite(total) ? Math.round(total) : 0;
+    return Number.isFinite(total) ? Math.round(total) : undefined;
   };
   const getSuccessfulRequests = (obj: {
     metadata: { namespace: string; name: string };
-  }): number => {
+  }): number | undefined => {
     const key = buildGatewayKey(obj.metadata.namespace, obj.metadata.name, metricsWorkloadSuffix);
     const success = totalRequestsByGateway[key]?.total - totalRequestsByGateway[key]?.errors;
-    return Number.isFinite(success) ? Math.round(success) : 0;
+    return Number.isFinite(success) ? Math.round(success) : undefined;
   };
-  const getErrorRate = (obj: { metadata: { namespace: string; name: string } }): string => {
+  const getErrorRate = (
+    obj: { metadata: { namespace: string; name: string } },
+  ): string | undefined => {
     const key = buildGatewayKey(obj.metadata.namespace, obj.metadata.name, metricsWorkloadSuffix);
     const rate = (totalRequestsByGateway[key]?.errors / totalRequestsByGateway[key]?.total) * 100;
-    return Number.isFinite(rate) ? rate.toFixed(1) : '-';
+    return Number.isFinite(rate) ? rate.toFixed(1) : undefined;
   };
-          {getTotalRequests(obj) || '-'}
+          {getTotalRequests(obj) ?? '-'}
...
-          {getSuccessfulRequests(obj) || '-'}
+          {getSuccessfulRequests(obj) ?? '-'}
...
-          {getErrorRate(obj) || '-'}%
+          {(() => {
+            const errorRate = getErrorRate(obj);
+            return errorRate == null ? '-' : `${errorRate}%`;
+          })()}

Also applies to: 688-707

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/KuadrantOverviewPage.tsx` around lines 551 - 566, The helpers
getTotalRequests, getSuccessfulRequests and getErrorRate treat 0 as missing
because they rely on falsy checks; change them to use explicit nullish handling:
for getTotalRequests use const total = totalRequestsByGateway[key]?.total ?? 0
and return Math.round(total); for getSuccessfulRequests read const total =
totalRequestsByGateway[key]?.total; const errors =
totalRequestsByGateway[key]?.errors ?? 0 and if total == null return 0 (or
preserve existing missing-vs-zero behavior by returning 0 when total is null?),
otherwise compute success = Math.round((total ?? 0) - errors); for getErrorRate
read const total = totalRequestsByGateway[key]?.total; const errors =
totalRequestsByGateway[key]?.errors; if total == null return '-'; otherwise
compute rate = total === 0 ? 0 : (errors ?? 0) / total * 100 and return
rate.toFixed(1); apply the same nullish-based fixes to the corresponding
helpers/cells referenced around lines 688-707.

Comment on lines +973 to +975
{!resourceRBAC['Gateway']?.create ? (
<Tooltip content="You do not have permission to create a Gateway">
<Button className="kuadrant-overview-create-button" isAriaDisabled>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Localise the new permission tooltips.

These messages are new user-facing strings but bypass t(...), so they will remain hard-coded in English while the rest of the page is translated.

🌐 Possible fix
-                      <Tooltip content="You do not have permission to create a Gateway">
+                      <Tooltip content={t('You do not have permission to create a Gateway')}>
...
-                      <Tooltip content="You do not have permission to create a HTTPRoute">
+                      <Tooltip content={t('You do not have permission to create a HTTPRoute')}>
As per coding guidelines, "Use the `useTranslation` hook for all user-facing strings and add corresponding i18n keys".

Also applies to: 1122-1124

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/KuadrantOverviewPage.tsx` around lines 973 - 975, The tooltip
strings in KuadrantOverviewPage are hard-coded (e.g. the Tooltip content "You do
not have permission to create a Gateway" used alongside
resourceRBAC['Gateway']?.create and the similar strings around the create Button
with class kuadrant-overview-create-button); update the component to use the
useTranslation hook and replace those literal strings with t('...') calls using
new i18n keys (e.g. gateway.permission.create.tooltip), then add the
corresponding keys/translations to your i18n resource files so the tooltips are
localisable.

@eguzki
Copy link
Copy Markdown
Collaborator

eguzki commented Apr 16, 2026

@eguzki I see how for a single active minor, tagging from main is simpler but we're moving to a place where we will need to do patch releases on multiple minors. Eg once kuadrant-operator v1.5.0 ships with console-plugin v0.4.x, any CVE or bug fix needed in v1.4.x requires a console-plugin v0.3.x patch. Plus it would be nice to have all repo's behave the same when it comes to releases; less surprises.

That’s a valid point, however, I’m not sure I fully agree. Minor versions, by semantic versioning, never break backward compatibility. Kuadrant patch releases should pick the latest minor version of the dependencies. This way, dependencies do not need to maintain stable minor release branches. I see Kuadrant dependencies as libraries, always moving forward instead of maintaining long-lived stable minor release branches. It obviously makes total sense to keep long-lived major release branches like release-v1.x.

Anyway, as I said, not a big deal. It's already been approved

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

6 participants