Skip to content

1P extensions: migrate to azdext.NewExtensionRootCommand and remove reserved flag conflicts #7950

@JeffreyCA

Description

@JeffreyCA

Summary

Audit and migrate the remaining first-party extensions in cli/azd/extensions/ to use azdext.NewExtensionRootCommand (introduced in #6856), and remove flags that conflict with azd's reserved global flag set (internal/reserved_flags.go). This is the same migration completed for azure.ai.agents in #7796 / PR #7950, generalized to the rest of the 1P fleet.

Reserved flags to remove: --debug, --no-prompt, --cwd, --environment (-e), --output (-o), --help (-h), --docs, --trace-log-file, --trace-log-url.

Scope

This issue covers all first-party extensions in one PR except microsoft.azd.extensions, which has additional surface area (scaffolding templates, --cwd semantic collision) and is tracked separately in #7951.

Conflicts to fix

Extension Conflicts Notes
azure.ai.finetune manual root --debug, --no-prompt; init --environment (long-name only, short is -n); operations --output/-o (×2) uses rootFlagsDefinition global pattern
azure.ai.models manual root --debug, --no-prompt; init --environment (long-name only, short is -n); custom show --output/-o; custom list --output/-o uses rootFlagsDefinition global pattern
azure.appservice manual root --debug, --no-prompt uses rootFlagsDefinition global pattern
azure.coding-agent manual root --debug minimal extension
microsoft.azd.concurx manual root --debug; up --debug (subcommand) duplicate registration on up
microsoft.azd.demo none directly, but custom root (no SDK) should still adopt NewExtensionRootCommand for consistency

Already migrated

Tracked separately

Stub / non-Go / dead — skip

  • azure.ai.customtraining — binary-only stub (no Go source)
  • azd.internal.pack — meta-package (no commands)
  • microsoft.azd.ai.builder — dead extension, not maintained

Migration template (per extension)

Mirror what was done for azure.ai.agents in #7796:

  1. Root: replace bespoke cobra.Command{} + rootFlagsDefinition pattern with:

    rootCmd, extCtx := azdext.NewExtensionRootCommand(azdext.ExtensionCommandOptions{
        Name:  "<name>",
        Use:   "<usage>",
        Short: "<short>",
    })

    Drop manual --debug / --no-prompt registrations and any AZD_* env-var fallback. Thread *azdext.ExtensionContext to subcommand constructors.

  2. init --environment: drop the local flag where present (azure.ai.finetune, azure.ai.models). Read extCtx.Environment instead.

  3. --output / -o: replace per-subcommand redeclarations with azdext.RegisterFlagOptions (azdext: add RegisterFlagOptions for per-subcommand flag config #7826) and read extCtx.OutputFormat in RunE. Per-command default + allowed values are expressed declaratively.

  4. PersistentPreRunE chains: remove any cmd.PersistentPreRunE that manually invokes parent.PersistentPreRunE / root.PersistentPreRunENewExtensionRootCommand sets cobra.EnableTraverseRunHooks = true, so the SDK pre-run already runs from root → leaf and double-invocation is wrong.

  5. go.mod bump: extensions in their own modules (azure.ai.finetune, azure.ai.models, azure.appservice, azure.coding-agent, microsoft.azd.concurx) need a bump to the SDK version that includes RegisterFlagOptions (azdext: add RegisterFlagOptions for per-subcommand flag config #7826) + EnableTraverseRunHooks + the reserved-flag registry (Add reserved global flags registry for extensions #7312). The monorepo extension (microsoft.azd.demo) follows the parent cli/azd module automatically.

  6. requiredAzdVersion in extension.yaml: bump to a version that ships the SDK enforcement so users on older azd see a clear install-time error rather than a runtime conflict.

Validation

Per extension touched:

cd cli/azd/extensions/<extension>
go build ./... && go test ./...
azd x build
azd <namespace> --help

Plus go test ./cli/azd/pkg/azdext/... for ValidateNoReservedFlagConflicts coverage.

Out of scope

Related

Metadata

Metadata

Labels

Type

No fields configured for Task.

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions