Skip to content

Introduce azdo pipelines pool command group #239

Description

@tmeckel

Command Group Description

Introduce a new pool subgroup under the existing azdo pipelines command group (umbrella tracked in #116). The pool subgroup is a thin router: it has no leaf commands of its own at the moment — it currently exists to register the show leaf (filed as a sub-issue of this umbrella) and to be the natural home for future agent-pool-related commands (e.g. list).

The pool subgroup surfaces the agent pool resource from the Azure Pipelines task agent API. It is distinct from the queue subgroup (sibling umbrella, filed in the same wave), which surfaces agent queues (a related but separate resource). Both subgroups share the same vendored SDK client (taskagent.Client) — the split is purely CLI ergonomics to match the Azure CLI's az pipelines pool vs az pipelines queue grouping.

Why a separate subgroup from build (#213) / runs (#214)? Agent pools are scoped to an organization (not a project). The build and runs subgroups operate on a project; pool (and queue) take a positional ORGANIZATION (or use the default) instead of the [ORGANIZATION/]PROJECT scope pattern. This matches the Azure CLI's az pipelines pool [ORGANIZATION] signature.

Implementation Notes

  • The pool subgroup has no behavior of its own. Its sole responsibility is to register child leaf commands via cmd.AddCommand(...).
  • The first child is azdo pipelines pool show (tracked in feat: Implement azdo pipelines pool show command #244).
  • No new SDK client is required — taskagent.Client is already wired in internal/azdo/connection.go:60 (interface) and internal/azdo/factory.go:133-139 (impl). No new mocks are required — MockTaskAgentClient.GetAgentPool and MockTaskAgentClient.GetAgentPools are already present at internal/mocks/taskagent_client_mock.go:411-441.
  • No new shared helpers are required for this parent. Future shared logic across multiple pool leaves may be extracted into this package's pool.go or a separate internal/cmd/pipelines/pool/shared package — do not pre-extract.
  • The Use: line should be pool (no description on the Use line itself; the Short and Long fields provide description text).
  • Aliases are not provided on group commands; only on leaf commands.
  • The subgroup does not take a positional project scope. Pool operations are org-scoped; ORGANIZATION (when provided) is the only positional. When omitted, the configured default organization is used.

Command Wiring

  1. Create internal/cmd/pipelines/pool/pool.go:
package pool

import (
	"github.com/spf13/cobra"

	"github.com/tmeckel/azdo-cli/internal/cmd/pipelines/pool/show"
	"github.com/tmeckel/azdo-cli/internal/cmd/util"
)

func NewCmd(ctx util.CmdContext) *cobra.Command {
	cmd := &cobra.Command{
		Use:   "pool [ORGANIZATION]",
		Short: "Manage Azure DevOps agent pools.",
		Long: `Surface for Azure DevOps agent pools.

Mirrors the 'az pipelines pool' group from the Azure CLI. Pools are scoped
to an organization (not a project); the optional ORGANIZATION positional
falls back to the configured default organization when omitted.`,
	}

	cmd.AddCommand(show.NewCmd(ctx))
	return cmd
}
  1. Register the new subgroup in the existing umbrella at internal/cmd/pipelines/pipelines.go:
import (
	// ... existing imports ...
	"github.com/tmeckel/azdo-cli/internal/cmd/pipelines/pool"
	"github.com/tmeckel/azdo-cli/internal/cmd/pipelines/queue"
	// ...
)

func NewCmd(ctx util.CmdContext) *cobra.Command {
	cmd := &cobra.Command{ /* ... existing ... */ }
	cmd.AddCommand(variablegroup.NewCmd(ctx))
	cmd.AddCommand(variable.NewCmd(ctx))
	cmd.AddCommand(build.NewCmd(ctx))     // #213
	cmd.AddCommand(runs.NewCmd(ctx))      // #214
	cmd.AddCommand(pool.NewCmd(ctx))      // new (this issue, #239)
	cmd.AddCommand(queue.NewCmd(ctx))     // new (sibling umbrella, #240)
	return cmd
}
  1. No change is required to internal/cmd/root/root.go (the pipelines group is already registered).

SDK / Client Requirements

  • Client: taskagent.Client (vendored, already wired).
    • Interface: internal/azdo/connection.go:60TaskAgent(ctx context.Context, organization string) (taskagent.Client, error).
    • Factory: internal/azdo/factory.go:133-139 — constructs the client from the connection.
    • Mock: internal/mocks/taskagent_client_mock.go — full mock implementing taskagent.Client; GetAgentPool is at lines 411-426, GetAgentPools at 441-456. Other pool/queue methods are present for future leaves.
  • No new vendored packages required. vendor/github.com/microsoft/azure-devops-go-api/azuredevops/v7/taskagent/ is already present.
  • No new mocks required for the parent itself. Mocks for future leaves (e.g. GetAgentPool for show) already exist.
  • No go mod tidy / go mod vendor / scripts/generate_mocks.sh work required for this parent or for its first leaf.

Sub-Issues

  • feat: Implement azdo pipelines pool show command #244feat: Implement \azdo pipelines pool show` command` (filed; new in this wave).
  • feat: Implement \azdo pipelines pool list` command` (planned; not yet filed).
  • feat: Implement \azdo pipelines pool create` command` (planned; not yet filed).
  • feat: Implement \azdo pipelines pool update` command` (planned; not yet filed).
  • feat: Implement \azdo pipelines pool delete` command` (planned; not yet filed).

Each new leaf will be filed as a follow-up issue using the same canonical 12-section body format (mirroring the boards show sub-issues #236/#237/#238). When filed, the issue number will replace the placeholder in the checklist above.

Tooling & Validation

  • go build ./... is clean.
  • go test ./internal/cmd/pipelines/pool/... passes.
  • go run cmd/azdo/azdo.go pipelines pool --help renders the subgroup's short and long descriptions and lists show as a child.
  • go run cmd/azdo/azdo.go pipelines --help shows pool alongside variable-group, variable, build, and runs.
  • make lint passes (golangci-lint, per .golangci.yml).
  • make docs regenerates docs/pipelines_pool.md with the new subgroup.

References

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions