Commit Graph

364 Commits

Author SHA1 Message Date
Zoltan Kochan
d3651ba831 ci: disable git hooks in the update-lockfile workflow too
Same failure mode as create-release-pr: the full install wires the husky
hooks and the push step runs the pre-push TS compile/lint on every daily
run. It only skips the Rust sweep when the remote chore/update-lockfile
branch already exists, because the shallow clone lacks the remote tip and
the hook's git log fails silently; on a fresh branch it does the full
cargo clippy/doc pass.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 11:48:17 +02:00
Zoltan Kochan
38e460ae7a ci: disable git hooks in the create-release-pr workflow
The pre-push hook ran the full TS compile/lint and the Rust clippy/doc
sweep inside the workflow's "Commit and push" step, because the shallow
clone and URL-based push remote make the hook's change detection always
conclude that Rust sources changed. Setting HUSKY=0 on the job keeps
husky from wiring any hooks on the runner.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 11:38:23 +02:00
Zoltan Kochan
0609982b29 refactor(pacquet): ship the CLI under its final pnpm name (#12923)
* **New Features**
  * The CLI build and distributed archives are now `pnpm`, with updated dev commands and release artifacts.
  * Shell completions are consistently branded as `pnpm` and generate `pnpm completion-server` wiring.
* **Bug Fixes**
  * Version output/user-agent reporting now aligns with `pnpm`.
  * Diagnostics and retry-related error codes are updated to `ERR_PNPM_*`.
* **Documentation**
  * Updated E2E and integrated-benchmark guides to reference `pnpm` build outputs.
  * SBOM metadata now identifies the tool as `pnpm`.
* **Chores**
  * Updated CI E2E/benchmark workflows and test suites to run the `pnpm` binary.
2026-07-11 02:07:14 +02:00
Zoltan Kochan
2d7e723cff fix(ci): stage the Rust release binary outside the repo root before archiving (#12918)
The Release pnpm (Rust) workflow renamed the built binary to `pnpm` at the
repo root before tarring it. Since the pacquet/ directory was renamed to
pnpm/, that `mv` moved the binary *into* the existing `pnpm/` source
directory instead, so the non-Windows archives contained the whole Rust
source tree. The publish job then extracted a directory where it expected a
binary and failed with EISDIR in generate-packages.mjs
(https://github.com/pnpm/pnpm/actions/runs/29113833296).

Stage the binary in a scratch directory and tar from there, keeping the
archive layout (a plain `pnpm` binary at the root) unchanged.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-10 21:15:55 +02:00
Zoltan Kochan
8e17c3d366 refactor: rename the pacquet/ directory to pnpm/ (#12913)
Pure directory move plus path fixups: the Rust port ships as pnpm v12,
so the source tree now lives at pnpm/ (alongside pnpm11/, the frozen
TypeScript line). No identifiers change in this pass — crate names
(pacquet-*), the pacquet bin, PACQUET_VERSION, the @pacquet/* npm
package names v11's runPacquet spawns, the .pacquet virtual-store dir,
the benchmark harness's clone dir, and the pacquet-*.yml workflow
filenames (npm trusted publishing is bound to them) all stay for a
follow-up.

Also removes the root /pnpm/ .gitignore entry (build detritus in the
pre-pnpm11 package location): pnpm/ is real source now and must not be
ignored. Developers with a stale generated pnpm/ dir should delete it
before checking out this change.
2026-07-10 18:06:56 +02:00
Zoltan Kochan
fb680c35fb ci: stop bumping pacquet config dep and self-update pnpm from next-12 (#12912)
The update-lockfile workflow still bumped the `@pnpm/pacquet` config
dependency, which has since been removed from the repo, so the daily run
would have re-added it. It also ran `pnpm self-update latest`, but the
repo is now on the pnpm v12 prereleases published under the `next-12`
dist-tag, so `latest` would have downgraded the `packageManager` and
`devEngines.packageManager` pins back to v11.

Drop the config-dependency bump and self-update from `next-12` instead,
updating the step names, commit message, and PR text accordingly.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-10 16:52:42 +02:00
Zoltan Kochan
c2248eb9ba ci: derive latest-<major> dist-tag from the version in the Tag workflow (#12911)
The Tag workflow hardcoded the latest-11 dist-tag (each release branch
carried its own hardcoded major), so dispatching it from the wrong branch
applied the wrong line's tag: tagging 10.34.5 from main pointed latest-11
at a v10 release (https://github.com/pnpm/pnpm/issues/12906).

Derive latest-<major> from the version input instead, and fail fast when
the requested tag names a different major than the version, or when a
plain 'latest' tag would move backwards to an older major.
2026-07-10 16:52:23 +02:00
Zoltan Kochan
7074b6b338 ci(pacquet): draft a GitHub release with install-script assets (#12907)
* ci(pacquet): draft a GitHub release with install-script assets

The Rust pnpm releases only published to npm, so get.pnpm.io's
install.sh / install.ps1 — which download pnpm-<platform>-<arch>[-musl]
archives from GitHub releases — could not install v12 at all.

Add a github-release job that repackages the build artifacts under the
v11 asset naming scheme (binary renamed from pacquet-<target> to pnpm /
pnpm.exe at the archive root), attests them, and drafts a GitHub
release. Draft keeps publication a deliberate maintainer action, same
as the staged npm wrappers; make_latest: false keeps a v12 prerelease
from taking the "Latest" badge from the stable v11 line.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* ci(pacquet): ship the release archives under their final pnpm names

Rename the build-job archives from pacquet-<target> to pnpm-<target>
with a plain pnpm / pnpm.exe binary at the archive root — the layout
the v11 releases use and the install scripts expect. The github-release
job now uploads the build artifacts byte-for-byte as attested, instead
of repackaging (and re-attesting) them.

Since every archive now holds an identically-named binary, the publish
job extracts each into a scratch dir and moves the binary out under its
target-qualified name (this also drops the third-party unzip action).
The generated native package dirs keep the pacquet- prefix so they
stay out of the pacquet/npm/pnpm* wrapper glob.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-10 16:38:46 +02:00
Zoltan Kochan
25da8c8cde chore: update package manager to pnpm v12 (#12811) 2026-07-10 00:49:52 +02:00
dependabot[bot]
fd20a6ee8a chore(deps): bump the github-actions group across 1 directory with 11 updates (#12785)
Bumps the github-actions group with 11 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [actions/checkout](https://github.com/actions/checkout) | `6.0.3` | `7.0.0` |
| [bencherdev/bencher](https://github.com/bencherdev/bencher) | `0.6.7` | `0.6.8` |
| [actions/cache/restore](https://github.com/actions/cache) | `5.0.5` | `6.1.0` |
| [actions/cache/save](https://github.com/actions/cache) | `5.0.5` | `6.1.0` |
| [taiki-e/install-action](https://github.com/taiki-e/install-action) | `2.82.0` | `2.82.5` |
| [actions/cache](https://github.com/actions/cache) | `5.0.5` | `6.1.0` |
| [actions/attest-build-provenance](https://github.com/actions/attest-build-provenance) | `4.1.0` | `4.1.1` |
| [softprops/action-gh-release](https://github.com/softprops/action-gh-release) | `3.0.0` | `3.0.1` |
| [warpdotdev/oz-agent-action](https://github.com/warpdotdev/oz-agent-action) | `1.0.19` | `1.0.21` |
| [cbrgm/mastodon-github-action](https://github.com/cbrgm/mastodon-github-action) | `2.2.1` | `2.2.2` |
| [zizmorcore/zizmor-action](https://github.com/zizmorcore/zizmor-action) | `0.5.6` | `0.5.7` |



Updates `actions/checkout` from 6.0.3 to 7.0.0
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v6.0.3...9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0)

Updates `bencherdev/bencher` from 0.6.7 to 0.6.8
- [Release notes](https://github.com/bencherdev/bencher/releases)
- [Commits](ec56bb69a7...5f9d4cf890)

Updates `actions/cache/restore` from 5.0.5 to 6.1.0
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](27d5ce7f10...55cc834586)

Updates `actions/cache/save` from 5.0.5 to 6.1.0
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](27d5ce7f10...55cc834586)

Updates `taiki-e/install-action` from 2.82.0 to 2.82.5
- [Release notes](https://github.com/taiki-e/install-action/releases)
- [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md)
- [Commits](b8cecb8356...bffeee26d4)

Updates `actions/cache` from 5.0.5 to 6.1.0
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](27d5ce7f10...55cc834586)

Updates `actions/attest-build-provenance` from 4.1.0 to 4.1.1
- [Release notes](https://github.com/actions/attest-build-provenance/releases)
- [Changelog](https://github.com/actions/attest-build-provenance/blob/main/RELEASE.md)
- [Commits](a2bbfa2537...0f67c3f485)

Updates `softprops/action-gh-release` from 3.0.0 to 3.0.1
- [Release notes](https://github.com/softprops/action-gh-release/releases)
- [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md)
- [Commits](b430933298...718ea10b13)

Updates `warpdotdev/oz-agent-action` from 1.0.19 to 1.0.21
- [Release notes](https://github.com/warpdotdev/oz-agent-action/releases)
- [Commits](501d24fbf4...1922f22c00)

Updates `cbrgm/mastodon-github-action` from 2.2.1 to 2.2.2
- [Release notes](https://github.com/cbrgm/mastodon-github-action/releases)
- [Commits](244bbe72e6...ac2d8e8c99)

Updates `zizmorcore/zizmor-action` from 0.5.6 to 0.5.7
- [Release notes](https://github.com/zizmorcore/zizmor-action/releases)
- [Commits](5f14fd08f7...192e21d79a)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 7.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
- dependency-name: bencherdev/bencher
  dependency-version: 0.6.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
- dependency-name: actions/cache/restore
  dependency-version: 6.1.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
- dependency-name: actions/cache/save
  dependency-version: 6.1.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
- dependency-name: taiki-e/install-action
  dependency-version: 2.82.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
- dependency-name: actions/cache
  dependency-version: 6.1.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
- dependency-name: actions/attest-build-provenance
  dependency-version: 4.1.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
- dependency-name: softprops/action-gh-release
  dependency-version: 3.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
- dependency-name: warpdotdev/oz-agent-action
  dependency-version: 1.0.21
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
- dependency-name: cbrgm/mastodon-github-action
  dependency-version: 2.2.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
- dependency-name: zizmorcore/zizmor-action
  dependency-version: 0.5.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-08 01:12:37 +02:00
Zoltan Kochan
febe5f36da ci: build the musl NAPI addon with dynamic CRT linking (#12837)
The 'Release pnpm (Rust)' workflow failed on the musl legs with
"cannot produce cdylib for pacquet-napi ... as the target
x86_64-unknown-linux-musl does not support these crate types". musl
targets link the CRT statically by default (crt-static), which is
incompatible with the cdylib crate type used by the .node addon.

Pass '-C target-feature=-crt-static' when building the addon, but only
for musl targets, so it links dynamically against musl libc at load
time - matching how napi-rs builds its musl prebuilds. The CLI binary
is built in a separate step and keeps crt-static, so it stays fully
static for portability across musl distros.
2026-07-07 12:38:01 +02:00
Zoltan Kochan
de1371daa9 feat(pacquet): add Node API bindings for the Rust engine (#12822)
Add `pacquet-napi`, a napi-rs cdylib crate, plus its `@pnpm/napi`
npm wrapper, exposing pacquet's programmatic engine surface to Node.js so
programmatic pnpm consumers can drive the Rust engine instead of the
TypeScript pnpm packages. Bit is the reference consumer.

Exports: install (in-memory importers, single and multi-importer workspaces,
a synchronous readPackage hook per resolved dependency manifest, build-script
approval, and depsRequiringBuild), rebuild, resolveDependency, pack,
parseBareSpecifier, engineVersion, and auth via authHeaderByUri.

The install runs on a dedicated 32 MiB-stack worker thread with its own
tokio runtime; the napi async fn awaits the result over a oneshot channel,
so pacquet's borrowed State never crosses the FFI boundary. A reporter
bridge forwards the engine's wire-compatible log events to a JS callback,
and errors carry pnpm's ERR_PNPM_* code and hint through a structured envelope.

Engine-core changes are minimal and inert for existing callers:
PackageManifest::from_value, and two Option fields on Install
(pnpmfile_hook_override and workspace_projects_override) defaulted to None
everywhere. A new napi-release profile sets panic = "unwind" since the
workspace release profile uses panic = "abort".

getPeerDependencyIssues is stubbed pending pacquet's own peer-issue renderer.
Distribution follows the @pnpm/exe.* model via scripts/generate-packages.mjs.
2026-07-07 10:45:03 +02:00
Zoltan Kochan
b7908f96e7 chore(release): stage the wrapper packages in the Rust release workflow (#12804)
The Rust release workflow authenticated every publish via npm trusted
publishing, but npm allows a single trusted publisher per package and
`pnpm` / `@pnpm/exe` have theirs bound to release.yml (the v11 TS
releases). The OIDC token exchange therefore returned 404, pnpm skipped
OIDC, and the unauthenticated PUT failed with E404.

Split the publish into two steps:

1. The `@pnpm/exe.<target>` natives are published only from this
   workflow, so they keep trusted publishing and go live directly.
2. The `pnpm` and `@pnpm/exe` wrappers are staged with
   `pnpm stage publish` using the static NPM_TOKEN. Nothing goes live
   from CI for those two names; a maintainer promotes them with
   `pnpm stage approve <stage-id> --otp`, which is where the
   proof-of-presence is consumed. Stage ids are teed into the job
   summary for the approver.

The steps must stay separate because `pnpm publish` skips OIDC as soon
as a static _authToken is configured (pnpm/pnpm#11495). `--provenance`
keeps working in both steps: it needs only the `id-token: write` OIDC
token, not trusted publishing. `set -o pipefail` guards the tee pipe
because the runner's default bash is -e without pipefail.
2026-07-04 22:51:50 +02:00
Zoltan Kochan
2f389d6cf7 feat(release): auto-refresh embedded signing keys in the release PR (#12798)
* feat(release): auto-refresh embedded signing keys in the release PR

The create-release-pr workflow previously failed when the embedded npm
signing keys or Node.js release keys drifted from their canonical
sources, requiring a manual update PR before a release could proceed.
Now the workflow runs the update scripts in --update mode and commits
the refreshed keys together with the version bumps, so the new trust
roots are reviewed as part of the release PR diff. A synthesized
changeset records the refresh in the changelogs of the affected
packages.

Also embeds the Node.js release team's new signing key
655F3B5C1FB3FA8D1A0CA6BDE4A7D232B936D2FD (Stewart X Addison), which the
last release run reported as missing, and fixes the Rust renderer in
update-node-release-keys.mjs so its output is lint-clean (angle-bracket
URL for dylint's bare-url lint, raw-string hashes only when the key
contains a quote for clippy's needless_raw_string_hashes) and matches
the committed file byte-for-byte on a no-drift run.

* fix(release): canonicalize npm key order and flag trust-root refreshes

Review follow-ups: sort the merged npm signing keys by keyid so a
reordering of npm's response cannot churn the generated file or
synthesize a spurious changeset, and leave an explicit warning comment
on the release PR whenever embedded trust roots were refreshed, so a
key change cannot slip through buried in a large version-bump diff.
2026-07-04 20:47:45 +02:00
Andrew Stegmaier
11a7fddb74 perf(npm-resolver): cache disk-loaded metadata in memory on offline resolution (#12760)
When resolving with --offline or --prefer-offline, pickPackage loaded a
package's metadata from the on-disk cache mirror but never stored it in
the in-memory metaCache, so every subsequent resolution of the same
package (once per dependent that references it) re-read and re-parsed
the full packument from disk. Store the parsed metadata in the
in-memory cache on those disk-return paths, so each package's metadata
is parsed at most once per command. On a large monorepo this collapses
23,746 metadata loads to 5,124 (66.8 GB of JSON parsed to 8.8 GB) and
takes pnpm dedupe --offline from ~140s to ~75s with a byte-identical
lockfile. The cache is the existing bounded LRU; online and network
paths are untouched.

Promotion alone would have made the top-of-function cache hit terminal:
a disk-promoted packument that predates a later-requested range would
turn a previously-recoverable network fallback into
ERR_PNPM_NO_MATCHING_VERSION. Track registry-unverified disk promotions
(a WeakSet keyed by object identity in TypeScript; a registry_verified
flag carried inside the cache value in pacquet, so meta and state are
read atomically) and let a cache hit whose pick fails on such an entry
fall through to the regular network-validating flow unless offline. The
revalidating fetch stores a verified entry, so each package revalidates
at most once. The pre-existing exact-version fast paths on both stacks
had the same latent failure mode and are covered by the same marking.
Pacquet's PackageMetaCache::set_unverified is a required trait method
so custom cache implementations cannot silently inherit the terminal
behavior, and the TypeScript PackageMetaCache documents the
object-identity contract its WeakSet relies on.

Also registry-qualify pacquet's verifier shared-meta-cache reads
(read_shared_meta queried bare name keys while the resolver stores
registry-qualified ones, so the fast path could never hit), mirroring
the TypeScript readSharedMeta lookup order.

Add an isolated-linker.fresh-resolve.hot-cache.offline benchmark
scenario (install --offline --lockfile-only against a warm mirror, with
an untimed online pre-warm pass and per-iteration node_modules +
lockfile wipes so the up-to-date short-circuit cannot skip the measured
resolution) to guard offline resolution on all Bencher testbeds. Fixing
it to measure real work also revived the pnpm benchmark pipeline,
silently dead since the pnpm11/ move: bench.sh resolved REPO_ROOT to
pnpm11/ where no Cargo.toml exists, the orchestrator probed the
pre-move pnpm/dist bundle path, and continue-on-error masked every
failure as a green run. The scenario measures this change directly:
pnpm@HEAD resolves the fixture offline in 2.41s vs 3.17s for pnpm@main
(1.31x), with metadata-mirror reads dropping from 2625 to 1297.

---------

Co-authored-by: Zoltan Kochan <z@kochan.io>
2026-07-04 17:50:02 +02:00
Zoltan Kochan
72b1927856 feat(pnpr): registry mounts as the only routing model (RFC pnpm/rfcs#13) (#12747)
Model every addressable registry origin in pnpr as a registry mount at
/~<mount>/: a pnpr-hosted organization registry, a single-origin upstream, and
a router mapping package-name patterns to one concrete source. Provenance is
declared, never inferred — no configuration can express a cross-origin
fall-through. Full replacement of the legacy Verdaccio-shaped model.

New `mount` module: a decidable PackagePattern language with a covers()
superset relation; first-match authoritative resolution; and Mounts::validate,
which rejects shadowed/unreachable routes (including a non-last catch-all),
duplicate patterns, and unknown/self/non-concrete sources at config load.

mounts:/defaultTarget: is the only routing surface; uplinks:, packages: proxy:
fallback chains, hosted-first serving, and multi-uplink tarball fallback are
removed. Path-less and write requests route through the mount graph; a router
no-route is a 404 with no fall-through and a down source errors rather than
404s. Served tarball URLs stay canonical for the client's base. Per-package
ACLs apply on every mount-served read.

Each hosted-org mount has its own storage namespace (local dir and S3/R2) so two
orgs hosting the same name@version cannot collide; the org is threaded through
staging, commit, and the publish journal so crash recovery lands in the right
org. Public upstream mounts use a stable, secret-free cache namespace.

The bundled config.yaml and the integrated-benchmark mock config are converted
to the mount model; registry-mock keeps working with no task or seed changes.

Implements the pnpr side of RFC pnpm/rfcs#13 only; lockfile registry-identity
changes for the TypeScript CLI and pacquet are out of scope.
2026-07-02 11:45:23 +02:00
Alessio Attilio
ddbb4899c2 feat(pacquet): implement bugs command (#12687)
Port the `pnpm bugs` command to pacquet, following the structure of the TypeScript handler at `pnpm11/deps/inspection/commands/src/bugs/index.ts` and matching its error codes (`ERR_PNPM_NO_BUGS_URL`, `ERR_PNPM_NO_IMPORTER_MANIFEST_FOUND`). The command supports local manifest lookup and registry lookup by package name, with repository URL normalization for GitHub/GitLab/Bitbucket shorthand, hosted git URLs, and self-hosted git servers. Unit tests cover all URL derivation branches (36 tests). Integration tests cover the CLI entry points with local manifests and a mocked registry (9 tests).

Related to pnpm/pnpm#11633.
2026-07-01 18:09:02 +02:00
Zoltan Kochan
c4acfadd86 fix(pnpr): stream proxied tarballs instead of buffering-then-verifying (and benchmark the cold pnpr cache) (#12729)
On a cache miss the proxy buffered the whole tarball into the cache, verified
its SRI, and only then streamed the finished file — a head-of-line stall on
every cold fetch: the client waited for the full upstream fetch plus a verify
pass before the first byte, with no overlap. Buffer-then-verify is the wrong
model for a streaming proxy.

Stream the upstream response to the client while teeing it into the cache and
hashing it (stream_verified_to_cache); promote the cache entry only once the
full body matches dist.integrity. A mismatched/truncated/oversize body is never
cached and the client re-verifies what it receives, so a bad upstream tarball
can't poison a later client — it just can't be turned into a BAD_GATEWAY, since
SRI is only known after the body is already streamed.

Converge the namespaced /~<uplink>/ route onto the same model (the integrity is
known from the packument either way), removing the now-dead uplink integrity
sidecar machinery. Stop forwarding the upstream Content-Length on streamed
responses (attacker-controlled, unverifiable before streaming; kept only for
the internal early oversize check). Add a cold-pnpr-cache benchmark scenario
that actually exercises the cold download/serve path (every other scenario
warms the mock); it runs frozen so resolution variance doesn't mask the
serve-path delta.

The measured speedup on that scenario is modest and within noise (this fixture
is small tarballs over a latency-bound link); the change is a correctness fix,
and the benchmark confirms no regression.

Out of scope: packuments with no usable dist.integrity (pnpm/pnpm#12727).
2026-06-29 23:42:49 +02:00
Khải
4dabe4c3d1 ci(benchmark): double the precompile-revisions timeout (#12713)
Bump the "Precompile benchmark revisions" step from 25 to 50 minutes; the
superset build of pacquet + pnpr revisions has been hitting the limit.


Claude-Session: https://claude.ai/code/session_01KtBQzmLLDU3RcGzzCMopPB

Co-authored-by: Claude <noreply@anthropic.com>
2026-06-29 06:06:34 +00:00
Zoltan Kochan
a33eeec9cd feat(pnpm): publish pnpm v12 (the Rust port) as pnpm and @pnpm/exe (#12670)
Make the pacquet Rust port installable from npm as pnpm v12, published with
equal content under two names — `pnpm` and `@pnpm/exe` — on the `next-12`
dist-tag (never `latest`, which keeps serving the production TypeScript pnpm
v11). First release is 12.0.0-alpha.0.

CLI presents as pnpm: clap name/bin_name are `pnpm`; PACQUET_VERSION holds the
pnpm 12.x version; the default User-Agent is the plain `pnpm/<version>` form;
the reporter footer reads `Done in ... using pnpm v<version>`; the `pnpm link`
/ `pnpm patch` / `pnpm patch-commit` hints now name pnpm (parity fixes); and
launched as `pnpx`/`pnx`, the binary injects the `dlx` subcommand itself by
detecting its current_exe name (porting pnpm's buildArgv).

npm packaging mirrors how `@pnpm/exe` ships pnpm: both the `pnpm` and `@pnpm/exe`
wrappers ship root-level placeholder bins (pnpm/pn/pnpx/pnx) plus an install.js
preinstall that hardlinks the host's native binary over the placeholder (no Node
launcher). Native binaries publish as `@pnpm/exe.<platform>-<arch>[-musl]` (file
`pnpm` inside). `pacquet`/`@pnpm/pacquet` are no longer published.

installPnpm initializes v12 exactly like `@pnpm/exe`: linkExePlatformBinary takes
the wrapper name and resolves the native binary via require, and PNPM_ALLOW_BUILDS
includes both names so the GVS hash is per-platform. resolvePackageManagerIntegrities
already resolves both `pnpm` and `@pnpm/exe`, so publishing `@pnpm/exe@12` makes
self-update / version-switch work with no v12-specific logic. From v12 the
install always uses the `pnpm` package (even from a `@pnpm/exe` build), via
pnpmPackageNameToInstall().

The configDependencies install-engine path still installs the published
`pacquet`/`@pnpm/pacquet` releases (which ship `@pacquet/<target>` binaries) and
is left untouched.
2026-06-27 01:24:33 +02:00
Zoltan Kochan
b98cbf8d89 chore: update lockfile, Node.js, pnpm, and pacquet versions (#12680)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-06-26 10:50:41 +02:00
YES!HYUNGSEOK
6beda88be8 ci: pin oz-agent-action to the exact tag for zizmor's version check (#12678) 2026-06-26 10:24:34 +02:00
A
ec76ca3cf3 feat(pacquet): port the "ping" command (#12666)
Add `pacquet ping`, ported from pnpm's ping command.

`ping` GETs `<registry>-/ping?write=true` and prints pnpm's PING/PONG
report, plus a pretty-printed `PONG <details>` line when the registry
returns a non-empty JSON body. It resolves the registry from `--registry`
or the configured default, adds a trailing slash before joining so a
registry path prefix is preserved (matching pnpm's
`new URL('./-/ping', ...)`), sends the optional `Authorization` header when
one is configured (unlike whoami it does not require auth), and issues a
single attempt with no retries (pnpm's `retry: { retries: 0 }`). Timing
wraps the request and body read, matching pnpm's `Date.now()` measurement.

Both a transport failure and a non-success status map to the single
`ERR_PNPM_PING_ERROR` code with pnpm's "Failed to reach registry" message;
the transport error message is credential-redacted before it reaches
stderr / CI logs, the same precaution as whoami. Unlike whoami's username
(printed raw, hence sanitized), ping's JSON details are re-serialized
through serde_json, which escapes control characters, so no raw registry
bytes reach the terminal.

Extract the registry-client builder duplicated from whoami into a shared
`cli_args::registry_client::build_registry_client` and switch whoami to it.

---------

Co-authored-by: Zoltan Kochan <z@kochan.io>
2026-06-26 03:05:23 +02:00
Zoltan Kochan
3fe10ac744 ci: add Oz cloud triage workflow for new issues (#12673)
* ci: add Oz cloud triage workflow for new issues

Wire Warp's Oz "cloud factory" issue-triage stage onto pnpm/pnpm as a
GitHub-triggered cloud agent (part of the pnpm x Warp OSS partnership).

- .github/workflows/triage-issues.yml runs on issues:[opened], skips
  Bot-authored issues, and invokes warpdotdev/oz-agent-action@v1 with the
  triage skill. Minimal permissions: contents:read, issues:write.
- .agents/skills/triage/SKILL.md adapts the canonical triage rubric to pnpm:
  it maps the four readiness states onto existing pnpm "state:" labels
  (accepted / needs design / needs steps to repro / blocked / rejected)
  instead of creating new ones, is aware of the TypeScript/pacquet/pnpr split
  and the install/add/update/remove parity rule, and is conservative about
  removing maintainer-applied labels.

Triage-only for now; the implementation/auto-PR stage is intentionally not
included. Activation also requires the WARP_API_KEY secret and the Oz by Warp
GitHub App with the org enabled in Warp's Admin Panel.

* ci: address CodeRabbit review on Oz triage PR

- Pin actions to commit SHAs (actions/checkout to the repo's v7.0.0 pin,
  warpdotdev/oz-agent-action to the v1 tag commit) with version comments,
  matching the repo convention and satisfying zizmor.
- Harden the triage skill against prompt injection: treat all fetched issue
  content (title, body, comments, attachments, linked docs) as untrusted data,
  never as instructions, and forbid actions beyond the defined read/label/comment
  steps.
- Make the non-bug "Needs info" path consistent across the decision rule, the
  label-application step, and the result template: apply no state label and post
  clarifying questions instead of forcing an ill-fitting label.
2026-06-26 00:21:22 +02:00
Zoltan Kochan
9f3df6b9b4 ci(pacquet): shrink test build debuginfo to avoid ENOSPC on the ubuntu runner (#12665)
The Rust CI test job's `cargo nextest` build holds a full set of
`--all-targets` debug binaries for the whole workspace (~60 crates plus
heavy C deps such as aws-lc-sys, ring, libsql-ffi, and tree-sitter) in
target/. That had grown close to the hosted ubuntu runner's free-disk
ceiling even after the fixed `Free up runner disk space` step, and a run
crossed it: the linker died with "No space left on device" while building
an unrelated crate's test binary (macOS and Windows were unaffected).

Build the test artifacts with line-tables-only debug info via job-level
CARGO_PROFILE_DEV_DEBUG / CARGO_PROFILE_TEST_DEBUG env. This drops most of
the debuginfo bytes that fill target/ while keeping panic backtraces
file:line-accurate. Setting it in the workflow rather than Cargo.toml
leaves local `just test` builds with full debug info.
2026-06-25 19:24:37 +02:00
YES!HYUNGSEOK
114e4f5aac ci: gate the pacquet release publish job behind the release environment (#12641) 2026-06-25 15:36:01 +02:00
YES!HYUNGSEOK
0c44bb94e6 ci: gate the pnpr release publish and docker jobs behind the release environment (#12640)
pnpr-release-to-npm.yml can be triggered via workflow_dispatch. Its publish job uses npm OIDC
trusted publishing to publish the `@pnpm/pnpr` package, and its docker job pushes the mutable
ghcr.io/pnpm/pnpr:latest tag. Neither had an environment gate, so any collaborator with write
access could publish to npm and overwrite the mutable Docker tag without reviewer approval.

Add an environment: release gate to the publish and docker jobs (the build job produces no
externally visible artifacts and is intentionally left ungated), matching the protection used
by release.yml.

Co-authored-by: Claude <noreply@anthropic.com>
2026-06-25 15:34:58 +02:00
YES!HYUNGSEOK
11c9fb168f ci: gate the docker.yml workflow_dispatch build behind the release environment (#12639)
The Docker workflow can be triggered via workflow_dispatch, and its build job pushes mutable
tags (:latest and :<major>) to ghcr.io/pnpm/pnpm. Unlike release.yml and update-latest.yml,
the build job had no environment gate, so any collaborator with write access could publish an
image to the public mutable tags without reviewer approval.

Add an environment: release gate to the build job so workflow_dispatch runs require approval
from the release environment reviewers, matching the protection already used by the other
publishing workflows. The release (published) event path is unaffected.

Co-authored-by: Claude <noreply@anthropic.com>
2026-06-25 15:33:38 +02:00
Zoltan Kochan
40441c3a83 ci: make review label automation tolerate queued captures (#12654)
* ci: make review label automation tolerate queued captures

* ci: harden review label lookup

* ci: skip review label runner for untrusted actors
2026-06-25 11:26:54 +00:00
dependabot[bot]
270aa1d713 chore(deps): bump the github-actions group across 1 directory with 4 updates (#12621)
Bumps the github-actions group with 4 updates in the / directory: [actions/checkout](https://github.com/actions/checkout), [pnpm/setup](https://github.com/pnpm/setup), [bencherdev/bencher](https://github.com/bencherdev/bencher) and [taiki-e/install-action](https://github.com/taiki-e/install-action).

Updates `actions/checkout` from 6.0.2 to 7.0.0
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v6.0.2...9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0)

Updates `pnpm/setup` from b1cac37306e39c21283b9dd6cb0ac288fb35ba6b to 77cf06832101b3ac8c65caaf76a21643936d07a4
- [Release notes](https://github.com/pnpm/setup/releases)
- [Commits](b1cac37306...77cf068321)

Updates `bencherdev/bencher` from 0.6.6 to 0.6.7
- [Release notes](https://github.com/bencherdev/bencher/releases)
- [Commits](50fb1e1386...ec56bb69a7)

Updates `taiki-e/install-action` from 2.81.8 to 2.82.0
- [Release notes](https://github.com/taiki-e/install-action/releases)
- [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md)
- [Commits](0631aa6515...b8cecb8356)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 7.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
- dependency-name: bencherdev/bencher
  dependency-version: 0.6.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
- dependency-name: pnpm/setup
  dependency-version: 77cf06832101b3ac8c65caaf76a21643936d07a4
  dependency-type: direct:production
  dependency-group: github-actions
- dependency-name: taiki-e/install-action
  dependency-version: 2.82.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-24 21:43:57 +02:00
Zoltan Kochan
689c42b73e ci: carry TS CI / Success only from pull_request and merge_group runs (#12635)
A branch that lives in this repo fires both a push and a pull_request
TS CI run for the same commit, and both report the TS CI / Success
required check. Branch protection then sees two results for that
context, so a cancellation or flake on the push side (e.g. two pushes
racing on the test.yml concurrency group) blocks the PR even when the
pull_request run passed.

Restrict push CI to main so PR branches carry TS CI / Success only via
their pull_request run (and the merge queue via merge_group). Since
pull_request now covers every PR, run the build/test jobs on every
pull_request (same-repo and fork) instead of relying on the push run,
and drop the same-repo/fork/chore-lockfile gating that existed only to
avoid duplicate push+pull_request builds. main stays covered pre-merge
by merge_group and post-merge by the push run.
2026-06-24 19:39:35 +02:00
Zoltan Kochan
e2dab007f8 ci(pnpr): publish a Docker image on release (#12619)
* ci(pnpr): publish a Docker image on release

Add a `docker` job to the pnpr release workflow that builds and pushes a
multi-arch (linux/amd64, linux/arm64) image to ghcr.io/pnpm/pnpr after the
npm packages are published.

The image is built from the static musl binaries the release job already
produces, so no Rust toolchain runs in the Docker build and the image
matches exactly what ships to npm. It is based on debian:stable-slim with
ca-certificates (pnpr reaches upstream registries over HTTPS via rustls'
platform cert verifier), runs as a non-root user, declares storage and
cache volumes, exposes 7677, and defaults to binding 0.0.0.0 so the server
is reachable from outside the container. The build self-checks that
`pnpr --version` matches the PNPR_VERSION build-arg.

Stable releases also move the mutable `latest` tag; prereleases (versions
containing a hyphen) only get the exact-version tag.

* ci(pnpr): drop unused id-token permission from docker job

The docker job uses only docker/build-push-action's built-in provenance
and SBOM attestations, which are pushed to GHCR via GITHUB_TOKEN. It does
not call actions/attest-build-provenance, so the OIDC id-token: write
permission was unused. Drop it to follow least privilege.

* ci(pnpr): verify staged binary checksum in the docker image build

The build job now pins each binary's SHA256 at build time and uploads it
with the artifact. The docker job verifies the staged binaries against
those checksums and passes them as build-args, and the Dockerfile
re-verifies the binary it copies before trusting it. A 'pnpr --version'
check only confirms reported metadata, so it cannot stand in for an
integrity check on the binary itself. Mirrors the existing pnpm image.

* ci(pnpr): extract release artifacts into an isolated directory

Extract the downloaded musl tarballs into a throwaway directory and move
only the expected, checksum-verified regular files into the Docker build
context. A malformed archive (path traversal or symlink entries) can no
longer escape into the workspace and overwrite the Dockerfile or staged
binaries before the image is pushed to GHCR.

* docs(pnpr): add a language to the docker README code fence

The image-name fenced block lacked a language identifier, tripping
markdownlint MD040. Tag it as text.
2026-06-24 14:40:29 +00:00
Zoltan Kochan
e3f2be02f0 ci: don't run push CI on merge-queue branches (#12633)
GitHub's merge queue runs each entry on a temporary
`gh-readonly-queue/**` branch, whose creation also fires a `push`
event. For `ci.yml` (`on: [push, pull_request, merge_group]`) that
produced two TS CI runs for the identical commit: one `push`, one
`merge_group`. Both reach the reusable `test.yml`, whose concurrency
group keys on `github.ref` with `cancel-in-progress: true`. Since the
two runs share `github.ref`, their per-(platform, node, chunk) test
jobs land in the same group and cancel each other.

The Windows shards are gated only on compile-and-lint + build-pnpr, so
both runs' Windows jobs start near-simultaneously and reliably collide.
The `merge_group` run — the only one the queue's required
`TS CI / Success` check reads — lost the race, so its cancelled test
jobs failed `Success` and ejected the PR for "failed status checks".

Restrict the `push` trigger to ignore `gh-readonly-queue/**` so only
the `merge_group` run executes for queued commits. `pacquet-ci.yml`
already scopes push to `main` and was unaffected. Apply the same
`branches-ignore` to `audit.yml` to drop its redundant push run on
those branches.
2026-06-24 15:28:30 +02:00
Zoltan Kochan
fe28cc6db6 ci: build pnpr per-OS so Linux tests don't wait on the Windows build (#12630)
* ci: build pnpr per-OS so Linux tests don't wait on the Windows build

The pnpr binaries were built by a single `build-pnpr` matrix job spanning
`[ubuntu-latest, windows-latest]`. A `needs` edge can only target a whole
job, never an individual matrix leg, so every consumer of `build-pnpr`
(the ubuntu smoke/test jobs and the windows test shards) blocked until both
legs finished. The Linux tests therefore waited for the slower Windows pnpr
build even though they only consume the Linux binary artifact.

Extract the build into a per-OS reusable workflow (`build-pnpr.yml`) and call
it twice from `ci.yml` as `build-pnpr-linux` and `build-pnpr-windows`. The
ubuntu test jobs now gate only on `build-pnpr-linux` and the windows shards
only on `build-pnpr-windows`, so neither platform waits on the other's build.

* ci: trigger TS CI when build-pnpr.yml changes

Add the new reusable .github/workflows/build-pnpr.yml to the dorny/paths-filter
ts: list so a PR touching only that workflow still runs the pnpr build and TS
test jobs it gates, instead of being skipped.
2026-06-24 15:21:28 +02:00
Abdullah Alaqeel
e583b04e34 ci(benchmark): show commit hash in Integrated-Benchmark Report (#12631)
The benchmark report comment identifies which revision was benchmarked
only via the workflow run, leaving the PR comment detached from the
exact SHA when read later. Add a clickable short-SHA line directly
under the report header so the comment is self-describing.

SHA source is the PR head SHA on pull_request events (stable commit
that survives merge), falling back to github.sha for push and
workflow_dispatch. Display-only — the comment workflow continues to
resolve the PR number from the trusted workflow_run payload, so the
SHA in the fork-controlled artifact cannot redirect where the comment
lands.
2026-06-24 11:40:14 +00:00
Zoltan Kochan
bf77ed25ea ci: run required checks on merge_group so the merge queue works (#12627)
* ci: run required checks on merge_group so the merge queue works

The merge queue dispatches a merge_group event against a temporary
gh-readonly-queue/main ref, but neither TS CI (ci.yml) nor Rust CI
(pacquet-ci.yml) listened for it. Their required status checks therefore
never ran in the queue, so every queued PR waited forever on the missing
contexts (e.g. Rust CI / Success never starting).

Add merge_group to both workflows' triggers and force the change
detection true for that event. Forcing matters because TS CI / Compile &
Lint is itself a required context: a skipped job never reports its
context, which would keep the queue waiting, so it has to actually run.
It also makes the queue test the fully merged result, which is the point
of a merge queue. The Rust deny job's nested path filter, which has no
push/PR base to diff against in the queue, runs unconditionally on
merge_group instead.

* ci: gate compile-and-lint and build-pnpr on merge_group explicitly

The merge queue tests the merged commit, so the gating jobs must run on
merge_group. build-pnpr (added by the Windows-sharding work) carries the
same event guard as compile-and-lint and feeds test-smoke/test/test-windows,
so it needs the merge_group clause too — otherwise the queue would skip the
whole test suite.
2026-06-24 10:23:46 +00:00
Zoltan Kochan
e42c2f23cb ci: shard Windows TS tests (#12612)
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.
2026-06-24 02:08:56 +02:00
Zoltan Kochan
dd79bdc08e ci: require release workflow to run on tags (#12613)
The Release workflow allowed workflow_dispatch from branch refs but only built `@pnpm/exe` artifacts on tag refs. A branch dispatch on main after the 11.9.0 release bump selected the platform artifact packages in the internal publish step, then failed in their prepublishOnly binary verification because the binaries had not been built.

Add a preflight job that accepts only refs/tags/v*.*.*. The real release job depends on that preflight, so non-tag dispatches fail before entering the protected release environment or configuring npm auth.

With non-tag refs rejected up front, the release job can run the full tag release path without per-step tag guards.
2026-06-23 23:20:03 +02:00
Zoltan Kochan
87a43b9d41 ci: fix release workflow body generation (#12614) 2026-06-23 22:13:19 +02:00
Zoltan Kochan
258b11274c fix(ci): point pnpm CLI bencher extraction at pnpm11/pnpm (#12544)
The TypeScript pnpm CLI was relocated from `pnpm/` to `pnpm11/pnpm/` in
pnpm/pnpm#12537, but the "Extract pnpm CLI e2e test duration" step still
passed `--package-dir pnpm`. That path no longer exists, so the
exec-summary lookup found no entry and the step exited 1, failing the
full TS CI test job on main.

Point `--package-dir` at the package's new location, `pnpm11/pnpm`.
2026-06-20 20:34:12 +02:00
btea
f6dde6246f ci: skip ecosystem-e2e on forks (#12541) 2026-06-20 20:18:47 +02:00
Zoltan Kochan
fc2f33912e refactor: move the TypeScript pnpm CLI into a pnpm11/ directory (#12537)
The TypeScript pnpm CLI freezes at v11; pnpm 12 will be the Rust pacquet
port. To make that split legible, all TypeScript source, test, and build
directories move under a new top-level pnpm11/ directory. The name states
the version boundary rather than implying a behavioral fork, since the two
stacks are meant to behave identically.

Scope is source-only: the shared workspace root stays at the repo root.
pnpm-workspace.yaml, package.json, pnpm-lock.yaml, .pnpmfile.cjs,
.meta-updater, __patches__, .changeset, .husky, and the lint/spell configs
remain in place, so one pnpm workspace and one Cargo workspace still span
all three products. pnpr/client and pacquet/tasks/registry-mock stay as
cross-product workspace members.

Rewiring the move required:
- pnpm-workspace.yaml globs prefixed with pnpm11/
- root package.json script paths, eslint.config.mjs, tsconfig.lint.json,
  .gitignore, and CODEOWNERS updated
- .meta-updater/src/index.ts literals repointed (pnpm11/pnpm/package.json,
  pnpm11/__utils__, pnpm11/__typings__, and the main package directory)
- regenerated every moved package's repository/homepage URL via meta-updater
- pnpm11/pnpm/bundle-deps.ts and __utils__/scripts/src/typecheck-only.ts
  climb one more level to reach the repo root

.meta-updater stays at the repo root because @pnpm/meta-updater resolves
its config at <cwd>/.meta-updater/main.mjs.

TS CI (.github/workflows/ci.yml) now only runs when pnpm11/-relevant paths
change, via a dorny/paths-filter changes job plus a TS CI / Success
aggregate gate; branch protection should require only that gate.
2026-06-20 14:36:25 +02:00
Zoltan Kochan
33745b892b fix(ci): grant pull-requests: write so the review label step can label PRs (#12501) 2026-06-18 16:11:04 +02:00
Zoltan Kochan
8d17c7b8cd chore: update lockfile, Node.js, pnpm, and pacquet versions (#12441)
* chore: update lockfile, Node.js, pnpm, and pacquet versions

* fix: node range

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-06-18 14:35:34 +02:00
Zoltan Kochan
6ee484e3c5 fix(ci): run PR review automation for fork PRs via workflow_run (#12493)
Approvals on PRs from forks never got the `reviewed: coderabbit` label or a
Discord announcement. A pull_request_review run triggered by a forked PR is
granted a read-only token and no secrets, so the label step failed with HTTP
403 and the Discord step had no webhook.

Split the automation in two: the pull_request_review workflow now only records
the approval as an artifact (no token, no secrets), and a new workflow_run
companion runs from the default branch in base-repo context — where it has the
write-scoped token and secrets — to add the label and post to Discord.

The privileged half never checks out or executes PR content: it reads inert
data files, validates the PR number is an integer, maps the reviewer to a fixed
label, requests only actions:read + issues:write, surfaces a failed (vs absent)
artifact download instead of passing as a silent no-op, and scopes the Discord
webhook secret to the announce step.

Also documents that agents must open PRs using .github/pull_request_template.md,
since gh pr create does not apply it automatically.
2026-06-18 14:25:52 +02:00
Alessio Attilio
c2414e8236 docs: add PR template and clarify changeset purpose (#11290)
Co-authored-by: Zoltan Kochan <z@kochan.io>
2026-06-18 11:47:53 +02:00
Zoltan Kochan
7a313077fe fix: restore CodeRabbit and Qodo PR auto-approval (#12474)
* chore: stop configuring CodeRabbit pre-merge checks

Defining any pre-merge check turned on the whole pre-merge-checks
subsystem, which under Request Changes Workflow replaces the
auto-approve flow: CodeRabbit emits a pre-merge-checks status block
instead of approving once review threads are resolved, leaving PRs at
REVIEW_REQUIRED even with all threads cleared and all checks green.

Remove the title check (added in pnpm/pnpm#12460) to restore
auto-approval and document why the block is intentionally absent.
Conventional Commits on the squash title stay covered by the commit-msg
hook and the squash-title convention.

* fix: declare Qodo auto-approval under [config]

enable_auto_approval and auto_approve_for_no_suggestions were declared
under [pr_reviewer], where Qodo never reads them, so auto-approval never
ran. Per the Qodo docs both keys belong under [config]. Move them and
drop the now-empty [pr_reviewer] section.

* chore: stop applying labels from Qodo

Product labels are applied by CodeRabbit (auto_apply_labels +
labeling_instructions in .coderabbit.yaml). Having Qodo also publish
labels via enable_custom_labels/publish_labels/custom_labels meant two
tools managing the same labels. Drop the Qodo label config and leave
labeling to CodeRabbit.

* ci: tag Qodo-approved PRs and fix the label step

Add an on-qodo-approval job that applies the 'reviewed: qodo' label when
qodo-free-for-open-source-projects[bot] approves, mirroring the existing
CodeRabbit job.

The label step used 'gh pr edit --add-label', which is broken (it errors
on the deprecated Projects-v1 GraphQL field), so adding the label failed
on approval. Switch all three jobs to the issues REST API
(POST /repos/{owner}/{repo}/issues/{number}/labels) instead.
2026-06-17 14:15:46 +02:00
Zoltan Kochan
c1f9cdfe95 ci: remove TS CI / Success aggregate gate job (#12466) 2026-06-17 10:03:40 +02:00
Zoltan Kochan
c7950e7fdb fix(ci): grant issues: write so the approval label step can run (#12464)
The pr-review-automation workflow merged in pnpm/pnpm#12462 fails at the
label step with 'Resource not accessible by integration
(addLabelsToLabelable)'. gh pr edit --add-label uses the GraphQL
addLabelsToLabelable mutation, which requires issues: write even when
labeling a PR; pull-requests: write alone is insufficient. Grant it per
job, matching pacquet-integrated-benchmark-comment.yml.
2026-06-17 08:07:08 +02:00
Zoltan Kochan
c38f68aecc ci: PR review automation (CodeRabbit approval + maintainer automerge) (#12462)
* ci: label and notify on CodeRabbit approval

Add a workflow that fires on pull_request_review and, when CodeRabbit
submits an approving review, applies the informational "reviewed:
coderabbit" label and (if a DISCORD_WEBHOOK secret is configured) posts
a notice to Discord.

PR fields reach the steps through the environment rather than script
interpolation, so an attacker-controlled PR title cannot inject shell
commands. The Discord step is skipped when the webhook secret is unset.

* ci: flag maintainer-approved PRs for automerge

Rename the approval workflow to cover both review automations and add a
second job: when zkochan submits an approving review, apply the existing
"state: automerge" label.

Like the CodeRabbit job, the PR number is passed through the environment
rather than interpolated into the run script.

* ci: harden PR review automation per review feedback

- Scope permissions to each job (top-level permissions: {}) instead of
  granting pull-requests: write workflow-wide (zizmor).
- Set allowed_mentions to {parse: []} on the Discord payload so a PR
  title containing `@everyone`/`@here` cannot ping the server.
- Add connect/overall timeouts and retries to the Discord curl call.
2026-06-17 01:33:50 +02:00