Skip to content

Put the pnpm workspace at client/, with galaxy-api-client as the first member#22554

Open
dannon wants to merge 6 commits intogalaxyproject:devfrom
dannon:feature/client-workspace
Open

Put the pnpm workspace at client/, with galaxy-api-client as the first member#22554
dannon wants to merge 6 commits intogalaxyproject:devfrom
dannon:feature/client-workspace

Conversation

@dannon
Copy link
Copy Markdown
Member

@dannon dannon commented Apr 23, 2026

Follow-up to #22514. That PR settled how the Galaxy client gets distributed to operators -- it ships via the galaxy-web-client Python wheel, not npm -- and as part of that it deleted the repo-root package.json that used to drive npm install @galaxyproject/galaxy-client. With that gone, there's no reason to keep the pnpm workspace at the repo root either. This PR puts it where it actually belongs: inside client/.

Along the way, it does the work the standalone client-api/ package has been waiting for since it landed -- makes it a real workspace member instead of a peer-of-client pretending to be separate, and flips the schema relationship so the OpenAPI types are canonical inside the package rather than re-exported from the main client via a symlink.

What changes

  • The workspace lives at client/ now. client/pnpm-workspace.yaml declares packages/*; a single client/pnpm-lock.yaml covers everything; the old per-package client-api/pnpm-lock.yaml is gone.
  • client-api/ moved to client/packages/api-client/. It's the first workspace member, consumed by the main client as a workspace:* dep.
  • OpenAPI schema is now canonical in the package. client/src/api/schema/index.ts is a one-line re-export from @galaxyproject/galaxy-api-client; the 48K-line schema.ts lives inside the package; the old symlink from api-client back into client/src/api/ is gone. make update-client-api-schema regenerates into the new location.
  • Dev-mode ergonomics: client/vite.config.mjs uses a conditional resolve.alias so during vite serve imports of @galaxyproject/galaxy-api-client resolve directly to package source -- edits HMR in the main client without a rebuild. Production builds still consume the package via its package.json exports / dist/.
  • postinstall on client/package.json runs pnpm --filter @galaxyproject/galaxy-api-client run build so dist/ is present for vue-tsc and production vite build.
  • CI is simplified to workspace-filtered invocations (pnpm --filter @galaxyproject/galaxy-api-client ...).
  • client/packages/README.md documents the layout, the criteria for adding a package, and common ops.

Commits, for atomic review

  1. Move client-api/ to client/packages/api-client/ -- mechanical relocation. Package remains a standalone pnpm project at the new path with its own lockfile; no workspace tooling yet.
  2. Adopt into the client pnpm workspace -- single client/pnpm-lock.yaml; CI simplified to pnpm --filter.
  3. Invert API types -- schema canonical in api-client; client re-exports; symlink removed; postinstall wired; Makefile target updated.
  4. Dev-mode source alias -- conditional resolve.alias in client/vite.config.mjs.

(Plus a docs commit adding client/packages/README.md and the cross-link from client/README.md.)

Not in this PR, but stacked on top

A follow-up PR relocates the G-prefixed base components (GButton, GLink, GModal, GHeading, GTabs, GTooltip, GOverlay, GTip, GForm*, etc.) into a second workspace package at client/packages/ui/ as @galaxyproject/galaxy-ui. That package stays internal (`"private": true`) for now -- it exists as an architectural boundary and a migration target for #21956 (Bootstrap-Vue replacement) and the eventual Vue 3 work. It flips to published when the interface stabilizes on Vue 3.

Issue #13336 captures the revised scope -- earlier framings listed utils / composables as packages too, but on closer review neither cleared the bar (no external consumer story, plenty of existing npm substitutes, and no useful internal forcing function). So the full decomposition is just these two package boundaries: this PR plus the `galaxy-ui` follow-up.

No runtime or API behavior change in the main client.

Test plan

  • `pnpm install --frozen-lockfile` succeeds; postinstall builds api-client
  • `pnpm --filter @galaxyproject/galaxy-api-client test` -- 9/9 pass
  • `pnpm type-check`, `pnpm eslint --quiet`, `pnpm format-check` all clean
  • `make client` produces a clean production bundle
  • `make update-client-api-schema` regenerates into the new canonical location and leaves the tree clean
  • `make client-dev-server` boots clean
  • Galaxy serves normally in dev (HMR picks up package source edits) and from the prebuilt wheel path

@mvdbeek
Copy link
Copy Markdown
Member

mvdbeek commented Apr 25, 2026

Do we need to update the publishing procedure and workflows too ?

@dannon
Copy link
Copy Markdown
Member Author

dannon commented Apr 28, 2026

Do we need to update the publishing procedure and workflows too?

Good catch -- yes. Just pushed a fix.

The issue: client/package.json now has @galaxyproject/galaxy-api-client at workspace:* plus a postinstall that runs pnpm --filter to build it. npm publish doesn't rewrite the workspace protocol, so the published tarball would carry the literal workspace:* and break downstream installs. The postinstall is also workspace-only -- if it ships, consumers' npm install would fail when pnpm tries to filter outside any workspace.

The fix in publish_artifacts.yaml swaps the publish client step to pnpm publish (which substitutes the real version) and runs npm pkg delete scripts.postinstall first to strip the workspace-only script. Verified locally with pnpm pack -- tarball is clean.

The client-api publish step is unchanged since it has no workspace deps.

Worth flagging: with #22514 landing, the @galaxyproject/galaxy-client npm publish is effectively redundant with the galaxy-web-client PyPI wheel that common_startup.sh and install-client now consume. I left a TODO in the workflow to drop the build+publish steps post-26.1 once we've confirmed no external consumers depend on the npm package.

@mvdbeek
Copy link
Copy Markdown
Member

mvdbeek commented Apr 28, 2026

Can you resolve the conflict ?

dannon added 6 commits April 28, 2026 09:36
Relocates the standalone @galaxyproject/galaxy-api-client package under
client/ as a sibling to the future workspace packages directory. No
workspace adoption yet -- the package remains a standalone pnpm project
at its new location, with its own lockfile.

Along with the move:
- Retarget src/api symlink to ../../../src/api (one level deeper).
- Adjust sync-version.js's GALAXY_ROOT relative path for the new depth.
- Update client-api-test.yaml and publish_artifacts.yaml paths.
- Add packages/ to client/.eslintrc.js ignorePatterns so nested workspace
  packages aren't pulled into client/tsconfig's lint scope.
- Prettier autofixes applied to the moved files by the pre-commit hook.
Adds client/pnpm-workspace.yaml so that pnpm install from client/
resolves galaxy-api-client as a workspace member. The per-package
client/packages/api-client/pnpm-lock.yaml goes away in favor of the
single client/pnpm-lock.yaml covering the whole workspace.

CI is simplified to a single install step, then workspace-filtered
build/test/publish invocations (pnpm --filter @galaxyproject/galaxy-api-client).

This is the first real workspace member; the packages/* glob is ready
to accept extractions (galaxy-utils, galaxy-ui, galaxy-composables) in
follow-up PRs.
With the workspace in place, flip the client<->api-client relationship.
The OpenAPI schema becomes canonical in the api-client package, and the
main client re-exports its types from @galaxyproject/galaxy-api-client
as a workspace dependency. The old symlink from api-client back into
client/src/api goes away -- the library no longer reaches into the app.

Changes:
- Move client/src/api/schema/schema.ts (48K lines) into
  client/packages/api-client/src/schema/schema.ts as the canonical copy.
- Add client/packages/api-client/src/schema/index.ts matching the old
  barrel.
- Update api-client's api-types.ts to import from the new local path;
  remove the no-longer-needed client/packages/api-client/src/api symlink.
- Replace client/src/api/schema/index.ts with a re-export from
  @galaxyproject/galaxy-api-client.
- Add @galaxyproject/galaxy-api-client as a workspace:* dep in client.
- Wire a postinstall hook in client/package.json to build api-client on
  pnpm install so its .d.ts is available to vue-tsc.
- Update make update-client-api-schema to generate into the new canonical
  location.
- Fix the one file still importing from @/api/schema/schema (the index
  barrel re-exports components already).

This PR now demonstrates the workspace end-to-end: a real library
package, consumed by the app, building through the workspace toolchain.
Further extractions (galaxy-utils, galaxy-ui, galaxy-composables) follow
in subsequent PRs using the same pattern.
During make client-dev-server, imports of @galaxyproject/galaxy-api-client
now resolve directly to packages/api-client/src/index.ts rather than its
built dist/. Edits to the package source trigger HMR in the main client
without a manual rebuild.

Production vite build is unchanged -- it still consumes the package via
its package.json exports (dist/index.js + dist/index.d.ts), so the built
bundle reflects the same interface external consumers would see.

defineConfig switches to a function form so 'command' is available for
the dev/build discriminator. Only the resolve.alias field is
command-dependent; everything else is shared.
Adds client/packages/README.md covering what lives there, the bar for
adding new packages, and common ops (pnpm --filter, postinstall, the
dev-mode source alias). Cross-links from client/README.md so the main
client docs point at it.
The client/ package.json now has @galaxyproject/galaxy-api-client at
workspace:* and a postinstall that filters into the workspace to build
it. npm publish doesn't rewrite the workspace: protocol, so the published
tarball would carry the literal "workspace:*" and break downstream
installs; pnpm publish substitutes the real version. The postinstall is
also workspace-only -- if it ships in the tarball, consumers' npm install
fails when pnpm --filter runs outside any workspace -- so npm pkg delete
strips it before pnpm publish runs.
@dannon dannon force-pushed the feature/client-workspace branch from 73d9731 to 776df11 Compare April 28, 2026 13:53
@dannon dannon marked this pull request as ready for review April 29, 2026 19:43
@github-actions github-actions Bot added this to the 26.1 milestone Apr 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Needs Review

Development

Successfully merging this pull request may close these issues.

2 participants