Skip to content

Keep extension flavor flag options in sync with supported values - #9029

Merged
durga256 merged 4 commits into
mainfrom
durga/template-based-flavor-validation
Oct 29, 2026
Merged

durga256 merged 4 commits into
mainfrom
durga/template-based-flavor-validation

Conversation

@durga256

@durga256 durga256 commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

WHY are these changes introduced?

Follow-up to #9013 and the Slack discussion.

The --flavor flag's options duplicate ExtensionFlavorValue and can drift, rejecting CLI-supported flavors such as liquid and config-only before the generator checks the selected template.

WHAT is this pull request doing?

Define the CLI-supported flavors once, deriving both the TypeScript type and the flag's options from that list. This preserves the options in --help and rejects unknown or explicitly empty values during parsing, before loading the app.

Keep template-metadata validation for known flavors used with an incompatible template, including a clear error when no fetched template supports a requested flavor. Add regression coverage and refresh the generated help and documentation.

How to manually test your changes?

Using a build or snapshot of this branch:

  1. Run shopify app generate extension --help. Confirm the flavor options include preact, liquid, and config-only, and explain that compatibility depends on the selected template.
  2. From a linked test app, run shopify app generate extension --template theme_app_extension --name liquid-flavor-check --flavor liquid --no-input. Confirm the extension is generated without a flavor prompt.
  3. Run shopify app generate extension --template admin_action --name invalid-flavor-check --flavor unknown --no-input. Confirm flag parsing rejects the unknown flavor and lists the CLI-supported options.
  4. From a linked test app, run shopify app generate extension --template admin_action --name incompatible-flavor-check --flavor rust --no-input. Confirm template validation rejects the known but incompatible flavor and lists the selected template's supported flavors.
  5. Run shopify app generate extension --template admin_action --name empty-flavor-check --flavor "" --no-input. Confirm flag parsing rejects the explicit empty value before loading the app or generating files.

Checklist

  • I've considered possible cross-platform impacts (Mac, Linux, Windows)
  • I've considered possible documentation changes
  • I've considered analytics changes to measure impact
  • The change is user-facing — I've identified the correct bump type (patch) and added a changeset.

@github-actions github-actions Bot added the Area: @shopify/app @shopify/app package issues label Oct 27, 2026
@durga256
durga256 marked this pull request as ready for review October 27, 2026 18:48
Copilot AI balanced review requested due to automatic review settings October 27, 2026 18:48
@durga256
durga256 requested review from a team as code owners October 27, 2026 18:48

Copilot AI left a comment

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.

🟡 Changes recommended

An explicitly empty flavor bypasses validation and can select the downloaded repository root instead of the intended flavor subdirectory.

1 open issue
What changed in this PR

Moves extension flavor validation from a fixed command flag allowlist to template metadata, extending the Preact fix to other supported flavors without duplicating metadata.

Changes:

  • Validates flavors against the selected template, or all fetched templates when none is selected.
  • Adds coverage for flag and environment delegation, supported flavors, and invalid-flavor errors.
  • Refreshes generated help and documentation and adds a patch changeset.
File Description
packages/​cli/​README.md Updates generated flavor usage and help.
packages/​cli/​oclif.manifest.json Removes fixed flavor options and updates help.
packages/​app/​src/​cli/​services/​generate.ts Validates flavors using template metadata.
packages/​app/​src/​cli/​services/​generate.test.ts Covers supported flavors and early rejection.
packages/​app/​src/​cli/​commands/​app/​generate/​extension.ts Delegates flavor validation to the generator.
packages/​app/​src/​cli/​commands/​app/​generate/​extension.test.ts Tests flag and environment delegation.
docs-shopify.dev/​generated/​generated_docs_data_v2.json Refreshes generated flavor documentation.
.changeset/​template-based-extension-flavors.md Records the user-facing patch.

Review effort: Balanced

'The Git URL to clone the function extensions templates from. Defaults to: https://github.com/Shopify/function-examples',
env: 'SHOPIFY_FLAG_CLONE_URL',
}),
flavor: Flags.string({

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.

Could we keep a finite list but derive it from ExtensionFlavorValue? e.g.

// services/generate/extension.ts
export const extensionFlavorValues = [
  'vanilla-js', 'preact', 'react', 'typescript', 'typescript-react',
  'rust', 'wasm', 'liquid', 'config-only',
] as const
export type ExtensionFlavorValue = (typeof extensionFlavorValues)[number]

then Flags.custom<ExtensionFlavorValue>({options: [...extensionFlavorValues], ...})() here, like commands/app/security/blocking-flag.ts.

That fixes the drift from #9013 (the type already has liquid and config-only, and adding a flavor forces updating getSrcFileExtension), keeps the options in --help, and rejects typos and empty values when the flag is parsed. The generator would only see flavors the CLI knows how to scaffold, and your per-template check still handles "valid flavor, wrong template". The ''/future-flavor delegation tests would flip to rejection tests.

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.

Agreed—keeping the CLI-supported set separate from template compatibility is better. Implemented in e521b79: extensionFlavorValues now drives both ExtensionFlavorValue and the typed Flags.custom options, including liquid and config-only.

Empty values, unknown future flavors, and typos now fail during parsing; template-specific validation remains for known flavors used with the wrong template. Updated the rejection tests and regenerated help/manifest output. All 80 focused tests, lint, and app type-checking pass locally.

@durga256 durga256 changed the title Validate extension flavors against template metadata Keep extension flavor flag options in sync with supported values Oct 29, 2026
@durga256
durga256 requested a review from isaacroldan October 29, 2026 15:26
Comment on lines +54 to +60
flavor: Flags.custom<ExtensionFlavorValue>({
hidden: false,
description:
'Choose a starting template for your extension, where applicable. Required if non interactive when the selected extension template supports multiple flavors.',
options: ['vanilla-js', 'preact', 'react', 'typescript', 'typescript-react', 'wasm', 'rust'],
'Choose a starting template for your extension, where applicable. Supported flavors depend on the selected extension template. Required if non interactive when the selected extension template supports multiple flavors.',
options: [...extensionFlavorValues],
env: 'SHOPIFY_FLAG_FLAVOR',
}),
})(),

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.

This is ok, but any reason why we can't use Flag.string here? extensionFlavorValues is still an array of strings no?

@durga256
durga256 requested a review from isaacroldan October 29, 2026 15:33
@durga256
durga256 added this pull request to the merge queue Oct 29, 2026
Merged via the queue into main with commit f22f94d Oct 29, 2026
29 checks passed
@durga256
durga256 deleted the durga/template-based-flavor-validation branch October 29, 2026 16:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: @shopify/app @shopify/app package issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants