Skip to content

AIR CLI Integration: -h for yaml configuration - #6239

Merged
riddhibhagwat-db merged 4 commits into
air-clifrom
air-config-help
Aug 12, 2026
Merged

AIR CLI Integration: -h for yaml configuration#6239
riddhibhagwat-db merged 4 commits into
air-clifrom
air-config-help

Conversation

@riddhibhagwat-db

Copy link
Copy Markdown
Contributor

Changes

Adds databricks experimental air run -h config. — a help path that documents any field of the run YAML config from the command line.

  • -h config lists the top-level fields; -h config.compute lists a section's fields; -h config.compute.accelerator_type shows one field's type, required-ness, and description
  • Unknown fields produce a "did you mean" suggestion plus the valid siblings; free-form maps (parameters, env_variables, secrets) report that their keys are user-defined rather than implying a typo

Why

air run takes a YAML config with 35 fields across 9 nested structs, and until now the only way to learn a field was to read runconfig.go or trip its validation error. This surfaces the schema in the CLI itself.

Tests

  • Unit: path resolution incl. bare paths, nested, slices, free-form maps and the 3 polymorphic unions; error cases incl. typo suggestion, distant-name (no suggestion), free-form key, scalar sub-field; renderer output for leaf vs container; command-help wiring (fallback, field help without --file, error-to-stderr with clean exit).
  • A guard test (TestConfigFieldsAllDocumented) fails if any schema field lacks a help: tag, so a new field can't merge undocumented. Verified it fails by removing a tag, then restored
  • Acceptance (acceptance/experimental/air/config-help/): 9 traced invocations pinning the rendered output

Manual verification:
Screenshot 2026-08-11 at 2 11 38 PM

Informational error outputs for unknown fields:
Screenshot 2026-08-11 at 2 13 11 PM

@eng-dev-ecosystem-bot

eng-dev-ecosystem-bot commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator

Integration test report

Commit: 512365f

Run: 31547237176

Env 💚​RECOVERED 🙈​SKIP ✅​pass 🙈​skip Time
💚​ aws linux 4 4 291 1104 5:35
💚​ aws windows 4 4 293 1102 6:09
💚​ azure linux 4 4 290 1104 5:49
💚​ azure windows 4 4 292 1102 6:21
💚​ gcp linux 1 5 291 1104 6:37
💚​ gcp windows 1 5 293 1102 6:06
8 interesting tests: 4 RECOVERED, 4 SKIP
Test Name aws linux aws windows azure linux azure windows gcp linux gcp windows
💚​ TestAccept 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R
🙈​ TestAccept/bundle/invariant/no_drift 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/vector_search_endpoints/drift/recreated_same_name 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/vector_search_indexes/recreate/embedding_dimension 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/ssh/connection 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
💚​ TestFetchRepositoryInfoAPI_FromRepo 💚​R 💚​R 💚​R 💚​R 🙈​S 🙈​S
💚​ TestFetchRepositoryInfoAPI_FromRepo/root 💚​R 💚​R 💚​R 💚​R
💚​ TestFetchRepositoryInfoAPI_FromRepo/subdir 💚​R 💚​R 💚​R 💚​R
Top 6 slowest tests (at least 2 minutes):
duration env testname
6:13 azure windows TestAccept
6:01 aws windows TestAccept
5:57 gcp windows TestAccept
2:56 gcp linux TestAccept
2:54 azure linux TestAccept
2:54 aws linux TestAccept

@ben-hansen-db ben-hansen-db 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.

Looks good just some nits and comments to fix before merging


Fields:
num_accelerators Total number of GPUs to allocate.
accelerator_type Which accelerator to run on: GPU_1xA10, GPU_1xH100, or GPU_8xH100.

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.

Do we have a docs link where folks can see what GPU types are supported? It would be nice to link that here.

You can say for instance GPU_1xA10 ... see [list] for current listing of gpu's offered

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 for accelerator_type below

=== polymorphic field reports both accepted shapes
>>> [CLI] experimental air run -h config.environment.dependencies
config.environment.dependencies
Either a path to a requirements.yaml file, or an inline list of packages. Not allowed alongside docker_image.

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.

not a path. Just an inline list of packages.

Comment thread experimental/air/cmd/runconfig.go Outdated
// configFieldSummary is the one-line description used in a field listing: the
// first sentence of the help text, annotated when the field is required.
func configFieldSummary(f configField) string {
summary, _, found := strings.Cut(f.help, ". ")

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 is this cut on first period? maybe skip known abbreviations e.g. i.e. etc. when finding sentence boundary

`air run` takes a YAML config with ~35 fields across 9 nested structs, and
the only way to learn a field was to read runconfig.go or trip its validation
error. Add schema help addressed by dotted path:

    air run -h config                      # list top-level fields
    air run -h config.compute              # list a section's fields
    air run -h config.compute.accelerator_type
    air run -h compute.accelerator_type    # the config. prefix is optional

Descriptions live in `help:` struct tags beside the `yaml:` tags, so they sit
next to the validation rules that enforce them. Required-ness is a string
rather than a bool because validate() enforces it contextually:
docker_image.url is required only once docker_image is present.

The path must be a separate argument. cobra hardcodes a bool read of the help
flag in execute(), so a string -h is rejected outright and -h=<path> cannot
work; the Long text says so rather than leaving it to be discovered. Cobra
returns flag.ErrHelp before Args and required-flag validation, which is why
this needs no --file.

A reflection test fails if any schema field lacks a `help:` tag, so a new
field cannot merge undocumented — the same guard annotations.yml gets from
its PLACEHOLDER convention.
`--override` path validation (runconfig_override.go) and `-h config.<field>`
(runconfig.go) each walked runConfig by reflection to resolve a dotted path.
Collapse them onto one walk: describeStruct now records whether a field is a
free-form map, and checkOverridePath resolves against the shared configSchema()
tree instead of its own yamlFields/underlyingStruct/freeFormFields helpers,
which are deleted.

Behavior is unchanged. --override keeps its own error voice (the messages its
tests pin), and a new test asserts both features resolve against the same
schema so they can't drift apart again.

@ben-hansen-db ben-hansen-db 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.

Thanks!

@riddhibhagwat-db
riddhibhagwat-db merged commit 1cce004 into air-cli Aug 12, 2026
24 checks passed
@riddhibhagwat-db
riddhibhagwat-db deleted the air-config-help branch August 12, 2026 00:46
riddhibhagwat-db added a commit that referenced this pull request Aug 13, 2026
## Summary

**#6153 ("AIR CLI Migration: `--download-to` flag for logs") was lost
from `air-cli`.** It merged on 2026-08-06, but `air-cli` was later
rewound to `1fcb3c09a` before #6239 merged (08-12), and the rebuilt line
(#6239#6244#6241) bypassed #6153. As a result `air-cli` today
still carries the **pre-#6153 stub**:

- `logs.go`: `--download-to is not implemented yet` (the flag is
rejected)
- no `logdownload.go` / `logdownload_test.go`
- no `acceptance/experimental/air/logs-download/` test dir

This PR restores #6153's change set onto the current `air-cli` tip.

## How

Cherry-pick of #6153's original squash commit (`60cd876910cd`) onto
`air-cli`. Verified equivalence to the original:

- Every file except `logstream.go` is **byte-identical** to what #6153
landed.
- `logstream.go` is re-merged against #6241's later edits to that file
(git auto-merged it cleanly; both changes coexist).

## Testing

- `go build ./experimental/air/...` — ok
- `go test ./experimental/air/...` — 548 pass
- `go test ./acceptance -run TestAccept/experimental/air` — 29 pass
(incl. `logs` and the restored `logs-download`)
- Package lints clean
- Confirmed the `--download-to is not implemented` stub is gone and
`logs.go` now wires the real implementation

This pull request and its description were written by Isaac.
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.

3 participants