What this issue is (and isn't)
This issue tracks the shared prerequisites that pacquet publish --recursive / --filter / --batch depends on but that don't exist in pacquet yet. It is not about implementing recursive publish itself — that will be done in #12691 once these prerequisites land. Please resolve only the blockers below; the publish command will assemble them on top.
Why
pnpm's own deployment CI (.github/workflows/release.yml) publishes the monorepo with three --filter invocations, e.g. pn publish --filter=!pnpm --filter=!@pnpm/exe … and pn publish --filter=pnpm …. Getting pacquet publish into that workflow is blocked not by publish logic, but by workspace-level infrastructure that isn't wired up.
Already in place (so these are not part of this issue)
The recursive publish machinery is largely ready in #12691 / the tree:
- topological project sort —
cli_args::recursive::sort_projects (ports sortProjects);
- recursive run summary writer —
cli_args::recursive::write_recursive_summary;
- single-package publish (the whole pack → PUT → lifecycle flow), including provenance;
- per-package registry resolution (
findRegistryInfo / registry_config_keys);
- the
workspace-projects-graph crate and a workspace-projects-filter crate (the latter already consumed by deploy).
Blockers to resolve
1. --filter selection is not applied in the recursive command dispatch. (primary)
The recursive command path (cli_args/recursive.rs, run/recursive.rs, exec/recursive.rs) currently operates on every workspace project — --filter narrowing is not wired in. This is documented in pacquet/crates/cli/src/cli_args/run/recursive.rs:
Scope versus upstream: … --filter narrowing of the selected set … are not ported yet — the selected set is every workspace project.
The workspace-projects-filter crate exists (and deploy uses it), so this is an integration task: thread --filter (including exclude selectors like !pnpm) through the recursive dispatch so the selected projects graph is the filtered set, and make that selected graph (plus each package's resolved registry config) available to the command being run. This is shared across all recursive commands, not just publish, which is why it belongs outside the publish PR.
2. An "is this version already published?" check. (smaller)
Recursive publish skips packages whose name@version is already on the registry (unless --force) — ports isAlreadyPublished. The building blocks exist (resolving-npm-resolver::fetch_full_metadata + filter_pkg_metadata_versions); what's missing is a thin, reusable helper that answers "is name@version published to this registry?" so the publish PR can call it.
3. --report-summary → pnpm-publish-summary.json. (smaller)
A --report-summary flag plus a writer for the { "publishedPackages": [...] } file. write_recursive_summary is a close pattern to follow.
Acceptance
--filter (include and exclude selectors) narrows the selected project set in the recursive command path, with the filtered selected-projects graph and per-package registry config reachable by the command.
- A reusable already-published check and the
--report-summary writer are available.
Once these land, #12691 will implement publish --recursive / --filter / --batch by assembling them (filter the set → sort_projects → skip already-published → per-package single-package publish → write summary).
Written by an agent (Claude Code, claude-opus-4-8).
What this issue is (and isn't)
This issue tracks the shared prerequisites that
pacquet publish --recursive/--filter/--batchdepends on but that don't exist in pacquet yet. It is not about implementing recursive publish itself — that will be done in #12691 once these prerequisites land. Please resolve only the blockers below; the publish command will assemble them on top.Why
pnpm's own deployment CI (
.github/workflows/release.yml) publishes the monorepo with three--filterinvocations, e.g.pn publish --filter=!pnpm --filter=!@pnpm/exe …andpn publish --filter=pnpm …. Gettingpacquet publishinto that workflow is blocked not by publish logic, but by workspace-level infrastructure that isn't wired up.Already in place (so these are not part of this issue)
The recursive publish machinery is largely ready in #12691 / the tree:
cli_args::recursive::sort_projects(portssortProjects);cli_args::recursive::write_recursive_summary;findRegistryInfo/registry_config_keys);workspace-projects-graphcrate and aworkspace-projects-filtercrate (the latter already consumed bydeploy).Blockers to resolve
1.
--filterselection is not applied in the recursive command dispatch. (primary)The recursive command path (
cli_args/recursive.rs,run/recursive.rs,exec/recursive.rs) currently operates on every workspace project —--filternarrowing is not wired in. This is documented inpacquet/crates/cli/src/cli_args/run/recursive.rs:The
workspace-projects-filtercrate exists (anddeployuses it), so this is an integration task: thread--filter(including exclude selectors like!pnpm) through the recursive dispatch so the selected projects graph is the filtered set, and make that selected graph (plus each package's resolved registry config) available to the command being run. This is shared across all recursive commands, not just publish, which is why it belongs outside the publish PR.2. An "is this version already published?" check. (smaller)
Recursive publish skips packages whose
name@versionis already on the registry (unless--force) — portsisAlreadyPublished. The building blocks exist (resolving-npm-resolver::fetch_full_metadata+filter_pkg_metadata_versions); what's missing is a thin, reusable helper that answers "isname@versionpublished to this registry?" so the publish PR can call it.3.
--report-summary→pnpm-publish-summary.json. (smaller)A
--report-summaryflag plus a writer for the{ "publishedPackages": [...] }file.write_recursive_summaryis a close pattern to follow.Acceptance
--filter(include and exclude selectors) narrows the selected project set in the recursive command path, with the filtered selected-projects graph and per-package registry config reachable by the command.--report-summarywriter are available.Once these land, #12691 will implement
publish --recursive/--filter/--batchby assembling them (filter the set →sort_projects→ skip already-published → per-package single-package publish → write summary).Written by an agent (Claude Code, claude-opus-4-8).