Skip to content

Update dependency vitest to v4 [SECURITY]#3002

Merged
gardener-prow[bot] merged 4 commits into
masterfrom
renovate/npm-vitest-vulnerability
Jun 2, 2026
Merged

Update dependency vitest to v4 [SECURITY]#3002
gardener-prow[bot] merged 4 commits into
masterfrom
renovate/npm-vitest-vulnerability

Conversation

@gardener-ci-robot

@gardener-ci-robot gardener-ci-robot commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

ℹ️ Note

This PR body was truncated due to platform limits.

This PR contains the following updates:

Package Change Age Confidence
vitest (source) ^3.0.0^4.0.0 age confidence

When Vitest UI server is listening, arbitrary file can be read and executed

CVE-2026-47429 / GHSA-5xrq-8626-4rwp

More information

Details

Summary

Arbitrary file can be read on Windows when Vitest UI server is listening, especially when exposed to the network.

Impact

Only users that match either of the following conditions are affected:

  • explicitly exposes the Vitest UI server to the network (using --api.host or api.host config option)
  • running the Vitest UI or Browser Mode on Windows
Details

The API handler for /__vitest_attachment__ uses the deprecated isFileServingAllowed incorrectly.
https://github.com/vitest-dev/vitest/blob/eb1abf08573032a532015b999ad3501c5e89e3bb/packages/ui/node/index.ts#L77
The function expects the passed value to use cleanUrl after the check before file system related operation.
Because of this, it is possible to bypass the check by \\?\\..\\. This is not possible on Linux as Linux errors if a directory named ? does not exist.

A similar problem exists in other places as well.

That said, this isFileServingAllowed check does not actually prevent the API to be abused. Since the API has rerun feature and file write feature, it's possible to run arbitrary script by writing a script as a test file using saveTestFile and running it using rerun. This means exposing the API / Vitest UI is equivalent to giving script execution access.
On the browser mode side, there're readFile / writeFile / saveSnapshotFile. So exposing the browser mode is equivalent to giving file read / write access.

PoC
  1. Run Vitest UI
  2. Get the API token by curl http://localhost:51204/__vitest__/
  3. Run curl "http://localhost:51204/__vitest_attachment__?path=C:\\path\\to\\project\\?\\..\\..\\secret.txt&contentType=text/plain&token=$TOKEN" (TOKEN is the API token)
  4. curl shows the content of secret.txt that is outside the project directory
Mitigations

Vitest now ships two configuration flags, allowWrite and allowExec, that gate the privileged operations exploited by this vulnerability. Both are disabled by default whenever the API server is bound to a non-localhost host, ensuring that exposing the server to the network no longer implicitly grants write or execute capabilities to remote clients.

When these flags are disabled, the UI also enters a read-only mode: in-browser code editing and test file execution are turned off, removing the attack surface that allowed remote code execution. Many Browser Mode features are also disabled, like attachments, artifacts or snapshots. See browser.api.

Users who require the full interactive UI on a networked host must explicitly opt in by setting allowWrite and/or allowExec to true.

Severity

  • CVSS Score: 9.8 / 10 (Critical)
  • Vector String: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


Release Notes

vitest-dev/vitest (vitest)

v4.1.0

Compare Source

Vitest 4.1 is out!

This release page lists all changes made to the project during the 4.1 beta. To get a review of all the new features, read our blog post.

   🚀 Features
   🐞 Bug Fixes
   🏎 Performance
    View changes on GitHub

v4.0.18

Compare Source

   🚀 Experimental Features
   🐞 Bug Fixes
    View changes on GitHub

v4.0.17

Compare Source

   🚀 Experimental Features
   🐞 Bug Fixes
    View changes on GitHub

v4.0.16

Compare Source

   🐞 Bug Fixes

Note

PR body was truncated to here.


Configuration

📅 Schedule: (UTC)

  • Branch creation
    • ""
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR has been generated by Mend Renovate.

Summary by CodeRabbit

  • Chores
    • Upgraded testing framework dev-dependencies (Vitest and coverage tooling) to v4 across the monorepo.
    • Adjusted coverage threshold settings slightly to reflect new tooling behaviour.
  • Tests
    • Updated test setup and mocks to be compatible with Vitest v4.

@gardener-ci-robot gardener-ci-robot added kind/enhancement Enhancement, improvement, extension renovate labels Jun 1, 2026
@gardener-prow gardener-prow Bot added cla: yes Indicates the PR's author has signed the cla-assistant.io CLA. labels Jun 1, 2026
@coderabbitai

coderabbitai Bot commented Jun 1, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Upgrade Vitest-related devDependencies from ^3.0.0 to ^4.0.0 across root and workspace manifests; convert several test mock arrow functions to regular function implementations; lower Vitest coverage thresholds in backend and frontend configs.

Changes

Vitest 4.0.0 Upgrade

Layer / File(s) Summary
Vitest devDependency bumps
package.json, backend/package.json, charts/package.json, frontend/package.json, packages/kube-client/package.json, packages/kube-config/package.json, packages/logger/package.json, packages/monitor/package.json, packages/polling-watcher/package.json, packages/request/package.json
Updated vitest (and where present @vitest/coverage-v8, @vitest/ui) devDependency version constraints from ^3.0.0 to ^4.0.0 in each manifest.
Test mock conversions and coverage config changes
backend/__tests__/mocks/@octokit/core.js, backend/__tests__/security.spec.js, frontend/vitest.setup.js, packages/request/__tests__/agent.spec.js, backend/vitest.config.js, frontend/vitest.config.js
Rewrote mocked constructor and test-double implementations from arrow functions to regular function expressions; lowered Vitest coverage thresholds in backend and frontend configs.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • holgerkoser
  • petersutter
  • grolu
  • klocke-io

Poem

🐰 I hopped through package files, version by version,
Swapped arrows for functions with careful precision.
Tests still mock, manifests now new,
Coverage gates lowered, the CI hums too.
Hooray — a tiny rabbit's update review!

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description is missing required template sections including /area, /kind categorization, 'What this PR does / why we need it', linked issues, special reviewer notes, and properly formatted release notes. Complete the description template by adding /area security, /kind enhancement, explaining the security fix, and provide a proper release note in the specified format.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main change: updating vitest to v4 and notes the security aspect, directly matching the changeset's primary objective.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch renovate/npm-vitest-vulnerability

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gardener-prow gardener-prow Bot added the size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. label Jun 1, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 9

🧹 Nitpick comments (2)
packages/request/package.json (1)

46-46: Advisory: Review security configuration for Vitest API/UI usage.

This upgrade addresses CVE-2026-47429 by adding api.allowWrite and api.allowExec options (disabled by default when bound to non-localhost). If your vitest configuration explicitly exposes the API server (via api.host), verify that the new security defaults align with your requirements.

🤖 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 `@packages/request/package.json` at line 46, The package's vitest upgrade adds
new security options; review the vitest dependency entry ("vitest") and any
Vitest configuration (e.g., vitest.config.* or package.json vitest section) and
explicitly set api.allowWrite and api.allowExec to false (or to values matching
your security policy) when api.host is non-localhost, and verify api.host isn't
unintentionally bound to 0.0.0.0; update the configuration to document and
enforce the desired defaults so the new CVE-related protections are applied.
packages/polling-watcher/package.json (1)

40-40: Advisory: Review security configuration for Vitest API/UI usage.

This upgrade addresses CVE-2026-47429 by adding api.allowWrite and api.allowExec options (disabled by default when bound to non-localhost). If your vitest configuration explicitly exposes the API server (via api.host), verify that the new security defaults align with your requirements.

🤖 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 `@packages/polling-watcher/package.json` at line 40, The package bumped vitest
to a version that introduces new security options; inspect your Vitest
configuration (e.g., vitest.config.ts or the "vitest" block in package.json) for
any non-localhost API exposure via the api.host setting and explicitly set
api.allowWrite and api.allowExec to false (or to the minimal required
privileges) when api.host is not localhost; update the config to document and
enforce these flags and run tests to confirm no regression.
🤖 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 `@backend/package.json`:
- Line 101: Update the `@vitest/coverage-v8` dependency to a v4-compatible major
to match vitest's ^4.0.0: change the package.json entry for
"`@vitest/coverage-v8`" from ^3.0.0 to a v4.x release (or use a range compatible
with vitest ^4.0.0), then run yarn/npm install and verify the "test-coverage"
script (vitest run --coverage) works; ensure package.json's "vitest" and
"`@vitest/coverage-v8`" versions are aligned so the peerDependency requirement is
satisfied.

In `@charts/package.json`:
- Line 38: Update the mismatched coverage provider by bumping the
`@vitest/coverage-v8` dependency to a v4 release to match vitest v4: modify the
devDependency entry for "`@vitest/coverage-v8`" (the package name symbol) to
"^4.0.0" in package.json, then reinstall dependencies (refresh lockfile) so
vitest run --coverage uses the compatible coverage-v8 v4 provider.

In `@frontend/package.json`:
- Line 110: The package.json currently sets "vitest": "^4.0.0" while
"`@vitest/ui`" and "`@vitest/coverage-v8`" remain on "^3.0.0", causing mixed-major
dependency issues; update the versions for "`@vitest/ui`" and
"`@vitest/coverage-v8`" to the v4 range (match the "vitest" major version) so all
Vitest packages are on the same major version and run a lockfile refresh/install
to ensure peers resolve correctly.

In `@packages/kube-client/package.json`:
- Line 53: Update the mismatched coverage package to match Vitest v4 by bumping
the dependency "`@vitest/coverage-v8`" to a v4 compatible major version in
packages/kube-client's package.json; locate the devDependencies entry for
"`@vitest/coverage-v8`" and change its version to the same major as "vitest" (v4)
so both "vitest" and "`@vitest/coverage-v8`" are on major version 4.

In `@packages/kube-config/package.json`:
- Line 44: The workspace has a Vitest version mismatch:
packages/kube-config/package.json pins "vitest": "^4.0.0" while
`@vitest/coverage-v8` is still at "^3.0.0"; update the dependency versions so they
match major versions (either downgrade "vitest" to a 3.x release or upgrade
"`@vitest/coverage-v8`" to a 4.x release) to ensure coverage hooks work
correctly—modify the package.json entry for "vitest" or the workspace dependency
for "`@vitest/coverage-v8`" accordingly and run the workspace install to verify no
other packages are left with conflicting Vitest major versions.

In `@packages/logger/package.json`:
- Line 39: The package.json in packages/logger lists vitest@^4.0.0 but still has
`@vitest/coverage-v8`@^3.0.0; update the devDependency for `@vitest/coverage-v8` to
the matching major (e.g. ^4.0.0) so it aligns with vitest v4, then
reinstall/update the lockfile (npm/yarn/pnpm) to resolve deps; check the
"devDependencies" entry for `@vitest/coverage-v8` and run the package manager to
regenerate the lockfile and ensure tests/coverage run under Vitest v4.

In `@packages/monitor/package.json`:
- Line 48: The package.json shows vitest upgraded to ^4.0.0 but
`@vitest/coverage-v8` remains at ^3.0.0; update the `@vitest/coverage-v8` dependency
to a v4-compatible release (match the Vitest major) in
packages/monitor/package.json and then regenerate lockfile entries (run yarn
install / yarn or npm install) so yarn.lock no longer contains mixed v3/v4
coverage-v8 versions; ensure references to "vitest" and "`@vitest/coverage-v8`" in
package.json align on major version.

In `@packages/polling-watcher/package.json`:
- Line 40: Update the `@vitest/coverage-v8` dependency to a Vitest v4-compatible
release: in package.json replace the current `@vitest/coverage-v8` version spec
(the dependency named "`@vitest/coverage-v8`") with a 4.x range such as "^4.0.0"
so it matches the "vitest" dependency "^4.0.0" used by the project and ensures
the "test-coverage" script ("vitest run --coverage") runs with compatible
coverage tooling.

In `@packages/request/package.json`:
- Line 46: package.json has vitest at v4 but `@vitest/coverage-v8` remains ^3.0.0,
which can break the test-coverage script; update the dependency
"`@vitest/coverage-v8`" to a matching v4 range (e.g., "^4.0.0" or "^4.x") so it
aligns with "vitest" and the "test-coverage" script continues to work, then run
install and verify the test-coverage script runs correctly.

---

Nitpick comments:
In `@packages/polling-watcher/package.json`:
- Line 40: The package bumped vitest to a version that introduces new security
options; inspect your Vitest configuration (e.g., vitest.config.ts or the
"vitest" block in package.json) for any non-localhost API exposure via the
api.host setting and explicitly set api.allowWrite and api.allowExec to false
(or to the minimal required privileges) when api.host is not localhost; update
the config to document and enforce these flags and run tests to confirm no
regression.

In `@packages/request/package.json`:
- Line 46: The package's vitest upgrade adds new security options; review the
vitest dependency entry ("vitest") and any Vitest configuration (e.g.,
vitest.config.* or package.json vitest section) and explicitly set
api.allowWrite and api.allowExec to false (or to values matching your security
policy) when api.host is non-localhost, and verify api.host isn't
unintentionally bound to 0.0.0.0; update the configuration to document and
enforce the desired defaults so the new CVE-related protections are applied.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 672b41f8-4f35-481c-9195-03bbe38c0098

📥 Commits

Reviewing files that changed from the base of the PR and between 8f0254f and 824be30.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (11)
  • .pnp.cjs
  • backend/package.json
  • charts/package.json
  • frontend/package.json
  • package.json
  • packages/kube-client/package.json
  • packages/kube-config/package.json
  • packages/logger/package.json
  • packages/monitor/package.json
  • packages/polling-watcher/package.json
  • packages/request/package.json

Comment thread backend/package.json
Comment thread charts/package.json
Comment thread frontend/package.json
Comment thread packages/kube-client/package.json
Comment thread packages/kube-config/package.json
Comment thread packages/logger/package.json
Comment thread packages/monitor/package.json
Comment thread packages/polling-watcher/package.json
Comment thread packages/request/package.json
@gardener-ci-robot

Copy link
Copy Markdown
Contributor Author

Edited/Blocked Notification

Renovate will not automatically rebase this PR, because it does not recognize the last commit author and assumes somebody else may have edited the PR.

You can manually request rebase by checking the rebase/retry box above.

⚠️ Warning: custom changes will be lost.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 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/vitest.config.js`:
- Around line 36-39: The frontend vitest coverage thresholds are much lower than
backend and may misrepresent real coverage after Vitest v4 removed coverage.all;
update frontend/vitest.config.js to (1) document and justify the chosen
thresholds (statements:52, branches:43, functions:42, lines:52) and include the
CI coverage report output proving the repo meets these exact numbers, (2) align
thresholds with backend or explain why they differ, and (3) add a
coverage.include pattern in the config to ensure measured scope matches intended
files (mirroring backend behavior) and add a short remediation plan to restore
stronger gates (e.g., target thresholds and steps: add tests, enable
instrumentation, incremental threshold bumps). Reference the keys
coverage.threshold and coverage.include and the file frontend/vitest.config.js
and ensure the PR includes the CI report snippet and the rationale/plan.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1862cd61-d83d-46ea-8263-dbc3a5dcfe3a

📥 Commits

Reviewing files that changed from the base of the PR and between 7e71b63 and aaee1c6.

📒 Files selected for processing (3)
  • backend/__tests__/security.spec.js
  • backend/vitest.config.js
  • frontend/vitest.config.js
✅ Files skipped from review due to trivial changes (1)
  • backend/vitest.config.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • backend/tests/security.spec.js

Comment thread frontend/vitest.config.js
Comment on lines +36 to +39
statements: 52,
branches: 43,
functions: 42,
lines: 52,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🌐 Web query:

Vitest v4 coverage calculation breaking changes

💡 Result:

Vitest v4 introduced several significant changes to code coverage calculation, primarily focused on improving accuracy and performance. If you are upgrading from v3, you should expect to see changes in your coverage reports [1][2]. Key Breaking Changes and Updates: 1. Coverage Options Removed: - coverage.all: This option has been completely removed [1][2]. Vitest now defaults to including only files that were loaded during the test run in the report [1][3]. If you need to include additional files, you must explicitly define them using the coverage.include configuration [1][2]. - coverage.extensions: This option has been removed [1][3]. - coverage.experimentalAstAwareRemapping: This option is removed as AST-based remapping is now enabled by default and serves as the only supported method [1][2]. - coverage.ignoreEmptyLines: This option is removed; lines without runtime code are now automatically excluded from reports [1][2]. 2. V8 Provider Improvements: - Improved Remapping: Vitest no longer uses v8-to-istanbul for V8 coverage remapping [1][2]. Instead, it uses a new, proprietary package utilizing AST-based analysis [1][3]. This change is intended to make V8 coverage reports as accurate as those generated by the Istanbul provider [1][2]. - New Support: The V8 provider now supports coverage.ignoreClassMethods [1][2]. 3. Configuration Recommendations: - Because coverage.all was removed, it is recommended that you explicitly define coverage.include in your vitest.config.ts file to ensure all relevant source files are measured [1][2]. - The default exclude behavior has been simplified; Vitest now only excludes tests from node_modules and.git folders by default, meaning other previously excluded patterns may need to be explicitly configured [2]. These changes are documented in the official Vitest migration guide [2]. Given the move to more accurate, AST-aware remapping, expect minor variations in coverage percentages when comparing v4 results to those from v3 [1][2].

Citations:


🏁 Script executed:

#!/bin/bash
# Check current actual coverage to see if thresholds match reality or are padded

cd frontend

# Run coverage report to see actual percentages
npx vitest run --coverage --reporter=json 2>/dev/null | jq -r '.coverageMap | if . then "Coverage data available" else "No coverage data" end' || echo "Coverage collection may require build"

# Look for coverage.all references in config history or docs
rg -n "coverage\.all" --type js -C 2

# Check if there are test changes or removals in this PR that would explain coverage drops
git log -1 --name-only --pretty=format:"%H %s" | head -20

Repository: gardener/dashboard

Length of output: 718


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== frontend/vitest.config.js (lines 1-120) =="
nl -ba frontend/vitest.config.js | sed -n '1,120p'

echo
echo "== Extract coverage-related config (frontend) =="
rg -n "coverage\.(all|include|exclude|extensions|ignoreEmptyLines)|coverage\s*:" frontend/vitest.config.js frontend/**/*.js frontend/**/*.ts frontend/package.json || true

echo
echo "== Search for coverage.all anywhere in frontend =="
rg -n "coverage\.all" frontend || true

echo
echo "== Search for coverage.include anywhere in frontend =="
rg -n "coverage\.include" frontend || true

echo
echo "== Attempt to run Vitest coverage and summarize actual coverage (may fail if deps missing) =="
cd frontend
# Try to run coverage; if it fails, we’ll print the error and exit gracefully.
set +e
npx vitest run --coverage --reporter=json > /tmp/vitest-coverage.json 2> /tmp/vitest-coverage.err
status=$?
set -e
if [ $status -ne 0 ]; then
  echo "vitest coverage run failed with exit code $status"
  echo "--- stderr (tail) ---"
  tail -200 /tmp/vitest-coverage.err || true
  exit 0
fi

python3 - <<'PY'
import json
p="/tmp/vitest-coverage.json"
data=json.load(open(p))
# Try multiple shapes (Vitest/istanbul variants)
cov = data.get("coverageMap") or data.get("coverage") or {}
if not cov:
    print("No coverageMap/coverage present in report JSON.")
    print("Top-level keys:", list(data.keys())[:50])
    raise SystemExit(0)

# Istanbul-like: coverageMap is a dict of files; compute totals from that if possible.
total = data.get("totals") or data.get("global") or data.get("result") or {}
if total:
    print("Totals/global present:", {k: total.get(k) for k in ["statements","branches","functions","lines","total"] if k in total})
    # If percentages exist:
    for k in ["statements","branches","functions","lines"]:
        v=total.get(k)
        if isinstance(v, dict) and "pct" in v:
            print(f"{k}: {v['pct']}")
    raise SystemExit(0)

# Fallback: compute pct by summing counts (rough; may differ if report shape differs)
def pct(hit, total):
    return None if total in (0,None) else (hit/total*100.0)

# If coverageMap exists, extract hits/total from each file’s summary if available
files = cov.values() if isinstance(cov, dict) else []
agg = {"statements":[0,0],"branches":[0,0],"functions":[0,0],"lines":[0,0]}
for f in files:
    s = f.get("statements",{})
    b = f.get("branches",{})
    fn= f.get("functions",{})
    # statements: list of {count}? or summary counts?
    # In some shapes, there is a 's'/'b' arrays; handle minimal common Istanbul structures:
    if isinstance(s, list):
        for x in s:
            c=x.get("count",0) if isinstance(x,dict) else 0
            agg["statements"][1]+=1
            if c>0: agg["statements"][0]+=1
    if isinstance(b, list):
        for x in b:
            # branches list items can have 'counts' array
            counts = x.get("counts") if isinstance(x,dict) else None
            if isinstance(counts,list):
                for c in counts:
                    agg["branches"][1]+=1
                    if (c or 0)>0: agg["branches"][0]+=1
    if isinstance(fn, list):
        for x in fn:
            c=x.get("count",0) if isinstance(x,dict) else 0
            agg["functions"][1]+=1
            if c>0: agg["functions"][0]+=1
    # lines sometimes mirrors statements in Istanbul; skip if not present

for k,(hit,totalc) in agg.items():
    if totalc:
        print(f"{k}: {pct(hit,totalc):.2f}% (hit {hit} / total {totalc})")
PY

echo
echo "== Done =="

Repository: gardener/dashboard

Length of output: 169


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== frontend/vitest.config.js (lines 1-140) =="
cat -n frontend/vitest.config.js | sed -n '1,140p'

echo
echo "== Extract coverage-related config (frontend) =="
rg -n "coverage\.(all|include|exclude|extensions|ignoreEmptyLines)|coverage\s*:" frontend/vitest.config.js frontend/**/*.js frontend/**/*.ts frontend/package.json || true

echo
echo "== Search for coverage.all anywhere in frontend =="
rg -n "coverage\.all" frontend || true

echo
echo "== Search for coverage.include anywhere in frontend =="
rg -n "coverage\.include" frontend || true

echo
echo "== Attempt to run Vitest coverage and summarize actual coverage =="
cd frontend
set +e
npx vitest run --coverage --reporter=json > /tmp/vitest-coverage.json 2> /tmp/vitest-coverage.err
status=$?
set -e
if [ $status -ne 0 ]; then
  echo "vitest coverage run failed with exit code $status"
  echo "--- stderr (tail) ---"
  tail -200 /tmp/vitest-coverage.err || true
  exit 0
fi

python3 - <<'PY'
import json
data=json.load(open('/tmp/vitest-coverage.json'))
cov = data.get("coverageMap") or data.get("coverage") or {}
print("JSON top-level keys:", list(data.keys())[:40])
if not cov:
    print("No coverageMap/coverage present.")
    raise SystemExit(0)

tot = data.get("totals") or data.get("global") or data.get("result") or {}
if isinstance(tot, dict) and any(k in tot for k in ["statements","branches","functions","lines","total"]):
    print("Detected global totals keys:", list(tot.keys()))
    for k in ["statements","branches","functions","lines","total"]:
        if k in tot:
            print(k, tot[k])
    raise SystemExit(0)

print("coverageMap shape detected (no obvious totals). Files:", len(cov) if isinstance(cov, dict) else type(cov))
# Try to find a file named like coverage summary
PY
echo "== Done =="

Repository: gardener/dashboard

Length of output: 9544


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== backend/vitest.config.js (lines 1-200) =="
if [ -f backend/vitest.config.js ]; then
  cat -n backend/vitest.config.js | sed -n '1,200p'
else
  echo "backend/vitest.config.js not found"
fi

echo
echo "== Search for coverage.all across repo =="
rg -n "coverage\.all" . || true

echo
echo "== Search for coverage.include across repo =="
rg -n "coverage\.include" . || true

echo
echo "== Search for 'coverage: {' blocks that set thresholds =="
rg -n "coverage:\s*\{" -S . || true

Repository: gardener/dashboard

Length of output: 1554


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== vitest versions in package.json files (root + workspace packages) =="
rg -n --glob '**/package.json' '"vitest"\s*:\s*"|vitest"\s*:\s*"' .
rg -n --glob '**/package.json' '"`@vitest/`|vitest"' package.json **/package.json || true

echo
echo "== Frontend package.json =="
cat frontend/package.json 2>/dev/null || echo "frontend/package.json not found"

echo
echo "== Root package.json =="
cat package.json 2>/dev/null || echo "root package.json not found"

Repository: gardener/dashboard

Length of output: 6575


Justify and align frontend coverage thresholds after Vitest v4 upgrade

  • frontend/vitest.config.js now enforces much lower gates: statements 52, branches 43, functions 42, lines 52.
  • This is inconsistent with backend/vitest.config.js, which sets far higher thresholds (e.g., branches 68, functions 93, statements/lines 89).
  • With Vitest v4, coverage.all was removed and coverage reports default to measuring only files loaded during the test run; frontend also does not set coverage.include, so the measured scope (and therefore the threshold meaning) may have changed.

Please provide:

  • The CI/coverage report output showing actual achieved coverage meets these exact thresholds.
  • The rationale for choosing these threshold values (and whether coverage.include should be set to match the intended measurement set / backend behavior).
  • A plan to restore stronger gates if these values were lowered to “make CI pass” rather than reflect real coverage quality.
🤖 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/vitest.config.js` around lines 36 - 39, The frontend vitest coverage
thresholds are much lower than backend and may misrepresent real coverage after
Vitest v4 removed coverage.all; update frontend/vitest.config.js to (1) document
and justify the chosen thresholds (statements:52, branches:43, functions:42,
lines:52) and include the CI coverage report output proving the repo meets these
exact numbers, (2) align thresholds with backend or explain why they differ, and
(3) add a coverage.include pattern in the config to ensure measured scope
matches intended files (mirroring backend behavior) and add a short remediation
plan to restore stronger gates (e.g., target thresholds and steps: add tests,
enable instrumentation, incremental threshold bumps). Reference the keys
coverage.threshold and coverage.include and the file frontend/vitest.config.js
and ensure the PR includes the CI report snippet and the rationale/plan.

@grolu

grolu commented Jun 2, 2026

Copy link
Copy Markdown
Member

/lgtm
/approve

@gardener-prow gardener-prow Bot added the lgtm Indicates that a PR is ready to be merged. label Jun 2, 2026
@gardener-prow

gardener-prow Bot commented Jun 2, 2026

Copy link
Copy Markdown

LGTM label has been added.

DetailsGit tree hash: ceafccd5169a42a0efe05495ea534ec0b8b21e90

@gardener-prow

gardener-prow Bot commented Jun 2, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: grolu

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@gardener-prow gardener-prow Bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Jun 2, 2026
@gardener-prow gardener-prow Bot merged commit a27bbd8 into master Jun 2, 2026
37 checks passed
@gardener-prow gardener-prow Bot deleted the renovate/npm-vitest-vulnerability branch June 2, 2026 13:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. cla: yes Indicates the PR's author has signed the cla-assistant.io CLA. kind/enhancement Enhancement, improvement, extension lgtm Indicates that a PR is ready to be merged. renovate size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants