Conversation
Replaces yarn 1 with pnpm 11 across the ui/ workspace and swaps ESLint/Prettier for oxlint/oxfmt, then brings the runtime libraries up to the versions the workspace is pinned against. Toolchain: - pnpm-workspace.yaml replaces the yarn "workspaces"/"resolutions" block; yarn.lock is dropped for pnpm-lock.yaml. Overrides, packageExtensions and allowBuilds carry over the constraints yarn resolutions encoded. - oxlintrc.json / .oxfmtrc.json replace the per-package .eslintrc and .prettierrc files; every package's lint/format scripts point at them. - tsconfig.base.json centralizes the compiler options each package used to repeat. Libraries: React 18 -> 19, React Router 6 -> 7, Vite 5 -> 8, Vitest 2 -> 4, TypeScript 5 -> 6, @testing-library/react 15 -> 16, jsdom 24 -> 29, @percona/percona-ui 1.0.23 -> 1.0.24. Two dependencies that yarn's flat node_modules provided implicitly are now declared, since pnpm's isolated store does not hoist them: material-react-table (apps/pmm) and @jest/globals (apps/pmm-compat). vitest.config.ts drops the hardcoded ../../node_modules React aliases, which do not exist under pnpm, in favour of resolve.dedupe. Build and dev environments learn pnpm via corepack, which resolves the version from the packageManager field in ui/package.json so it is pinned in exactly one place: the rpmbuild images, the devcontainer setup and the UI CI workflow. yarn stays installed for dashboards/pmm-app, which is still a yarn 1 project. Signed-off-by: Ignacio Durand <ignacio.durand@l7informatics.com>
|
Ignacio Durand seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account. You have signed the CLA already but the status is still pending? Let us recheck it. |
WalkthroughThe UI workspace migrates from Yarn to pnpm and from ESLint/Prettier to Oxc tooling. It adds workspace and TypeScript configuration, updates application dependencies and tests, and aligns development, CI, container, and documentation workflows. ChangesUI tooling migration
Estimated code review effort: 3 (Moderate) | ~25 minutes Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #5728 +/- ##
==========================================
+ Coverage 43.59% 44.81% +1.22%
==========================================
Files 415 418 +3
Lines 43134 43334 +200
==========================================
+ Hits 18804 19420 +616
+ Misses 22454 22001 -453
- Partials 1876 1913 +37
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 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 `@ui/Makefile`:
- Around line 1-31: Add a .PHONY declaration covering every command target
defined in the Makefile—dev, ci, format, format-check, lint, test, setup, build,
release, and clean—so matching files or directories cannot cause GNU Make to
skip their recipes.
In `@ui/packages/shared/package.json`:
- Around line 9-24: Update the package entry mappings in package.json so
published consumers resolve only generated artifacts under dist: change the
typesVersions target from src/index.tsx and the exports "." target from
src/index.ts to their corresponding dist files. Preserve the existing main,
module, and types entries.
🪄 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 Plus
Run ID: 64ede41a-cc65-4f62-b444-b65244f73733
⛔ Files ignored due to path filters (2)
ui/pnpm-lock.yamlis excluded by!**/pnpm-lock.yamlui/yarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (49)
.devcontainer/Makefile.devcontainer/setup.sh.github/workflows/ui.ymlAGENTS.mdbuild/docker/rpmbuild/Dockerfile.el8build/docker/rpmbuild/Dockerfile.el9build/docker/rpmbuild/Dockerfile.hetzner-el9ui/.oxfmtrc.jsonui/.vscode/settings.jsonui/Makefileui/README.mdui/apps/pmm-compat/.config/webpack/webpack.config.tsui/apps/pmm-compat/.eslintrcui/apps/pmm-compat/.prettierrc.jsui/apps/pmm-compat/package.jsonui/apps/pmm-compat/src/compat.test.tsui/apps/pmm-compat/src/compat.tsui/apps/pmm-compat/src/compat/toolbar.tsxui/apps/pmm-compat/src/contexts/theme/theme.provider.tsxui/apps/pmm-compat/src/lib/constants.tsui/apps/pmm-compat/src/lib/utils/document.test.tsui/apps/pmm-compat/src/lib/utils/document.tsui/apps/pmm-compat/src/lib/utils/navigator.tsui/apps/pmm-compat/src/lib/utils/shortcuts.tsui/apps/pmm-compat/src/lib/utils/variables.test.tsui/apps/pmm-compat/src/lib/utils/variables.tsui/apps/pmm-compat/src/plugin.jsonui/apps/pmm-compat/src/theme.tsui/apps/pmm-compat/tsconfig.jsonui/apps/pmm/.eslintrc.cjsui/apps/pmm/README.mdui/apps/pmm/package.jsonui/apps/pmm/src/contexts/grafana/grafana.context.types.tsui/apps/pmm/src/contexts/grafana/grafana.provider.tsxui/apps/pmm/src/hooks/utils/useKioskMode.test.tsui/apps/pmm/src/utils/dom.utils.test.tsui/apps/pmm/src/vite-env.d.tsui/apps/pmm/tsconfig.jsonui/apps/pmm/vite.config.tsui/apps/pmm/vitest.config.tsui/oxlintrc.jsonui/package.jsonui/packages/shared/.eslintrc.cjsui/packages/shared/.prettierignoreui/packages/shared/package.jsonui/packages/shared/tsconfig.jsonui/pnpm-workspace.yamlui/tsconfig.base.jsonui/tsconfig.json
💤 Files with no reviewable changes (6)
- ui/packages/shared/.prettierignore
- ui/apps/pmm-compat/.prettierrc.js
- ui/apps/pmm/.eslintrc.cjs
- ui/apps/pmm-compat/.eslintrc
- ui/packages/shared/.eslintrc.cjs
- ui/apps/pmm-compat/.config/webpack/webpack.config.ts
| "files": [ | ||
| "dist" | ||
| ], | ||
| "exports": { | ||
| ".": "./src/index.ts" | ||
| }, | ||
| "type": "module", | ||
| "main": "dist/esm/index.js", | ||
| "module": "dist/esm/index.js", | ||
| "types": "dist/index.d.ts", | ||
| "typesVersions": { | ||
| "*": { | ||
| "*": [ | ||
| "./src/index.tsx" | ||
| ] | ||
| } | ||
| }, | ||
| "prettier": "@percona/prettier-config", | ||
| "exports": { | ||
| ".": "./src/index.ts" |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
Point package entry points at published artifacts.
When this package is packed, files includes only dist, but typesVersions and exports resolve consumers to files under src. Those files are absent from the package, so installed consumers can fail. Point the mappings to the generated dist files.
Suggested export map
"exports": {
- ".": "./src/index.ts"
+ ".": {
+ "types": "./dist/index.d.ts",
+ "import": "./dist/esm/index.js"
+ }
},🤖 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 `@ui/packages/shared/package.json` around lines 9 - 24, Update the package
entry mappings in package.json so published consumers resolve only generated
artifacts under dist: change the typesVersions target from src/index.tsx and the
exports "." target from src/index.ts to their corresponding dist files. Preserve
the existing main, module, and types entries.
There was a problem hiding this comment.
Not taking this one — the suggested change would break the workspace. But it did point at a real (adjacent) bug, which is fixed in aa6feae.
Why the suggestion doesn't work: @pmm/shared has no build script. Its scripts block is lint, test, test:watch, format — nothing runs the rollup config, and turbo run build has no build task to invoke for it. So dist/ is never produced. Pointing exports at ./dist/esm/index.js and types at ./dist/index.d.ts would make every consumer resolve to files that don't exist, and turbo run check-types / build would fail immediately.
Resolving to src is deliberate here: consumers (apps/pmm, apps/pmm-compat) link the package through the pnpm workspace and compile it from source, so there's no build step to sequence.
The premise is also moot: the package is private, so it is never packed or published — the files/dist fields are vestigial. (private was actually the string "true", which npm's schema ignores; @copilot caught that separately and it's now a boolean, so this is properly enforced.)
What was genuinely broken: typesVersions pointed at ./src/index.tsx, and the entry is src/index.ts — a dangling path. Since consumers resolve through exports, I dropped the stale block rather than repointing it.
Verified after the change: turbo run check-types, lint, test and build all clean.
There was a problem hiding this comment.
Pull request overview
This PR migrates the PMM UI workspace tooling to pnpm (via corepack) and replaces ESLint/Prettier with oxlint/oxfmt, along with associated UI library upgrades and environment/CI updates to keep builds and local dev flows working.
Changes:
- Switch
ui/workspace management from Yarn 1 to pnpm (workspace file, pinned version viapackageManager, updated Make targets, CI/devcontainer/rpmbuild setup). - Replace ESLint/Prettier configuration and per-package lint/format scripts with centralized
oxlintrc.json+.oxfmtrc.json. - Upgrade and adapt UI dependencies/config/tests (React 19, React Router 7, Vite 8, Vitest 4, TS ~6) including pnpm-specific module resolution adjustments.
Reviewed changes
Copilot reviewed 47 out of 51 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| ui/tsconfig.json | Root tsconfig wiring (currently still extends shared package config). |
| ui/tsconfig.base.json | New shared TS compiler options baseline. |
| ui/README.md | Update UI docs from Yarn to pnpm. |
| ui/pnpm-workspace.yaml | New pnpm workspace + overrides/extensions/build allowances. |
| ui/packages/shared/tsconfig.json | Formatting/structure adjustments to shared package TS config. |
| ui/packages/shared/package.json | Switch shared package scripts to oxlint/oxfmt; dependency/peer updates. |
| ui/packages/shared/.prettierignore | Remove Prettier ignore file (Prettier removed). |
| ui/packages/shared/.eslintrc.cjs | Remove ESLint config (ESLint removed). |
| ui/package.json | Workspace root updated for pnpm + oxlint/oxfmt + TS 6. |
| ui/oxlintrc.json | Add centralized oxlint rule set + ignores. |
| ui/Makefile | Replace yarn invocations with pnpm + corepack bootstrap. |
| ui/apps/pmm/vitest.config.ts | Remove hardcoded node_modules aliases; use dedupe/inline for pnpm React singleton. |
| ui/apps/pmm/vite.config.ts | Docs tweak for pnpm link. |
| ui/apps/pmm/tsconfig.json | TS option update (ignoreDeprecations) and config tweaks for TS6. |
| ui/apps/pmm/src/vite-env.d.ts | Add wildcard module declaration for @fontsource/* side-effect imports. |
| ui/apps/pmm/src/utils/dom.utils.test.ts | Test timeout adjustment + globalThis usage fix. |
| ui/apps/pmm/src/hooks/utils/useKioskMode.test.ts | Update mocking approach for React Router v7 ESM module semantics. |
| ui/apps/pmm/src/contexts/grafana/grafana.provider.tsx | Ref typing initialization adjustment for stricter TS/react types. |
| ui/apps/pmm/src/contexts/grafana/grafana.context.types.ts | Update iframe ref typing to allow null. |
| ui/apps/pmm/README.md | Update local linking docs from yarn link to pnpm link workflow. |
| ui/apps/pmm/package.json | Upgrade core UI deps (React 19, Router 7, Vite/Vitest/TS) + add missing deps under pnpm. |
| ui/apps/pmm/.eslintrc.cjs | Remove ESLint config (ESLint removed). |
| ui/apps/pmm-compat/tsconfig.json | Add ts-node compiler options for tooling compatibility. |
| ui/apps/pmm-compat/src/theme.ts | Formatting changes (oxfmt). |
| ui/apps/pmm-compat/src/plugin.json | Formatting changes (oxfmt). |
| ui/apps/pmm-compat/src/lib/utils/variables.ts | Formatting changes (oxfmt). |
| ui/apps/pmm-compat/src/lib/utils/variables.test.ts | Formatting changes (oxfmt). |
| ui/apps/pmm-compat/src/lib/utils/shortcuts.ts | Formatting changes (oxfmt). |
| ui/apps/pmm-compat/src/lib/utils/navigator.ts | Formatting changes (oxfmt). |
| ui/apps/pmm-compat/src/lib/utils/document.ts | Formatting changes (oxfmt). |
| ui/apps/pmm-compat/src/lib/utils/document.test.ts | Formatting changes (oxfmt). |
| ui/apps/pmm-compat/src/lib/constants.ts | Formatting changes (oxfmt). |
| ui/apps/pmm-compat/src/contexts/theme/theme.provider.tsx | Formatting changes (oxfmt). |
| ui/apps/pmm-compat/src/compat/toolbar.tsx | Formatting changes (oxfmt). |
| ui/apps/pmm-compat/src/compat.ts | Formatting + minor readability changes while adapting toolchain. |
| ui/apps/pmm-compat/src/compat.test.ts | Formatting changes (oxfmt). |
| ui/apps/pmm-compat/package.json | Switch lint/format to oxlint/oxfmt; add explicit deps needed under pnpm. |
| ui/apps/pmm-compat/.prettierrc.js | Remove Prettier config (Prettier removed). |
| ui/apps/pmm-compat/.eslintrc | Remove ESLint config (ESLint removed). |
| ui/apps/pmm-compat/.config/webpack/webpack.config.ts | Remove ESLint webpack plugin integration. |
| ui/.vscode/settings.json | Switch editor integration hints from ESLint to oxc/oxlint. |
| ui/.oxfmtrc.json | Add centralized oxfmt config + ignore patterns. |
| build/docker/rpmbuild/Dockerfile.hetzner-el9 | Enable corepack in rpmbuild image for pnpm resolution. |
| build/docker/rpmbuild/Dockerfile.el9 | Enable corepack in rpmbuild image for pnpm resolution. |
| build/docker/rpmbuild/Dockerfile.el8 | Enable corepack in rpmbuild image for pnpm resolution. |
| AGENTS.md | Update UI dependency add guidance from yarn to pnpm. |
| .github/workflows/ui.yml | Switch CI caching to pnpm + enable corepack. |
| .devcontainer/setup.sh | Install pnpm via corepack (keep yarn for dashboards/pmm-app). |
| .devcontainer/Makefile | Update devcontainer UI targets from yarn to pnpm. |
| - name: Enable corepack | ||
| run: corepack enable | ||
|
|
||
| - name: Setup nodejs | ||
| uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 | ||
| with: | ||
| node-version-file: ui/.nvmrc | ||
| cache: yarn | ||
| cache-dependency-path: ui/yarn.lock | ||
| cache: pnpm | ||
| cache-dependency-path: ui/pnpm-lock.yaml | ||
|
|
There was a problem hiding this comment.
I checked this one and I'm keeping the current order — the ordering is required, not incidental.
actions/setup-node with cache: pnpm shells out to pnpm store path to work out what to cache. If pnpm isn't resolvable before setup-node runs, that step fails with Unable to locate executable file: pnpm. This is why pnpm's own CI docs put the pnpm setup step ahead of setup-node.
On the "runs against the runner's default Node" concern: corepack enable writes shims into the current Node's bin dir, but those shims resolve node from PATH at invocation time. setup-node prepends the pinned toolchain to PATH, so by the time make setup runs, the shim is driving the pinned Node — which is what we want.
Empirically the UI CI check is green on this PR, exercising make format-check, make lint, make test and make build through that shim. Swapping the order would break the cache step, so I'd rather not.
| { | ||
| "extends": "./packages/shared/tsconfig.json" | ||
| } No newline at end of file | ||
| } |
There was a problem hiding this comment.
Correct, and thanks — that was a real gap. Fixed in aa6feae.
ui/tsconfig.json now extends the new base:
{ "extends": "./tsconfig.base.json" }The old target was worse than just "not the base": extending ./packages/shared/tsconfig.json also inherited that package's "include": ["src"], which is meaningless at the workspace root.
One clarification on the "centralize/shared" framing, and I've corrected the PR description accordingly: on this branch the base is consumed only by the root config. The packages that actually extend it — packages/sep/{api,framework,shared} and packages/plugins/atw — arrive in the stacked child PR #5653, which is why the file lands here.
I deliberately did not make apps/pmm and apps/pmm-compat extend it. Their configs are not incidental duplication: apps/pmm pins target: ES2020 / lib: ES2020 against the base's ES2022/ES2023, and pmm-compat extends @grafana/tsconfig because it is a Grafana plugin. Rehoming those is a behavior change in its own right, not part of a package-manager swap.
- ui/tsconfig.json extends tsconfig.base.json instead of reaching into packages/shared/tsconfig.json. The old target also dragged in that package's `include: ["src"]`, which is meaningless at the workspace root. - @pmm/shared: `private` was the string "true" rather than a boolean, so npm's schema validation ignores it; and `typesVersions` pointed at ./src/index.tsx, which does not exist (the entry is index.ts). Consumers resolve through `exports`, so the stale block is dropped rather than repointed. - ui/Makefile declares its command targets .PHONY so a stray file or directory named after one cannot make GNU Make skip the recipe. Signed-off-by: Ignacio Durand <ignacio.durand@l7informatics.com>
Ticket number: PMM-15288
Feature build: SUBMODULES-0
What
Splits the toolchain half of #5653 into its own PR. This one carries only the package manager, linter/formatter and library upgrades; the SEP UI migration (new components, routes,
packages/sep/*) stays in #5653, which is now stacked on top of this branch.Toolchain
ui/.pnpm-workspace.yamlreplaces the yarnworkspaces/resolutionsblock;yarn.lock→pnpm-lock.yaml.overrides,packageExtensionsandallowBuildscarry over the constraints the yarnresolutionsencoded.oxlintrc.json+.oxfmtrc.jsonat the workspace root replace the per-package.eslintrc/.prettierrcfiles.tsconfig.base.jsonholds the compiler options shared across packages; the workspace roottsconfig.jsonextends it. Its main consumers —packages/sep/*andpackages/plugins/atw— arrive in the stacked child PR PMM-15216 Migrate the SEP UI into PMM #5653, which is why it lands here.apps/pmmandapps/pmm-compatintentionally keep their own configs (ES2020 target and@grafana/tsconfigrespectively).Libraries
React 18 → 19, React Router 6 → 7, Vite 5 → 8, Vitest 2 → 4, TypeScript 5 → 6,
@testing-library/react15 → 16, jsdom 24 → 29,@percona/percona-ui1.0.23 → 1.0.24.Two dependencies that yarn's flat
node_modulesprovided implicitly are now declared, since pnpm's isolated store doesn't hoist them:material-react-table(apps/pmm) and@jest/globals(apps/pmm-compat).vitest.config.tsdrops the hardcoded../../node_modulesReact aliases — those paths don't exist under pnpm — in favour ofresolve.dedupe.Build & dev environments
corepackteaches the rpmbuild images, the devcontainer and the UI CI workflow about pnpm. It resolves the version from thepackageManagerfield inui/package.json, so the version is pinned in exactly one place and a bump needs no Dockerfile edit. yarn stays installed fordashboards/pmm-app, which is still a yarn 1 project.Review comments from #5653 addressed here
npm install -g pnpm@11.1.3is gone from all three rpmbuild Dockerfiles, replaced byRUN corepack enable. corepack readspackageManagerfromui/package.jsonat build time, so the version lives in one place.ui/builds with pnpm;dashboards/pmm-app(the QAN Grafana plugin) is still a yarn 1 project and is built from the same image. The Dockerfile comment now says so explicitly.Verification
From
ui/:pnpm installmake format-check(oxfmt)make lint(oxlint)make test(vitest)make buildturbo run check-typesRe-run after the review fixes in
aa6feae; all still clean.Related
If this PR adds, removes or alters one or more API endpoints, please review and update the relevant API documentation as well:
Summary by CodeRabbit
Development Experience
Tooling
Quality