Skip to content

Introduce azdo boards work-item relation command group #271

@tmeckel

Description

@tmeckel

Sub-issue of #138. Hardened spec — do not re-derive decisions. This umbrella introduces the azdo boards work-item relation subgroup beneath azdo boards work-item. Sibling umbrella: #138 itself.

Command Group Description

Create a relation subgroup beneath azdo boards work-item that centralises work-item link management flows. The group exposes the four Azure Boards work-item relation operations that map directly to the official AzDO Extension's boards work-item relation group (Python implementation at azure-devops/azext_devops/dev/boards/relations.py):

Each leaf is a thin JSON-Patch wrapper over workitemtracking.Client.UpdateWorkItem (for add and remove) and a thin read wrapper over workitemtracking.Client.GetWorkItem / GetRelationTypes (for show and list-type). The REST surface is Work Items - Update (REST 7.1) and Relation Types - Get (REST 7.1).

Implementation Notes

  • Add internal/cmd/boards/workitem/relation/relation.go that exposes NewCmd(ctx util.CmdContext) *cobra.Command.
  • Register the new subgroup inside internal/cmd/boards/workitem/workitem.go so that commands such as azdo boards work-item relation add are discoverable via the CLI hierarchy.
  • Keep the short description focused on Azure Boards work-item relations; do not duplicate descriptions of the parent work-item group.
  • The Python implementation calls the work item with expand='All' after every write so that the response carries the populated relations array (with friendly names). We mirror this in all add/remove/show leaves.
  • Each leaf command lives in its own subdirectory under internal/cmd/boards/workitem/relation/<leaf>/<leaf>.go per AGENTS.md "New Subgroup Under Existing Group" guidance.
  • The four leaves share a small helper at internal/cmd/boards/workitem/relation/shared/relation.go that resolves a friendly relation-type name to its ReferenceName (mirroring get_system_relation_name in the Python source) and a second helper that fills friendly names in a *WorkItem's relations array (mirroring fill_friendly_name_for_relations_in_work_item). The helpers are owned by the umbrella and consumed by the leaves.
  • The add leaf additionally needs util.SplitAndTrimCSV (in internal/cmd/util/csv.go or a relation-shared CSV helper) to support both repeated-flag and comma-separated target lists. If the umbrella is implemented before util.SplitAndTrimCSV exists in the codebase, the add leaf's implementation must add it as a relation-shared helper at internal/cmd/boards/workitem/relation/shared/csv.go to keep the scope contained.

Command Wiring

  • Implement the relation group in internal/cmd/boards/workitem/relation/relation.go and ensure NewCmd only wires child commands under this package.
  • Update internal/cmd/boards/workitem/workitem.go to call cmd.AddCommand(relation.NewCmd(ctx)) so the work-item hierarchy exposes the relation subtree.
  • Each leaf exports NewCmd(ctx util.CmdContext) *cobra.Command from its own subdirectory.
  • Run make docs once wiring is complete to update generated documentation.

SDK / Client Requirements

  • All four leaves rely on the Work Item Tracking client via ClientFactory().WorkItemTracking(...).
  • The add and remove leaves additionally call GetWorkItem and GetRelationTypes for friendly-name resolution and target validation.
  • No new client methods are required: UpdateWorkItem, GetWorkItem, GetRelationTypes are all in the vendored SDK (vendor/.../v7/workitemtracking/client.go:205, 137, 113).

Tooling & Validation

  • Format new Go code with gofmt/goimports.
  • Run go build ./cmd/azdo/... to ensure the CLI compiles with the new wiring.
  • Add/update hermetic tests and execute go test ./... (include documentation regeneration in the validation checklist).
  • Per AGENTS.md, do not regenerate mocks: internal/mocks/workitemtracking_client_mock.go already contains the GetWorkItem, GetRelationTypes, and UpdateWorkItem mocks (lines 849, 669, 1358).

Sub-Issues

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