Skip to content

[Feature] Add build.typegen_command support for non-JS Shopify Functions#6870

Merged
davejcameron merged 3 commits intomainfrom
functions-typegen-command-support
Feb 26, 2026
Merged

[Feature] Add build.typegen_command support for non-JS Shopify Functions#6870
davejcameron merged 3 commits intomainfrom
functions-typegen-command-support

Conversation

@davejcameron
Copy link
Contributor

WHY are these changes introduced?

Currently, typegen for Shopify Functions is hardcoded to run npm exec -- graphql-code-generator --config package.json, which only works for JavaScript functions. For other languages (Rust, Zig, C), users must bundle their typegen step inside a build.sh script alongside their actual build command. This makes it impossible to run typegen independently via shopify app function typegen for non-JS functions.

WHAT is this pull request doing?

Adds a build.typegen_command TOML field so users can specify a custom typegen command that runs both via shopify app function typegen and automatically before the build command.

Example TOML:

[build]
command = "zig build -Doptimize=ReleaseSmall"
typegen_command = "npx shopify-function-codegen --language zig"

Changes:

  • Adds typegen_command as an optional string field in the function extension schema
  • Adds typegenCommand getter on ExtensionInstance
  • Updates buildGraphqlTypes to run custom command when set, falling back to the existing JS codegen flow
  • Runs typegen automatically before the build command for both JS and non-JS functions when typegen_command is configured
  • Updates the typegen CLI command description to be language-agnostic
  • Adds tests across all affected files

How to test your changes?

  1. Run function build tests: npx vitest run packages/app/src/cli/services/function/build.test.ts
  2. Run extension build tests: npx vitest run packages/app/src/cli/services/build/extension.test.ts
  3. Run function schema tests: npx vitest run packages/app/src/cli/models/extensions/specifications/function.test.ts

To test manually with a non-JS function:

  1. Add typegen_command = "echo typegen running" under [build] in a function's TOML
  2. Run shopify app function typegen — should execute the custom command
  3. Run shopify app function build — should run typegen before the build command

Measuring impact

How do we know this change was effective? Please choose one:

  • n/a - this doesn't need measurement, e.g. a linting rule or a bug-fix

Checklist

  • I've considered possible cross-platform impacts (Mac, Linux, Windows)
  • I've considered possible documentation changes

@davejcameron davejcameron requested a review from a team as a code owner February 19, 2026 19:48
@github-actions
Copy link
Contributor

We detected some changes at packages/*/src and there are no updates in the .changeset.
If the changes are user-facing, run pnpm changeset add to track your changes and include them in the next release CHANGELOG.

Caution

DO NOT create changesets for features which you do not wish to be included in the public changelog of the next CLI release.

@github-actions
Copy link
Contributor

github-actions bot commented Feb 19, 2026

Coverage report

St.
Category Percentage Covered / Total
🟡 Statements 78.79% 14500/18403
🟡 Branches 73.11% 7209/9860
🟡 Functions 79.01% 3688/4668
🟡 Lines 79.13% 13708/17323

Test suite run success

3774 tests passing in 1448 suites.

Report generated by 🧪jest coverage report action from 64cb7a9

@davejcameron davejcameron force-pushed the functions-typegen-command-support branch from 58d6dfa to acd9b69 Compare February 19, 2026 20:06
@shayarnett
Copy link

🎩

Before: Screenshot 2026-02-19 at 3 04 50 PM

After:
Screenshot 2026-02-19 at 3 14 10 PM

@davejcameron davejcameron force-pushed the functions-typegen-command-support branch 2 times, most recently from d1d70cd to 9cf1e5d Compare February 20, 2026 00:21
@davejcameron davejcameron requested a review from a team as a code owner February 20, 2026 00:21
@davejcameron davejcameron force-pushed the functions-typegen-command-support branch from 9cf1e5d to 40c3b83 Compare February 20, 2026 00:28
@davejcameron davejcameron force-pushed the functions-typegen-command-support branch from 5ccee3c to 47cf622 Compare February 25, 2026 14:43
get typegenCommand() {
const config = this.configuration as unknown as FunctionConfigType
return config.build?.typegen_command
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I'll ping @ryancbahan here for an unrelated project discussion.
This is the kind of thing that shouldn't be in the generic extension-instance, but is an existing pattern with no real alternative right now.

The specification for Functions (or appmodule definition, or whatever we end up calling it) should own its build process, including the typegen step.

@davejcameron davejcameron force-pushed the functions-typegen-command-support branch from 47cf622 to ed41c58 Compare February 25, 2026 17:20
@davejcameron davejcameron force-pushed the functions-typegen-command-support branch from ed41c58 to e35df76 Compare February 26, 2026 13:21
const commandComponents = fun.typegenCommand.split(' ')
return runWithTimer('cmd_all_timing_network_ms')(async () => {
return exec(commandComponents[0]!, commandComponents.slice(1), {
cwd: fun.directory,

Choose a reason for hiding this comment

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

Broken command parsing for typegen_command (quotes/escaping/Windows) + possible empty command crash

The new custom typegen flow parses typegen_command with split(' '), which is not a shell parser. This breaks common valid commands:

  • Quoted args: typegen_command = "tool --out 'generated types.ts'" → gets split into ["tool","--out","'generated","types.ts'"]
  • Windows paths: C:\Program Files\Tool\tool.exe --flag → split into ["C:\\Program","Files\\Tool\\tool.exe", ...]
  • Extra spaces / tabs produce empty tokens; typegen_command = " npx foo" makes commandComponents[0] an empty string, and exec(commandComponents[0]!, ...) can throw or attempt to spawn ''.
    This will cause typegen to fail for many real-world configs, including the exact reason this feature exists (non-JS toolchains often require quoted paths).

Evidence:

const commandComponents = fun.typegenCommand.split(' ')
return exec(commandComponents[0]!, commandComponents.slice(1), ...)

Impact:

  • Users: shopify app function typegen / shopify app function build can fail for valid configs (especially on Windows), blocking builds/deploys.
  • Support/CI: increased failures and confusing errors from spawning an empty/nonexistent executable.
  • Scale: affects any user with spaces/quoting in commands (very common).

@binks-code-reviewer
Copy link

binks-code-reviewer bot commented Feb 26, 2026

🤖 Code Review · #projects-dev-ai for questions
React with 👍/👎 or reply — all feedback helps improve the agent.

Complete - 1 findings

📋 History

✅ 2 findings → ✅ 1 findings

@davejcameron davejcameron added this pull request to the merge queue Feb 26, 2026
Merged via the queue into main with commit 08c1fba Feb 26, 2026
26 checks passed
@davejcameron davejcameron deleted the functions-typegen-command-support branch February 26, 2026 14:44
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