Skip to content

feat: Implement azdo pipelines variable delete command #131

@tmeckel

Description

@tmeckel

This issue tracks the implementation of the azdo pipelines variable delete command.

Command Description

Delete a variable from a pipeline definition. The Azure CLI obtains the definition, removes the variable from its dictionary, and updates the definition (source). azdo should provide confirmation prompts, fix the Azure CLI’s name/id lookup bug, and offer consistent output.

Important REST constraints:

  • This command is implemented via Build Definitions: GET the definition, mutate its variables map, then PUT the updated definition.
  • Definitions - Update requires the request body revision to match the current definition revision (GET → modify → PUT).
  • Azure DevOps REST never returns secret variable values; this command must not attempt to display them (delete should not print values).

azdo Command Signature

azdo pipelines variable delete [ORGANIZATION/]PROJECT/PIPELINE_ID_OR_NAME --name VARIABLE_NAME [--yes]

Behavior

  • Resolve scope and pipeline ID (when only a name is provided, look up the definition by name—note that the Azure CLI mistakenly passes the variable name instead; correct this in azdo).
  • Start progress indicator, fetch definition, and locate the variable case-insensitively.
  • Prompt for confirmation unless --yes is set (Delete variable '' from pipeline ''?). Return util.ErrCancel if declined.
  • Remove the variable, update the definition (preserving the server’s revision requirement), stop progress.
  • Output:
    • If stdout is connected to a TTY: print Variable deleted..
    • If stdout is not a TTY: emit no output on success.
  • Debug logging for pipeline resolution, prompt decisions, and variable removal.

Implementation Notes (filled checklist)

  • Implement command: internal/cmd/pipelines/variable/delete/delete.go (type opts struct, NewCmd(ctx), run(ctx, opts)).
  • Wire command: internal/cmd/pipelines/variable/variable.go must AddCommand(delete.NewCmd(ctx)) and be reachable from azdo pipelines.
  • Parse scope: util.ParseProjectTargetWithDefaultOrganization(ctx, targetArg) for [ORGANIZATION/]PROJECT/PIPELINE_ID_OR_NAME; wrap parse errors with util.FlagErrorWrap.
  • Clients:
    • Build: ctx.ClientFactory().Build(ctx.Context(), scope.Organization) using Definitions - Get and Definitions - Update.
    • Prompter only for confirmation prompt (unless --yes).
  • Resolution algorithm:
    • If PIPELINE_ID_OR_NAME is numeric, treat as definitionId.
    • Otherwise resolve by name via Definitions - List (handle multiple matches explicitly).
  • Update algorithm:
    • GET definition by id.
    • Delete variable key (case-insensitive).
    • PUT updated definition, ensuring revision matches the GET result.
  • Output:
    • If stdout is a TTY: print Variable deleted..
    • If stdout is not a TTY: no output on success.
  • Tests:
    • Add unit tests at internal/cmd/pipelines/variable/delete/delete_test.go.
    • Hermetic mocks: Build client + prompter.
    • Table-driven cases: delete by id with --yes, delete by name resolution, missing variable, prompt decline -> util.ErrCancel, stdout TTY vs non-TTY output behavior.

Command Wiring

  • Implement the command in internal/cmd/pipelines/variable/delete/delete.go exposing NewCmd(ctx util.CmdContext) *cobra.Command.
  • Register it from the parent internal/cmd/pipelines/variable/variable.go so the CLI hierarchy includes azdo pipelines variable delete.

SDK / Client Requirements

  • Requires the Build client (ClientFactory().Build(...)) to retrieve and update pipeline definitions. Confirm that the client is exposed; if not, follow "Handling Missing Azure DevOps SDK Clients" in AGENTS.md (extend ClientFactory, run go mod tidy and go mod vendor, update scripts/generate_mocks.sh, and implement the factory method).

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions