devops_utils.core.azure_devops.workitems module

Work-item operations against the Azure DevOps REST API.

All functions are pure in the sense that they take an explicit AzureDevOpsClient; nothing here reads global state or machine creds.

Design notes for cross-compat (cloud + on-prem Server):

  • Comments use the System.History field patch, which every server supports, rather than the preview-only /comments endpoint.

  • Search uses WIQL CONTAINS rather than the Search extension (a separate host that is not always present on-prem).

devops_utils.core.azure_devops.workitems.add_attachment(client: AzureDevOpsClient, work_item_id: int, file_path: str, *, comment: str | None = None) → dict[str, Any][source]

Upload a local file and attach it to a work item (2-step).

devops_utils.core.azure_devops.workitems.add_comment(client: AzureDevOpsClient, work_item_id: int, text: str) → dict[str, Any][source]

Add a comment to a work item via the System.History field.

Add a reference (relation) to a work item.

Parameters:
  • kind – One of commit, pull_request, branch (all need project + repo), build (value = build id), work_item / parent / child / predecessor / successor (value = target work-item id), or hyperlink (value = raw URL).

  • value – Commit SHA / PR id / branch name / build id / work-item id / URL per kind.

  • project – Team project (required for commit/pull_request/branch).

  • repo – Repository name or id (required for commit/pull_request/branch).

  • comment – Optional note stored on the relation.

devops_utils.core.azure_devops.workitems.create_work_item(client: AzureDevOpsClient, project: str, work_item_type: str, title: str, *, description: str | None = None, tags: list[str] | None = None, area_path: str | None = None, iteration_path: str | None = None, assigned_to: str | None = None, parent: int | None = None, fields: dict[str, Any] | None = None) → dict[str, Any][source]

Create a work item and return the trimmed result.

Parameters:
  • project – Team project name or id.

  • work_item_type – e.g. Bug, Task, User Story.

  • title – Work-item title (System.Title).

  • description – Optional System.Description (HTML).

  • tags – Optional list of tags.

  • iteration_path (area_path /) – Optional classification nodes.

  • assigned_to – Optional identity (email or display name).

  • parent – Optional parent work-item id; links the new item under it.

  • fields – Optional extra/custom fields as {reference_name: value}, e.g. {"Custom.RiskLevel": "High"}. Reference names are process or org specific; use the field’s reference name, not its display label. Applied after the named args above, so a key here overrides e.g. area_path if it targets System.AreaPath.

devops_utils.core.azure_devops.workitems.get_work_item(client: AzureDevOpsClient, work_item_id: int, *, relations: bool = False, full: bool = False) → dict[str, Any][source]

Fetch a single work item (trimmed).

Parameters:
  • relations – When true, include the item’s relations (parent/child links, related work items, hyperlinks, attachments, artifact links) as a relations list of {kind, target, ...} dicts.

  • full –

    When true, add the item’s complete raw fields mapping (keyed by field reference name) plus its rev. The trimmed keys stay put; this is the only way to read a description, a scheduling date, or a Custom.* field that _trim() drops, and rev is what a caller needs for a concurrency-safe follow-up patch.

    The whole response body already carries these — no extra request and no REST fields= selector, which matters because fields= and $expand are mutually exclusive server-side (undocumented; it surfaces only as a runtime 400). Reading the default body instead keeps full and relations freely composable.

devops_utils.core.azure_devops.workitems.list_work_items(client: AzureDevOpsClient, project: str, *, states: list[str] | None = None, types: list[str] | None = None, assigned_to: str | None = None, tags: list[str] | None = None, parent: int | None = None, area_path: str | None = None, iteration_path: str | None = None, top: int = 50) → list[dict[str, Any]][source]

List work items in a project, optionally filtered by state/type/assignee/tags.

assigned_to="@Me" uses the WIQL @Me macro, resolving the identity behind the token server-side. Each tag becomes an AND-joined [System.Tags] CONTAINS clause. parent matches direct children of that work item via [System.Parent] (Azure DevOps Services / Server 2019.1+). area_path/iteration_path match the given node and everything under it (Azure Boards area/iteration tree).

devops_utils.core.azure_devops.workitems.query_wiql(client: AzureDevOpsClient, project: str, wiql: str, top: int = 50) → list[int][source]

Run a WIQL query and return the matching work-item ids.

Remove a reference (relation) from a work item.

Accepts the same kind/value pairs as add_link(). The relation is located by matching its rel type and URL, then removed by index with a guarding test op (the REST API only removes relations by index).

Raises:

ValueError – If no matching relation exists on the work item.

devops_utils.core.azure_devops.workitems.search_work_items(client: AzureDevOpsClient, project: str, text: str, *, states: list[str] | None = None, types: list[str] | None = None, assigned_to: str | None = None, tags: list[str] | None = None, parent: int | None = None, area_path: str | None = None, iteration_path: str | None = None, top: int = 50) → list[dict[str, Any]][source]

Text-search work items by title/description using WIQL CONTAINS.

Supports the same assigned_to (incl. @Me), tags, parent, area_path, and iteration_path filters as list_work_items().

devops_utils.core.azure_devops.workitems.set_tags(client: AzureDevOpsClient, work_item_id: int, tags: list[str], mode: str = 'add') → dict[str, Any][source]

Set work-item tags.

Parameters:
  • tags – Tags to apply.

  • mode – "add" merges with existing tags; "replace" overwrites.

devops_utils.core.azure_devops.workitems.update_work_item(client: AzureDevOpsClient, work_item_id: int, *, state: str | None = None, assigned_to: str | None = None, title: str | None = None, description: str | None = None, area_path: str | None = None, iteration_path: str | None = None, fields: dict[str, Any] | None = None) → dict[str, Any][source]

Update mutable fields of an existing work item.

Parameters:
  • state – New System.State (process-template-specific, e.g. Closed, Done, Resolved).

  • assigned_to – New assignee identity (email or display name).

  • title – New System.Title.

  • description – New System.Description (HTML).

  • area_path – New System.AreaPath (e.g. Project\Team), used to move the item between Azure Boards areas.

  • iteration_path – New System.IterationPath (e.g. Project\Sprint 3), used to move the item between sprints.

  • fields – Optional extra/custom fields as {reference_name: value}, e.g. {"Custom.RiskLevel": "High"}. Reference names are process or org specific; use the field’s reference name, not its display label. Applied after the named args above, so a key here overrides e.g. state if it targets System.State.

Raises:

ValueError – If no field to update was given.