Skip to content

ci: shard Windows TS tests#12612

Merged
zkochan merged 9 commits into
mainfrom
win-tests
Jun 24, 2026
Merged

ci: shard Windows TS tests#12612
zkochan merged 9 commits into
mainfrom
win-tests

Conversation

@zkochan

@zkochan zkochan commented Jun 23, 2026

Copy link
Copy Markdown
Member

Summary

  • Run Windows TS CI only on Node.js 22 and split it into three parallel test chunks.
  • Add a CI helper that shards Jest test files while preserving package setup and pnpm execution summaries.
  • Keep Bencher performance data for each Windows chunk with chunk-specific benchmark names under the existing pnpm.windows.node22 testbed.
  • CI-only change; no pnpm CLI behavior or pacquet porting is needed.

Squash Commit Body

Run Windows TypeScript test jobs only on Node.js 22 and split them into three parallel chunks.

Windows TS tests are significantly slower than Linux, and running the full suite on three Node versions spends the extra capacity on duplicate runtime coverage instead of reducing wall clock time. The reusable test workflow now accepts chunk inputs, includes chunk identity in concurrency and artifact names, and keeps Bencher uploads with chunk-specific benchmark names.

Add a CI helper that discovers the selected workspace packages for the same full or affected test scope, shards Jest test files into balanced chunks, runs selected package files with the same Jest Node options and package pretest setup, and writes pnpm-style execution summaries so the pnpm CLI e2e duration extraction still works.

Checklist

  • CI-only change; no TypeScript CLI behavior or Rust pacquet porting is needed.
  • Updated the TS CI test workflow and validated chunk selection.

Written by an agent (Codex, GPT-5).

Summary by CodeRabbit

  • New Features
    • Added deterministic, chunked TypeScript test execution in CI, including chunk-aware Jest scheduling and chunk-specific benchmark outputs/metadata.
  • Chores
    • Updated CI change detection to treat modifications under the CI scripts area as TypeScript-relevant.
    • Extended the reusable test workflow to accept test_chunk/test_chunk_total, run the appropriate chunk commands, and merge chunk results.
  • Bug Fixes
    • Improved benchmark result parsing to optionally tolerate missing entries when extracting chunked CLI e2e durations.

@qodo-free-for-open-source-projects

Copy link
Copy Markdown

PR Summary by Qodo

ci: shard Windows TypeScript tests into 3 chunks on Node 22
⚙️ Configuration changes ✨ Enhancement 🕐 20-40 Minutes

Grey Divider

Description

• Shard Windows TypeScript CI tests into three parallel chunks on Node 22 only.
• Add a helper to shard Jest files per workspace package and run them consistently.
• Preserve Bencher artifacts with chunk-specific benchmark and artifact naming.
Diagram

graph TD
  A[".github/workflows/ci.yml (matrix)"] --> B[".github/workflows/test.yml (reusable)"] --> C{"chunking enabled?"}
  C -->|"total=1"| D["pn run ci:test-* (pnpm)"] --> H[("Bencher JSON + artifact")]
  C -->|"total>1"| E["run-ts-tests-chunk.mjs"] --> F["pnpm list + discover Jest files"] --> G["pnpm exec jest --runTestsByPath"] --> I[("pnpm-exec-summary.json")]
  I --> H
  subgraph Legend
    direction LR
    _wf["Workflow/Step"] ~~~ _dec{"Decision"} ~~~ _art[("Artifact/File")]
  end
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Use Jest built-in sharding (--shard)
  • ➕ Eliminates custom file discovery and greedy balancing logic
  • ➕ Leverages a standardized, well-tested sharding mechanism
  • ➖ Hard to apply cleanly across a pnpm monorepo with per-package pretest/setup
  • ➖ Does not naturally preserve pnpm-style per-package execution summaries used by existing Bencher extraction
2. Shard by workspace package (not by test file)
  • ➕ Much simpler implementation (split package list into N buckets)
  • ➕ Stable chunk membership even when files move within a package
  • ➖ Likely poor load balancing because package test sizes vary widely
  • ➖ Still needs special handling for non-Jest .test scripts and pretest hooks
3. GitHub Actions dynamic matrix from discovered tests
  • ➕ Moves sharding to workflow level; clearer CI visibility per shard
  • ➕ Potentially easier artifact isolation per shard
  • ➖ Complex to generate/consume dynamic matrices reliably across runners
  • ➖ Still requires custom discovery logic; more moving parts than the current approach

Recommendation: Keep the PR’s approach: a single helper that shards Jest files while preserving per-package setup and pnpm execution summaries. This best matches the monorepo constraints (pretest hooks, mixed test scripts, and existing Bencher tooling) while delivering predictable wall-clock improvements on Windows via 3-way parallelism.

Files changed (3) +414 / -24

Other (3) +414 / -24
run-ts-tests-chunk.mjsAdd CI helper to shard TS Jest tests into balanced chunks +333/-0

Add CI helper to shard TS Jest tests into balanced chunks

• Introduces a Node script that selects workspace packages (full vs affected), enumerates Jest test files, greedily balances them into N chunks by file size, and runs selected files via per-package Jest invocations. Preserves package pretest behavior, injects required NODE_OPTIONS, and writes a pnpm-style execution summary for downstream Bencher duration extraction.

.github/scripts/run-ts-tests-chunk.mjs

ci.ymlShard Windows TS test matrix and limit Windows runs to Node 22 +26/-14

Shard Windows TS test matrix and limit Windows runs to Node 22

• Extends the TS CI change filter to include .github/scripts, ensuring CI changes trigger the workflow. Replaces the previous multi-node Windows matrix with three Windows chunk entries (1/3, 2/3, 3/3) on Node 22, while keeping Ubuntu coverage across Node 22 and 26, and wires chunk inputs into the reusable test workflow.

.github/workflows/ci.yml

test.ymlAdd chunk inputs and chunk-aware concurrency/Bencher artifacts to reusable test workflow +55/-10

Add chunk inputs and chunk-aware concurrency/Bencher artifacts to reusable test workflow

• Adds workflow_call inputs for chunk index/total and includes them in the job name and concurrency group to avoid cross-chunk cancellation. Runs either the existing pnpm test script or the new sharding helper, and updates Bencher benchmark names, merged result inputs, metadata, and artifact names to be chunk-specific while staying under the existing testbed naming scheme.

.github/workflows/test.yml

@coderabbitai

coderabbitai Bot commented Jun 23, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a new Node.js script that discovers Jest packages in the pnpm monorepo, enumerates test files with size-based weights, selects a greedy-balanced chunk, and executes Jest per package. Updates ci.yml to use an explicit matrix with chunk parameters and test.yml to conditionally invoke the chunk runner and produce chunk-aware Bencher benchmark names and artifacts. Extends Bencher result parsing to support --allow-missing flag.

Changes

Chunked TypeScript test execution

Layer / File(s) Summary
Chunk-runner: CLI, orchestration, and argument validation
.github/scripts/run-ts-tests-chunk.mjs
Implements CLI entrypoint that initializes fixtures and cleanup, main orchestration loop selecting packages and tasks, executing Jest and non-Jest runners per package, persisting execution summary JSON, and setting exit code on failure; argument parser validates script mode (ci:test-all, ci:test-branch) and numeric chunk constraints, with usage error handler.
Chunk-runner: Package discovery, task enumeration, and chunk selection
.github/scripts/run-ts-tests-chunk.mjs
Discovers pnpm workspace packages filtered to those with .test scripts; detects Jest usage in package scripts and expands Jest packages into weighted file tasks based on file size, while non-Jest packages become single weight-1 tasks; selects one chunk using greedy weight-balancing and groups selected Jest tasks by package.
Chunk-runner: Execution (Jest/non-Jest, command wrapping, utilities)
.github/scripts/run-ts-tests-chunk.mjs
Jest package runner augments NODE_OPTIONS with required Jest VM flags, prepends .bin directories to PATH, runs optional pretest, and executes jest --runTestsByPath with selected file batches split by isolated files and command-length limits; non-Jest runner limited to pd package; test discovery recursively finds JS/TS test files excluding fixtures and test-utils; execution status with duration and exitCode written to JSON summary; spawn wrappers handle child process execution; package.json reading loads manifest data.
CI matrix and workflow_call inputs
.github/workflows/ci.yml, .github/workflows/test.yml
Replaces ci.yml test job matrix with explicit include list enumerating Node/platform combinations and adding test_chunk/test_chunk_total; extends ts path filter to include .github/scripts/**; adds test_chunk and test_chunk_total optional inputs to test.yml workflow_call with default '1'; updates job display name and concurrency group to include chunk values.
test.yml: Chunk-conditional execution and Bencher integration
.github/workflows/test.yml
Test-run step validates chunk parameters as positive integers within bounds, sets TEST_CHUNK/TEST_CHUNK_TOTAL, and switches to run-ts-tests-chunk.mjs when chunking is enabled; CLI e2e duration extraction appends chunk suffix to benchmark name and writes chunk-specific file; Bencher staging derives chunk-suffixed names; result merging includes chunk bench file and optional CLI file, writes metadata.json with chunk index/total, and uploads artifacts with chunk-suffixed names.
Bencher result script: --allow-missing flag support
.github/scripts/bencher-result-from-pnpm-summary.mjs
Updates argument parsing to recognize --allow-missing flag; when execution summary has no entry for the resolved package directory, exits successfully (status 0) if flag is set; otherwise logs error and exits with status 1. Usage output documents the new option.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • pnpm/pnpm#12388: Introduces .test:heavy script suffix on specific test files; the chunk runner detects isolated test file patterns from .test:* scripts for separate batch execution.
  • pnpm/pnpm#12404: The chunk runner generates pnpm-exec-summary.json with per-package duration and status; the related PR modifies bencher-result-from-pnpm-summary.mjs which consumes this output.
  • pnpm/pnpm#12544: Both modify the Bencher extraction and merge steps in test.yml; this PR adds chunk-aware benchmark naming and conditional CLI duration extraction with --allow-missing support.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch win-tests

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.

@github-actions github-actions Bot added the reviewed: coderabbit CodeRabbit submitted an approving review label Jun 23, 2026
@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Jun 23, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (6) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Action required

1. PATH hijacks pn command ✓ Resolved 🐞 Bug ⛨ Security
Description
runJestPackage() prepends workspace node_modules/.bin directories to PATH and then invokes
runPnpm(), which spawns the bare command pn; this allows a pn executable placed in those
.bin dirs to hijack the runner and potentially skip/fake test execution or summaries. This is a CI
integrity/security issue introduced by the new chunk runner’s environment setup and command spawning
behavior.
Code

.github/scripts/run-ts-tests-chunk.mjs[R119-143]

+  const env = {
+    ...process.env,
+    NODE_OPTIONS: withJestNodeOptions(process.env.NODE_OPTIONS),
+    PNPM_SCRIPT_SRC_DIR: pkg.path,
+  }
+  prependPath(env, [
+    path.join(pkg.path, 'node_modules', '.bin'),
+    path.join(rootDir, 'node_modules', '.bin'),
+  ])
+  if (pkg.manifest.name === '@pnpm/installing.deps-installer') {
+    env.PNPM_REGISTRY_MOCK_PORT = '7769'
+  }
+
+  let status = 'passed'
+  let exitCode = 0
+  try {
+    if (pkg.manifest.scripts.pretest != null) {
+      await runPnpm(['--dir', pkg.path, 'run', 'pretest'], { env })
+    }
+    for (const [index, files] of batches.entries()) {
+      if (batches.length > 1) {
+        console.log(`Running batch ${index + 1}/${batches.length} (${files.length} Jest file(s)) in ${relDir}`)
+      }
+      await runPnpm(['--dir', pkg.path, 'exec', 'jest', '--runTestsByPath', ...files], { env })
+    }
Evidence
The script explicitly prepends pkg.path/node_modules/.bin and rootDir/node_modules/.bin to PATH,
then runs runPnpm() using that environment; runPnpm() ultimately spawns the bare command pn
(resolved via PATH), enabling executable shadowing/hijack via those prepended directories.

.github/scripts/run-ts-tests-chunk.mjs[112-143]
.github/scripts/run-ts-tests-chunk.mjs[284-311]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The chunk runner prepends `node_modules/.bin` to `PATH` and then executes `pn` by name. Because `spawn()` resolves bare commands via `PATH`, any `pn` binary/shim in those prepended directories can be executed instead of the intended pnpm runner.
### Issue Context
This happens inside `runJestPackage()` when preparing the environment for Jest runs, and affects all subsequent `runPnpm()` calls made with that `env`.
### Fix Focus Areas
- Ensure `runPnpm()`/`capturePnpm()` invoke a trusted `pn` executable (prefer an absolute path resolved once at startup, e.g. from `PNPM_HOME`, or a pre-resolved `which/where pn` result) so later PATH edits cannot change which binary runs.
- Alternatively, avoid prepending `.bin` to PATH entirely (pnpm `exec` already resolves package bins), or append instead of prepend so toolchain resolution stays stable.
- .github/scripts/run-ts-tests-chunk.mjs[112-143]
- .github/scripts/run-ts-tests-chunk.mjs[284-309]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Heavy test isolation lost ✓ Resolved 🐞 Bug ☼ Reliability
Description
run-ts-tests-chunk.mjs runs one Jest invocation per package with --runTestsByPath, bypassing
package .test script sequencing. For @pnpm/installing.deps-installer, this can place
test/install/deepRecursive.ts in the same Jest process as other tests when they land in the same
chunk, undermining the repo’s existing heavy/rest split and increasing the chance of Windows CI
timeouts/flakes.
Code

.github/scripts/run-ts-tests-chunk.mjs[R133-136]

+    if (pkg.manifest.scripts.pretest != null) {
+      await runPnpm(['--dir', pkg.path, 'run', 'pretest'], { env })
+    }
+    await runPnpm(['--dir', pkg.path, 'exec', 'jest', '--runTestsByPath', ...relFiles], { env })
Evidence
The new runner always calls pn ... exec jest --runTestsByPath ...relFiles, so it does not honor
per-package .test script logic. The deps-installer package.json demonstrates the repo previously
isolated deepRecursive.ts into a separate test phase (.test:heavy) before running the rest,
which the new runner can defeat when a chunk includes both heavy and non-heavy files for that
package.

.github/scripts/run-ts-tests-chunk.mjs[111-137]
pnpm11/installing/deps-installer/package.json[49-58]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The chunk runner executes Jest directly with `--runTestsByPath` over all selected files for a package, which bypasses packages’ `.test` orchestration. `@pnpm/installing.deps-installer` explicitly splits its suite into a heavy test (`deepRecursive.ts`) and the rest; the current sharding runner can recombine those into one Jest process whenever the chunk selects both.
### Issue Context
- `@pnpm/installing.deps-installer`’s `.test` script runs `.test:heavy` (only `test/install/deepRecursive.ts`) and then `.test:rest` (everything else).
- The sharded runner currently runs `jest --runTestsByPath ...relFiles` once per package, so a chunk that includes `deepRecursive.ts` and other files will execute them together.
### Fix Focus Areas
- .github/scripts/run-ts-tests-chunk.mjs[111-147]
- pnpm11/installing/deps-installer/package.json[49-59]
### Suggested fix approach
In `runJestPackage`, add a small package-specific preservation of the existing split:
- If `pkg.manifest.name === '@pnpm/installing.deps-installer'` and the selected `relFiles` contains `test/install/deepRecursive.ts` *and* at least one other file, run two Jest commands:
1) `jest --runTestsByPath test/install/deepRecursive.ts`
2) `jest --runTestsByPath <all remaining files>`
- Keep the existing `pretest` handling and `PNPM_REGISTRY_MOCK_PORT` env.
- Ensure failures from either invocation are reflected in `executionStatus[pkg.path]` (current outer timing can remain as-is).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Bencher summary entry missing ✓ Resolved 🐞 Bug ☼ Reliability
Description
run-ts-tests-chunk.mjs only records executionStatus entries for packages that actually run in
the selected chunk, so a chunk can omit pnpm11/pnpm entirely. When full_tests == true,
test.yml always runs bencher-result-from-pnpm-summary.mjs --package-dir pnpm11/pnpm, which exits
non-zero if that summary entry is missing, failing the job.
Code

.github/scripts/run-ts-tests-chunk.mjs[R24-34]

+if (!dryRun) {
+  for (const pkg of packages) {
+    const selectedPackage = selectedPackages.get(pkg.path)
+    if (selectedPackage != null) {
+      await runJestPackage(pkg, selectedPackage)
+    } else if (selectedTasks.some((task) => task.kind === 'script' && task.packagePath === pkg.path)) {
+      await runScriptTask(pkg)
+    }
+  }
+  await writeSummary(summary, executionStatus)
+}
Evidence
The chunk runner only runs packages that have tasks selected for that chunk and only then inserts an
executionStatus entry; the Bencher extractor requires an entry for pnpm11/pnpm and exits 1 if it
is missing, while the workflow runs this extractor on full test runs regardless of whether the chunk
executed that package.

.github/scripts/run-ts-tests-chunk.mjs[16-34]
.github/scripts/run-ts-tests-chunk.mjs[52-109]
.github/scripts/run-ts-tests-chunk.mjs[111-143]
.github/scripts/bencher-result-from-pnpm-summary.mjs[6-20]
.github/workflows/test.yml[177-217]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The chunked TS test runner writes `pnpm-exec-summary.json` with `executionStatus` entries only for packages executed in that chunk. The workflow later always tries to extract a Bencher result for `pnpm11/pnpm` from that summary on full test runs; if a chunk contains no `pnpm11/pnpm` tasks, the summary omits that key and the extraction step fails.
### Issue Context
- `run-ts-tests-chunk.mjs` iterates all packages but only executes packages present in `selectedPackages` (jest files) or a selected `script` task, and only then writes `executionStatus[pkg.path]`.
- `bencher-result-from-pnpm-summary.mjs` hard-fails if the entry for `resolve('pnpm11/pnpm')` is missing.
- `test.yml` always runs the CLI-duration extraction step when `full_tests == true`, including chunked runs.
### Fix Focus Areas
Choose one of these approaches (A is minimal and safest):
A) **Make CLI-duration extraction non-fatal/optional when chunked**
- Add a flag to `bencher-result-from-pnpm-summary.mjs` like `--optional` (or `--allow-missing`) that exits 0 without writing output when the summary entry is missing (or not `passed`).
- In `.github/workflows/test.yml`, pass that flag when `TEST_CHUNK_TOTAL != 1` (or gate the step similarly), relying on the later merge step which already conditionally includes the CLI benchmark file only if it exists.
B) **Guarantee `pnpm11/pnpm` appears in every chunk**
- Adjust task selection to pre-seed each chunk with at least one Jest file from `pnpm11/pnpm` (or otherwise enforce presence), so the package is always executed and a summary entry is always produced.
- .github/scripts/run-ts-tests-chunk.mjs[16-34]
- .github/scripts/bencher-result-from-pnpm-summary.mjs[6-20]
- .github/workflows/test.yml[177-217]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

4. Matrix build blocks tests 🐞 Bug ➹ Performance
Description
The new build-pnpr job is a single Linux+Windows matrix and is listed in needs for both Ubuntu
and Windows test jobs, which forces Ubuntu tests to wait for the Windows pnpr build even though they
only consume the Linux artifact. This increases CI wall-clock time and makes a Windows-only pnpr
build failure prevent Linux tests from running, reducing feedback signal.
Code

.github/workflows/ci.yml[R77-89]

+  # Build the pnpr server and registry fixture preparer once per OS, then
+  # share the binaries with every test job/shard as an artifact. Building
+  # inside each test job instead rebuilt pnpr once per shard, because the
+  # parallel shards all miss the build cache at job start.
+  build-pnpr:
+    needs: changes
+    if: ${{ !cancelled() && needs.changes.outputs.ts == 'true' && (github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository || github.head_ref == 'chore/update-lockfile') }}
+    name: TS CI / Build pnpr / ${{ matrix.os }}
+    strategy:
+      fail-fast: false
+      matrix:
+        os: [ubuntu-latest, windows-latest]
+    runs-on: ${{ matrix.os }}
Evidence
build-pnpr is defined as a two-OS matrix job, while test-smoke and test-windows both declare
needs: [compile-and-lint, build-pnpr]. Since needs waits on the aggregate matrix result, Ubuntu
tests are gated on the Windows pnpr build completing successfully.

.github/workflows/ci.yml[77-89]
.github/workflows/ci.yml[145-219]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`build-pnpr` is implemented as a single matrix job over `ubuntu-latest` and `windows-latest`, and downstream jobs depend on the whole matrix via `needs: build-pnpr`. In GitHub Actions, that means downstream jobs wait for *all* matrix children to complete, so Ubuntu tests are unnecessarily blocked on the Windows pnpr build.
### Issue Context
The tests download OS-specific artifacts (`pnpr-bins-${{ runner.os }}`) and do not need the other OS’s artifact.
### Fix Focus Areas
- .github/workflows/ci.yml[77-219]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


5. Silent benchmark drop 🐞 Bug ◔ Observability
Description
When --allow-missing is set, bencher-result-from-pnpm-summary.mjs exits 0 without emitting any
warning or writing an output JSON, so a missing CLI-duration entry is silently ignored and benchmark
completeness issues are hard to detect.
Code

.github/scripts/bencher-result-from-pnpm-summary.mjs[R14-16]

+  if (allowMissing) {
+    process.exit(0)
+  }
Evidence
The script exits successfully on missing entries when --allow-missing is set, and the workflow
later conditionally merges the CLI benchmark file only if it exists; together this makes missing
CLI-duration benchmark data silently disappear.

.github/scripts/bencher-result-from-pnpm-summary.mjs[12-18]
.github/workflows/test.yml[253-256]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`--allow-missing` currently causes an early `process.exit(0)` with no log and no output file. In the shard workflow, the CLI benchmark file is optional, so this becomes a silent drop of benchmark telemetry when the summary entry is unexpectedly absent.
### Issue Context
This behavior is intentional to avoid failing shards that don’t run `pnpm11/pnpm`, but it still needs a signal when it happens so missing benchmark data doesn’t go unnoticed.
### Fix Focus Areas
- .github/scripts/bencher-result-from-pnpm-summary.mjs[12-19]
### Suggested change
In the `allowMissing` branch, emit a GitHub Actions warning (and/or a stderr warning) including `packagePath` and `summaryPath` before exiting, e.g.:
- `console.log('::warning::...')` then `process.exit(0)`.
This preserves shard success while making missing benchmark output discoverable in logs.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


6. Stale pnpr cache key 🐞 Bug ☼ Reliability
Description
The new build-pnpr cache key only hashes Rust manifests and *.rs files, but the pnpr binaries embed
non-Rust assets (e.g. config.yaml and the repo LICENSE) via include_str!. As a result, CI can
restore and run stale pnpr binaries after those assets change, masking behavior changes and
producing incorrect test coverage/results.
Code

.github/workflows/ci.yml[R105-111]

+    - name: Restore prebuilt pnpr binaries
+      id: pnpr-bins
+      uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+      with:
+        path: .pnpr-bin
+        key: pnpr-bins-${{ runner.os }}-${{ hashFiles('rust-toolchain.toml', '**/Cargo.lock', '**/Cargo.toml', 'pnpr/**/*.rs', 'pacquet/**/*.rs') }}
+    - name: Install Rust
Evidence
The workflow cache key hashes only Rust sources/manifests, but pnpr and pnpr-fixtures compile in
non-Rust files using include_str!, so changes to those files won’t invalidate the cache and can lead
to stale restored binaries.

.github/workflows/ci.yml[105-111]
pnpr/crates/pnpr/src/config.rs[19-26]
pnpr/crates/pnpr-fixtures/src/lib.rs[273-292]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`build-pnpr` caches `.pnpr-bin` using a key that ignores non-Rust files that are compiled into the pnpr binaries via `include_str!`. This can restore stale binaries when those embedded assets change.
### Issue Context
The cache key currently hashes `rust-toolchain.toml`, all `Cargo.*`, and `pnpr/**/*.rs` + `pacquet/**/*.rs`, but pnpr and pnpr-fixtures embed non-`.rs` files into the binaries.
### Fix Focus Areas
- .github/workflows/ci.yml[105-111]
### What to change
- Expand the `hashFiles(...)` key inputs to include embedded assets that affect the compiled output, at minimum:
- `pnpr/crates/pnpr/config.yaml`
- `LICENSE`
- Optionally, also include any other non-Rust files referenced by `include_str!` / `include_bytes!` in the built crates (keep it scoped to avoid hashing large fixture trees).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


View more (7)
7. Chunk strings miscompared 🐞 Bug ≡ Correctness
Description
test.yml validates test_chunk/test_chunk_total numerically but later decides whether sharding is
enabled via string comparison against "1", so non-canonical values like "01" can pass validation yet
still enable chunk mode and produce inconsistent benchmark/artifact names (e.g. ".chunk01"). This
can cause unexpected chunk runner execution and mismatched Bencher benchmark identifiers for callers
of the reusable workflow.
Code

.github/workflows/test.yml[R177-223]

+    - name: Validate test chunk inputs
+      shell: bash
+      env:
+        TEST_CHUNK: ${{ inputs.test_chunk }}
+        TEST_CHUNK_TOTAL: ${{ inputs.test_chunk_total }}
+      run: |
+        case "$TEST_CHUNK" in
+          ''|*[!0-9]*)
+            echo "::error::test_chunk must be a positive integer"
+            exit 1
+            ;;
+        esac
+        case "$TEST_CHUNK_TOTAL" in
+          ''|*[!0-9]*)
+            echo "::error::test_chunk_total must be a positive integer"
+            exit 1
+            ;;
+        esac
+        if (( TEST_CHUNK < 1 || TEST_CHUNK_TOTAL < 1 || TEST_CHUNK > TEST_CHUNK_TOTAL )); then
+          echo "::error::test_chunk must be between 1 and test_chunk_total"
+          exit 1
+        fi
- name: Run tests (${{ steps.test-scope.outputs.scope }})
timeout-minutes: 70
shell: bash
env:
BENCHMARK: ${{ steps.test-scope.outputs.benchmark }}
PNPM_WORKERS: 3
TEST_SCRIPT: ${{ steps.test-scope.outputs.script }}
+        TEST_CHUNK: ${{ inputs.test_chunk }}
+        TEST_CHUNK_TOTAL: ${{ inputs.test_chunk_total }}
run: |
+        benchmark="$BENCHMARK"
+        command=(pn run "$TEST_SCRIPT")
+        if [ "$TEST_CHUNK_TOTAL" != "1" ]; then
+          benchmark="${BENCHMARK}.chunk${TEST_CHUNK}"
+          command=(
+            node .github/scripts/run-ts-tests-chunk.mjs
+            --script "$TEST_SCRIPT"
+            --chunk "$TEST_CHUNK"
+            --chunks "$TEST_CHUNK_TOTAL"
+          )
+        fi
node .github/scripts/measure-command.mjs \
-          --name "$BENCHMARK" \
-          --output ".bench/${BENCHMARK}.json" \
-          -- pn run "$TEST_SCRIPT"
+          --name "$benchmark" \
+          --output ".bench/${benchmark}.json" \
+          -- "${command[@]}"
Evidence
The workflow first checks numeric validity via bash arithmetic, but later branches on a string
comparison (!= "1") and interpolates the raw string into benchmark names; this makes
numerically-equal but non-canonical strings take different execution paths and naming.

.github/workflows/test.yml[177-223]
.github/workflows/test.yml[224-246]
.github/workflows/test.yml[247-262]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`test_chunk` / `test_chunk_total` are treated as strings in later branching (`!= "1"`) and name construction, but are validated using numeric comparisons. Inputs like `01` therefore behave like 1 for validation yet still trigger chunk mode and generate `.chunk01` benchmark/artifact names.
### Issue Context
This workflow is reusable (`workflow_call`), so while `ci.yml` currently passes canonical values (`'1'`, `'2'`, `'3'`), other callers can pass non-canonical numeric strings.
### Fix Focus Areas
- .github/workflows/test.yml[177-223]
### Implementation sketch
- In the "Validate test chunk inputs" step, after validation, normalize both values and export them for subsequent steps, e.g.:
- `chunk=$((10#$TEST_CHUNK))`
- `total=$((10#$TEST_CHUNK_TOTAL))`
- `echo "TEST_CHUNK=$chunk" >> "$GITHUB_ENV"`
- `echo "TEST_CHUNK_TOTAL=$total" >> "$GITHUB_ENV"`
- In later steps, prefer numeric branching (e.g. `if (( TEST_CHUNK_TOTAL != 1 )); then`) and use the normalized env vars when forming `benchmark`/artifact names.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


8. Empty shards still do setup 🐞 Bug ➹ Performance
Description
.github/scripts/run-ts-tests-chunk.mjs runs prepare-fixtures and remove-temp-dir before it
knows whether the selected shard has any tasks, so shards that end up empty still pay that setup
cost and can delay the overall workflow. This is plausible on non-main branches where test.yml
selects ci:test-branch (affected packages) while ci.yml always schedules 3 Windows chunks.
Code

.github/scripts/run-ts-tests-chunk.mjs[R14-22]

+if (!dryRun) {
+  await runPnpm(['run', 'prepare-fixtures'])
+  await runPnpm(['run', 'remove-temp-dir'])
+}
+
+const packages = await listSelectedPackages(script)
+const tasks = await listTestTasks(packages)
+const selectedTasks = selectChunk(tasks, { chunk, chunks })
+const selectedPackages = groupJestTasksByPackage(selectedTasks)
Evidence
The chunk runner performs setup before computing selectedTasks, while the CI workflow always
creates 3 Windows chunks and can select an “affected packages” scope that may not fill all chunks.

.github/scripts/run-ts-tests-chunk.mjs[14-37]
.github/workflows/ci.yml[89-133]
.github/workflows/test.yml[146-219]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`run-ts-tests-chunk.mjs` runs expensive setup (`prepare-fixtures`, `remove-temp-dir`) before it has determined whether the current chunk contains any work. When a chunk has no selected tasks, this is wasted time and can extend the critical path for the overall CI run.
### Issue Context
Windows is always split into 3 chunks in the workflow matrix, but the “affected packages” scope can be smaller than that, producing empty chunks.
### Fix Focus Areas
- .github/scripts/run-ts-tests-chunk.mjs[14-37]
### Suggested fix
1. Move the `prepare-fixtures` / `remove-temp-dir` calls to after `selectedTasks` is computed.
2. If `selectedTasks.length === 0` (and not `--dry-run`):
- write an empty summary file (so downstream steps that read `pnpm-exec-summary.json` don’t fail), e.g. `await writeSummary(summary, {})`.
- exit successfully without running setup or tests.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


9. Unbounded stat fan-out 🐞 Bug ➹ Performance
Description
listTestTasks() does an unbounded Promise.all() over stat() for every discovered Jest test
file, which can saturate filesystem/threadpool work and slow shard startup on Windows. This cost
scales with test file count because the repo’s Jest preset matches all files under test/
(**/test/**/*.[jt]s?(x)).
Code

.github/scripts/run-ts-tests-chunk.mjs[R68-78]

+    const testFiles = await findJestTestFiles(pkg.path)
+    tasks.push(...await Promise.all(testFiles.map(async (file) => {
+      const fileStat = await stat(file)
+      return {
+        file,
+        id: normalizePath(path.relative(rootDir, file)),
+        kind: 'jest',
+        packagePath: pkg.path,
+        weight: Math.max(1, fileStat.size),
+      }
+    })))
Evidence
The chunk runner stats every discovered test file concurrently, and the Jest preset explicitly
matches all test/**/*.[jt]s?(x) files, which makes the stat fan-out proportional to the size of
the test tree.

.github/scripts/run-ts-tests-chunk.mjs[55-79]
pnpm11/utils/jest-config/config.js[3-16]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`listTestTasks()` calls `Promise.all(testFiles.map(stat))`, creating an unbounded burst of concurrent filesystem stats. On Windows runners this can be a noticeable startup penalty.
### Issue Context
The Jest preset’s `testMatch` includes all files under `test/`, so large packages can produce a large `testFiles` list.
### Fix Focus Areas
- .github/scripts/run-ts-tests-chunk.mjs[55-80]
### Suggested fix
Replace the unbounded `Promise.all()` with a bounded-concurrency mapper (e.g. process in batches of 32–64, or implement a small async pool) so discovery cost is smoother and less spiky on Windows.
Example approach:
- Build tasks in a loop with a small in-flight set.
- Or chunk `testFiles` into groups of N and `await Promise.all()` per group.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


10. Excess Jest invocations ✓ Resolved 🐞 Bug ➹ Performance
Description
getJestFileBatches() forces fixed 10-file batching for the “rest” set whenever a package has any
split .test: Jest scripts, turning one Jest run into many per package. On large packages (e.g.
@pnpm/installing.deps-installer), this multiplies Jest startup overhead on Windows and can offset
the intended wall-clock gains from sharding or increase timeout risk.
Code

.github/scripts/run-ts-tests-chunk.mjs[R248-259]

+function getJestFileBatches (pkg, relFiles) {
+  const isolatedFiles = Array.from(getExplicitJestFiles(pkg.manifest.scripts))
+    .filter((file) => relFiles.includes(file))
+  if (isolatedFiles.length === 0 && !hasSplitJestScripts(pkg.manifest.scripts)) return [relFiles]
+
+  const isolatedFileSet = new Set(isolatedFiles)
+  const remainingFiles = relFiles.filter((file) => !isolatedFileSet.has(file))
+  return [
+    ...isolatedFiles.map((file) => [file]),
+    ...chunkArray(remainingFiles, JEST_FILES_PER_SPLIT_SCRIPT_BATCH),
+  ].filter((files) => files.length > 0)
+}
Evidence
The new chunk runner unconditionally chunks remaining files into 10-file batches whenever any split
.test: Jest scripts exist, which increases the number of Jest processes. The
@pnpm/installing.deps-installer package explicitly defines a two-phase heavy/rest Jest split that
will now be expanded into multiple “rest” batches.

.github/scripts/run-ts-tests-chunk.mjs[248-259]
.github/scripts/run-ts-tests-chunk.mjs[261-263]
pnpm11/installing/deps-installer/package.json[49-58]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The chunk runner batches remaining Jest files into groups of 10 whenever split `.test:` Jest scripts exist. For packages where the original setup ran the “rest” tests in a single Jest process (e.g. heavy/rest split), this can explode the number of Jest invocations and add significant overhead on Windows.
### Issue Context
- `@pnpm/installing.deps-installer` runs heavy+rest as two Jest invocations (explicit file + regex rest).
- The chunk runner currently converts the “rest” selection into N/10 Jest invocations.
### Fix Focus Areas
- .github/scripts/run-ts-tests-chunk.mjs[248-259]
### Implementation guidance
- Keep isolated explicit files as single-file batches.
- For the remaining files, prefer **one Jest invocation** (single batch) unless it would exceed a safe command-line size for the current OS/shell.
- Replace the fixed `JEST_FILES_PER_SPLIT_SCRIPT_BATCH` behavior with dynamic splitting based on an estimated command length (sum of `jest` args + file path lengths + separators), and only split when needed.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


11. Unvalidated chunk input usage ✓ Resolved 🐞 Bug ⛨ Security
Description
test.yml defines test_chunk/test_chunk_total as string inputs and interpolates them into
benchmark output paths and into metadata.json without validating they are numeric, so malformed
inputs can produce invalid JSON or unexpected benchmark filenames. This can break Bencher artifact
staging/consumption for any workflow caller that passes a non-numeric value (even though the Node
chunk runner validates its own --chunk/--chunks).
Code

.github/workflows/test.yml[R260-267]

cat > "$artifact_dir/metadata.json" <<EOF
{
"kind": "pnpm",
-          "testbed": "pnpm.${platform_slug}.node${node_major}"
+          "testbed": "pnpm.${platform_slug}.node${node_major}",
+          "chunk": {
+            "index": ${TEST_CHUNK},
+            "total": ${TEST_CHUNK_TOTAL}
+          }
Evidence
The workflow inputs are explicitly typed as strings and are used to build filenames and JSON fields
directly in bash, without any numeric validation step before emitting .bench/${benchmark}.json and
metadata.json.

.github/workflows/test.yml[4-26]
.github/workflows/test.yml[177-216]
.github/workflows/test.yml[260-269]
.github/scripts/run-ts-tests-chunk.mjs[311-342]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The reusable workflow accepts `test_chunk` and `test_chunk_total` as strings and uses them in bash to form benchmark filenames and to emit numeric JSON fields without validation. This allows malformed values to generate invalid JSON and inconsistent artifact/benchmark naming.
## Issue Context
- Inputs are declared as `type: string` and flow into bash variables.
- Benchmark/output filenames and metadata are derived from these inputs.
- The Node helper script validates `--chunk/--chunks`, but the workflow also uses the inputs directly when composing `.bench/*` filenames and `metadata.json`.
## Fix
- Change workflow_call input types to `number` (if compatible) and/or add explicit bash validation (e.g., `[[ $TEST_CHUNK =~ ^[0-9]+$ ]]` and same for total) before using them.
- When writing `metadata.json`, serialize safely (e.g., `jq -n --argjson index "$TEST_CHUNK" ...`) or quote values as strings if the consumer allows.
## Fix Focus Areas
- .github/workflows/test.yml[4-27]
- .github/workflows/test.yml[177-201]
- .github/workflows/test.yml[260-269]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


12. Repeated full test file scan ✓ Resolved 🐞 Bug ➹ Performance
Description
Each shard runs a full recursive test-file discovery across all selected packages and then does a
sequential stat() per discovered file to compute weights, and this whole scan repeats
independently for each Windows chunk. This adds substantial extra filesystem work on Windows (the
slowest runner), reducing the net CI wall-clock savings from sharding.
Code

.github/scripts/run-ts-tests-chunk.mjs[R52-74]

+async function listTestTasks (packages) {
+  const tasks = []
+  for (const pkg of packages) {
+    if (!usesJest(pkg.manifest.scripts)) {
+      tasks.push({
+        id: normalizePath(path.relative(rootDir, pkg.path)),
+        kind: 'script',
+        packagePath: pkg.path,
+        weight: 1,
+      })
+      continue
+    }
+
+    for (const file of await findJestTestFiles(pkg.path)) {
+      const fileStat = await stat(file)
+      tasks.push({
+        file,
+        id: normalizePath(path.relative(rootDir, file)),
+        kind: 'jest',
+        packagePath: pkg.path,
+        weight: Math.max(1, fileStat.size),
+      })
+    }
Evidence
The helper script performs a recursive directory walk and per-file stat() to build weighted tasks,
and ci.yml explicitly configures three Windows chunks, meaning the same discovery work is repeated
in each shard job.

.github/scripts/run-ts-tests-chunk.mjs[52-74]
.github/scripts/run-ts-tests-chunk.mjs[174-200]
.github/workflows/ci.yml[89-133]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The chunk runner computes shard weights by recursively walking `test/` and `src/` per package and performing `stat()` for every discovered test file, sequentially. With 3 Windows shards, this scan is performed 3 times, increasing total CI time spent in filesystem discovery.
## Issue Context
- `listTestTasks()` loops packages and awaits `stat()` for each test file.
- `findJestTestFiles()` recursively walks directories.
- `ci.yml` fans out Windows into 3 chunks, so the same scan runs in each shard job.
## Fix
Pick one:
- Drop `stat()` sizing and use constant weights (or a cheaper heuristic), avoiding per-file `stat()` entirely.
- Or parallelize file stats with a small concurrency limit (e.g., 32–64) to reduce wall time on Windows.
- Optionally restrict discovery to `test/` only if `src/*.test.ts` is rare, or use a faster index such as `git ls-files` to enumerate candidates rather than recursive `readdir`.
## Fix Focus Areas
- .github/scripts/run-ts-tests-chunk.mjs[52-77]
- .github/scripts/run-ts-tests-chunk.mjs[174-200]
- .github/workflows/ci.yml[89-133]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


13. Windows shell arg injection ✓ Resolved 🐞 Bug ⛨ Security
Description
.github/scripts/run-ts-tests-chunk.mjs spawns pn with shell: true on Windows and forwards
filesystem-derived arguments (notably Jest test file paths) without rejecting cmd.exe
metacharacters, which can execute unintended commands or break invocations. This deviates from the
repo’s existing defensive pattern in measure-command.mjs, which validates args before spawning on
Windows.
Code

.github/scripts/run-ts-tests-chunk.mjs[R245-273]

+function runCommand (command, args, opts = {}) {
+  return new Promise((resolve, reject) => {
+    const child = spawn(command, args, {
+      cwd: opts.cwd ?? rootDir,
+      env: opts.env ?? process.env,
+      shell: process.platform === 'win32',
+      stdio: 'inherit',
+    })
+    child.on('error', reject)
+    child.on('close', (code, signal) => {
+      if (signal) {
+        reject(Object.assign(new Error(`${command} terminated by signal ${signal}`), { exitCode: 1 }))
+      } else if (code === 0) {
+        resolve()
+      } else {
+        reject(Object.assign(new Error(`${command} exited with code ${code}`), { exitCode: code ?? 1 }))
+      }
+    })
+  })
+}
+
+function captureCommand (command, args) {
+  return new Promise((resolve, reject) => {
+    let stdout = ''
+    const child = spawn(command, args, {
+      cwd: rootDir,
+      shell: process.platform === 'win32',
+      stdio: ['ignore', 'pipe', 'inherit'],
+    })
Evidence
The new runner forwards repo-derived test file paths into a Windows shell: true spawn without
validation; the repo’s existing CI runner script uses an explicit metacharacter guard before
spawning with shell: true on Windows, showing the intended safety baseline.

.github/scripts/run-ts-tests-chunk.mjs[111-133]
.github/scripts/run-ts-tests-chunk.mjs[245-273]
.github/scripts/measure-command.mjs[70-97]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
On Windows, `child_process.spawn(..., { shell: true })` routes execution through `cmd.exe`, where characters like `& | < > ^ %` and newlines can change command parsing. `run-ts-tests-chunk.mjs` enables `shell: true` but does not validate or escape arguments; it also passes repo-derived test file paths into the spawned command line.
This creates a Windows-specific command-injection/argument-smuggling risk in CI and can also cause confusing failures if any path contains shell metacharacters.
## Issue Context
The repo already has a defensive implementation in `.github/scripts/measure-command.mjs` (`validateWindowsShellArgs`) that rejects Windows shell metacharacters before spawning.
## Fix Focus Areas
- .github/scripts/run-ts-tests-chunk.mjs[245-273]
- .github/scripts/run-ts-tests-chunk.mjs[111-133]
- .github/scripts/measure-command.mjs[70-97]
## Suggested fix
- Copy (or factor out and reuse) the `validateWindowsShellArgs` logic from `measure-command.mjs`.
- In `runCommand()` and `captureCommand()`, when `process.platform === 'win32'`, validate `[command, ...args]` before calling `spawn`.
- Preferably, also add a clear error message indicating which argument contained metacharacters and which command was being executed.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

Comment thread .github/scripts/run-ts-tests-chunk.mjs
@qodo-free-for-open-source-projects

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit 0d4195a

@qodo-free-for-open-source-projects

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit ffd4e61

Comment thread .github/scripts/run-ts-tests-chunk.mjs Outdated
@qodo-free-for-open-source-projects

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit ffd4e61

@qodo-free-for-open-source-projects

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit 618a4b2

Comment thread .github/scripts/run-ts-tests-chunk.mjs
@qodo-free-for-open-source-projects

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit 618a4b2

@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 @.github/scripts/run-ts-tests-chunk.mjs:
- Around line 338-345: The issue is that when spawn() is called with shell: true
on Windows, Node.js concatenates the command and args array into a single string
without quoting individual arguments, causing arguments containing spaces to be
split into multiple tokens. The validateWindowsShellArgs function only blocks
injection metacharacters but does not address this problem. Fix this by either
removing the shell option entirely from the spawn() calls (at lines 338-345,
364-370, and 403-409) so that the process is spawned directly with the args
array properly handled by Node.js, or by constructing a single properly-quoted
command string as the first argument to spawn() and passing undefined as the
args parameter. Choose the approach that best fits the codebase's current
architecture.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 0005c6b4-eb41-4665-8e14-7c6961c2d860

📥 Commits

Reviewing files that changed from the base of the PR and between 618a4b2 and 087d0cc.

📒 Files selected for processing (3)
  • .github/scripts/bencher-result-from-pnpm-summary.mjs
  • .github/scripts/run-ts-tests-chunk.mjs
  • .github/workflows/test.yml
🚧 Files skipped from review as they are similar to previous changes (1)
  • .github/workflows/test.yml

Comment thread .github/scripts/run-ts-tests-chunk.mjs Outdated
@qodo-free-for-open-source-projects

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit 087d0cc

1 similar comment
@qodo-free-for-open-source-projects

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit 087d0cc

spawn(cmd, args, { shell: true }) on Windows joins args into one string
without quoting, so an arg containing a space would be split into
multiple tokens. Build the quoted command line ourselves and pass it as
a single string to cmd.exe, and reject embedded double quotes so the
quoting stays unambiguous.
@qodo-free-for-open-source-projects

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit 8f1b5d9

1 similar comment
@qodo-free-for-open-source-projects

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit 8f1b5d9

…generalize chunk runner

The chunk runner hardcoded `if name === deps-installer set PNPM_REGISTRY_MOCK_PORT=7769`.
Derive the port from the package's own `.test` scripts instead, so the
runner carries over any package's pin without naming it.

Also decouple the 'fail if a package cannot be fetched' test from the
pinned port: it served committed packument fixtures whose tarball URLs
hardcoded localhost:7769, matched only when the mock agent's origin used
that port. Rebuild each fixture tarball URL from the live REGISTRY_MOCK_PORT
at load time and drop the magic port from the fixtures.

The deps-installer port pin itself stays: the lockfile normalization test
installs the `@pnpm.e2e/pkg-with-tarball-dep-from-registry` fixture, whose
dependency is an absolute tarball URL served verbatim by the live registry,
so the registry must answer on the baked port.
@qodo-free-for-open-source-projects

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit 3f3d400

The full test matrix waited on test-smoke. Split Windows into its own
test-windows job gated only on compile-and-lint, so its three shards run
alongside the ubuntu Node 24 smoke job. The other Node.js versions
(ubuntu 22/26) still wait for the smoke job. The Success gate aggregates
all of them.
@qodo-free-for-open-source-projects

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit 3f3d400

@qodo-free-for-open-source-projects

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit 3c0ab11

1 similar comment
@qodo-free-for-open-source-projects

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit 3c0ab11

The pnpr build lived inside the reusable test job, keyed on a cache that
actions/cache reads at job start. Because the test matrix (ubuntu 22/26
and the three Windows shards) fans out in parallel, every job missed the
cache and rebuilt pnpr from scratch.

Hoist the build into a dedicated build-pnpr job (matrix over ubuntu and
windows) that runs alongside compile-and-lint, uploads the binaries as a
per-OS artifact, and keeps the source-keyed binary cache. Each test job
now downloads pnpr-bins-<os> instead of compiling, restoring the
executable bit that artifacts drop on POSIX.
@qodo-free-for-open-source-projects

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit 3918c2a

1 similar comment
@qodo-free-for-open-source-projects

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit 3918c2a

The pnpr binaries live in `.pnpr-bin`, a dotfile directory that
actions/upload-artifact skips by default (include-hidden-files: false),
so the build-pnpr upload found no files and failed. Opt the hidden dir in.
@qodo-free-for-open-source-projects

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit 503b673

1 similar comment
@qodo-free-for-open-source-projects

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit 503b673

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

reviewed: coderabbit CodeRabbit submitted an approving review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant