Skip to content

cligen: omit immutable (create-only) fields from update-command flags - #7309

Open
janniklasrose wants to merge 3 commits into
mainfrom
janniklasrose/cligen-immutable-create-flags
Open

janniklasrose wants to merge 3 commits into
mainfrom
janniklasrose/cligen-immutable-create-flags

Conversation

@janniklasrose

@janniklasrose janniklasrose commented Nov 3, 2026 •

Copy link
Copy Markdown
Member

Changes

Teach the CLI command generator that an IMMUTABLE request-body field (AIP-203: settable at create, cannot change on update) keeps its --flag on create-type commands but is omitted from update-type commands. Computed/output-only fields are untouched and stay flagless everywhere.

This is the CLI half of a two-part change; the other half is the genkit PR databricks-eng/universe#2777642.

How the two PRs fit together

Layer Change Where
genkit (universe) Surface two pieces of metadata that already exist in the code layer into the commands block of cli.json: FieldJSON.is_immutable (from behaviors: [IMMUTABLE]) and MethodJSON.is_crud_update (from x-databricks-crud: update). databricks-eng/universe#2777642
cligen (this PR) Read those two keys (internal/clijson/types.go, regenerated from the genkit contract), propagate them into the render model, and skip the flag in service.go.tmpl when .IsImmutable && $method.IsCrudUpdate. The new branch sits after the .IsComputed / .IsOutputOnly branches, so computed fields keep today's behaviour. this PR
regen (follow-up) Bump .codegen/_openapi_sha past the genkit change, run ./task generate-clijson + generate-cligen. Only then do the keys appear in cli.json and the stubs change. after #2777642 merges

Ordering: ./task generate-clijson builds genkit from source at _openapi_sha, so the regenerated cli.json is reproducible only once the genkit change is on universe master and the SHA is bumped past it. This PR is deliberately logic only — no cli.json/stub changes — and is inert against today's cli.json (the keys are absent, so nothing is skipped). It can merge before or after the genkit PR; the regen must come last.

Why

Motivated by #5983 (databricks lakeview create --parent-path disappeared). Root cause there is that Dashboard.parent_path is annotated computed: true in the proto (a separate proto fix is needed for that field; see the issue). While investigating, it turned out cligen has no notion of immutability at all: immutable fields either get a flag on both create and update, or (if also computed) on neither. This PR adds the missing create-only case so that, once parent_path drops computed, it comes back on create but not on update — and fixes the same thing for every other immutable field today.

Impact once regenerated (measured)

Joint test at current universe master (e4c1445cc07c3, the rebased head of #2777642): built //deco/genkit and //openapi:all-internal.json from that branch, ran genkit update-sdk against this checkout, then generate-cligen. The regenerated cli.json gains 826 is_immutable and 193 is_crud_update keys, and 15 flags disappear from 11 update-* commands across 6 services; no create flag changes and lakeview is untouched (its parent_path is still computed):

Command Flags removed
account disaster-recovery update-failover-group --name
agent-kit update-memory --session-id, --source-type
agent-kit update-memory-store --display-name
agent-kit update-session --parent-session-id
ai-gateway update-mcp-service / update-model-provider-service / update-model-service / update-skill --name
domains update-domain --name, --parent-domain-id
environments update-default-workspace-base-environment --name
feature-engineering update-feature --filter-condition
feature-engineering update-materialization-set --materialization-set-id
feature-engineering update-materialized-feature --materialized-feature-id

Control: stripping the two new keys from that same cli.json (jq 'del(.. | .is_immutable?, .is_crud_update?)') and re-rendering leaves only an unrelated instance-pools doc-string change from spec drift — so the removals above are entirely attributable to the new keys. The regenerated stubs compile (go build ./cmd/...).

These flags were non-functional (the API rejects changing an immutable field), but their removal is user-visible (unknown flag), hence the .nextchanges/cli entry. The rule keys strictly off x-databricks-crud: update; e.g. BundleDeployments.UpdateOperation describes itself as an update but isn't annotated, so its flags are unchanged.

Why the changes are safe

  • go build ./... and go test ./internal/cligen ./internal/clijson pass on the rebased branch.
  • go run ./internal/cligen --input .codegen/cli.json --output . against main's current cli.json produces no diff — the template change is a no-op until the keys exist.
  • Joint regeneration with the genkit branch, plus the key-stripped control run, as described above.

Tests

Unit tests above; the measurable behaviour change (stub diff) is verified by the joint regeneration and will be committed in the follow-up regen PR once _openapi_sha can be bumped past the genkit change.

This pull request and its description were written by Isaac.

janniklasrose and others added 2 commits November 3, 2026 12:17
An IMMUTABLE (AIP-203), non-computed request-body field is settable at
create but cannot change on update. Such fields now keep their CLI flag on
create-type commands (and any non-update command) and are omitted from
update-type commands. Computed/output-only fields are unchanged and stay
flagless everywhere, so a field that is both immutable and computed (e.g.
dashboards parent_path) is unaffected.

This wires the IMMUTABLE behavior and the update-crud signal from cli.json
into the render model:
- internal/clijson/types.go: FieldJSON.IsImmutable, MethodJSON.IsCrudUpdate
  (regenerated verbatim from the genkit contract).
- transform.go / model.go: propagate both into the CLI render model.
- templates/service.go.tmpl: skip immutable, non-computed fields on
  update-type methods in both the flag-declaration and well-known-type
  parse loops.

Depends on the matching genkit change (deco/genkit/rendering/cli) landing
in universe so a future generate-clijson emits is_immutable/is_crud_update.

Co-authored-by: Isaac <no-reply@databricks.com>
Co-authored-by: Isaac <no-reply@databricks.com>
@eng-dev-ecosystem-bot

eng-dev-ecosystem-bot commented Nov 3, 2026 •

Copy link
Copy Markdown
Collaborator

Integration test report

Commit: 88fb3cc

Run: 41648399259

Env 🔄​flaky ✅​pass 🙈​skip Time
✅​ aws linux-2core-8gb 271 15 10:26
🔄​ aws-windows-latest-4core-16gb 1 272 13 7:37
✅​ azure linux-2core-8gb 270 15 9:20
✅​ azure-windows-latest-4core-16gb 272 13 7:22
✅​ gcp linux-2core-8gb 271 15 9:41
✅​ gcp-windows-latest-4core-16gb 273 13 7:21
Test Name aws-windows-latest-4core-16gb
🔄​ TestSyncIncrementalSyncPythonNotebookToFile 🔄​f
Top 6 slowest tests (at least 2 minutes):
duration env testname
7:15 azure-windows-latest-4core-16gb TestAccept
7:15 gcp-windows-latest-4core-16gb TestAccept
7:14 aws-windows-latest-4core-16gb TestAccept
4:17 gcp linux-2core-8gb TestAccept
4:12 azure linux-2core-8gb TestAccept
4:05 aws linux-2core-8gb TestAccept

The template change alone has no effect on any existing command (cli.json does not carry the new keys yet), so the user-visible entry belongs with the regeneration that removes flags.

Co-authored-by: Isaac <no-reply@databricks.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants