Skip to content

[wrangler] Add wrangler flagship commands#14423

Open
akshitsinha wants to merge 3 commits into
cloudflare:mainfrom
akshitsinha:asinha/flagship
Open

[wrangler] Add wrangler flagship commands#14423
akshitsinha wants to merge 3 commits into
cloudflare:mainfrom
akshitsinha:asinha/flagship

Conversation

@akshitsinha

@akshitsinha akshitsinha commented Jun 25, 2026

Copy link
Copy Markdown
Member

Adds wrangler flagship for managing Cloudflare Flagship apps and feature flags.

This includes apps commands for create/list/get/update/delete, and flags commands for create/list/get/update/set/split/rollout/enable/disable/evaluate/delete/changelog, with aliases, --json output, config binding fallback for app IDs, human-readable rendering, and unit test coverage.

Includes a wrangler minor changeset.


  • Tests
    • Tests included/updated
    • Automated tests not possible - manual testing has been completed as follows:
    • Additional testing not necessary because:
  • Public documentation

Open in Devin Review

@changeset-bot

changeset-bot Bot commented Jun 25, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: a556313

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
wrangler Minor
@cloudflare/vite-plugin Patch
@cloudflare/vitest-pool-workers Patch

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

@github-project-automation github-project-automation Bot moved this to Untriaged in workers-sdk Jun 25, 2026
@workers-devprod workers-devprod requested review from a team and emily-shen and removed request for a team June 25, 2026 09:31
@workers-devprod

Copy link
Copy Markdown
Contributor

Codeowners approval required for this PR:

  • @cloudflare/wrangler
Show detailed file reviewers
  • .changeset/flagship-cli-commands.md: [@cloudflare/wrangler]
  • packages/wrangler/src/tests/flagship.test.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/tests/index.test.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/core/teams.d.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/flagship/apps/create.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/flagship/apps/delete.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/flagship/apps/get.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/flagship/apps/list.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/flagship/apps/update.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/flagship/client.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/flagship/flags/changelog.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/flagship/flags/create.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/flagship/flags/delete.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/flagship/flags/enable.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/flagship/flags/evaluate.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/flagship/flags/get.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/flagship/flags/list.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/flagship/flags/rollout.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/flagship/flags/set.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/flagship/flags/split.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/flagship/flags/update.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/flagship/index.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/flagship/render.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/flagship/resolve.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/flagship/shared.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/index.ts: [@cloudflare/wrangler]

@pkg-pr-new

pkg-pr-new Bot commented Jun 25, 2026

Copy link
Copy Markdown
@cloudflare/autoconfig

npm i https://pkg.pr.new/@cloudflare/autoconfig@14423

create-cloudflare

npm i https://pkg.pr.new/create-cloudflare@14423

@cloudflare/deploy-helpers

npm i https://pkg.pr.new/@cloudflare/deploy-helpers@14423

@cloudflare/kv-asset-handler

npm i https://pkg.pr.new/@cloudflare/kv-asset-handler@14423

miniflare

npm i https://pkg.pr.new/miniflare@14423

@cloudflare/pages-shared

npm i https://pkg.pr.new/@cloudflare/pages-shared@14423

@cloudflare/unenv-preset

npm i https://pkg.pr.new/@cloudflare/unenv-preset@14423

@cloudflare/vite-plugin

npm i https://pkg.pr.new/@cloudflare/vite-plugin@14423

@cloudflare/vitest-pool-workers

npm i https://pkg.pr.new/@cloudflare/vitest-pool-workers@14423

@cloudflare/workers-auth

npm i https://pkg.pr.new/@cloudflare/workers-auth@14423

@cloudflare/workers-editor-shared

npm i https://pkg.pr.new/@cloudflare/workers-editor-shared@14423

@cloudflare/workers-utils

npm i https://pkg.pr.new/@cloudflare/workers-utils@14423

wrangler

npm i https://pkg.pr.new/wrangler@14423

commit: a556313

devin-ai-integration[bot]

This comment was marked as resolved.

@akshitsinha akshitsinha marked this pull request as draft June 25, 2026 10:17
devin-ai-integration[bot]

This comment was marked as resolved.

Add `wrangler flagship` commands for managing Flagship apps and feature flags.

The new `wrangler flagship apps` and `wrangler flagship flags` command groups
let you create, list, get, inspect, update, set, split, rollout, enable,
disable, evaluate, and delete Flagship apps and flags from the CLI, including
targeting rules, variations, percentage rollouts, evaluation context, and flag
changelogs.
@akshitsinha akshitsinha marked this pull request as ready for review July 1, 2026 13:22
@workers-devprod

workers-devprod commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Codeowners approval required for this PR:

  • ✅ @cloudflare/wrangler
Show detailed file reviewers

devin-ai-integration[bot]

This comment was marked as resolved.

@petebacondarwin petebacondarwin requested review from petebacondarwin and removed request for emily-shen July 1, 2026 13:43
devin-ai-integration[bot]

This comment was marked as resolved.

@devin-ai-integration devin-ai-integration Bot 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.

Devin Review found 1 new potential issue.

Open in Devin Review

Comment on lines +151 to +156
export async function listApps(config: Config): Promise<App[]> {
const accountId = await requireAuth(config);
return await fetchResult(config, `/accounts/${accountId}/flagship/apps`, {
method: "GET",
});
}

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.

🚩 Apps listing does not support pagination unlike flags listing

The listApps function at packages/wrangler/src/flagship/client.ts:151-156 uses a simple fetchResult call that returns all apps in a single response. In contrast, listFlags (client.ts:192-205) uses fetchPage with cursor-based pagination, and the CLI exposes --limit, --cursor, and --all options. If the number of apps grows large enough to be paginated by the API, listApps would only return the first page. This may be intentional if the API doesn't paginate apps, but it's an asymmetry worth noting.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

@petebacondarwin petebacondarwin 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.

Left a small number of nits but looks good.
Can you get a member of your product team to either actually approve the PR or comment with their approval that this all does what it is expected of the product?

}
const byPriority = new Map(rules.map((rule) => [rule.priority, rule]));
const existing = sortedRules(rules).map((rule) => rule.priority);
if (order.length !== rules.length || new Set(order).size !== order.length) {

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.

NIT: you could probably just do:

Suggested change
if (order.length !== rules.length || new Set(order).size !== order.length) {
if (new Set(order).size !== rules.length) {

Comment on lines +17 to +22
target: {
type: "string",
array: true,
demandOption: true,
description: "The app ID followed by one or more flag keys to delete",
},

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.

Why does this command not take the app-id as its own positional parameter?

Comment on lines +19 to +24
target: {
type: "string",
array: true,
demandOption: true,
description: `The app ID followed by one or more flag keys to ${verb.toLowerCase()}`,
},

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.

Similarly, why does target conflate app-id and keys?

import type { FlagType, Rule } from "../client";

export const flagshipFlagsUpdateCommand = createCommand({
metadata: {

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 feels like a command that could really do with some examples.

import { UserError } from "@cloudflare/workers-utils";
import { logger } from "../logger";

export function splitAppIdAndKeys(targets: 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.

why export this one?

if (typeof value === "string") {
return `"${value}"`;
}
return JSON.stringify(value) ?? String(value);

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.

stringify() will always return a string or undefined so I assume what you want here is that if value is undefined we get the string "undefined"?

Comment on lines +16 to +18
if (typeof value === "string") {
return `"${value}"`;
}

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 not necessary since if value is a string then JSON.stringify(value) will return exactly what is being generated here.

@workers-devprod workers-devprod 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.

Codeowners reviews satisfied

@github-project-automation github-project-automation Bot moved this from Untriaged to Approved in workers-sdk Jul 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Approved

Development

Successfully merging this pull request may close these issues.

3 participants