Commit Graph
432 Commits
Author SHA1 Message Date
dependabot[bot] 19dbe1324d chore(deps): bump vedantmgoyal9/winget-releaser
Bumps the github-actions group with 1 update in the / directory: [vedantmgoyal9/winget-releaser](https://github.com/vedantmgoyal9/winget-releaser).


Updates `vedantmgoyal9/winget-releaser` from 7bd472be23763def6e16bd06cc8b1cdfab0e2fd5 to b3a5dae0047c6180023acba3f548c55fdf6b7193
- [Release notes](https://github.com/vedantmgoyal9/winget-releaser/releases)
- [Commits](https://github.com/vedantmgoyal9/winget-releaser/compare/7bd472be23763def6e16bd06cc8b1cdfab0e2fd5...b3a5dae0047c6180023acba3f548c55fdf6b7193)

---
updated-dependencies:
- dependency-name: vedantmgoyal9/winget-releaser
  dependency-version: b3a5dae0047c6180023acba3f548c55fdf6b7193
  dependency-type: direct:production
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-09-11 11:51:30 +00:00
Zoltan KochanandClaude Opus 5 822f2dcb23 chore(ci): install every crate through pnpm (#14824)
Commit the pnpm-managed Cargo source block. The block is a function of
Cargo.lock, so an install regenerates it byte for byte and the tracked
`.cargo/config.toml` stops reporting as modified after every install. A new
Rust CI step fails if the committed block and the lockfile drift apart.

Cargo now resolves every crate through `.pnpm/crates` and falls back to its
own registry nowhere, so each job that runs cargo needs an install behind it.
Eight did not have one: both cargo-unused jobs, the micro-benchmark, the
integrated benchmark's build and executor jobs, and the three release builds.
The new `install-crates` action gives them one and narrows the JavaScript half
with `--filter pacquet`, which a filter does not do to the Cargo half.

The release builds go through `cross`, which mounts the checkout at
`/project`. pnpm links each crate into `.pnpm/crates` with a relative symlink,
so a store outside the checkout stops resolving under that mount. Those jobs
install into a store inside the checkout instead, on Linux, the one host where
cross containerizes the build at all.

The two workflows that commit no longer discard the block. It is tracked
content now, and a run that changes it should carry the change.


Claude-Session: https://claude.ai/code/session_01Gg6uVUzLw1MniCLC81TQjP
Claude-Session: https://claude.ai/code/session_01HwJS1pAz9HHQpJWEJAiaUu

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-11 02:27:47 +02:00
Zoltan KochanandClaude Opus 5 4d32532cc7 chore: install the Rust dependencies with pnpm (#14689)
* chore: install the Rust dependencies with pnpm

Turn on `cargo.enabled` so `pnpm install` installs the crates `Cargo.lock`
pins alongside the JavaScript dependencies. pnpm links the registry crates
into `.pnpm/crates/crates-io` and the git-sourced ones into
`.pnpm/crates/git`, then writes a source replacement block into
`.cargo/config.toml` that points Cargo at both.

The `node-semver` fork stays patched in. pnpm installs git-sourced crates
since pnpm/pnpm#14694, which shipped in the 12.4.1 the repository pins, so
enabling this no longer costs the fork's `<=` range and `Ord for Bound`
fixes.

Document the workflow, including the two things a contributor hits first:
`pnpm install` shells out to `cargo`, so it fails when `cargo` is off
`PATH`, and the generated block leaves the tracked `.cargo/config.toml`
modified after every install.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SDxJNVEeyUBb4pcepEpGcj

* ci: initialize Rust before pnpm installs dependencies

Every `pnpm install` now shells out to `cargo metadata`, and there is no
way to opt one out: `cargo.enabled` is read from `pnpm-workspace.yaml`
only, no CLI flag or `PNPM_CONFIG_*` variable overrides it, and `--filter`
does not narrow the Cargo half. So each job whose install runs gets the
pinned toolchain first. `pnpm/setup` installs unless told not to,
`pnpm/update` runs its own install, and `pnpm pipeline` installs before it
runs anything.

The step has to precede the install rather than follow it. The rustup
action ends with `git restore .`, which would otherwise wipe the source
replacement block back out of `.cargo/config.toml`.

Keep that block out of the two workflows that commit. It points at the
gitignored `.pnpm/crates`, so a commit carrying it would break every
Rust-only job and every checkout that has not installed. Both workflows
also decide whether to commit at all by reading `git status --porcelain`,
which the block would make non-empty on every run. Each discards it right
before that check: the release PR in a step of its own, the lockfile
update through the `post-update` command pnpm/update runs between its
install and its commit.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SDxJNVEeyUBb4pcepEpGcj

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-10 21:17:43 +02:00
Zoltan Kochan d2c5ecbb63 chore(ci): run checks through pnpm pipelines (#14690)
Declare CI pipelines and root task scripts, and invoke them from the
TypeScript, Rust, reusable test, and pnpr build workflows. Let pipelines
perform frozen installs and order TypeScript compilation before linting.

Keep existing test runners responsible for affected-package selection,
file-level sharding, and summary generation. Read shard settings from the
workflow environment, with explicit command-line arguments taking precedence.

Run root tasks with --include-workspace-root --full: the scripts live in the
root manifest only, and the test runners already select their own scope. Pass
--no-cache so a task that later declares outputs cannot skip a check.

Keep the dependency install in its own step in the two jobs whose commands are
timed for Bencher, so the reported duration stays a test duration. Preserve
existing job gates and artifact handoffs.
2026-09-10 21:05:01 +02:00
Zoltan Kochanandgithub-actions[bot] a75be2f56d chore: update dependencies, Node.js, pnpm, and GitHub Actions (#14806)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-09-10 19:11:38 +02:00
Zoltan Kochan c09981cf7d ci: parallelize integrated benchmark builds and scenarios (#14799)
Resolve main and HEAD once and build their Rust client/server pairs in
parallel while retaining the per-commit binary caches. Build the executor
in a third independent job. Exclude the peer-heavy fixture from the shared
npm proxy cache and invalidate potentially incomplete cache entries. Transfer the
binaries and shared benchmark executor in tar archives to preserve
executable permissions.

Run each scenario on a separate runner, keeping all compared revisions
within the same hyperfine invocation. Build the TypeScript CLI only for
the peer-heavy scenario. Aggregate scenario artifacts into the existing
report and Bencher formats, and propagate the peer-heavy gate result
after publishing measurements.

This changes CI orchestration only and needs no package changeset.
2026-09-10 16:56:12 +02:00
Zoltan Kochanandgithub-actions[bot] c52f5d3686 chore: update dependencies, Node.js, pnpm, and GitHub Actions (#14762)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-09-10 08:33:20 +02:00
Zoltan Kochanandgithub-actions[bot] c39ee2bff9 chore: update dependencies, Node.js, pnpm, and GitHub Actions (#14724)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-09-09 13:28:18 +02:00
Zoltan Kochan 2fa282950f style: adopt perfectionist's new size and shape rules (#14730)
Pin the perfectionist dylint library to a revision instead of a tag and
enable the four rules that revision adds: arbitrary_source_item_ordering,
core_instead_of_std, excessive_cognitive_complexity with a limit of 10,
and redundant_derive_more_forward_template.

The tree is made to pass them by refactoring rather than by exemptions:
no #[expect], no #[allow], and no raised limit. Oversized functions are
split into named steps, conditions that carried a meaning are given
names, three-way outcomes become enums, repeated parameter lists become
types that own the shared values, and the nearly sixty CLI config
overrides that repeated the same three shapes are driven from macro
tables.

cargo-dylint refuses a library built against a newer dylint_linting, so
CI moves to cargo-dylint/dylint-link 6.0.4 to match the pinned revision.
The 6.0.1 bootstrap failure the previous 6.0.0 pin worked around is fixed
there.

Related to https://github.com/pnpm/pnpm/issues/14562. That issue plans
seven size-and-shape rules; only excessive_cognitive_complexity has
landed upstream so far. It also proposed a per-site #[expect] for every
existing violation, which this PR deliberately does not do.
2026-09-09 13:15:59 +02:00
Zoltan Kochanandgithub-actions[bot] 2a762b7d53 chore: update dependencies, Node.js, pnpm, and GitHub Actions (#14681)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-09-08 13:29:35 +02:00
Zoltan KochanandClaude Opus 5 e91c63887e feat: add android-arm64 and android-x64 builds (#14660)
Build the Rust CLI and the NAPI addon for aarch64-linux-android and
x86_64-linux-android and publish them as `@pnpm/exe.android-*` and
`@pnpm/napi.android-*`, so installing pnpm in Termux resolves a native binary
instead of failing the preinstall with no prebuilt binary for the platform.
Closes pnpm/pnpm#14431.

pnpm 11 reached Android because it was a JavaScript CLI and bionic was
irrelevant to it. pnpm 12 ships per-platform native binaries, which turned that
into a hard install failure.

This ships a dedicated artifact rather than aliasing the existing musl one onto
android. Aliasing would mean dropping `libc: ["musl"]` from the shared packages
and weakening that metadata for Alpine consumers, and it does not work anyway:
the musl binary's `getaddrinfo` reads `/etc/resolv.conf`, which Android does
not have and which cannot be created without root, so every registry lookup
fails there. A bionic binary resolves through Android's own resolver. The
generated manifests carry `os: ["android"]` with no `libc` field, since bionic
is neither of the two the field can name.

Cross.toml pins newer images for the two targets. The ones cross picks by
default carry NDK r21, whose toolchain predates Rust's move from libgcc to
libunwind, so linking fails with `cannot find -lunwind`. They are pinned by
digest rather than tag because they build published, attested binaries.

Android has no CI behind it: nothing in the release pipeline or the test suite
runs on a device or an emulator, so this is best-effort.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-07 16:35:46 +02:00
Zoltan Kochan 52859b9bfd feat: add freebsd-x64, linux-ppc64 and linux-s390x builds (#14656)
Build the Rust CLI and the NAPI addon for x86_64-unknown-freebsd,
powerpc64le-unknown-linux-gnu and s390x-unknown-linux-gnu, and publish them as
`@pnpm/exe.*` and `@pnpm/napi.*` platform packages, so installing pnpm on those
hosts resolves a native binary instead of failing the preinstall with no
prebuilt binary for the platform. Closes pnpm/pnpm#14597.

pnpm 11's npm package was a JavaScript CLI that ran wherever Node.js ran, so
all three worked without anyone building for them. pnpm 12 ships per-platform
native binaries, which turned that into a hard install failure. ppc64le and
s390x were the only two architectures Node.js ships an official binary for that
pnpm did not; both were reported on pnpm/pnpm#14651, which stays open for
OpenBSD, a tier 3 Rust target with no rustup std and no cross image.

The release matrix builds all three with cross on the existing x86_64 Linux
runner, the same way it already builds the aarch64 and riscv64 targets, so no
new hardware is involved.

The little-endian POWER package is `@pnpm/exe.linux-ppc64`, not `-ppc64le`.
Node reports both endiannesses as `ppc64` and npm's `cpu` field cannot express
which, so the name has to be what `process.arch` yields. Only the little-endian
build is released, matching Node.

FreeBSD's platform entry is a bare specifier rather than a glibc/musl pair. It
has no libc split, so it takes the same shape as darwin and win32 and never
reaches the libc ordering, and its manifest carries no `libc` field.
2026-09-07 14:57:22 +02:00
velonica0andZoltan Kochan 7a27a8efd9 feat: add linux-riscv64 build (#14529)
Build the Rust CLI for riscv64gc-unknown-linux-gnu and publish it as
@pnpm/exe.linux-riscv64, so installing pnpm on a riscv64 host resolves a
native binary instead of finding no prebuilt binary for the platform.

The release matrix builds the target with cross on the existing x86_64 Linux
runner, the same way it already builds both aarch64 targets, so no riscv64
hardware is involved.

PLATFORMS.linux gets a plain string specifier rather than a glibc/musl pair.
Only a glibc build is released, and the libc ordering maps over the pair's
keys, so a pair with a missing musl entry would yield an undefined specifier.

---------

Co-authored-by: Zoltan Kochan <z@kochan.io>
2026-09-07 12:30:44 +02:00
Zoltan Kochanandgithub-actions[bot] 08e64d4b83 chore: update dependencies, Node.js, pnpm, and GitHub Actions (#14603)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-09-07 11:29:41 +02:00
Zoltan Kochan 6ba99fb386 feat(pnpr): share cargo compilation caches (#14620)
Expose named compiler caches through the WebDAV subset used by sccache.
Apply pnpr account access and publication policies before buffering uploads,
including existing token restrictions. Entries are immutable and verified
against a digest bound to their cache scope, key, and bytes before serving.
Reuse the shared artifact store's filesystem/S3 selection, quota accounting,
publication lifecycle, and orphan reclamation.

Bound compiler uploads to two concurrent bodies per server and reject excess
requests before buffering. Store digest and payload as separate buffers in
one conditional object write. Use metadata-only HEAD and duplicate checks;
GET still verifies content before serving it.

Stock sccache trusts the server and allowed publishers; it does not verify
pnpm signed envelopes. Document trusted CI publication and HTTPS requirements.
Also document sccache 0.17's absolute Rust build-path requirement and its
read-only multilevel behavior: remote hits backfill disk, but new compilation
misses are not cached locally when a tier is read-only.

Add HTTP, policy, integrity, quota, and real Cargo integration coverage.
Install sccache for Rust CI and local test setup. Extract the existing
miette diagnostic normalization into a shared test helper to fix a shim
assertion exposed by the full suite's longer temporary paths.
2026-09-06 15:35:06 +02:00
Zoltan Kochan 427bece813 feat(cli): integrate python with shared install and artifact lifecycles (#14586)
Exercise the multi-ecosystem architecture through a usable Python
integration, not test-only metadata writers.

Keep Python requirement, marker, lockfile and environment semantics
separate from npm and Cargo. Reuse the install-wide HTTP/auth budget,
verified artifact ingestion, CAS and store index.

Extract a shared install lifecycle without ecosystem-specific branches.
Native tasks declare metadata footprints and return prepared projections.
Settle all work before publishing Cargo or Python state, and reverse
attempted publications before restoring metadata on failure.
Retain resources when rollback fails so recovery remains possible.

Enroll npm with its existing in-place materialization semantics, and
keep npm-only dispatch on its early path. Do not unify native resolvers,
lockfile formats, target identity or package layouts.

Consolidate archive ingestion below the ecosystem boundary. Share cache
validation, authenticated requests, extraction retries and publication
across tarballs and ZIPs, retaining tar streaming and ZIP decoding.
Test the shared contracts across both formats and preserve npm fast paths.

Use standard pylock.toml, independently validated with uv.
New features target pnpm v12 only. Shared archive URL-redaction fixes
also cover pnpm v11.

Related to pnpm/pnpm#14566 and pnpm/rfcs#34.
2026-09-05 22:58:05 +02:00
Zoltan Kochan cf5a7bf514 fix(ci): allow pnpm v12 install scripts in tag upgrade check (#14592)
The upgrade check only allowed install scripts for `@pnpm/exe`, so
installing the pnpm v12 wrapper failed before self-update could run.
Allow scripts for the package selected by the existing wrapper loop.
This preserves verification of both published wrappers and allows
pnpm v12 promotions to proceed through the upgrade gate.

Verified both published 12.3.4 wrappers using the workflow's pinned
pnpm 11.13.1, including self-update and doctor --offline.
2026-09-05 19:23:51 +02:00
Zoltan Kochanandgithub-actions[bot] 7a0a0655cb chore: update dependencies, Node.js, pnpm, and GitHub Actions (#14577)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-09-05 09:38:08 +02:00
Zoltan Kochan 779b40eb47 fix(pacquet): make the placeholder bin runnable without a shebang (#14527)
The npm package's `pnpm` bin is a placeholder that the preinstall script
replaces with the native binary. It has to stay shebang-less, because a bin
shim generated from a shebang records that interpreter and pnpm 11 generates
the shim before it puts the binary at that path. Installers that skip build
scripts never replace it, and a prose placeholder is not a shell script, so
every command failed with `syntax error near unexpected token ')'`.

Make the placeholder a valid `sh` script with no shebang. On ENOEXEC the shell
and glibc's `execvp` both retry the file under `/bin/sh`, so it runs from a
symlinked bin, from a shim that execs it, and from a direct spawn; it hands
over to `bin/pnpm.mjs`, which finds the installed binary or downloads one.
A shim generated from it still execs the file itself, so pnpm 11 delegation
keeps working once the binary takes the same path.

Windows has no ENOEXEC fallback and cannot run an extension-less file, so a
script-blocked install there still cannot run pnpm.

Closes pnpm/pnpm#14346.
2026-09-04 12:20:48 +02:00
Zoltan Kochan 949c8d3b62 ci(release): retry cross builds on transient failures (#14522)
The v12.3.2 release run died in "Package pnpm-napi darwin-x64" because
Apple clang segfaulted while linking the httparse build script. Nothing
in the tree changed; the same Blacksmith image built v12.3.1 fine the
day before. Every other packaging job was cancelled and the release had
to wait for the run to finish before "re-run failed jobs" was possible.

Route the three release cross builds through a wrapper script that
retries up to three times. Cargo keeps the crates a failed attempt
finished, so a retry only redoes the crate that died.

The Windows legs of build-rust and build-pnpr now run the build step
under bash instead of the default pwsh, as the napi packaging job
already did on both Windows targets. The clang-cl environment for
win32-arm64 is exported through GITHUB_ENV and GITHUB_PATH, so it
reaches bash the same way.
2026-09-04 03:12:51 +02:00
Zoltan Kochan d34902d5a6 chore: update dependencies, Node.js, pnpm, and GitHub Actions (#14400) 2026-09-02 18:35:33 +02:00
Zoltan Kochan 28bb2a339b ci: reference same-repository actions and workflows with the self-repository syntax (#14452)
zizmor's self-repository audit flags every `uses: ./.github/...` reference
now that GitHub has a dedicated `$/` form. The `$/` form resolves against the
workflow's own commit rather than the runtime checkout, so it cannot load an
action cloned into the workspace at runtime, and GitHub treats it as pinned.

Rewrites all 22 references (18 local actions, 4 reusable workflow calls).

With the `$/` form the runner downloads the whole repository as an action
archive at job setup, and that download fails on any broken symlink in the
tree. The four broken symlinks were all test fixtures: the directory-fetcher
and cafs tests now copy their fixture into a temp dir and create the broken
symlink there, and the has-not-outdated-deps fixture drops two dangling
node_modules links that `pnpm outdated` never followed.

pnpm's GitHub Actions dependency discovery only followed `./` references
into local actions and reusable workflows; both stacks now follow `$/` too.
2026-09-02 13:58:57 +02:00
Zoltan Kochan 355741239a ci: cancel stale workflow approval requests (#14415)
Add a trusted scheduled workflow that cancels action-required workflow runs once their 30-minute approval window expires.

Use the workflow-runs API because approval-held jobs never start and therefore cannot enforce their own job timeout. Re-check each run immediately before cancellation to tolerate approvals racing the scheduled sweep.
2026-09-01 15:37:19 +02:00
Zoltan Kochan d754f7f413 fix: ignore non-pnpm releases in Docker workflow (#14391) 2026-09-01 01:39:34 +02:00
Zoltan Kochan 340c0384aa fix(release): verify declared Rust pnpm binary (#14390) 2026-09-01 01:29:29 +02:00
Zoltan Kochanandgithub-actions[bot] 4c356251c9 chore: update dependencies, Node.js, pnpm, and GitHub Actions (#14344)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-31 16:33:34 +02:00
Zoltan Kochanandgithub-actions[bot] a3f44249db chore: update dependencies, Node.js, pnpm, and GitHub Actions (#14328)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-29 16:36:52 +02:00
Benjamin Staneck 16ee230e7b fix(napi): validate peer issue options (#14313)
Decode peer dependency query options through the typed N-API boundary instead of manually rebuilding install options from JSON. This preserves shared proxy and network settings and rejects malformed fields.

Range-check the two u32 length values because N-API number conversion does not reject overflow.

Fixes pnpm/pnpm#14312.
2026-08-29 12:04:54 +02:00
Zoltan Kochanandgithub-actions[bot] d241d0ba15 chore: update dependencies, Node.js, pnpm, and GitHub Actions (#14271)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-28 15:07:35 +02:00
Zoltan Kochan 03436d6880 fix: repair TS CI compile and lint after the dependency and Node.js update (#14206)
The dependency update (pnpm/pnpm#14205) broke TS CI / Compile & Lint in
two independent ways.

streamx 2.28.1 declares the 'data' event payload as unknown, so the five
tar-stream data handlers in the releasing commands that annotated the
chunk as Buffer no longer typechecked. They now take the chunk as
unknown and cast at the use site; tar-stream emits Buffers at runtime,
so the emitted JavaScript is unchanged.

The Node.js v26.8.0 binaries on nodejs.org were built with a bogus
version string and self-report as 26.8.0-alpha.0.0.0 (Node.js shipped
26.8.1 the next day to correct it). That prerelease-looking version made
cspell's engine guard reject the runtime during lint and made node-gyp
request a nonexistent v26.8.0-alpha.0.0.0 headers tarball for native
builds. The pinned runtime is bumped to 26.8.1 in the root devEngines,
the compile-only script, the CI test matrix, and the benchmark and
release workflows.
2026-08-27 00:49:41 +02:00
Zoltan Kochanandgithub-actions[bot] 2bd58ac4d4 chore: update dependencies, Node.js, pnpm, and GitHub Actions (#14205)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-27 00:16:37 +02:00
Zoltan Kochanandgithub-actions[bot] 07527caf1c chore: update dependencies, Node.js, pnpm, and GitHub Actions (#14122)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-25 14:06:01 +02:00
Zoltan Kochan 05129e1fd2 perf(release): build the NAPI addon on its own runners (#14138)
The Rust release built the CLI binary and the NAPI addon back to back in
one matrix leg per target. The two are compiled under different Cargo
profiles — `release` for the CLI, `napi-release` for the addon, which
must keep `panic = "unwind"` so a panic reaching the FFI boundary becomes
a JS exception instead of aborting the host node process. Different
profile means a different target directory, so the two builds shared not
one compiled dependency: every leg paid for the whole graph twice, in
series.

Split the addon into its own `build-rust-napi` matrix over the same eight
targets. Measured on the 12.0.0-rc.9 release run, per-leg build time was:

  target             CLI     addon    leg
  win32-arm64        508s    369s     17m09s
  win32-x64          495s    363s     15m06s
  darwin-arm64       477s    241s     12m30s
  darwin-x64         461s    235s     12m10s
  linux-*        322-351s  217-238s   ~10m

The stage is bounded by its slowest leg, so dropping the addon out of
win32-arm64 takes the critical path from ~17 to ~11 minutes and the whole
release run from ~25m30s to roughly 19 minutes. The addon legs run
alongside and gate nothing.

Downstream needs no changes: the new job uploads to
`binaries-rust-napi-<code-target>`, which the `binaries-rust-*` download
pattern the verify, publish and draft-release jobs already use picks up
and merges into the same directory. It is also free of the node-gyp
payload dependency, since only the CLI archives ship `dist/`.

The toolchain prelude the two jobs share — installing cross, the
clang-cl/ARM64 Visual Studio components, the rustup target, and the guard
that the committed PNPM_VERSION matches the tag — moves into a
`rust-release-target` composite action rather than being duplicated.
zizmor flags that action's writes to GITHUB_ENV/GITHUB_PATH because a
composite action cannot see who calls it; the values come from the
Visual Studio install and `vcvarsall`, and the only caller is a release
job running on a maintainer-signed tag, so the audit is suppressed on
that step with that justification.
2026-08-24 21:16:43 +02:00
Zoltan Kochan 9798c9f611 revert: "chore(release): stop publishing @pnpm/exe from v12 (#14121)" (#14133)
This reverts commit afb4071811.
2026-08-24 15:35:45 +02:00
Zoltan Kochan afb4071811 chore(release): stop publishing @pnpm/exe from v12 (#14121)
Up to v11, `@pnpm/exe` was the build of pnpm that bundled a Node.js
runtime, so it ran where the JavaScript `pnpm` package could not. From
v12 the `pnpm` package is itself the native executable and needs no
Node.js, which left `@pnpm/exe` an equal-content copy of it, published
and dist-tagged for nothing.

generate-packages.mjs no longer emits the `pnpm-exe` wrapper dir, and
release.yml no longer packs or stages it. The per-platform
`@pnpm/exe.<target>` native packages are unchanged: they carry the
binaries the `pnpm` wrapper resolves.

update-latest.yml would have failed on the first v12 promotion, since it
unconditionally installs and dist-tags `@pnpm/exe` at the promoted
version. Both sites now pick the wrapper by major. The upgrade check
gates on the *starting* version so upgrading a v11 `@pnpm/exe` onto a
v12 release is still covered, and it gained `--allow-build=pnpm` because
from v12 the preinstall that swaps the placeholder bin for the native
one lives on the `pnpm` package -- without it that check would have
validated a placeholder.

No runtime code changes: both stacks' package-to-install selection
already converges on `pnpm` for major >= 12, the update notifier already
prints `pnpm`, and `@pnpm/exe` stays in the bin-resolver and global-alias
lists so v11-and-earlier installs keep working. Only the comments that
justified those behaviors with "published under both names" needed
correcting.
2026-08-24 02:39:51 +02:00
Zoltan KochanandClaude Opus 5 a390e363b8 fix: include sponsors in v12 release descriptions (#14118)
* fix: include sponsors in v12 release descriptions

The v11 release description comes from `pn make-release-description`, which
appends the sponsors table. v12 builds its description in the workflow by
dumping the pending changelog, so its release pages never showed sponsors.

Adds .github/release-sponsors.md — a checked-in fragment carrying the same
platinum and gold tables with release_notes attribution — and cats it onto
RELEASE.md in the Rust release job. A missing fragment warns rather than
fails; the sponsors table is not worth losing a release over.

The fragment is regenerated from pnpm.io's sponsors.json alongside the
READMEs and the v11 release text.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* refactor: read the sponsors table from the shared fragment in v11 too

make-release-description inlined its own copy of the sponsors tables — 109
lines of HTML that had to be regenerated in lockstep with the READMEs. Now
that v12 reads a fragment, v11 can read the same one.

getChangelogEntry goes back to returning just the changelog section, and
writeReleaseText appends the fragment. A missing fragment warns and writes
the description without the table, matching the v12 job: the workflow falls
back to a diagnostic description when this script fails, so throwing here
would trade a missing sponsors table for missing release notes.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* test: assert the sponsors fragment is appended exactly once

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-24 00:42:22 +02:00
Zoltan Kochanandgithub-actions[bot] de2cbefa9d chore: update dependencies, Node.js, pnpm, and GitHub Actions (#14052)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-23 15:46:09 +02:00
Zoltan Kochanandgithub-actions[bot] c233e72abe chore: update dependencies, Node.js, pnpm, and GitHub Actions (#14006)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-20 23:27:00 +02:00
Zoltan Kochanandgithub-actions[bot] 0c5af94e08 chore: update dependencies, Node.js, pnpm, and GitHub Actions (#13978)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-18 22:02:17 +02:00
Zoltan Kochan fe8ec8fbec refactor(pacquet): rename the Rust crates from pacquet- to pnpm- (#13948)
The Rust CLI ships as `pnpm`; `pacquet` survives only as the in-repo
package identifier that keeps the npm wrapper from colliding with the
TypeScript CLI's name. Carrying that identifier into all 75 Cargo crate
names made every `use` statement and every `cargo nextest run -p ...`
spell a name users never see. This renames the crates to the product
they belong to.

Mechanical, name-only: package/lib/bin names, the root
`[workspace.dependencies]` keys, every dependency entry, and every Rust
path reference. All the crates are `publish = false`, so nothing about
the released artifacts changes and no changeset is needed.

Also updated the tooling and docs that spell crate names: the `codecov`
cargo alias, the `registry-mock` just recipe, the release workflow's
`-p` targets and `libpnpm_napi.*` artifact paths, the `libpacquet` ->
`libpnpm` cspell dictionary entry, and the crate names quoted across
`AGENTS.md`, `CONTRIBUTING.md`, `CODE_STYLE_GUIDE.md`, and the plans.

Two spots needed more than a token swap. The five insta snapshot files
carry the crate name in their filename, since insta derives it from the
module path, so they are renamed too — otherwise the tests fail with
"snapshot not found" rather than a diff. And the private module in
`pnpm-lockfile-verification` that mirrors the npm verifier's violation
codes is named after the crate it shadows, so it moved with it.

Two knock-on fixes: the shorter names let rustfmt fit three macro
invocations onto one line, where `perfectionist::macro_trailing_comma`
rejects the trailing comma that was legal while they were wrapped; and
the `libpacquet` cspell entry became `libpnpm` for the NAPI addon's
shared library.

Left alone deliberately, none of which are crate names: the product name
in prose and in the changeset package identifier, the `--pacquet`
benchmark flag and testbed IDs, test helpers and temp-dir prefixes
(`pacquet-test-*`, `../pacquet-store`), the released changesets that
quote error codes shipped versions actually emitted, the
`.github/workflows/pacquet-*.yml` filenames, and the
`@pnpm-private/pacquet-registry-mock-launcher` npm package.
2026-08-16 23:18:23 +02:00
Zoltan Kochan a6e8159eef ci(benchmark): measure the shared virtual store (#13944)
Adds `gvs-linker.fresh-restore.hot-cache.hot-store` to the integrated
benchmark job, feeding both Bencher testbeds.

The harness has carried this scenario for a while, but nothing invoked
it: every scenario the workflow ran pins `enableGlobalVirtualStore:
false` in its fixture. Since pnpm/pnpm#13940 that pin is the opposite
of what users get, so the layout pnpm 12 installs into by default had
no continuous measurement at all — a regression in slot reuse could
land without any gate noticing.

It pairs with the isolated fresh-restore hot/hot scenario: same frozen
install, same warm cache and store, and the per-iteration wipe takes
`node_modules` either way, so the difference is what the layout is
worth. Measured locally over 5 runs: 187.8 ms ± 5.6 shared versus
1.047 s ± 0.119 project-local, because the materialized package
directories survive the wipe under the shared store and only the
symlinks have to be rebuilt.

Both testbeds get the scenario. `pnpr@HEAD` under the shared store had
never been exercised — the pre-warm site notes it as hypothetical — so
it was run end to end first: the server starts, both targets pre-warm,
and both installs measure clean.
2026-08-16 14:03:16 +02:00
Zoltan Kochan e97b44f6b1 feat(pacquet): let Corepack run pnpm 12 (#13922)
Corepack installs no dependencies and runs no lifecycle scripts, so the
`@pnpm/exe.<target>` package that carries the native binary is never
installed and the preinstall that links it over the placeholder bins never
runs. `corepack use pnpm@next-12` therefore died with MODULE_NOT_FOUND
(Closes pnpm/pnpm#13018).

Corepack hardcodes `./bin/pnpm.mjs` and `./bin/pnpx.mjs` as the entry
points of every pnpm >=11, so ship them. They resolve the native binary —
from the platform package when a package manager installed one, otherwise
by downloading the pinned `@pnpm/exe.<target>` tarball from the registry
and verifying it against the checksum the registry published — and hand
over to it. The binary is cached next to the wrapper, where it also finds
the `dist/` payload node-gyp ships in, so only the first run downloads.

`package.json#bin` is untouched: an ordinary install still points at the
native binary and pays no Node.js startup. This is the compatibility
wrapper Yarn 6 ships for the same reason, adapted to how pnpm distributes
its binary (https://github.com/nodejs/corepack/pull/887#issuecomment-5292891262).

Registry access mirrors Corepack's own environment (COREPACK_NPM_REGISTRY,
COREPACK_NPM_TOKEN, COREPACK_NPM_USERNAME/PASSWORD, COREPACK_ENABLE_NETWORK),
and the download has no dependencies of its own, since Corepack would not
install those either.
2026-08-15 18:47:40 +02:00
Zoltan Kochan f361560ab4 perf(pnpr): skip the server exchange when there is nothing to resolve (#13905)
With a configured pnprServer, every install paid a full server exchange
even when the answer was already on disk, making pnpr strictly slower
than a direct install on up-to-date projects. Close that gap in three
layers, each deciding locally that the server has nothing to add:

- Let the pre-runtime "Already up to date" fast path run with a pnpr
  server configured. The check decides purely locally that nothing
  changed since the last install; asking the server cannot change that
  answer. The trust/policy settings guard pnpm already records in the
  workspace state (trustPolicy, trustPolicyExclude,
  trustPolicyIgnoreAfter, minimumReleaseAgeStrict,
  minimumReleaseAgeExclude) is now recorded and compared by pacquet
  too, so a policy change still defeats the fast path.

- Gate the resolve exchange on a local satisfaction check: an
  unfiltered install whose on-disk lockfile still satisfies every
  manifest goes straight to the frozen materialization, exactly like
  the non-pnpr preferFrozenLockfile dispatch.

- Consult the local lockfile-verified.jsonl cache before delegating
  input-lockfile verification to the server, and record server-verified
  and server-resolved lockfiles into that cache (pnpm's
  writeWantedLockfileAndRecordVerified), so repeat verifications of an
  unchanged lockfile stay local.

Add repeat-install scenarios (populated node_modules, hot and cold
cache) to the integrated benchmark, pre-warmed before hyperfine runs
and wired into the pnpr-not-slower-than-direct gate with an absolute
slack for tens-of-milliseconds runs.

Closes pnpm/pnpm#13904
2026-08-14 15:25:16 +02:00
Zoltan Kochanandgithub-actions[bot] 5d33ac39b0 chore: update dependencies, Node.js, pnpm, and GitHub Actions (#13871)
* chore: update dependencies, Node.js, pnpm, and GitHub Actions

* fix: update undici

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-13 18:53:42 +02:00
Langning Zhang 7e5783681a fix(cli): restore CI frozen lockfile default (#13782)
## Summary

- Restore the Rust CLI default that freezes an existing non-empty `pnpm-lock.yaml` in CI, so an outdated lockfile fails without being rewritten.
- Preserve explicit `frozenLockfile` and `preferFrozenLockfile` choices from CLI flags, trusted configuration, environment variables, and `.pnpmfile.cjs` hooks.
- Recognize `CI=1`, `CI=true`, and GitHub Actions; let explicit `CI=false` opt out, and prevent repository-controlled `pnpm-workspace.yaml` from overriding CI detection.
- Keep missing, byte-empty, and semantically empty lockfiles writable, and isolate CI-sensitive spawned commands in the Rust test workflow.

The TypeScript CLI already has this behavior; this brings the Rust `pnpm/` port back into parity.

Fixes pnpm/pnpm#13760.
2026-08-11 13:58:11 +02:00
Zoltan Kochanandgithub-actions[bot] 54e9c96eac chore: update dependencies, Node.js, pnpm, and GitHub Actions (#13753)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-11 11:47:49 +02:00
Zoltan Kochan 478aee6ab2 chore: update dependencies, Node.js, pnpm, and GitHub Actions (#13675) 2026-08-10 00:06:01 +02:00
Zoltan Kochan 9b205980e0 fix: make the Ecosystem E2E workflow pass (#13727)
The Ecosystem E2E workflow failed on every run since it was added, for
two stacked reasons.

The matrix jobs relied on the runner image's system Node (v20), while
the built pnpm bundle needs at least v22.13 for node:sqlite, so every
scaffold died with ERR_UNKNOWN_BUILTIN_MODULE before any cell ran. The
jobs now install the devEngines.runtime pin via pnpm/setup, the same
way the workflow's build job already did.

With scaffolding unblocked, the angular and nuxt global-virtual-store
cells failed in both binaries: "@angular/build" requires tslib and
"@nuxt/vite-builder" (since v4) imports unplugin without declaring
them, and the global virtual store only exposes declared dependencies.
Since neither entry is in the "@yarnpkg/extensions" compatibility DB
yet, carry them as pnpm-specific compatibility packageExtensions in
both stacks, merged after the upstream DB and gated by the same
ignoreCompatibilityDb setting. Drop an entry once the upstream DB or
the package itself declares the dependency.
2026-08-08 13:16:35 +02:00
YES!HYUNGSEOKandZoltan Kochan 97f20b05f7 fix(ci): resume partial pnpr npm publishes (#13635)
Make pnpr npm publication resumable after a partially successful run. Check each native package's publication state, skip immutable versions that already exist, and publish only missing packages.

Treat lookup failures as fatal rather than as missing versions, and continue publishing the wrapper only after every native package is confirmed available.

---------

Co-authored-by: Zoltan Kochan <z@kochan.io>
2026-08-07 15:54:39 +02:00
Zoltan Kochan 9c50782610 ci(release): stage pnpm packages before publishing (#13702)
Keep staged publishing above direct OIDC publishing in the trust-policy ranking.
Use the stronger release path instead of lowering the rank.

Stage the TypeScript `@pnpm/exe` and `pnpm` packages in dependency order.
Stage Rust native packages, wrappers, and the `pnpm` gate as separate layers.
Let CI finish after creating every stage without polling for approval.
Maintainers approve the completed stages later with interactive 2FA.

Pin publication traffic to the npm registry and ignore ambient auth configuration.
Sanitize stage output before logging registry-provided content.

Closes pnpm/pnpm#13693.
2026-08-07 14:25:35 +02:00