feat(build-cli): support pnpm catalog references in flub release report#26614
feat(build-cli): support pnpm catalog references in flub release report#26614alexvy86 merged 8 commits intomicrosoft:mainfrom
Conversation
`flub release report` (and the release state machine) would throw `TypeError: Invalid comparator: catalog:X` when any package in the repo used pnpm catalog protocol references in its dependencies. Adds a `catalog.ts` utility that reads `pnpm-workspace.yaml` and resolves `catalog:` / `catalog:default` / `catalog:X` references to their actual version ranges before any semver operations. Both `getFluidDependencies` and `getPreReleaseDependencies` in `package.ts` now resolve catalog references via a per-workspace-root cache, making `getFluidDependencies` async. The `release report` command is updated to await the now-async call. Includes a `testRepoCatalog` fixture and unit/integration tests that cover the catalog resolution logic end-to-end. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
build-tools/packages/build-cli/src/test/library/package.test.ts
Outdated
Show resolved
Hide resolved
build-tools/packages/build-cli/src/test/library/package.test.ts
Outdated
Show resolved
Hide resolved
build-tools/packages/build-cli/src/test/library/package.test.ts
Outdated
Show resolved
Hide resolved
- Rename catalog.ts → pnpmCatalog.ts for clarity - Remove redundant `|| catalogRef === "default"` in resolveCatalogVersion - Only swallow ENOENT in readPnpmCatalogs; propagate other read errors - Use distinct catalog vs. input versions in the "unchanged" test to confirm the catalog is not consulted for non-catalog strings - Tighten error regex in both `throws` tests to match the full message Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR fixes a TypeError: Invalid comparator: catalog:X crash in flub release report (and the release state machine) when any package in the repo uses pnpm catalog protocol references (catalog: / catalog:default / catalog:X) in its dependencies. It adds a new pnpmCatalog.ts utility that reads pnpm-workspace.yaml and resolves catalog references to their actual version ranges before any semver operations.
Changes:
- Adds
pnpmCatalog.tswithreadPnpmCatalogs()andresolveCatalogVersion()utilities plus theyamlnpm dependency - Integrates catalog resolution in
getPreReleaseDependencies()andgetFluidDependencies()(now async) inpackage.ts, with per-workspace-root caching; updatesreport.tstoawaitthe now-async call - Adds a
testRepoCatalogfixture and unit/integration tests covering catalog resolution logic
Reviewed changes
Copilot reviewed 14 out of 15 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
build-tools/pnpm-lock.yaml |
Adds the yaml@2.8.1 dependency for parsing pnpm-workspace.yaml |
build-tools/packages/build-cli/package.json |
Declares the new yaml runtime dependency |
build-tools/packages/build-cli/src/library/pnpmCatalog.ts |
New utility: reads pnpm catalog from pnpm-workspace.yaml and resolves catalog: references |
build-tools/packages/build-cli/src/library/package.ts |
Adds catalog resolution in both getPreReleaseDependencies and getFluidDependencies (now async), with per-workspace-root caching |
build-tools/packages/build-cli/src/commands/release/report.ts |
Adds await for now-async getFluidDependencies call |
build-tools/packages/build-cli/src/test/init.ts |
Exports path to new testRepoCatalog fixture |
build-tools/packages/build-cli/src/test/library/package.test.ts |
Unit tests for resolveCatalogVersion and integration test for getFluidDependencies with catalog refs |
build-tools/packages/build-infrastructure/src/test/data/testRepoCatalog/* |
New test fixture files: pnpm-workspace.yaml, fluidBuild.config.cjs, and package structures for pkg-a, pkg-b, and pkg-c |
Files not reviewed (1)
- build-tools/pnpm-lock.yaml: Language not supported
build-tools/packages/build-cli/src/test/library/package.test.ts
Outdated
Show resolved
Hide resolved
|
Thanks for the PR — I reviewed this with focus on correctness, reliability, and security/perf. I found two actionable items:
Security/performance-wise, I didn’t find any major concerns; the caching + async propagation look good. |
tylerbutler
left a comment
There was a problem hiding this comment.
Seems good though I don't like the async change. I'm surprised this is the only place that needs to understand the catalogs, though. Won't other tools continue to be confused, including vs code?
- Make readPnpmCatalogs synchronous; revert getFluidDependencies to sync - Use typed variable declaration for YAML.parse result instead of as-cast; guard against null return (empty/whitespace-only pnpm-workspace.yaml) - Import PnpmCatalogMap directly; use Map<string, PnpmCatalogMap> for cache - Fix import order in package.ts (pnpmCatalog after context, per alpha order) - Fix error message in getFluidDependencies to report resolvedVersion - Add missing test: package not found in an existing catalog - Remove redundant resolveCatalogVersion test from getFluidDependencies block - Run pnpm lint:fix and pnpm format Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… error messages Store the resolved semver range (not the raw catalog: reference) in prereleasePackages/prereleaseGroups so that the version displayed to the user in the release prompts shows the actual version constraint rather than an opaque "catalog:X" string. Also update error messages to include both the original value from package.json and the resolved version when they differ, making it easier to diagnose catalog resolution issues. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…dency The ignore-filter callback in getTscCommandDependencies already handled workspace: references, but catalog: references in the same build group would reach semver.satisfies() and throw "Invalid comparator: catalog:X". Extract the callback into a tested, exported shouldIgnoreBuildDependency function and add a guard: once a dep is confirmed to be in the same group, a catalog: version is treated as a real local dependency (return false / don't ignore), analogous to how workspace: is handled. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… fixture The testRepoCatalog fixture package.json files were missing the homepage, repository (with directory), and private fields required by the npm-package-metadata-and-sorting, npm-package-license, and npm-private-packages policy checks, causing npm run policy-check to fail. Modeled after the existing testRepo fixture which already satisfies these policies. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…Dependency catalog: references pin versions for external or cross-workspace packages; same-group packages always use the workspace: protocol. So encountering catalog: in the same-group path is unexpected — the right response is to ignore the dep (return true) rather than treating it as a confirmed local build dependency. Also remove @internal tag (not a convention used in build-tools) and restore the historical comment that was lost when the logic was extracted. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Do you have an idea of what exactly would confuse VSCode? The only error that surfaced (and we noticed) when we tried pnpm catalogs last time was this issue with |
Seems like that flag is an escape hatch to restore old behavior which was arguably incorrect, and probably isn't being used? Under that assumption, I'm skipping handling |
|
/azp run Build - build-tools |
|
Azure Pipelines successfully started running 1 pipeline(s). |
I think this is the right call. |
I was thinking it would get confused about where, say, the biome bin is. But I think I'm comcpletely wrong about that. vscode cares about the actual files on disk in node_modules and that should be the same with or without catalogs. I'm mostly worried about places where we bump versions or calculate versions. Even though we should skip those, it might be nice if, say, version parsing in version-tools threw a useful error or something when parsing them. But maybe that's not needed in practice. I would trust a Claude review on that front. |
tylerbutler
left a comment
There was a problem hiding this comment.
I'm good with these as-is.
## Description - Introduces a `buildTools` catalog in `pnpm-workspace.yaml` for the client release group to centralize version management of `@fluid-tools/build-cli`, `@fluid-tools/version-tools`, `@fluidframework/build-tools`, and `@fluidframework/bundle-size-tools` across the release group, and updates all package.json files in the release group to leverage the catalog instead of explicit version specifiers Second attempt at #23935, made possible by having merged #26614. --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Description
flub release report(and the release state machine) would throwTypeError: Invalid comparator: catalog:Xwhen any package in the repo used pnpm catalog protocol references in its dependencies.This PR adds a
catalog.tsutility that readspnpm-workspace.yamland resolvescatalog:/catalog:default/catalog:Xreferences to their actual version ranges before any semver operations. BothgetFluidDependenciesandgetPreReleaseDependenciesinpackage.tsnow resolve catalog references via a per-workspace-root cache, makinggetFluidDependenciesasync. Therelease reportcommand is updated to await the now-async call.Includes a
testRepoCatalogfixture and unit/integration tests that cover the catalog resolution logic end-to-end.This will enable us to use pnpm catalogs to simplify our version ranges across the repo.
Reviewer Guidance
The review process is outlined on this wiki page.