feat: add Flagship binding support#13139
Conversation
Add the Flagship binding to the shared config and type system: - Add flagship binding type to EnvironmentNonInheritable (environment.ts) - Add default value flagship: [] (config.ts) - Add friendly names, notInheritable() validation, and validateFlagshipBinding (validation.ts) - Add CfFlagship interface and CfWorkerInit.bindings.flagship field (worker.ts) - Add flagship to WorkerMetadataBinding and Binding union types (types.ts) - Add flagship case in mapWorkerMetadataBindings (map-worker-metadata-bindings.ts)
Create a new miniflare plugin for Flagship feature flag bindings: - New plugins/flagship/index.ts with zod schema, getBindings, getNodeBindings, and getServices (remote proxy only, no local simulation) - Register FLAGSHIP_PLUGIN in the PLUGINS object and WorkerOptions type
…elines Add Flagship binding support across the deployment and dev subsystems: - Add to getBindings() and createWorkerUploadForm() (deployment-bundle) - Wire through dev.ts, start-dev.ts, and miniflare/index.ts (dev wiring) - Add both convert functions in startDevWorker/utils.ts - Add CLI display in print-bindings.ts (always remote mode) - Add to ValidKeys exclusion in add-created-resource-config.ts - Add flagship: [] default in secret/index.ts draft worker
- Add flagship -> Flags type mapping in both type generation code paths so `wrangler types` emits FLAGS: Flags for configured flagship bindings - Add flagship:read and flagship:write to DefaultScopes for wrangler login
🦋 Changeset detectedLatest commit: b47e65c The changes in this PR will be included in the next version bump. Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
Codeowners approval required for this PR:
Show detailed file reviewers
|
…vice entry Match the pattern used by AI and VPC plugins — pass the potentially-undefined remoteProxyConnectionString through to remoteProxyClientWorker() which handles the undefined case gracefully, instead of short-circuiting with an empty return.
create-cloudflare
@cloudflare/kv-asset-handler
miniflare
@cloudflare/pages-shared
@cloudflare/unenv-preset
@cloudflare/vite-plugin
@cloudflare/vitest-pool-workers
@cloudflare/workers-editor-shared
wrangler
commit: |
…nding Warn users who define flagship as an unsafe binding that it is directly supported by wrangler, matching the pattern of other safe binding types.
- Rename 'fs' to 'flagshipBinding' in type-generation to avoid shadowing - Fix formatting in worker.ts and type-generation/index.ts
Add flagship:read and flagship:write to inline snapshot expectations in user.test.ts (6), deploy/core.test.ts (2), and whoami.test.ts (3).
This is the current CI error, a simple re-run should fix it |
Add flagship binding to bindingsConfigMock to satisfy the EnvironmentNonInheritable type constraint.
Update 3 inline snapshots that output the full generated Env interface to include the FLAGS: Flags binding from the flagship config mock.
There was a problem hiding this comment.
🚩 No tests included for flagship binding integration
Per the AGENTS.md and CONTRIBUTING.md guidelines, every non-trivial change should include tests. This PR adds a new binding type across multiple packages (miniflare plugin, config validation, type generation, deployment form, print bindings) but includes no test files. Existing bindings like Hello World have tests in packages/miniflare/test/plugins/. Config validation changes typically have tests in packages/workers-utils/src/config/__tests__/. The type generation changes have tests in packages/wrangler/src/__tests__/type-generation/. At minimum, the miniflare plugin, config validation, and type generation should have corresponding tests.
Was this helpful? React with 👍 or 👎 to provide feedback.
| flagship: Object.fromEntries( | ||
| flagshipBindings.map((binding) => [ | ||
| binding.binding, | ||
| { | ||
| app_id: binding.app_id, | ||
| remoteProxyConnectionString, | ||
| }, | ||
| ]) | ||
| ), |
There was a problem hiding this comment.
🚩 Flagship miniflare plugin doesn't emit warnOrError for always-remote usage like vpc_services does
In packages/wrangler/src/dev/miniflare/index.ts:788-796, the flagship binding is set up for miniflare with remoteProxyConnectionString always passed through. Compare with vpc_services at packages/wrangler/src/dev/miniflare/index.ts:854-863 which calls warnOrError("vpc_service", vpc.remote, "always-remote") to warn users when they try to use it without remote dev. The flagship plugin silently passes through, which means users running wrangler dev (local only, no --remote) will get a non-functional binding without a helpful warning. This isn't a correctness bug (the binding won't crash — the remote proxy client just won't connect), but it's a missing user experience improvement compared to other always-remote bindings.
Was this helpful? React with 👍 or 👎 to provide feedback.
| }); | ||
| } | ||
|
|
||
| addBinding(flagshipBinding.binding, "Flags", "flagship", envName); |
There was a problem hiding this comment.
🚩 Type generation uses 'Flags' as the generated TypeScript type
The type generation at packages/wrangler/src/type-generation/index.ts:1834 and packages/wrangler/src/type-generation/index.ts:2763 uses "Flags" as the TypeScript type name for flagship bindings. This will generate FLAGS: Flags in the user's worker-configuration.d.ts. This type needs to exist in @cloudflare/workers-types for the generated types to compile correctly. If Flags is not yet exported from workers-types, users would get a compile error after running wrangler types. This may already be handled in a separate workers-types PR, but is worth verifying.
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
Also, from the point of view of working well with the ecosystem, I would say that Flags as a global ambient type is a bit to general. It could easily conflict with something in the future. I would push for something a bit more specific, e.g. CloudflareFlags or Flagship or something. cc @danlapid
| if (flagship.length > 0) { | ||
| output.push( | ||
| ...flagship.map(({ binding, app_id }) => { | ||
| return { | ||
| name: binding, | ||
| type: getBindingTypeFriendlyName("flagship"), | ||
| value: app_id, | ||
| mode: getMode({ isSimulatedLocally: false }), | ||
| }; | ||
| }) | ||
| ); | ||
| } |
There was a problem hiding this comment.
🚩 Flagship binding always shown as remote in print-bindings, unlike vpc_services which checks remote flag
In packages/wrangler/src/utils/print-bindings.ts:462-473, the flagship binding unconditionally uses getMode({ isSimulatedLocally: false }), meaning it always displays as remote mode. By contrast, other always-remote bindings like vpc_services (print-bindings.ts:370-379) still check remote && !context.remoteBindingsDisabled before deciding the mode. This is technically correct since the CfFlagship interface (packages/workers-utils/src/worker.ts:256-259) doesn't have a remote field, so there's no flag to check. However, this means the binding will show as remote even when remoteBindingsDisabled is true in context (e.g. --local mode), which could be confusing in the output since other always-remote bindings respect that context flag.
Was this helpful? React with 👍 or 👎 to provide feedback.
| case "flagship": { | ||
| for (const { binding, ...x } of info) { | ||
| output[binding] = { type: "flagship", ...x }; | ||
| } | ||
| break; | ||
| } |
There was a problem hiding this comment.
🚩 No pages guard for flagship in convertConfigToBindings
In packages/wrangler/src/api/startDevWorker/utils.ts:358-363, the flagship case does NOT have a if (pages) { break; } guard, unlike some other bindings (e.g., unsafe_hello_world at line 349-351, pipelines at line 335-336). This means flagship bindings would be processed even in Pages projects. Other always-remote bindings like secrets_store_secrets (line 343) also lack the pages guard, so this appears intentional. If flagship should NOT be available in Pages, this would need to be added.
Was this helpful? React with 👍 or 👎 to provide feedback.
Summary
Add end-to-end support for the Flagship binding across
@cloudflare/workers-utils,miniflare, andwrangler.Corresponding
workerdPR: cloudflare/workerd#6456@cloudflare/workers-utils: Config schema, validation, default values,CfFlagshiptype,WorkerMetadataBinding/Bindingunion entries, and metadata binding mappingminiflare: New remote-only plugin (plugins/flagship/) with zod schema, proxy bindings, and remote proxy client wiringwrangler: Deployment bundle upload, dev wiring (miniflare options,convertConfigToBindings), CLI binding display, type generation (Flagstype in both code paths), OAuth scopes (flagship:read,flagship:write), and config-diffs support