Skip to content

feat(experimental): support merge reports for non-sharded multi-environment runs (take 2)#10031

Open
hi-ogawa wants to merge 51 commits intovitest-dev:mainfrom
hi-ogawa:feat-merge-report-label-v2
Open

feat(experimental): support merge reports for non-sharded multi-environment runs (take 2)#10031
hi-ogawa wants to merge 51 commits intovitest-dev:mainfrom
hi-ogawa:feat-merge-report-label-v2

Conversation

@hi-ogawa
Copy link
Copy Markdown
Collaborator

@hi-ogawa hi-ogawa commented Mar 31, 2026

Description

Alternative take for #9967 (comment)

Usage example

Set --label when creating blobs:

vitest run --reporter=blob --label=linux
vitest run --reporter=blob --label=macos

Or via test config:

// vitest.config.ts
export default defineConfig({
  test: {
    label: process.platform
    reporters: ['blob'],
  },
})

The label is included in the default blob filename (blob-linux.json) to avoid collisions. When merging, each labeled run is shown separately:

$ vitest --merge-reports
 ✓  linux  src/basic.test.ts (2 tests)
 ✓  macos  src/basic.test.ts (2 tests)

How it works

test.label is a core config option — not a blob reporter option. It generalizes the existing __typecheck__ pattern: createFileTask salts File.id with the label and stores it in File.meta.label. State deduplication treats (filepath, projectName, meta.typecheck, meta.label) as the identity key, so same-filepath files with different labels coexist naturally — with no changes to readBlobs, no project cloning, and no ID rewriting at merge time.

The blob reporter uses the label only for one thing: deriving the default output filename as blob-(label)-(shard).json.

Reporters read meta.label and display a badge at all times — not just during --merge-reports. A run with --label=linux will show the badge live as tests execute, in the same way a run with a named project shows the project badge. --merge-reports is simply the context where having multiple labeled runs side-by-side becomes useful.

The difference from #9967

Concern #9967 (label as project.name) This PR (label as File.meta)
Mechanism Clone TestProject per label at read time Salt File.id + File.meta.label during test run
readBlobs changes Significant — label discovery, ID rewrite, env module rewrite None
file.projectName Mutated to include label Unchanged
Pattern Browser-mode clone pattern __typecheck__ generalization
Config option [["blob", { label }]] reporter option test.label top-level option

Demo

I setup CI to upload html reports for test/cli and test/core. It's viewable on newly introduced viewer #10023.

https://viewer.vitest.dev/?url=https://github.com/vitest-dev/vitest/actions/runs/23789865129/artifacts/6196385971

image

Please don't delete this checklist! Before submitting the PR, please make sure you do the following:

  • It's really useful if your PR references an issue where it is discussed ahead of time. If the feature is substantial or introduces breaking changes without a discussion, PR might be closed.
  • Ideally, include a test that fails without this PR but passes with it.
  • Please, don't make changes to pnpm-lock.yaml unless you introduce a new test example.
  • Please check Allow edits by maintainers to make review process faster. Note that this option is not available for repositories that are owned by Github organizations.

Tests

  • Run the tests with pnpm test:ci.

Documentation

  • If you introduce new functionality, document it. You can run documentation with pnpm run docs command.

Changesets

  • Changes in changelog are generated from PR name. Please, make sure that it explains your changes in an understandable manner. Please, prefix changeset messages with feat:, fix:, perf:, docs:, or chore:.

hi-ogawa and others added 13 commits March 31, 2026 15:32
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@netlify
Copy link
Copy Markdown

netlify bot commented Mar 31, 2026

Deploy Preview for vitest-dev ready!

Built without sensitive environment variables

Name Link
🔨 Latest commit b2ab294
🔍 Latest deploy log https://app.netlify.com/projects/vitest-dev/deploys/69cce79b7448090008438e9c
😎 Deploy Preview https://deploy-preview-10031--vitest-dev.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@hi-ogawa hi-ogawa marked this pull request as ready for review March 31, 2026 09:42
hi-ogawa and others added 4 commits March 31, 2026 18:47
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@hi-ogawa hi-ogawa requested a review from Copilot March 31, 2026 10:03
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a first-class test.label concept to disambiguate identical test files across multiple environment runs (e.g. OS/Node matrix) so blob reports can be merged without collisions, and makes reporters/UI surface that label consistently.

Changes:

  • Introduces test.label config + --label CLI option, propagating it into serialized config and TaskMeta.
  • Salts file IDs with { typecheck, label } via generateFileHash/createFileTask, and updates state deduplication to treat (filepath, projectName, meta.typecheck, meta.label) as the identity.
  • Updates blob reporter default filenames, default/summary reporters, UI, docs, tests, and CI workflow to generate/merge labeled blob reports.

Reviewed changes

Copilot reviewed 37 out of 37 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
test/test-utils/index.ts Extends error tree helpers to optionally key modules by label for merge-report assertions.
test/core/vite.config.ts Emits blob reports in CI when a label env var is set and passes test.label.
test/cli/vitest.config.ts Emits blob reports in CI when a label env var is set and passes test.label.
test/cli/test/test-specifications.test.ts Updates parametrized test API usage and expected stable IDs.
test/cli/test/reporters/merge-reports.test.ts Adds merge-reports coverage for labeled runs (and projects+labels).
test/cli/test/reporters/__snapshots__/html.test.ts.snap Updates snapshot to new hashed task IDs.
test/cli/test/reported-tasks.test.ts Updates expectations for new hashed test specification IDs.
packages/ws-client/src/state.ts Aligns file deduplication key with (projectName, typecheck, label) for WS client state.
packages/vitest/src/types/global.ts Adds label?: string to TaskMeta typing.
packages/vitest/src/typecheck/collect.ts Uses createFileTask to unify ID/meta generation for typecheck collection.
packages/vitest/src/runtime/config.ts Adds label to serialized runtime config shape.
packages/vitest/src/node/types/config.ts Adds label to InlineConfig and resolved config typing.
packages/vitest/src/node/test-specification.ts Allows hashing specs with { typecheck, label } meta.
packages/vitest/src/node/state.ts Updates file collection deduplication to include meta.label.
packages/vitest/src/node/reporters/summary.ts Displays label badge in the summary reporter output.
packages/vitest/src/node/reporters/blob.ts Includes label in default blob filename to avoid collisions.
packages/vitest/src/node/reporters/base.ts Displays label badge in default reporter prefixes and failure headers.
packages/vitest/src/node/project.ts Propagates root vitest label into project resolved config and spec creation API.
packages/vitest/src/node/core.ts Preserves file meta (incl. label) when creating specifications during merge-reports replay.
packages/vitest/src/node/config/serializeConfig.ts Serializes label into worker/runtime config.
packages/vitest/src/node/cli/cli-config.ts Adds --label <label> CLI option.
packages/ui/client/composables/explorer/utils.ts Stores file label into UI explorer tree nodes.
packages/ui/client/composables/explorer/types.ts Extends FileTreeNode with optional label.
packages/ui/client/components/views/ViewTestReport.vue Treats label as a well-known meta field in the report view.
packages/ui/client/components/FileDetails.vue Displays a label badge in file details header.
packages/ui/client/components/explorer/ExplorerItem.vue Displays a label badge next to file items in explorer.
packages/ui/client/components/explorer/Explorer.vue Wires label into explorer item props.
packages/runner/src/utils/collect.ts Salts file hashes with { typecheck, label } and plumbs meta through createFileTask.
packages/runner/src/types/runner.ts Adds label to runner config typing.
packages/runner/src/collect.ts Passes config.label into createFileTask meta during collection.
docs/guide/reporters.md Documents using --label for multi-environment blob merges.
docs/guide/improving-performance.md Updates CI sharding example to include labels and avoid artifact collisions.
docs/guide/cli.md Notes default blob output path includes shard + label.
docs/guide/cli-generated.md Adds generated CLI docs entry for --label.
docs/config/label.md New config reference page for test.label.
docs/.vitepress/config.ts Adds label to config nav.
.github/workflows/ci.yml Uploads labeled blob artifacts per matrix entry and adds a merge-reports job producing HTML.

@hi-ogawa hi-ogawa changed the title feat: support merge reports for non-sharded multi-environment runs (take 2) feat(experimental): support merge reports for non-sharded multi-environment runs (take 2) Apr 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support merging reports for non-sharded multi-environment runs

2 participants