Contributions are welcome. This document covers coding standards, testing, and the pull request process.
For initial setup (clone, install, running the dev server), see README.md.
- Functional components only, typed with
FCfrom React - Use PatternFly 6 components for all UI — no custom HTML elements for standard patterns
- One component per file — utility files, types (aside from props), constants, etc. go in a
utils/folder within the component's directory - Define props as TypeScript
typein the same file or a co-locatedtypes.ts - Default export for page-level components
- Use path aliases for cross-directory imports:
@utils/*,@models,@images/*
All user-visible strings must be translated. Use useNMStateTranslation() for simple strings and the Trans component for strings with embedded HTML:
import { useNMStateTranslation } from '@utils/hooks/useNMStateTranslation';
const MyComponent: FC = () => {
const { t } = useNMStateTranslation();
return <p>{t('My translatable string')}</p>;
};Never hardcode English text in JSX. Run npm run i18n to extract new translation keys.
The project uses ESLint + Prettier with enforced import sorting:
npm run lint # Check for lint errors
npm run lint:fix # Auto-fix lint errorsKey rules:
- Prettier: single quotes, trailing commas, 100-char print width
- Import sorting: enforced via
simple-import-sort— React first, then external packages, then internal paths, then relative imports, then CSS - No unused variables:
@typescript-eslint/no-unused-varsis set toerror - No prop-types: disabled (TypeScript types are used instead)
- Create a directory under
src/views/{view-name}/ - Add a
manifest.tsexporting{View}ExposedModulesand{View}Extensions - Register the extensions in
plugin-manifest.ts - Add a K8s model in
src/console-models/if needed - Export the model from
src/console-models/index.ts
Create a new file in src/console-models/ following the existing pattern:
import { K8sModel } from '@openshift-console/dynamic-plugin-sdk';
const MyResourceModel: K8sModel = {
apiGroup: 'nmstate.io',
apiVersion: 'v1',
kind: 'MyResource',
plural: 'myresources',
// ... other fields
};
export default MyResourceModel;Export it from src/console-models/index.ts and use @models to import.
npm test # Run all tests
npm run test:coverage # Run with coverage report
npm run test:updateSnapshot # Update snapshotsTests live alongside source files as *.test.ts(x) or *.spec.ts(x). The SDK and i18n are mocked via src/__mocks__/.
npm run cypress # Headless Chrome
npm run cypress:open # Interactive modeE2E specs live in cypress/e2e/. Tests run against http://localhost:9000 by default (override with BRIDGE_BASE_ADDRESS).
- New components: at minimum, test that they render without errors
- Utility functions: test edge cases and expected transformations
- E2E: cover user-facing workflows for new views or significant UI changes
Follow the existing commit style — short imperative subject line describing the change. Reference the Jira/Bugzilla ID when applicable (e.g., CNV-12345: add physical networks page).
- Run
npm run lintand fix any errors - Run
npm testand ensure tests pass - Test your changes in the console (run
npm run start-console) - Update translations if you added user-visible strings (
npm run i18n) - Update context files (CLAUDE.md, AGENTS.md, ARCHITECTURE.md) if adding or modifying the directory structure
- PRs require approval from at least one person in the reviewer list and a different person from the approver list in OWNERS. If the submitter is in one of the lists, their ack is added automatically
- Merge via merge commit (the repo uses merge commits, not squash)
- CI runs Prow-based checks — ensure
test-prow-e2e.shpasses
CVE fixes are the most common PR type. The typical workflow:
- Identify the vulnerable transitive dependency (e.g.,
lodash,immutable,qs) from anOCPBUGS-*ticket - Update or pin the dependency in
package.jsonand regeneratepackage-lock.json - Create the fix on
main, then cherry-pick to every active release branch (currentlyrelease-4.17throughrelease-4.23) - Title format:
OCPBUGS-{id}: CVE remediation for {package}onmain, prefixed with[release-X.Y]on release branches
Each release branch gets its own PR. Use openshift-cherrypick-robot labels or create cherry-picks manually.
The repo maintains multiple active release branches (release-4.17, release-4.18, ..., release-4.23). Each branch tracks a specific OpenShift release:
main— development branch for the next releaserelease-X.Y— stable branch for OpenShift X.Y; receives bug fixes and CVE remediations via cherry-picks- SDK version must correspond to the target release branch (e.g.,
release-4.22uses SDK 4.22.x)
This project is licensed under the Apache License 2.0.