Skip to content

fix: give --environment one meaning across the CLI - #1275

Open
mridang wants to merge 25 commits into
mainfrom
refactor/cli-environment-flag
Open

mridang wants to merge 25 commits into
mainfrom
refactor/cli-environment-flag

Conversation

@mridang

@mridang mridang commented Sep 22, 2026

Copy link
Copy Markdown
Contributor

Summary

--environment meant two unrelated things in the CLI. On variables (#1259) it names a real environment on the platform, checked by the server. On plan, apply and every resource command it was a leftover from the first CLI prototype (#14), where development, preview and production were separate Zitadel servers: a closed development | preview | production enum whose only effect was to read a server URL from zitadel.json environments.<name>.server. Nothing has written that key since the CLI rewrite (#158), and the enum matches none of the platform's environments (dev, staging, prod, any DNS label), so apply -e prod was rejected and apply -e production was accepted while doing nothing. A user who learned -e prod on variables would reasonably expect apply -e prod to target prod.

This follows #1259 (now merged) and leaves its EnvironmentCommand as the only definition of the flag.

  • environmentSchema is deleted, along with every options: that used it.
  • The dead config-env server tier is gone: readEnvServer, the environment input to resolveServer, and the "development" default in BaseCommand.toMeta. --server, ZITADEL_API_BASE, the top-level server in zitadel.json, local and the default are unchanged.
  • plan and apply no longer take --environment. What they sync (schemas, flow definitions, branding, IdPs) is project-scoped and none of those endpoints takes an environment; the server has no deployments endpoints yet, so there is no environment for the flag to name. Giving them a server-checked -e would suggest apply -e prod targets prod when it does no such thing. deploy (ADR 035) is where a real environment target arrives.
  • The resource commands no longer take --environment. Their endpoints are project-scoped, and the flag never reached the API. environment is also dropped from the crud builder's reserved flag names, since no generated command owns it now.
  • Removed rather than hidden. A hidden, deprecated flag was considered to keep old scripts running, but it would keep a flag that does nothing just to warn about it. The CLI is pre-release, so passing -e to these commands now fails with oclif's Nonexistent flag error.
  • EnvironmentCommand no longer withholds the flag from server resolution; with the config-env tier gone there is nothing for it to redirect.

Validation

  • corepack pnpm exec vitest run in apps/cli: 130 files, 1431 tests passing. plan.test.ts, apply.test.ts and resources.test.ts pin that -e/--environment is refused, and resources.test.ts also asserts that no generated resource command declares an environment flag or an -e short flag. tests/unit/lib/server.test.ts drops the config-env cases and asserts that an environments.<name>.server block is ignored; tests/unit/lib/environment.test.ts drops the enum cases.
  • corepack pnpm exec oxlint .: 0 errors (28 pre-existing warnings, none in touched files).
  • corepack pnpm exec tsc -p tsconfig.app.json --noEmit: no errors in touched files; the remaining errors are pre-existing in local-server/env-vars.ts and orca/patchers.
  • prettier --check on touched files: the only reports are pre-existing lines in resources.ts, base.ts and crud/fields.ts that this change does not touch.
  • apps/cli/README.md entries for plan, apply and the 35 resource commands updated from COLUMNS=80 node bin/run.js <cmd> --help, and each checked to match it exactly. grants create and grants list were already out of date on the base branch (they predate feat(api): accept user and team locators on grants #1192's locators), so only their -e lines changed. The pinned help in tests/unit/commands/help.test.ts did not shift.
  • Live against a real server (go build under devbox, sqlite, --migrate, a project from POST /projects), with zitadel.json holding server: http://localhost:8080 and environments.production.server pointing at a closed port:
    • apply -e prod, apply --environment production and users list -e production fail with Nonexistent flag, exit 3.
    • plan --json and apply --json succeed against http://localhost:8080, so the stale per-environment block is ignored.
    • environments list shows dev, prod, staging; variables set GREETING -e prod then variables get GREETING -e prod round-trips; variables list -e nope returns environment not found; variables list with no owner is refused, naming the three environments.

Release notes / changeset

  • Changeset: .changeset/drop-dead-environment-flag.md. @zitadel/cli minor, marked Breaking: a flag is removed from shipped commands.

Notes

  • apps/cli/SKILLS.md now says that plan, apply and the resource commands take no --environment and do not select an environment, that variables is the only command group that addresses one, and that putting config onto an environment is deploy's job.
  • The type is fix because a CLI user could hit the broken behaviour: apply -e production was accepted and did nothing (CONTRIBUTING.md title ladder).

Context: ADR 035, ADR 062, #1259.

Adds variables list, set, remove and import over the endpoints ADR 062
shipped. Values are prompted for or piped, never passed as a flag.
Keep the owner flag out of server resolution, honour --dry-run in set,
accept an empty value, cap names at 255, parse __proto__ safely, and
document the commands.
Prettier stripped a list continuation indent. Every variables command now
prints the server it resolved, so the target is never silent.
Matches the CRUD verb set in the CLI design doc and ADR 064, and the
delete verb gh and wrangler both use.
Dry-run emits an ok plan like reset and apply, delete takes the same
force-or-confirm gate as reset, and the owner moves into the table header
the way schemas list carries its objectType.
A stored value is chosen by anyone holding variable.write, so printing it
raw let a newline break the table and an escape byte drive the terminal.
Adds variables get, which the API already exposed.
parseEnvFile builds its map from entries rather than assigning into one,
which also removes the null-prototype workaround. Drops two non-null
assertions and an unused import.
Inlining the prompt dropped its nullish guard, so submitting nothing would
have stored the literal "undefined". Adds the missing tests for get.
A run with --environment and --secret was told to retry without either,
which would write a non-secret at project scope. Dimensions now follow the
is_/count naming and are documented with a conformance test.
…tsa-51ce4e

Adapts the variables commands to #1210: registers them in the explicit
command table, declares --force per command, drops groupOrder so they sort
with the resource commands, and prints the project header only on a TTY.
Adds an EnvironmentCommand base: --environment (alias --env) or
--project-level, prompting a person and refusing a non-interactive run
that names neither. Drops variables import for now.
Values were always sent as strings, so a whole-field reference resolved
to "5" instead of 5. --type is refused with --secret, and an integer too
large to store exactly is refused rather than rounded.
Vercel uses --type for secret versus config, which reads the opposite way.
Dry runs answer with dry_run: true instead of claiming a deletion. The
API coverage guard now counts the variables commands' calls, and the
name-length test once again exercises the cap.
list and get share the house table, --plain and pipe rules; the four commands share one
connect step and carry examples.
…resources

It only picked a server from zitadel.json environments.<name>.server, which
nothing writes, and its enum matched none of the platform's environments.
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@vercel

vercel Bot commented Sep 22, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
nextgen Ready Ready Preview Sep 23, 2026 5:48am UTC
nextgen-docs Ready Ready Preview Sep 23, 2026 5:48am UTC
nextgen-mock-zitadel Ready Ready Preview Sep 23, 2026 5:48am UTC

Request Review

@github-actions

github-actions Bot commented Sep 22, 2026

Copy link
Copy Markdown
Contributor

🦋 Changeset detected

Latest commit: 7a258e3

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

This PR includes changesets to release 20 packages
Name Type
@zitadel/cli Minor
@zitadel/testing Minor
@zitadel/server Minor
@zitadel/server-linux-x64 Minor
@zitadel/server-linux-arm64 Minor
@zitadel/server-darwin-x64 Minor
@zitadel/server-darwin-arm64 Minor
@zitadel/server-win32-x64 Minor
@zitadel/api Minor
@zitadel/config Minor
@zitadel/components Minor
@zitadel/sdk-core Minor
@zitadel/sdk-next Minor
@zitadel/sdk-nuxt Minor
@zitadel/sdk-react Minor
@zitadel/sdk-vue Minor
@zitadel/sdk-angular Minor
@zitadel/sdk-solid Minor
@zitadel/sdk-svelte Minor
@zitadel/sdk-qwik Minor

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

@mridang
mridang requested a balanced review from Copilot September 22, 2026 03:30
@mridang mridang moved this from Inbox to In progress in Engineering Kanban Sep 22, 2026

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.

Copilot review overview

🟡 Changes recommended

The agent contract is inaccurate, command-level regression coverage is missing, and the PR title conflicts with repository classification rules.

Get a fresh assessment by requesting another Copilot review.

Review effort: Balanced
Findings: 1 Medium severity · 2 Low severity

Open (3)
What changed in this PR

Aligns --environment with platform environments by removing its obsolete server-selection meaning.

Changes:

  • Removes the flag from plan, apply, and resource commands.
  • Simplifies server resolution to ignore per-environment config blocks.
  • Updates tests, CLI documentation, and release notes.
File Description
.changeset/​drop-dead-environment-flag.md Documents the breaking CLI change.
apps/​cli/​README.md Updates generated command help.
apps/​cli/​SKILLS.md Describes the revised environment contract.
apps/​cli/​src/​commands/​apply.ts Removes the environment flag.
apps/​cli/​src/​commands/​plan.ts Removes the environment flag.
apps/​cli/​src/​commands/​resources.ts Removes environment flags from generated commands.
apps/​cli/​src/​lib/​environment.ts Deletes the obsolete closed enum.
apps/​cli/​src/​lib/​oclif/​base.ts Stops forwarding an environment to server resolution.
apps/​cli/​src/​lib/​oclif/​crud/​fields.ts Allows environment-named body fields.
apps/​cli/​src/​lib/​oclif/​crud/​types.ts Generalizes flag documentation.
apps/​cli/​src/​lib/​oclif/​environment-command.ts Passes owner flags through normally.
apps/​cli/​src/​lib/​server.ts Removes per-environment server resolution.
apps/​cli/​tests/​unit/​lib/​environment.test.ts Removes obsolete enum tests.
apps/​cli/​tests/​unit/​lib/​server.test.ts Verifies environment blocks are ignored.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread apps/cli/src/commands/resources.ts
Comment thread .changeset/drop-dead-environment-flag.md
Comment thread apps/cli/SKILLS.md Outdated
…nment

Also stop SKILLS.md implying apply changes what environments run.
@vercel
vercel Bot temporarily deployed to Preview – nextgen-docs September 22, 2026 03:41 Inactive
@vercel
vercel Bot temporarily deployed to Preview – nextgen-mock-zitadel September 22, 2026 03:41 Inactive
@mridang mridang changed the title refactor: give --environment one meaning across the CLI fix: give --environment one meaning across the CLI Sep 22, 2026
@vitorbari
vitorbari self-requested a review September 22, 2026 08:01
@mridang mridang moved this from In progress to In review in Engineering Kanban Sep 22, 2026
Base automatically changed from claude/heuristic-kapitsa-51ce4e to main September 22, 2026 09:39
…nvironment-flag

# Conflicts:
#	apps/cli/src/lib/environment.ts
#	apps/cli/src/lib/oclif/environment-command.ts
#	apps/cli/tests/unit/lib/environment.test.ts

This branch was successfully deployed

3 active deployments
Preview – nextgen-docs 7a258e37 Deployed Sep 23, 2026 by vercel[bot]
Preview – nextgen-mock-zitadel 7a258e37 Deployed Sep 23, 2026 by vercel[bot]
Preview – nextgen 7a258e37 Deployed Sep 23, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In review

Development

Successfully merging this pull request may close these issues.

2 participants