Skip to content

feat: Implement azdo pipelines list command #256

Description

@tmeckel

Sub-issue of #116. Hardened spec — do not re-derive decisions. Mirrors az pipelines list from the Azure CLI and the Python implementation at azure-dev-ops-cli-extension/azure-dev-ops-cli-extension/azure-dev-ops/azure-devops/azext_devops/dev/pipelines/pipeline.py#L26-L41.

Command Description

List pipeline definitions (YAML or classic) in a project. The command fetches the matching definitions via the Definitions REST 7.1 endpoint with optional filters and renders them as a default table (with optional JSON export). Output passes through ctx.Printer("list") for the table and opts.exporter.Write(ios, view) for JSON.

GET https://dev.azure.com/{organization}/{project}/_apis/build/definitions?name={filter}&repositoryId={repoId}&repositoryType={tfsgit|github}&top={n}&path={folderPath}&queryOrder={order}&api-version=7.1

Locked Decisions (do not re-derive)

# Decision Rationale
1 Use the vendored SDK build.Client.GetDefinitions (not raw HTTP). Mock already generated at internal/mocks/build_client_mock.go:837. Consistent with the other pipelines siblings.
2 Pipelines are project-scoped: positional [ORGANIZATION/]PROJECT (via util.ParseProjectScope). Mirrors az pipelines list and consistent with the broader pipelines group.
3 Optional filter --name (string) maps to GetDefinitionsArgs.Name. Mirrors az pipelines list --name. Accepts a prefix or exact name.
4 Optional --repository (string) maps to GetDefinitionsArgs.RepositoryId (resolved by name when not a UUID). Optional --repository-type (enum tfsgit github) maps to GetDefinitionsArgs.RepositoryType. When --repository is given, --repository-type defaults to tfsgit.
5 Optional --top (int) maps to GetDefinitionsArgs.Top. Optional --folder-path (string) maps to GetDefinitionsArgs.Path. Optional --query-order (enum) maps to GetDefinitionsArgs.QueryOrder. Mirrors Python pipeline_list parameters.
6 Default output is a table. JSON output via --json passes a dedicated view struct []pipelineJSON to opts.exporter.Write. The view struct flattens Path (truncated to 50 chars + .. if longer) and Queue (name only) with omitempty. Mirrors pipelines/variablegroup/list/list.go.
7 JSON view struct fields: id, name, path (truncated), revision, type (BuildDefinitionType), quality (definition quality, drives the Draft column), queueStatus, defaultQueue (name only). Symmetric with the show sibling.
8 --max-items (int, default 0 = no cap) — if positive, truncate the result slice client-side. Mirrors pipelines/variablegroup/list --max-items.
9 Aliases: ls, l. Project convention.
10 No new SDK client, no new helper, no new package beyond internal/cmd/pipelines/list. Mandate: minimal code.
11 Mock for GetDefinitions is already generated at internal/mocks/build_client_mock.go:837. Do not regenerate. Verified.

Command Signature

azdo pipelines list [ORGANIZATION/]PROJECT
  [--name NAME]                          (string, prefix or exact)
  [--repository REPOSITORY]              (string: name or UUID)
  [--repository-type tfsgit|github]      (enum; default: tfsgit if --repository given)
  [--top TOP]                            (int, max definitions to return)
  [--folder-path FOLDER_PATH]            (string, e.g. "user1/production")
  [--query-order definitionNameAscending|definitionNameDescending|lastModifiedAscending|lastModifiedDescending|none]
  [--max-items MAX]                      (int, 0 = no cap)
  [--json ...]
  • Aliases: ls, l
  • cobra.ExactArgs(1)args[0] → project scope (via util.ParseProjectScope).

Flags

Flag Maps to Notes
--name (string) GetDefinitionsArgs.Name Optional name filter (prefix or exact)
--repository (string) GetDefinitionsArgs.RepositoryId Resolved by name when not a UUID
--repository-type (enum) GetDefinitionsArgs.RepositoryType tfsgit (default) or github; uses util.StringEnumFlag
--top (int) GetDefinitionsArgs.Top Server-side cap on results
--folder-path (string) GetDefinitionsArgs.Path Folder path within the project
--query-order (enum) GetDefinitionsArgs.QueryOrder One of 5 enum values; uses util.StringEnumFlag
--max-items (int) client-side cap 0 = no cap; truncates after SDK returns
--json / --jq / --template util.AddJSONFlags JSON export

JSON Output Contract

type pipelineJSON struct {
    ID           *int    `json:"id,omitempty"`
    Name         *string `json:"name,omitempty"`
    Path         *string `json:"path,omitempty"`
    Revision     *int    `json:"revision,omitempty"`
    Type         *string `json:"type,omitempty"`
    Quality      *string `json:"quality,omitempty"`
    QueueStatus  *string `json:"queueStatus,omitempty"`
    DefaultQueue *string `json:"defaultQueue,omitempty"`
}

Path is truncated to 50 chars + .. suffix when longer, mirroring the Python _transform_pipeline_row truncation. DefaultQueue is the queue name only (not the full AgentPoolQueue).

Table Output Contract

Default columns: ID, PATH, NAME, [DRAFT?], STATUS, DEFAULT QUEUE (mirrors transform_pipelines_table_output from _format.py). The DRAFT column is included only when at least one definition in the result has quality: draft. Results sorted by ID asc, matching the existing list-sibling convention.

Command Wiring

  • Package path: internal/cmd/pipelines/list
  • Files:
    • list.goNewCmd(ctx util.CmdContext) *cobra.Command + listOptions + runList
    • list_test.go — table-driven gomock tests
  • Update internal/cmd/pipelines/pipelines.go to add list.NewCmd(ctx) as a top-level leaf (cmd.AddCommand(...)). Update the Example block.
  • Higher-level parents must already remain wired: pipelineslist (top-level).

API Surface

Reuse the already-vendored client. No new SDK clients or mocks required.

  • build.Client.GetDefinitionsDefinitions - List (REST 7.1)
  • build.GetDefinitionsArgs struct: {Project *string, Name *string, RepositoryId *string, RepositoryType *string, Top *int, Path *string, QueryOrder *string}.
  • build.GetDefinitionsResponseValue struct: {Value *[]BuildDefinitionReference, Count *int}.

Mock for GetDefinitions is already generated at internal/mocks/build_client_mock.go:837. No mock regeneration needed.

Reference Existing Patterns

References

Metadata

Metadata

Assignees

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions