From 6e950241872afb680cef8977159108385cc3beb5 Mon Sep 17 00:00:00 2001 From: logonoff Date: Wed, 25 Feb 2026 16:38:54 -0500 Subject: [PATCH 1/2] NO-JIRA: Context improvements --- .claude/skills/update-package/SKILL.md | 2 +- .coderabbit.yaml | 1 - AGENTS.md | 108 ++++++++++++++++++------- ARCHITECTURE.md | 65 --------------- STYLEGUIDE.md | 4 +- TESTING.md | 78 ++++++++++-------- 6 files changed, 129 insertions(+), 129 deletions(-) delete mode 100644 ARCHITECTURE.md diff --git a/.claude/skills/update-package/SKILL.md b/.claude/skills/update-package/SKILL.md index d1fbc2bfa78..43ae8dd9e66 100644 --- a/.claude/skills/update-package/SKILL.md +++ b/.claude/skills/update-package/SKILL.md @@ -59,7 +59,7 @@ Update the specified package to its reasonably latest stable version or to the v ## Guidelines **Code Standards**: -- For coding patterns and project structure: Read `ARCHITECTURE.md`, `STYLEGUIDE.md`, and `AGENTS.md` +- For coding patterns and project structure: Read `STYLEGUIDE.md`, `AGENTS.md`, and other relevant documentation - Follow existing code patterns found in the codebase **Package Update Rules**: diff --git a/.coderabbit.yaml b/.coderabbit.yaml index 2a1b510549c..f68df195192 100644 --- a/.coderabbit.yaml +++ b/.coderabbit.yaml @@ -76,7 +76,6 @@ knowledge_base: filePatterns: # Repository documentation - "AGENTS.md" - - "ARCHITECTURE.md" - "TESTING.md" - "STYLEGUIDE.md" - "CONTRIBUTING.md" diff --git a/AGENTS.md b/AGENTS.md index f75d5b3a6cf..ed73016eddb 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,35 +1,88 @@ # Instructions for large language models and AI coding agents -This is the entry point for AI-assisted development. Read this first and follow links for details. +You are a senior developer working on OpenShift console, a complex enterprise web application designed to be an extensible platform for OpenShift and Kubernetes cluster management. + +Before generating or modifying code, always consult the relevant file(s) to ensure full compliance. ## Project overview - **Monorepo:** `frontend/` (React + TypeScript, yarn workspaces), `pkg/` - Go backend code, `cmd/` - Go CLI commands -- **Static plugins:** dependencies listed in `frontend/packages/console-app/package.json` -- **Key Packages:** `@console/dynamic-plugin-sdk` (public API), `@console/shared` (utils), `@console/internal` (core UI/k8s) +- **Key packages:** `@console/dynamic-plugin-sdk` (public API), `@console/shared` (utils), `@console/internal` (`public` folder - core UI/k8s) + +## Static plugins + +Static plugins are built into the console bundle and are core parts of the application. They may be deprecated or extracted into dynamic plugins over time. For the complete list of static plugins, see `console-app/package.json` dependencies. Static plugins have the following characteristics: + +- **Extension points:** Defined in `console-extensions.json` of each static plugin yarn workspace. This mechanism provides static plugins a way to extend the Console UI. +- **Code references:** `$codeRef` points to a specific export from a plugin's **exposed modules** (defined in their `package.json`) that are consumed by the extension point. +- **Type safety:** When writing code for static plugins, ensure that all `$codeRef` ALWAYS **reference the corresponding extension type from the dynamic plugin SDK package**. This ensures type safety and consistency across both static and dynamic plugins. + +Example: +```jsonc +// In console-extensions.json of a static plugin +{ + "type": "console.flag", + "$codeRef": "exampleFlag.handler" +} +``` + +```typescript +// In the exampleFlag exposed module of the static plugin: +import type { FeatureFlagHandler } from '@console/dynamic-plugin-sdk/src/extensions/feature-flags'; + +// Exposed type from dynamic plugin SDK is used for type safety +export const handler: FeatureFlagHandler = (setFeatureFlag) => { + setFeatureFlag('EXAMPLE', true); +}; +``` + +## Dynamic plugin SDK + +OpenShift console is designed to be an extensible platform that allows "dynamic plugins" to extend the UI. Dynamic plugins load over the network at runtime, enabling operators and custom resources to contribute UI without rebuilding the console. + +The `console-dynamic-plugin-sdk` is the public API based on Webpack module federation that enables both static and dynamic plugins to integrate with the console. + +**BREAKING CHANGES REQUIRE EXTREME CARE** - this is a public API consumed by external plugins. + +### Re-exports + +The dynamic plugin SDK provides a re-export layer to allow dynamic plugins to consume APIs from multiple Console packages without directly depending on them. + +Before starting ANY changes, ensure your changes do not impact the public API by checking `frontend/packages/console-dynamic-plugin-sdk/src/api/internal-*.ts` files to avoid breakage. + +### Development guidelines + +- Always consider impact on external plugin developers +- Maintain backward compatibility as it's a public API +- Comprehensive documentation for all public APIs +- Changes to extension schemas need migration paths + +For detailed plugin API review guidelines and workflow, use the `plugin-api-review` skill to ensure all changes are properly vetted for public API impact. ## Common commands ```bash -cd frontend && yarn install # Install frontend dependencies -cd frontend && yarn lint # ESLint / prettier linting (can specify file path) -cd frontend && yarn test # Run frontend tests (can specify test path) -cd frontend && yarn build # Production build -cd frontend && yarn dev-once # Development build (no watch mode) -cd frontend && yarn i18n # Update i18n keys -go mod vendor && go mod tidy # Update Go dependencies -./build-frontend.sh # Production build of frontend -./build-backend.sh # Build backend Go code -./test-backend.sh # Run backend tests -./build.sh # Full build (frontend + backend) +cd frontend && yarn install # Install frontend dependencies +cd frontend && yarn eslint # ESLint / prettier linting (must specify file path) +cd frontend && yarn lint # ESLint / prettier linting (lints entire codebase) +cd frontend && yarn test [] # Run frontend tests (can specify test path) +cd frontend && yarn build # Production build +cd frontend && yarn dev-once # Development build (no watch mode) +cd frontend && yarn i18n # Update i18n keys +go mod vendor && go mod tidy # Update Go dependencies +./build-frontend.sh # Production build of frontend +./build-backend.sh # Build backend Go code +./test-backend.sh # Run backend tests +./build.sh # Full build (frontend + backend) ``` -## Global practices +## Development workflow ### Commit strategy -- **Backend dependency updates**: Separate vendor folder changes into their own commit to isolate core logic changes -- **Frontend i18n updates**: Run `yarn i18n` and commit updated keys alongside any code changes that affect i18n +- Backend dependency updates: Separate vendor folder changes into their own commit to isolate core logic changes +- Bug fixes: prefix with bug number or Jira key (e.g., `OCPBUGS-1234: Fix ...`) +- Frontend i18n updates: Run `yarn i18n` and commit updated keys alongside any code changes that affect i18n ### Branch naming @@ -37,19 +90,20 @@ go mod vendor && go mod tidy # Update Go dependencies - Bug fixes: `OCPBUGS-####` (Jira bug number) - Base branch: `main` -## Required reference files for AI coding agents +## Reference files -**REQUIRED FOR ALL CODING AGENTS**: Before generating or modifying code, always consult the relevant file(s) to ensure full compliance. These files are the single source of truth for architecture, coding standards, and testing. +These files are the single source of truth for architecture, coding standards, and testing. Consult them when working in the relevant area. ### General -- **[ARCHITECTURE.md](ARCHITECTURE.md)** -- **[TESTING.md](TESTING.md)** -- **[README.md](README.md)** -- **[CONTRIBUTING.md](CONTRIBUTING.md)** -- **[STYLEGUIDE.md](STYLEGUIDE.md)** -- **[INTERNATIONALIZATION.md](INTERNATIONALIZATION.md)** +- [TESTING.md](TESTING.md) - testing frameworks, patterns, and best practices. Consult before writing or modifying tests. +- [STYLEGUIDE.md](STYLEGUIDE.md) - code style for TypeScript, Go, and SCSS. Consult when writing new code or reviewing style questions. +- [INTERNATIONALIZATION.md](INTERNATIONALIZATION.md) - i18n patterns and `useTranslation` usage. Consult when adding or modifying user-facing strings. +- [CONTRIBUTING.md](CONTRIBUTING.md) - contribution workflow and commit message conventions. +- [README.md](README.md) - project setup, build instructions, and architecture overview. -### Plugin development +### Dynamic plugin SDK -- **[frontend/packages/console-dynamic-plugin-sdk/README.md](frontend/packages/console-dynamic-plugin-sdk/README.md)** - Comprehensive dynamic plugin SDK documentation +- [Dynamic Plugin SDK documentation](frontend/packages/console-dynamic-plugin-sdk/README.md) - architecture, design principles, and development guidelines. Consult before modifying SDK code. +- [Extension Types Reference](frontend/packages/console-dynamic-plugin-sdk/docs/console-extensions.md) - complete extension type definitions, naming conventions (`console.*`), and deprecation notices. +- [Console API Documentation](frontend/packages/console-dynamic-plugin-sdk/docs/api.md) - React components, hooks, utilities, and TypeScript types exported by the SDK. diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md deleted file mode 100644 index 953353f87ab..00000000000 --- a/ARCHITECTURE.md +++ /dev/null @@ -1,65 +0,0 @@ -# ARCHITECTURE - -## Console Dynamic Plugin SDK - -The `console-dynamic-plugin-sdk` is a key part of this repository - it's the public API that enables OpenShift Console's extensibility. - -## Key packages & areas - -### Core packages - -- **console-dynamic-plugin-sdk**: Public API for external plugins (⚠️ breaking changes require careful vetting) -- **console-app**: Main application that loads all plugins -- **console-shared**: Shared utilities and components -- **console-internal**: Core UI and Kubernetes integration - -### Dynamic plugins - -For the complete list of console plugins, see `console-app/package.json` dependencies. Static plugins (built-in) may be deprecated or extracted over time. - -- **Extension Points System**: 25+ extension types (NavItem, Page, ResourceListPage, DashboardsCard, etc.) -- **Module Federation**: Runtime plugin loading via Webpack Module Federation -- **Type Safety**: Comprehensive TypeScript definitions for all extension points -- **Code References**: Lazy loading with `$codeRef` for performance - -### Official extension types & API documentation - -- [Dynamic Plugin SDK documentation](frontend/packages/console-dynamic-plugin-sdk/README.md)- Authoritative for how the SDK works -- [Extension Types Reference](frontend/packages/console-dynamic-plugin-sdk/docs/console-extensions.md) - Complete extension type definitions, naming conventions (`console.*`), and deprecation notices -- [Console API Documentation](frontend/packages/console-dynamic-plugin-sdk/docs/api.md) - React components, hooks, utilities, and TypeScript types exported by the SDK - -### Critical Considerations - -- **⚠️ BREAKING CHANGES REQUIRE EXTREME CARE**: This is a public API consumed by external plugins -- **Backward Compatibility**: Must maintain compatibility across versions -- **Schema Evolution**: Extension schema changes need migration paths -- **Performance Impact**: Plugin loading affects console startup time -- **Type Safety**: Strong TypeScript support prevents runtime errors - -### ⚠️ Public API Sources - Breaking Change Risk - -The dynamic plugin SDK re-exports APIs from multiple Console packages: - -- **`@console/shared`** - Dashboard components, UI components, hooks -- **`@console/internal`** - Core UI, editors, hooks, K8s utilities -- **`@console/plugin-sdk`** - Extension system, plugin infrastructure -- **`@console/app`** - Application context -- **`@console/topology`** - Topology components, data transforms, graph views - -**BEFORE MODIFYING ANYTHING IN THESE OR OTHER PACKAGES:** Verify SDK re-exports by checking `frontend/packages/console-dynamic-plugin-sdk/src/api/internal-*.ts` files to avoid breaking the public API. - -### SDK Utilities - -- **Resource Hooks**: `useK8sWatchResource`, `useActivePerspective`, `useActiveNamespace` -- **Component Utilities**: Navigation helpers, telemetry, validation -- **Build Integration**: `ConsoleRemotePlugin` for Webpack Module Federation - -### Development Guidelines - -**SDK-Specific:** - -- Always consider impact on external plugin developers -- Maintain backward compatibility as it's a public API -- Comprehensive documentation for all public APIs - -**For detailed plugin API review guidelines and workflow, use the plugin-api-review skill to ensure all changes are properly vetted for public API impact.** diff --git a/STYLEGUIDE.md b/STYLEGUIDE.md index eedb80d0238..8257d604c0b 100644 --- a/STYLEGUIDE.md +++ b/STYLEGUIDE.md @@ -39,9 +39,9 @@ - New code MUST be written in TypeScript, not JavaScript. - Prefer functional programming patterns and immutable data structures -- Use React functional components with hooks instead of class components. +- Use React functional components with hooks instead of class components - Run the linter and follow all rules defined in .eslintrc -- Never use absolute paths in code. The app should be able to run behind a proxy under an arbitrary path. +- Never use absolute paths in code. The app should be able to run behind a proxy under an arbitrary path - TESTS: Should follow a similar "test tables" convention as used in Go where applicable. ### Frontend Patterns diff --git a/TESTING.md b/TESTING.md index 801c6603489..fc5d8167ba6 100644 --- a/TESTING.md +++ b/TESTING.md @@ -1,29 +1,34 @@ # TESTING ## Frontend Test Types -- **Unit Tests** - - Framework: Jest - - Libraries: @testing-library/react, redux-mock-store - -- **End-to-End (E2E) Tests** - - Tool: Cypress - - Specialized test suites for components: - - Core Console - - OLM (Operator Lifecycle Manager) - - Dev Console - - Shipwright - - Web Terminal - - Telemetry - - Knative - - Helm - - Topology - - Supports headless and interactive modes +### Unit tests +Focuses on testing individual React components, hooks, and utilities in isolation. + +- Framework: Jest +- Libraries: `@testing-library/react`, `@testing-library/jest-dom` + +### Integration tests +- Tool: Cypress +- Specialized test suites for components: + - Core Console + - OLM (Operator Lifecycle Manager) + - Dev Console + - Shipwright + - Web Terminal + - Telemetry + - Knative + - Helm + - Topology +- Supports headless and interactive modes ## Unit Testing with Jest and React Testing Library + +When generating unit tests, ALWAYS use the `gen-rtl-test` skill to create tests that follow our best practices and conventions. + ### Testing Best Practices -1. **User-Centric Testing** - Test what users see and interact with. +1. **User-Centric Testing** - Test what users see and interact with. **DO NOT test:** - Internal component state - Private component methods @@ -35,7 +40,7 @@ 3. **Semantic Over Generic** - Always prefer role-based queries (e.g., `getByRole`) over generic selectors -4. **DRY Helpers** - Use reusable function in frontend/packages/console-shared/src/test-utils directory and sub-directory if exists else extract repetitive setup into reusable functions +4. **DRY Helpers** - Use reusable function such as `renderWithProviders`, `renderHookWithProviders` in `frontend/packages/console-shared/src/test-utils`. Extract repetitive setup not covered by these helpers into custom functions if needed. 5. **Async-Aware** - Handle asynchronous updates with `findBy*` and `waitFor` @@ -48,10 +53,10 @@ ### Test File Co-location and Naming Convention -**File Structure:** - Test file must be in `__tests__/` directory within component directory - Test file must have same name as implementation file - Use `.spec.tsx` extension + ``` MyComponentDirectory/ ├── __tests__/ @@ -62,14 +67,17 @@ MyComponentDirectory/ ### Mocking Strategies When mocking is necessary: -- **ALWAYS** use ES6 `import` statements at the top of the file -- Keep mocks **simple** - return `null`, strings, or `children` directly + +- **ALWAYS** use ESM `import` statements at the top of the file - **NEVER** use `require('react')` or `React.createElement()` in mocks +- Prefer `jest.mock()` for module mocks and `jest.fn()` for component mocks instead of `jest.spyOn()` +- Keep mocks **simple** - return `null`, strings, or `children` directly - Use `jest.fn(() => null)` for simple component mocks - Use `jest.fn(() => 'ComponentName')` for mocks that need to display text - Use `jest.fn((props) => props.children)` for wrapper components **Correct Mock Patterns:** + ```typescript // CORRECT - Return null jest.mock('../MyComponent', () => () => null); @@ -94,13 +102,17 @@ jest.mock('../Component', () => () =>
Mock
); ``` **Mock Custom Hooks with jest.fn()** + ```typescript -jest.mock('../useCustomHook', () => ({ - useCustomHook: jest.fn(() => [/* mock data */]), +jest.mock("../useCustomHook", () => ({ + useCustomHook: jest.fn(() => [ + /* mock data */ + ]), })); ``` **Test user behavior, not implementation** + ```typescript // GOOD - Testing user-visible behavior expect(screen.getByRole('heading', { name: 'Resource Details' })).toBeVisible(); @@ -109,7 +121,8 @@ expect(screen.getByRole('heading', { name: 'Resource Details' })).toBeVisible(); expect(wrapper.find(DetailsPage).props()).toEqual({...}); ``` -**Clean up mocks** +**Clean up mocks** + ```typescript // GOOD - Proper cleanup afterEach(() => { @@ -117,12 +130,12 @@ afterEach(() => { }); // BAD - No cleanup -jest.spyOn(module, 'function'); +jest.spyOn(module, "function"); ``` ## End-to-End Testing -Integration/E2E tests validate full user workflows against a real/simulated OpenShift cluster using Cypress + Cucumber (Gherkin BDD). +Integration/E2E tests validate full user workflows against a real/simulated OpenShift cluster using Cypress + Cucumber (Gherkin BDD). - **Focus Areas**: Core Console, OLM, Dev Console, Shipwright, Web Terminal, Telemetry, Knative, Helm, Topology. - **Key Characteristics**: Gherkin scenarios (.feature files) + step definitions; supports headless/interactive modes; integrates axe-core for a11y. @@ -133,11 +146,10 @@ Integration/E2E tests validate full user workflows against a real/simulated Open - **Mocking**: MSW for API responses; mock external services (e.g., K8s API) to avoid cluster dependency. ### Running E2E Tests (Setup & Commands) + For full prerequisites (cluster login, Cypress install), see [README.md#integration-tests](README.md#integration-tests). -| Mode/Command | Purpose | Example | -|-------------------------------|--------------------------------------|------------------------------------| -| `yarn cypress:run` | Headless run (all packages) | - | -| `yarn cypress:run:` | Headless for specific package | `yarn cypress:run:dev-console` | -| `yarn cypress:open:` | Interactive UI for debugging | `yarn cypress:open:console` | -| `yarn cypress:run: --env debug=true` | Verbose/debug mode | `yarn cypress:run:helm --env debug=true` | \ No newline at end of file +See `package.json` scripts for a list of available commands to run E2E tests in different modes. +- `yarn test-cypress-` to open an interactive window for a specific Cypress test suite (e.g., `yarn test-cypress-olm`, `yarn test-cypress-devconsole`). **AI agents may struggle with interactive mode**. +- `yarn test-cypress--headless` to run the same suite in headless mode (e.g., `yarn test-cypress-olm-headless`) +- `yarn test-cypress--nightly` runs an extended suite of tests in headless mode, intended for CI/nightly runs (e.g., `yarn test-cypress-olm-nightly`) From 673b5645eb7ab0ee2c682aa3dca6ba2ca308e5d7 Mon Sep 17 00:00:00 2001 From: logonoff Date: Thu, 26 Feb 2026 17:28:24 -0500 Subject: [PATCH 2/2] NO-JIRA: More context improvements --- AGENTS.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/AGENTS.md b/AGENTS.md index ed73016eddb..0a6091f1612 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -8,10 +8,13 @@ Before generating or modifying code, always consult the relevant file(s) to ensu - **Monorepo:** `frontend/` (React + TypeScript, yarn workspaces), `pkg/` - Go backend code, `cmd/` - Go CLI commands - **Key packages:** `@console/dynamic-plugin-sdk` (public API), `@console/shared` (utils), `@console/internal` (`public` folder - core UI/k8s) +- **Testing:** Jest (unit), Cypress (E2E), Go tests (backend). Read [TESTING.md](TESTING.md) for patterns and best practices. Use the `gen-rtl-test` skill for React Testing Library test generation. ## Static plugins -Static plugins are built into the console bundle and are core parts of the application. They may be deprecated or extracted into dynamic plugins over time. For the complete list of static plugins, see `console-app/package.json` dependencies. Static plugins have the following characteristics: +Static plugins are built into the console bundle and are core parts of the application. They may be deprecated or extracted into dynamic plugins over time. For the complete list of static plugins, see `console-app/package.json` dependencies. + +### Extension points and type safety - **Extension points:** Defined in `console-extensions.json` of each static plugin yarn workspace. This mechanism provides static plugins a way to extend the Console UI. - **Code references:** `$codeRef` points to a specific export from a plugin's **exposed modules** (defined in their `package.json`) that are consumed by the extension point. @@ -82,6 +85,7 @@ go mod vendor && go mod tidy # Update Go dependencies - Backend dependency updates: Separate vendor folder changes into their own commit to isolate core logic changes - Bug fixes: prefix with bug number or Jira key (e.g., `OCPBUGS-1234: Fix ...`) +- Subject line answers "what changed"; body answers "why" - Frontend i18n updates: Run `yarn i18n` and commit updated keys alongside any code changes that affect i18n ### Branch naming @@ -90,6 +94,16 @@ go mod vendor && go mod tidy # Update Go dependencies - Bug fixes: `OCPBUGS-####` (Jira bug number) - Base branch: `main` +## Common pitfalls + +- **Barrel imports:** NEVER import from package index files (e.g., `@console/shared`) in new code, as they can create circular dependencies and slow builds. Import from specific file paths instead. +- **Public API breakage:** Always check `console-dynamic-plugin-sdk/src/api/internal-*.ts` before modifying anything in the SDK. External plugins depend on this API. +- **Missing i18n keys:** Forgetting `yarn i18n` after adding translatable strings causes missing key warnings and E2E failures. +- **Backticks in t():** The i18n parser cannot extract keys from template literals. Use single or double quotes. +- **Deprecated imports in new code:** NEVER import from deprecated packages or use code which has the `@deprecated` TSdoc tag in new code. +- **Absolute paths:** Never use absolute URLs or paths. The console runs behind a proxy under an arbitrary path. +- **Custom CSS:** Exhaust PatternFly component options before writing custom SCSS. When necessary, use BEM with `co-` prefix. + ## Reference files These files are the single source of truth for architecture, coding standards, and testing. Consult them when working in the relevant area.