Skip to content

Use function directory package manager for GraphQL typegen#7239

Merged
dmerand merged 1 commit intomainfrom
donald/function-typegen-package-manager-fix
Apr 14, 2026
Merged

Use function directory package manager for GraphQL typegen#7239
dmerand merged 1 commit intomainfrom
donald/function-typegen-package-manager-fix

Conversation

@dmerand
Copy link
Copy Markdown
Contributor

@dmerand dmerand commented Apr 9, 2026

Stack context

This stack is not trying to reduce Shopify CLI's supported package managers or preserve every detail of npm's local-prefix behavior.

The real problem is that Shopify CLI answers several different package-manager questions through helpers that are too broad for the caller's intent.

The end state is to make callers choose intent, not implementation. Concretely, the codebase needs clearer helper boundaries for:

  • launcher/global-install resolution
  • broad upward-walk package-manager detection
  • known project-root resolution
  • directory-local execution

This PR establishes the directory-local execution boundary for function GraphQL typegen.

What

Use the function directory to choose the package manager for the default JavaScript GraphQL typegen path instead of always running npm exec.

Add a cli-kit helper that builds the right command for running a project binary from a directory, and use it from buildGraphqlTypes(...).

Why

The current typegen path hardcodes npm, which breaks apps whose function directories are managed by pnpm, yarn, or bun.

This keeps the fix scoped to the function typegen problem. It does not change the broader getPackageManager(...) contract for other callers.

How

Build packageManagerBinaryCommandForDirectory(...) on top of the current main upward-walk package-manager detection instead of introducing a separate detection path.

That helper resolves the package manager for the function directory and returns the right binary invocation shape for npm, pnpm, yarn, or bun.

While touching this path, restore missing marker coverage for directory-local resolution:

  • pnpm-workspace.yaml
  • bun.lock

Existing bun.lockb support remains in place.

Testing

  • pnpm exec vitest run packages/cli-kit/src/public/node/node-package-manager.test.ts packages/app/src/cli/services/function/build.test.ts

To test manually:

  1. Create or use an app with a JavaScript function managed by pnpm, yarn, or bun
  2. Run shopify app function build
  3. Confirm GraphQL type generation runs through that package manager instead of npm

Copilot AI review requested due to automatic review settings April 9, 2026 21:28
@dmerand dmerand requested a review from a team as a code owner April 9, 2026 21:28
Copy link
Copy Markdown
Contributor Author

dmerand commented Apr 9, 2026

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates GraphQL type generation for function builds to execute graphql-code-generator via the package manager inferred from the function’s directory (or its ancestors), rather than always using npm exec.

Changes:

  • Added a directory-based package manager inference helper and a shared command builder for executing local binaries.
  • Updated function type generation to use the new helper when running GraphQL codegen.
  • Added unit tests for the new helper and updated function build tests to assert the helper is used.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
packages/cli-kit/src/public/node/node-package-manager.ts Adds directory-based package manager inference and builds the correct {command,args} to run a local binary via npm/pnpm/yarn/bun.
packages/cli-kit/src/public/node/node-package-manager.test.ts Adds coverage for packageManagerBinaryCommandForDirectory across npm/pnpm/yarn/bun and fallback behavior.
packages/app/src/cli/services/function/build.ts Switches GraphQL typegen execution to the shared package-manager-aware command builder.
packages/app/src/cli/services/function/build.test.ts Mocks the shared helper and verifies buildGraphqlTypes executes the returned command.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@dmerand dmerand force-pushed the donald/function-typegen-package-manager-fix branch 2 times, most recently from f955628 to 7cf64a7 Compare April 9, 2026 21:39
@dmerand
Copy link
Copy Markdown
Contributor Author

dmerand commented Apr 9, 2026

/snapit

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 9, 2026

🫰✨ Thanks @dmerand! Your snapshot has been published to npm.

Test the snapshot by installing your package globally:

npm i -g --@shopify:registry=https://registry.npmjs.org @shopify/cli@0.0.0-snapshot-20260409214500

Caution

After installing, validate the version by running shopify version in your terminal.
If the versions don't match, you might have multiple global instances installed.
Use which shopify to find out which one you are running and uninstall it.

@dmerand dmerand force-pushed the donald/function-typegen-package-manager-fix branch from ad4d161 to 9bdcacc Compare April 13, 2026 18:49
@github-actions
Copy link
Copy Markdown
Contributor

Differences in type declarations

We detected differences in the type declarations generated by Typescript for this branch compared to the baseline ('main' branch). Please, review them to ensure they are backward-compatible. Here are some important things to keep in mind:

  • Some seemingly private modules might be re-exported through public modules.
  • If the branch is behind main you might see odd diffs, rebase main into this branch.

New type declarations

We found no new type declarations in this PR

Existing type declarations

packages/cli-kit/dist/public/node/node-package-manager.d.ts
@@ -68,6 +68,14 @@ export declare function packageManagerFromUserAgent(env?: NodeJS.ProcessEnv): Pa
  * @returns The dependency manager
  */
 export declare function getPackageManager(fromDirectory: string): Promise<PackageManager>;
+/**
+ * Builds the command and argv needed to execute a local binary using the package manager
+ * detected from the provided directory or its ancestors.
+ */
+export declare function packageManagerBinaryCommandForDirectory(fromDirectory: string, binary: string, ...binaryArgs: string[]): Promise<{
+    command: string;
+    args: string[];
+}>;
 interface InstallNPMDependenciesRecursivelyOptions {
     /**
      * The dependency manager to use to install the dependencies.

}

const command = await packageManagerBinaryCommandForDirectory(
fun.directory,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fun!


/** The name of the bun lock file */
export const bunLockfile = 'bun.lockb'
const modernBunLockfile = 'bun.lock'
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TIL

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I, as well, learned this in this process.

* Builds the command and argv needed to execute a local binary using the package manager
* detected from the provided directory or its ancestors.
*/
export async function packageManagerBinaryCommandForDirectory(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Much simpler with this helper, thanks for merging it with my PR!

@dmerand dmerand added this pull request to the merge queue Apr 14, 2026
Merged via the queue into main with commit 0009967 Apr 14, 2026
25 checks passed
@dmerand dmerand deleted the donald/function-typegen-package-manager-fix branch April 14, 2026 13:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants