Uh oh!
There was an error while loading. Please reload this page.
CONSOLE-5307: Add knip-based dead code detection in CI - #16523
Conversation
Adds knip-based static analysis to identify unused exports and dependencies across the monorepo.
A custom knip compiler for console-extensions.json handles console-specific patterns that standard analysis tools cannot trace:
- $codeRef values are detected uing isEncodedCodeRef and parsed with parseEncodedCodeRefValue from the SDK's coderef-resolver, then resolved via exposedModules in each plugin's package.json
- Plugin packages are resolved once via resolvePluginPackages and reused for both the compiler lookup and workspace extension detection
- Dynamic plugin SDK exports are excluded from reporting since they may be consumed by external plugins
- Workspace configs are auto-discovered from the packages/ directory
Knip cannot natively trace which specific export is accessed from dynamic `import().then(m => m.X)` or CJS `require('path').X` patterns in TypeScript files. Without help, it marks the entire dynamically-imported module as used, hiding genuinely unused exports.
Add a compileScript compiler for ts/tsx/js/jsx that uses @babel/core parseSync to build an AST and extract:
- `import('./mod').then(m => m.X)` → `import { X } from './mod'`
- `require('pkg/mod').X` → `import { X } from 'pkg/mod'`
Matched patterns are surgically removed from the source using AST node positions, so knip no longer treats the entire module as used. The static named imports give knip export-level granularity while keeping each module in the dependency graph for transitive import tracing.
AST-based detection avoids the fragility of regex comment/string stripping (which broke on `/*` inside JSX string attributes like `path="/api-resource/:plural/*"`).@logonoff: This pull request references CONSOLE-5037 which is a valid jira issue. Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "5.0.0" version, but no target version was set. DetailsIn response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository. |
WalkthroughThis PR introduces knip, an unused exports detection tool, with custom compilers to trace exports across a monorepo. The knip configuration handles dynamic imports and scans console-extensions.json. Knip is integrated into the CI pipeline and identifies several unused components and hooks that are then removed. ChangesKnip Configuration and Unused Exports Cleanup
🎯 3 (Moderate) | ⏱️ ~20 minutes 🚥 Pre-merge checks | ✅ 15✅ Passed checks (15 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
logonoff
commented
Jun 1, 2026
/label px-approved |
openshift-ci-robot
commented
Jun 1, 2026
@logonoff: This PR has been marked as verified by DetailsIn response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository. |
@logonoff: This pull request references CONSOLE-5037 which is a valid jira issue. Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "5.0.0" version, but no target version was set. DetailsIn response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository. |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
frontend/scripts/knip.ts (1)
99-104: ⚡ Quick winAvoid
anyin the AST walker.
(n as any)[key]turns off the type checking in the new compiler right where the node-shape assumptions matter most. A typed dictionary cast keeps the dynamic lookup without dropping back toany.♻️ Proposed fix
- const child = (n as any)[key];+ const child = (n as Record<string, unknown>)[key];As per coding guidelines, "Flag use of
anytype and suggest proper type definitions instead".🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@frontend/scripts/knip.ts` around lines 99 - 104, The walker uses (n as any)[key] which disables type checking; replace it with a typed index lookup like (n as Record<string, unknown>)[key] or (n as t.Node & Record<string, unknown>)[key] in the loop where t.VISITOR_KEYS, walk, and n are used, then treat the result as unknown (const child) and keep the existing Array.isArray and t.isNode guards (and type the array iterator param as unknown) so you don't rely on any while preserving the runtime checks.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@frontend/package.json`:
- Line 294: Update the frontend package.json devDependency for "knip" to use an
exact version instead of a semver range: locate the "knip" entry under
devDependencies (devDependencies.knip) and replace "^6.14.2" with "6.14.2" so
the dependency is pinned exactly.
---
Nitpick comments:
In `@frontend/scripts/knip.ts`:
- Around line 99-104: The walker uses (n as any)[key] which disables type
checking; replace it with a typed index lookup like (n as Record<string,
unknown>)[key] or (n as t.Node & Record<string, unknown>)[key] in the loop where
t.VISITOR_KEYS, walk, and n are used, then treat the result as unknown (const
child) and keep the existing Array.isArray and t.isNode guards (and type the
array iterator param as unknown) so you don't rely on any while preserving the
runtime checks.
🪄 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: Repository: openshift/coderabbit/.coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 4dd30ef5-46b9-447b-9b2f-e5e6bc4a0215
⛔ Files ignored due to path filters (1)
frontend/yarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (10)
frontend/package.jsonfrontend/packages/console-app/src/components/cluster-configuration/ClusterConfigurationCheckboxField.tsxfrontend/packages/console-app/src/components/cluster-configuration/ClusterConfigurationField.tsxfrontend/packages/console-app/src/components/cluster-configuration/ClusterConfigurationTextField.tsxfrontend/packages/console-app/src/components/cluster-configuration/hooks.tsfrontend/packages/console-app/src/components/data-view/ConsoleDataView.tsxfrontend/packages/console-shared/src/hooks/__tests__/useSelectList.tsfrontend/packages/console-shared/src/hooks/useSelectList.tsfrontend/scripts/knip.tstest-frontend.sh
💤 Files with no reviewable changes (6)
- frontend/packages/console-app/src/components/cluster-configuration/hooks.ts
- frontend/packages/console-shared/src/hooks/useSelectList.ts
- frontend/packages/console-shared/src/hooks/tests/useSelectList.ts
- frontend/packages/console-app/src/components/cluster-configuration/ClusterConfigurationField.tsx
- frontend/packages/console-app/src/components/cluster-configuration/ClusterConfigurationTextField.tsx
- frontend/packages/console-app/src/components/cluster-configuration/ClusterConfigurationCheckboxField.tsx
Uh oh!
There was an error while loading. Please reload this page.
@logonoff: all tests passed! Full PR test history. Your PR dashboard. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here. |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: logonoff, TheRealJon The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
Uh oh!
There was an error while loading. Please reload this page.
Follow up on #16513
Solution description:
Adds knip-based static analysis to identify unused exports and dependencies across the monorepo.
A custom knip compiler for console-extensions.json handles console-specific patterns that standard analysis tools cannot trace:
Knip cannot natively trace which specific export is accessed from dynamic
import().then(m => m.X)or CJSrequire('path').Xpatterns in TypeScript files. Without help, it marks the entire dynamically-imported module as used, hiding genuinely unused exports.Add a compileScript compiler for ts/tsx/js/jsx that uses @babel/core parseSync to build an AST and extract:
import('./mod').then(m => m.X)→import { X } from './mod'require('pkg/mod').X→import { X } from 'pkg/mod'Matched patterns are surgically removed from the source using AST node positions, so knip no longer treats the entire module as used. The static named imports give knip export-level granularity while keeping each module in the dependency graph for transitive import tracing.
AST-based detection avoids the fragility of regex comment/string stripping (which broke on
/*inside JSX string attributes likepath="/api-resource/:plural/*").Test cases:
console-dynamic-plugin-sdkbecause plugins could consume some code in some path which is dead to us but not for themSummary by CodeRabbit