Skip to content

fix(plugin-js-packages): prevent negative scores in yarn v2+ workspaces #1025

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 7, 2025

Conversation

matejchalk
Copy link
Collaborator

Error reported by customer trying to integrate @code-pushup/js-packages-plugin in their Yarn 4 workspace.

$ yarn outdated --json

[ warn ] Plugins failed: 
[ warn ] Error: - Plugin JS Packages (js-packages) produced the following error:
  - Audit output is invalid: [
  {
    "code": "too_small",
    "minimum": 0,
    "type": "number",
    "inclusive": true,
    "exact": false,
    "message": "Number must be greater than or equal to 0",
    "path": [
      0,
      "score"
    ]
  },
  {
    "code": "too_small",
    "minimum": 0,
    "type": "number",
    "inclusive": true,
    "exact": false,
    "message": "Number must be greater than or equal to 0",
    "path": [
      1,
      "score"
    ]
  }
]
Error: Executing 1 plugin failed.

The cause of the negative scores is the number of packages with outdated major versions (from yarn outdated --json) exceeds the total number of packages (from root package.json). This is likely caused by the fact that by default, yarn-plugin-outdated includes all workspaces in it's output, and this can even result in a package being listed several times. For example, running yarn outdated in rx-angular (also uses Yarn v4 workspaces) results in this output (notice duplicates like tslib):

➤ YN0000: Package                                  Current    Latest        Workspace                   Package Type   
➤ YN0000: @angular-devkit/build-angular            19.0.0     20.0.5        rx-angular                  devDependencies
➤ YN0000: @angular-devkit/core                     19.0.0     20.0.5        rx-angular                  devDependencies
➤ YN0000: @angular-devkit/schematics               19.0.0     20.0.5        rx-angular                  devDependencies
➤ YN0000: @angular-eslint/eslint-plugin            19.0.2     20.1.1        rx-angular                  devDependencies
➤ YN0000: @angular-eslint/eslint-plugin-template   19.0.2     20.1.1        rx-angular                  devDependencies
➤ YN0000: @angular-eslint/template-parser          19.0.2     20.1.1        rx-angular                  devDependencies
➤ YN0000: @angular/animations                      19.0.0     20.0.6        rx-angular                  dependencies
➤ YN0000: @angular/build                           19.0.0     20.0.5        rx-angular                  devDependencies
➤ YN0000: @angular/cdk                             19.0.0     20.0.5        rx-angular                  dependencies
➤ YN0000: @angular/cdk-experimental                19.0.0     20.0.5        rx-angular                  dependencies
➤ YN0000: @angular/cli                             19.0.0     20.0.5        rx-angular                  devDependencies
➤ YN0000: @angular/common                          19.0.0     20.0.6        rx-angular                  dependencies
➤ YN0000: @angular/compiler                        19.0.0     20.0.6        rx-angular                  dependencies
➤ YN0000: @angular/compiler-cli                    19.0.0     20.0.6        rx-angular                  devDependencies
➤ YN0000: @angular/core                            19.0.0     20.0.6        rx-angular                  dependencies
➤ YN0000: @angular/forms                           19.0.0     20.0.6        rx-angular                  dependencies
➤ YN0000: @angular/language-service                19.0.0     20.0.6        rx-angular                  devDependencies
➤ YN0000: @angular/material                        19.0.0     20.0.5        rx-angular                  dependencies
➤ YN0000: @angular/platform-browser                19.0.0     20.0.6        rx-angular                  dependencies
➤ YN0000: @angular/platform-browser-dynamic        19.0.0     20.0.6        rx-angular                  dependencies
➤ YN0000: @angular/platform-server                 19.0.0     20.0.6        rx-angular                  dependencies
➤ YN0000: @angular/router                          19.0.0     20.0.6        rx-angular                  dependencies
➤ YN0000: @angular/ssr                             19.0.0     20.0.5        rx-angular                  dependencies
➤ YN0000: @commitlint/cli                          19.2.1     19.8.1        rx-angular                  devDependencies
➤ YN0000: @commitlint/config-angular               19.1.0     19.8.1        rx-angular                  devDependencies
➤ YN0000: @docusaurus/core                         2.0.1      3.8.1         docs                        dependencies
➤ YN0000: @docusaurus/module-type-aliases          2.0.1      3.8.1         docs                        devDependencies
➤ YN0000: @docusaurus/preset-classic               2.0.1      3.8.1         docs                        dependencies
➤ YN0000: @easyops-cn/docusaurus-search-local      0.32.1     0.51.1        docs                        dependencies
➤ YN0000: @jscutlery/semver                        5.5.1      5.6.0         rx-angular                  devDependencies
➤ YN0000: @mdx-js/react                            1.6.22     3.1.0         docs                        dependencies
➤ YN0000: @nx-plus/docusaurus                      14.1.0     15.0.0-rc.0   rx-angular                  devDependencies
➤ YN0000: @nx/angular                              20.1.0     21.2.2        rx-angular                  devDependencies
➤ YN0000: @nx/cypress                              20.1.0     21.2.2        rx-angular                  devDependencies
➤ YN0000: @nx/eslint                               20.1.0     21.2.2        rx-angular                  devDependencies
➤ YN0000: @nx/eslint-plugin                        20.1.0     21.2.2        rx-angular                  devDependencies
➤ YN0000: @nx/jest                                 20.1.0     21.2.2        rx-angular                  devDependencies
➤ YN0000: @nx/js                                   20.1.0     21.2.2        rx-angular                  devDependencies
➤ YN0000: @nx/node                                 20.1.0     21.2.2        rx-angular                  devDependencies
➤ YN0000: @nx/workspace                            20.1.0     21.2.2        rx-angular                  devDependencies
➤ YN0000: @schematics/angular                      19.0.0     20.0.5        rx-angular                  devDependencies
➤ YN0000: @swc-node/register                       1.9.2      1.10.10       rx-angular                  devDependencies
➤ YN0000: @swc/core                                1.5.7      1.12.9        rx-angular                  devDependencies
➤ YN0000: @tsconfig/docusaurus                     1.0.7      2.0.3         docs                        devDependencies
➤ YN0000: @types/benchmark                         2.1.2      2.1.5         rx-angular                  devDependencies
➤ YN0000: @types/express                           4.17.14    5.0.3         rx-angular                  devDependencies
➤ YN0000: @types/jest                              29.5.14    30.0.0        rx-angular                  devDependencies
➤ YN0000: @types/klaw-sync                         6.0.1      6.0.5         rx-angular                  devDependencies
➤ YN0000: @types/lodash                            4.14.196   4.17.20       rx-angular                  devDependencies
➤ YN0000: @types/node                              18.19.21   24.0.10       rx-angular                  devDependencies
➤ YN0000: @typescript-eslint/eslint-plugin         8.15.0     8.35.1        rx-angular                  devDependencies
➤ YN0000: @typescript-eslint/parser                8.15.0     8.35.1        rx-angular                  devDependencies
➤ YN0000: @typescript-eslint/utils                 7.18.0     8.35.1        rx-angular                  dependencies
➤ YN0000: @typescript-eslint/utils                 7.10.0     8.35.1        @rx-angular/eslint-plugin   dependencies
➤ YN0000: autoprefixer                             10.4.18    10.4.21       rx-angular                  devDependencies
➤ YN0000: bootstrap                                5.2.3      5.3.7         rx-angular                  dependencies
➤ YN0000: browser-sync                             3.0.2      3.0.4         rx-angular                  devDependencies
➤ YN0000: clsx                                     1.2.1      2.1.1         docs                        dependencies
➤ YN0000: cypress                                  13.16.0    14.5.1        rx-angular                  devDependencies
➤ YN0000: eslint                                   8.57.1     9.30.1        rx-angular                  devDependencies
➤ YN0000: eslint-config-prettier                   9.1.0      10.1.5        rx-angular                  devDependencies
➤ YN0000: eslint-plugin-cypress                    4.1.0      5.1.0         rx-angular                  devDependencies
➤ YN0000: eslint-plugin-simple-import-sort         12.0.0     12.1.1        rx-angular                  devDependencies
➤ YN0000: express                                  4.18.2     5.1.0         rx-angular                  devDependencies
➤ YN0000: husky                                    9.0.11     9.1.7         rx-angular                  devDependencies
➤ YN0000: jest                                     29.7.0     30.0.4        rx-angular                  devDependencies
➤ YN0000: jest-environment-jsdom                   29.7.0     30.0.4        rx-angular                  devDependencies
➤ YN0000: jest-preset-angular                      14.1.0     14.6.0        rx-angular                  devDependencies
➤ YN0000: jsonc-eslint-parser                      2.3.0      2.4.0         rx-angular                  devDependencies
➤ YN0000: klaw-sync                                6.0.0      7.0.0         rx-angular                  devDependencies
➤ YN0000: lint-staged                              12.5.0     16.1.2        rx-angular                  devDependencies
➤ YN0000: markdown-link-check                      3.11.2     3.13.7        rx-angular                  devDependencies
➤ YN0000: ng-morph                                 4.0.3      4.8.4         @rx-angular/cdk             dependencies
➤ YN0000: ng-morph                                 4.0.3      4.8.4         @rx-angular/state           dependencies
➤ YN0000: ng-morph                                 4.0.3      4.8.4         @rx-angular/template        dependencies
➤ YN0000: ng-packagr                               19.0.1     20.0.1        rx-angular                  devDependencies
➤ YN0000: ngx-skeleton-loader                      7.0.0      11.2.1        rx-angular                  dependencies
➤ YN0000: nx                                       20.1.0     21.2.2        rx-angular                  devDependencies
➤ YN0000: postcss                                  8.4.23     8.5.6         rx-angular                  devDependencies
➤ YN0000: postcss-import                           14.1.0     16.1.1        rx-angular                  devDependencies
➤ YN0000: postcss-preset-env                       7.5.0      10.2.4        rx-angular                  devDependencies
➤ YN0000: prettier                                 3.2.5      3.6.2         rx-angular                  devDependencies
➤ YN0000: prism-react-renderer                     1.3.5      2.4.1         docs                        dependencies
➤ YN0000: react                                    17.0.2     19.1.0        docs                        dependencies
➤ YN0000: react-dom                                17.0.2     19.1.0        docs                        dependencies
➤ YN0000: react-player                             2.12.0     3.1.0         rx-angular                  dependencies
➤ YN0000: rx-query                                 1.0.2      2.0.1         rx-angular                  dependencies
➤ YN0000: rxjs                                     7.8.0      7.8.2         rx-angular                  dependencies
➤ YN0000: ts-jest                                  29.1.0     29.4.0        rx-angular                  devDependencies
➤ YN0000: ts-node                                  10.9.1     10.9.2        rx-angular                  devDependencies
➤ YN0000: tslib                                    2.5.0      2.8.1         rx-angular                  dependencies
➤ YN0000: tslib                                    2.5.0      2.8.1         @rx-angular/cdk             dependencies
➤ YN0000: tslib                                    2.5.0      2.8.1         @rx-angular/isr             dependencies
➤ YN0000: tslib                                    2.5.0      2.8.1         @rx-angular/state           dependencies
➤ YN0000: tslib                                    2.5.0      2.8.1         @rx-angular/template        dependencies
➤ YN0000: tslib                                    2.5.0      2.8.1         @test-helpers/rx-angular    dependencies
➤ YN0000: typescript                               5.5.4      5.8.3         rx-angular                  devDependencies
➤ YN0000: typescript                               4.9.5      5.8.3         docs                        devDependencies
➤ YN0000: zone.js                                  0.14.10    0.15.1        rx-angular                  dependencies

Our plugin isn't designed to handle workspaces, so the simplest solution is to filter out results from other packages using --workspace=.. Tested in rx-angular, where the output becomes (notice no duplicate packages and Workspace column is always the same):

➤ YN0000: Package                                  Current    Latest        Workspace    Package Type   
➤ YN0000: @angular-devkit/build-angular            19.0.0     20.0.5        rx-angular   devDependencies
➤ YN0000: @angular-devkit/core                     19.0.0     20.0.5        rx-angular   devDependencies
➤ YN0000: @angular-devkit/schematics               19.0.0     20.0.5        rx-angular   devDependencies
➤ YN0000: @angular-eslint/eslint-plugin            19.0.2     20.1.1        rx-angular   devDependencies
➤ YN0000: @angular-eslint/eslint-plugin-template   19.0.2     20.1.1        rx-angular   devDependencies
➤ YN0000: @angular-eslint/template-parser          19.0.2     20.1.1        rx-angular   devDependencies
➤ YN0000: @angular/animations                      19.0.0     20.0.6        rx-angular   dependencies
➤ YN0000: @angular/build                           19.0.0     20.0.5        rx-angular   devDependencies
➤ YN0000: @angular/cdk                             19.0.0     20.0.5        rx-angular   dependencies
➤ YN0000: @angular/cdk-experimental                19.0.0     20.0.5        rx-angular   dependencies
➤ YN0000: @angular/cli                             19.0.0     20.0.5        rx-angular   devDependencies
➤ YN0000: @angular/common                          19.0.0     20.0.6        rx-angular   dependencies
➤ YN0000: @angular/compiler                        19.0.0     20.0.6        rx-angular   dependencies
➤ YN0000: @angular/compiler-cli                    19.0.0     20.0.6        rx-angular   devDependencies
➤ YN0000: @angular/core                            19.0.0     20.0.6        rx-angular   dependencies
➤ YN0000: @angular/forms                           19.0.0     20.0.6        rx-angular   dependencies
➤ YN0000: @angular/language-service                19.0.0     20.0.6        rx-angular   devDependencies
➤ YN0000: @angular/material                        19.0.0     20.0.5        rx-angular   dependencies
➤ YN0000: @angular/platform-browser                19.0.0     20.0.6        rx-angular   dependencies
➤ YN0000: @angular/platform-browser-dynamic        19.0.0     20.0.6        rx-angular   dependencies
➤ YN0000: @angular/platform-server                 19.0.0     20.0.6        rx-angular   dependencies
➤ YN0000: @angular/router                          19.0.0     20.0.6        rx-angular   dependencies
➤ YN0000: @angular/ssr                             19.0.0     20.0.5        rx-angular   dependencies
➤ YN0000: @commitlint/cli                          19.2.1     19.8.1        rx-angular   devDependencies
➤ YN0000: @commitlint/config-angular               19.1.0     19.8.1        rx-angular   devDependencies
➤ YN0000: @jscutlery/semver                        5.5.1      5.6.0         rx-angular   devDependencies
➤ YN0000: @nx-plus/docusaurus                      14.1.0     15.0.0-rc.0   rx-angular   devDependencies
➤ YN0000: @nx/angular                              20.1.0     21.2.2        rx-angular   devDependencies
➤ YN0000: @nx/cypress                              20.1.0     21.2.2        rx-angular   devDependencies
➤ YN0000: @nx/eslint                               20.1.0     21.2.2        rx-angular   devDependencies
➤ YN0000: @nx/eslint-plugin                        20.1.0     21.2.2        rx-angular   devDependencies
➤ YN0000: @nx/jest                                 20.1.0     21.2.2        rx-angular   devDependencies
➤ YN0000: @nx/js                                   20.1.0     21.2.2        rx-angular   devDependencies
➤ YN0000: @nx/node                                 20.1.0     21.2.2        rx-angular   devDependencies
➤ YN0000: @nx/workspace                            20.1.0     21.2.2        rx-angular   devDependencies
➤ YN0000: @schematics/angular                      19.0.0     20.0.5        rx-angular   devDependencies
➤ YN0000: @swc-node/register                       1.9.2      1.10.10       rx-angular   devDependencies
➤ YN0000: @swc/core                                1.5.7      1.12.9        rx-angular   devDependencies
➤ YN0000: @types/benchmark                         2.1.2      2.1.5         rx-angular   devDependencies
➤ YN0000: @types/express                           4.17.14    5.0.3         rx-angular   devDependencies
➤ YN0000: @types/jest                              29.5.14    30.0.0        rx-angular   devDependencies
➤ YN0000: @types/klaw-sync                         6.0.1      6.0.5         rx-angular   devDependencies
➤ YN0000: @types/lodash                            4.14.196   4.17.20       rx-angular   devDependencies
➤ YN0000: @types/node                              18.19.21   24.0.10       rx-angular   devDependencies
➤ YN0000: @typescript-eslint/eslint-plugin         8.15.0     8.35.1        rx-angular   devDependencies
➤ YN0000: @typescript-eslint/parser                8.15.0     8.35.1        rx-angular   devDependencies
➤ YN0000: @typescript-eslint/utils                 7.18.0     8.35.1        rx-angular   dependencies
➤ YN0000: autoprefixer                             10.4.18    10.4.21       rx-angular   devDependencies
➤ YN0000: bootstrap                                5.2.3      5.3.7         rx-angular   dependencies
➤ YN0000: browser-sync                             3.0.2      3.0.4         rx-angular   devDependencies
➤ YN0000: cypress                                  13.16.0    14.5.1        rx-angular   devDependencies
➤ YN0000: eslint                                   8.57.1     9.30.1        rx-angular   devDependencies
➤ YN0000: eslint-config-prettier                   9.1.0      10.1.5        rx-angular   devDependencies
➤ YN0000: eslint-plugin-cypress                    4.1.0      5.1.0         rx-angular   devDependencies
➤ YN0000: eslint-plugin-simple-import-sort         12.0.0     12.1.1        rx-angular   devDependencies
➤ YN0000: express                                  4.18.2     5.1.0         rx-angular   devDependencies
➤ YN0000: husky                                    9.0.11     9.1.7         rx-angular   devDependencies
➤ YN0000: jest                                     29.7.0     30.0.4        rx-angular   devDependencies
➤ YN0000: jest-environment-jsdom                   29.7.0     30.0.4        rx-angular   devDependencies
➤ YN0000: jest-preset-angular                      14.1.0     14.6.0        rx-angular   devDependencies
➤ YN0000: jsonc-eslint-parser                      2.3.0      2.4.0         rx-angular   devDependencies
➤ YN0000: klaw-sync                                6.0.0      7.0.0         rx-angular   devDependencies
➤ YN0000: lint-staged                              12.5.0     16.1.2        rx-angular   devDependencies
➤ YN0000: markdown-link-check                      3.11.2     3.13.7        rx-angular   devDependencies
➤ YN0000: ng-packagr                               19.0.1     20.0.1        rx-angular   devDependencies
➤ YN0000: ngx-skeleton-loader                      7.0.0      11.2.1        rx-angular   dependencies
➤ YN0000: nx                                       20.1.0     21.2.2        rx-angular   devDependencies
➤ YN0000: postcss                                  8.4.23     8.5.6         rx-angular   devDependencies
➤ YN0000: postcss-import                           14.1.0     16.1.1        rx-angular   devDependencies
➤ YN0000: postcss-preset-env                       7.5.0      10.2.4        rx-angular   devDependencies
➤ YN0000: prettier                                 3.2.5      3.6.2         rx-angular   devDependencies
➤ YN0000: react-player                             2.12.0     3.1.0         rx-angular   dependencies
➤ YN0000: rx-query                                 1.0.2      2.0.1         rx-angular   dependencies
➤ YN0000: rxjs                                     7.8.0      7.8.2         rx-angular   dependencies
➤ YN0000: ts-jest                                  29.1.0     29.4.0        rx-angular   devDependencies
➤ YN0000: ts-node                                  10.9.1     10.9.2        rx-angular   devDependencies
➤ YN0000: tslib                                    2.5.0      2.8.1         rx-angular   dependencies
➤ YN0000: typescript                               5.5.4      5.8.3         rx-angular   devDependencies
➤ YN0000: zone.js                                  0.14.10    0.15.1        rx-angular   dependencies

In Yarn 4 projects which don't use workspaces (simulated in rx-angular by removing workspaces from package.json), the output is the same regardless of --workspace=. being present, except the Workspace column isn't included (but we don't use it anyway).

@matejchalk matejchalk self-assigned this Jul 7, 2025
@github-actions github-actions bot added the 🧩 js-packages-plugin Plugin for audit and outdated dependencies label Jul 7, 2025
@matejchalk matejchalk added the 🐛 bug something isn't working label Jul 7, 2025
@matejchalk matejchalk requested a review from BioPhoton July 7, 2025 14:13
Copy link

github-actions bot commented Jul 7, 2025

Code PushUp

😟 Code PushUp report has regressed – compared current commit 3880ae4 with previous commit 562c83b.

🕵️ See full comparison in Code PushUp portal 🔍

🏷️ Categories

🏷️ Category ⭐ Previous score ⭐ Current score 🔄 Score change
Performance 🔴 46 🔴 43 ↓ −3.3
Code coverage 🟢 90 🟢 90
Security 🟡 61 🟡 61
Updates 🟡 77 🟡 77
Accessibility 🟢 92 🟢 92
Best Practices 🟢 100 🟢 100
SEO 🟡 61 🟡 61
Type Safety 🟢 100 🟢 100
Bug prevention 🟢 100 🟢 100
Miscellaneous 🟢 100 🟢 100
Code style 🟢 100 🟢 100
Documentation 🔴 23 🔴 23
👎 1 group regressed, 👎 5 audits regressed, 12 audits changed without impacting score

🗃️ Groups

🔌 Plugin 🗃️ Group ⭐ Previous score ⭐ Current score 🔄 Score change
Lighthouse Performance 🔴 46 🔴 43 ↓ −3.3

20 other groups are unchanged.

🛡️ Audits

🔌 Plugin 🛡️ Audit 📏 Previous value 📏 Current value 🔄 Value change
Lighthouse Speed Index 🟥 6.5 s 🟥 7.4 s ↑ +14.9 %
Lighthouse Largest Contentful Paint 🟨 4.0 s 🟥 4.2 s ↑ +4.8 %
Lighthouse First Contentful Paint 🟥 3.2 s 🟥 3.4 s ↑ +5 %
Lighthouse Time to Interactive 🟥 12.7 s 🟥 14.1 s ↑ +10.9 %
Lighthouse Total Blocking Time 🟥 3,840 ms 🟥 4,660 ms ↑ +21.3 %
Lighthouse Avoids enormous network payloads 🟩 Total size was 1,900 KiB 🟩 Total size was 1,916 KiB ↑ +0.8 %
Lighthouse Minimizes main-thread work 🟥 16.4 s 🟥 18.3 s ↑ +11.8 %
Lighthouse JavaScript execution time 🟥 6.5 s 🟥 8.0 s ↑ +23.7 %
Lighthouse Metrics 🟩 100% 🟩 100% ↑ +10.9 %
Lighthouse Max Potential First Input Delay 🟥 2,140 ms 🟥 2,580 ms ↑ +20.7 %
Lighthouse Reduce unused CSS 🟥 Potential savings of 68 KiB 🟥 Potential savings of 69 KiB ↓ −82.4 %
Lighthouse Uses efficient cache policy on static assets 🟨 30 resources found 🟨 30 resources found ↑ +0.1 %
Lighthouse Server Backend Latencies 🟩 160 ms 🟩 250 ms ↑ +57.5 %
Lighthouse Network Round Trip Times 🟩 10 ms 🟩 60 ms ↑ +303 %
Lighthouse Initial server response time was short 🟩 Root document took 450 ms 🟩 Root document took 480 ms ↑ +6.3 %
Lighthouse Avoids an excessive DOM size 🟥 2,248 elements 🟥 2,246 elements ↓ −0.1 %
Code coverage Branch coverage 🟨 85.7 % 🟨 85.7 % ↓ −0.1 %

588 other audits are unchanged.

@matejchalk matejchalk merged commit b6f9633 into main Jul 7, 2025
17 checks passed
@matejchalk matejchalk deleted the fix-yarn-modern-workspaces branch July 7, 2025 14:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🐛 bug something isn't working 🧩 js-packages-plugin Plugin for audit and outdated dependencies
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants