Skip to content

Fan out one events module per subscription behind an organization flag or environment opt-in - #8426

Draft
rezaansyed wants to merge 1 commit into
events-config-link-shape-tolerancefrom
events-subscription-fanout
Draft

Fan out one events module per subscription behind an organization flag or environment opt-in#8426
rezaansyed wants to merge 1 commit into
events-config-link-shape-tolerancefrom
events-subscription-fanout

Conversation

@rezaansyed

Copy link
Copy Markdown
Contributor

WHY are these changes introduced?

Stacked on #8425.

Shopify Core is migrating events app modules from one list-shaped module (subscription: [...], uid "events") to one single-subscription module per subscription (subscription: {...}, uid = subscription handle). The Core contract, uid derivation, and validation already support both shapes; this PR makes the CLI deploy the new shape.

WHAT is this pull request doing?

  • Loader fan-out (loader.ts): when enabled, each [[events.subscription]] entry in the TOML becomes its own events module instance with {events: {api_version, subscription: <object>}} — the single shape Core recognizes. The fan-out runs inside createConfigExtensionInstances so the events key is still claimed (no "Unsupported section(s)" false positive). The tuple shape changed from [instance, keys] to [instances[], keys].
  • Identity (extension-instance.ts): for a single-shape events config, buildHandle/buildUIDFromStrategy return the subscription handle — shape-driven and strategy-agnostic, mirroring Core's uid derivation (uid = subscription handle). Duplicate subscription handles are rejected by the loader's existing global duplicate-handle check.
  • Gating: fan-out is enabled by either
    • the org-scoped exp flag f_single_subscription_events_modules_cli, fetched in appFromIdentifiers via the existing organizationExpFlags Business Platform query and surfaced through the previously-empty Flag enum / remoteFlags pipe (Flag.SingleSubscriptionEventsModules), best-effort with a catch-all so a failed lookup never breaks a command; or
    • the SHOPIFY_CLI_EVENTS_SUBSCRIPTION_FANOUT env var as a local opt-in/escape hatch.

Core's per-app Verdict flag remains the authoritative server-side gate: a fanned-out deploy for an app that isn't allowed the single shape fails loudly at Core validation.

How to test your changes?

  • pnpm vitest run src/cli/models/app/loader.test.ts src/cli/utilities/developer-platform-client/app-management-client.test.ts src/cli/models/extensions/extension-instance.test.ts (new tests: fan-out shapes/handles/uids via env var, fan-out via remote flag, disabled path unchanged, duplicate-handle rejection, exp-flag enabled/disabled/failure in appFromIdentifiers).
  • Manually: set SHOPIFY_CLI_EVENTS_SUBSCRIPTION_FANOUT=1, add two [[events.subscription]] entries with handles, run app deploy against an app allowlisted in Core — the version should contain two events modules whose uids are the subscription handles.

Post-release steps

  • Create the org-scoped exp flag f_single_subscription_events_modules_cli before ramping (until then the env var is the only way to enable fan-out).

Measuring impact

  • n/a: measured server-side via Core's next_gen_events.list_shape_module_validated metric decline

Checklist

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

…g or environment opt-in

Assisted-By: devx/aa56a38c-289a-416e-8a9a-0de281e4e3e7
@github-actions github-actions Bot added the Area: @shopify/app @shopify/app package issues label Aug 28, 2026
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.

1 participant