devops_utils.core.azure_devops package
Submodules
Module contents
Azure DevOps REST helpers (cloud + on-prem Server).
Requires the azure extra (httpx); the dependency is deferred-imported so
importing devops_utils never pulls it in when unused.
- class devops_utils.core.azure_devops.AzureDevOpsClient(org_url: str, token: str, auth_scheme: str = 'bearer', api_version: str = '7.1', transport: Any | None = None)[source]
Bases:
objectThin wrapper over
httpxfor the Azure DevOps REST API.- Parameters:
org_url – Base URL. Cloud
https://dev.azure.com/{org}or on-premhttps://server/tfs/{collection}. A trailing slash is stripped.token – Bearer token or Personal Access Token (see
auth_scheme).auth_scheme –
"bearer"sendsAuthorization: Bearer <token>;"pat"sendsAuthorization: Basic base64(":" + token)which is how Azure DevOps expects a raw PAT.api_version – REST
api-versionquery value. Lower it for older on-prem servers (e.g."6.0").
- classmethod from_env() AzureDevOpsClient[source]
Build a client from environment variables.
Reads
AZURE_DEVOPS_ORG_URLandAZURE_DEVOPS_TOKEN(both required), and optionalAZURE_DEVOPS_AUTH_SCHEME(defaultbearer) andAZURE_DEVOPS_API_VERSION(default7.1).
- request(method: str, path: str, *, params: dict[str, Any] | None = None, json: Any | None = None, content: bytes | None = None, content_type: str | None = None, api_version: str | None = None, base_url: str | None = None) Any[source]
Perform a request and return the parsed JSON body (or
None).api-versionis injected into the query string unless already present.base_urloverridesorg_urlfor APIs served from a different host (e.g. cloud code search onalmsearch.dev.azure.com). RaisesAzureDevOpsErrorfor any non-2xx response.
- exception devops_utils.core.azure_devops.AzureDevOpsError(status_code: int, method: str, url: str, body: str)[source]
Bases:
RuntimeErrorRaised when the Azure DevOps API returns a non-2xx response.
- exception devops_utils.core.azure_devops.PlanError[source]
Bases:
ValueErrorA plan failed validation; the message lists every problem found.
- devops_utils.core.azure_devops.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.add_build_tags(client: AzureDevOpsClient, project: str, build_id: int, tags: list[str]) list[str][source]
Add tags to a build and return the build’s resulting tag list.
- devops_utils.core.azure_devops.add_comment(client: AzureDevOpsClient, work_item_id: int, text: str) dict[str, Any][source]
Add a comment to a work item via the
System.Historyfield.
- devops_utils.core.azure_devops.add_link(client: AzureDevOpsClient, work_item_id: int, kind: str, value: str, *, project: str | None = None, repo: str | None = None, comment: str | None = None) dict[str, Any][source]
Add a reference (relation) to a work item.
- Parameters:
kind – One of
commit,pull_request,branch(all needproject+repo),build(value= build id),work_item/parent/child/predecessor/successor(value= target work-item id), orhyperlink(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.apply_plan(client: AzureDevOpsClient, plan: dict[str, Any], *, stop_on_error: bool = False) list[dict[str, Any]][source]
Apply a validated plan sequentially and return per-item results.
Each result is
{"ref", "action", "status", "id", "url"}withstatusone ofcreated/updated/failed(plus"error"when failed). A failed item never stops ref resolution bookkeeping; later items parented to it fail with a clear message instead of mis-parenting.- Parameters:
stop_on_error – When true, stop at the first failed item (already applied items stay applied — there is no rollback).
- devops_utils.core.azure_devops.code_search(client: AzureDevOpsClient, project: str, text: str, *, repo: str | None = None, branch: str | None = None, top: int = 25) list[dict[str, Any]][source]
Search code content via the Search extension API.
Cloud (dev.azure.com) always has the extension; on-prem servers need the Code Search extension installed — without it this raises a clear error, and
find_repo_items()/ WIQL work-item search are the fallbacks.- Parameters:
text – Search text (supports the code-search syntax, e.g.
def:Foo).repo – Optional repository name to scope to.
branch – Optional branch to scope to.
top – Maximum number of results.
- Returns:
A list of
{path, repo, project, matches}dicts, wherematchescounts content hits in the file.
- devops_utils.core.azure_devops.comment_on_pull_request(client: AzureDevOpsClient, project: str, repo: str, pull_request_id: int, text: str, *, thread_id: int | None = None) dict[str, Any][source]
Comment on a pull request.
Without
thread_ida new (active) comment thread is created; with it the comment is appended to that existing thread as a reply.Returns a trimmed
{thread_id, comment_id, status}dict.
- devops_utils.core.azure_devops.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_pathif it targetsSystem.AreaPath.
- devops_utils.core.azure_devops.find_repo_items(client: AzureDevOpsClient, project: str, repo: str, *, path_pattern: str = '*', branch: str | None = None, top: int = 100) list[dict[str, Any]][source]
Find files in a repository by path pattern (no Search extension needed).
Lists the full tree via the Git Items API and matches each path against
path_patternwithfnmatch(*also crosses/here because a bare filename pattern like*.ymlshould match at any depth).- Parameters:
path_pattern – Glob matched against the repo-relative path (leading
/stripped), e.g.*.ymlorsrc/*/pipeline*.branch – Optional branch to list (defaults to the repo default branch).
top – Maximum number of matches to return.
- Returns:
A list of
{path, size, commit, url}dicts for matching blobs.
- devops_utils.core.azure_devops.get_build(client: AzureDevOpsClient, project: str, build_id: int) dict[str, Any][source]
Fetch a single build by id (trimmed).
- devops_utils.core.azure_devops.get_build_log(client: AzureDevOpsClient, project: str, build_id: int, log_id: int, *, start_line: int | None = None, end_line: int | None = None) str[source]
Fetch a build log’s content as plain text.
- Parameters:
end_line (start_line /) – Optional line range. To tail, set
start_linetoline_count - N(fromlist_build_logs()).
- devops_utils.core.azure_devops.get_build_timeline(client: AzureDevOpsClient, project: str, build_id: int) list[dict[str, Any]][source]
Fetch a build’s timeline: its stages/phases/jobs/tasks with status.
Each record carries a
log_id(when the step produced a log) that can be passed toget_build_log(), andissueswith the step’s error and warning messages — the fastest way to locate why a run failed.- Returns:
Timeline records sorted by their
order, trimmed to{id, parent_id, type, name, state, result, log_id, start_time, finish_time, issues}.
- devops_utils.core.azure_devops.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
relationslist of{kind, target, ...}dicts.full –
When true, add the item’s complete raw
fieldsmapping (keyed by field reference name) plus itsrev. The trimmed keys stay put; this is the only way to read a description, a scheduling date, or aCustom.*field that_trim()drops, andrevis 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 becausefields=and$expandare mutually exclusive server-side (undocumented; it surfaces only as a runtime 400). Reading the default body instead keepsfullandrelationsfreely composable.
- devops_utils.core.azure_devops.list_build_logs(client: AzureDevOpsClient, project: str, build_id: int) list[dict[str, Any]][source]
List a build’s logs as
{id, line_count}entries.Use
line_countwithget_build_log()’sstart_lineto tail a large log instead of downloading it whole.
- devops_utils.core.azure_devops.list_builds(client: AzureDevOpsClient, project: str, *, definitions: list[int] | None = None, branch: str | None = None, statuses: list[str] | None = None, results: list[str] | None = None, top: int = 25) list[dict[str, Any]][source]
List builds in a project, newest first (API default order).
- Parameters:
definitions – Optional pipeline definition ids to filter on.
branch – Optional source branch (short names get
refs/heads/prefixed).statuses – Optional status filter values (
inProgress,completed,notStarted,cancelling,postponed).results – Optional result filter values (
succeeded,partiallySucceeded,failed,canceled).top – Maximum number of builds to return.
- devops_utils.core.azure_devops.list_definitions(client: AzureDevOpsClient, project: str, *, name: str | None = None, top: int = 25) list[dict[str, Any]][source]
List build (pipeline) definitions in a project.
- Parameters:
name – Optional definition name filter;
*wildcards are supported by the API (e.g.CI*).top – Maximum number of definitions to return.
- devops_utils.core.azure_devops.list_repositories(client: AzureDevOpsClient, project: str | None = None, *, name_filter: str | None = None) list[dict[str, Any]][source]
List Git repositories, optionally scoped to a single project.
- Parameters:
name_filter – Optional case-insensitive substring to filter repo names by.
Returns a trimmed list of
{id, name, project, default_branch, web_url}.
- devops_utils.core.azure_devops.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@Memacro, resolving the identity behind the token server-side. Each tag becomes an AND-joined[System.Tags] CONTAINSclause.parentmatches direct children of that work item via[System.Parent](Azure DevOps Services / Server 2019.1+).area_path/iteration_pathmatch the given node and everything under it (Azure Boards area/iteration tree).
- devops_utils.core.azure_devops.load_plan(text: str) dict[str, Any][source]
Parse a YAML (or JSON — a YAML subset) plan document.
- devops_utils.core.azure_devops.plan_preview(items: list[dict[str, Any]]) list[dict[str, Any]][source]
Summarize normalized items for the human review window (no requests).
- devops_utils.core.azure_devops.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.
- devops_utils.core.azure_devops.remove_link(client: AzureDevOpsClient, work_item_id: int, kind: str, value: str, *, project: str | None = None, repo: str | None = None) dict[str, Any][source]
Remove a reference (relation) from a work item.
Accepts the same
kind/valuepairs asadd_link(). The relation is located by matching its rel type and URL, then removed by index with a guardingtestop (the REST API only removes relations by index).- Raises:
ValueError – If no matching relation exists on the work item.
- devops_utils.core.azure_devops.resolve_repo(client: AzureDevOpsClient, project: str, repo: str) dict[str, str][source]
Look up a repository by id or name and return its ids.
Returns
{"project_id": ..., "repo_id": ...}. Both GUIDs are needed to build thevstfs://artifact URIs used for commit/PR/branch links.
- devops_utils.core.azure_devops.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, anditeration_pathfilters aslist_work_items().
- devops_utils.core.azure_devops.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.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.stateif it targetsSystem.State.
- Raises:
ValueError – If no field to update was given.
- devops_utils.core.azure_devops.validate_plan(plan: dict[str, Any]) tuple[list[dict[str, Any]], list[str]][source]
Normalize and validate a plan.
Merges
defaultsinto every item (item values win; the twofieldsmaps are merged key-wise), resolves the effective project, and checks ordering ofref:references.- Returns:
(items, warnings)— the normalized items in application order and human-readable warnings (unknown keys, …) for the review window.- Raises:
PlanError – With every hard problem found, one per line.