Skip to main content

azdo-build-investigator

Investigate CI failures for dotnet/maui PRs — build errors, Helix test logs, and binlog analysis. Use when asked about failing checks, CI status, test failures, 'why is CI red', 'build failed', 'what's failing on PR', Helix failures, or device test failures.

Stars
23,266
Source
dotnet/maui
Updated
2026-05-30
Slug
dotnet--maui--azdo-build-investigator
View on GitHubRaw SKILL.md

// install — copy + paste into any project

mkdir -p .claude/skills && curl -fsSL https://raw.githubusercontent.com/dotnet/maui/HEAD/.github/skills/azdo-build-investigator/SKILL.md -o .claude/skills/azdo-build-investigator.md

Drops the SKILL.md into .claude/skills/azdo-build-investigator.md. Works with Claude Code, Cursor, and any agent that loads SKILL.md files from .claude/skills/.

dotnet/maui CI Investigation Context

This skill provides MAUI-specific context for CI investigation. Use it together with the ci-analysis skill (loaded from the dotnet-dnceng@dotnet-arcade-skills plugin via .github/copilot/settings.json).

First: invoke the ci-analysis skill — it handles the core investigation workflow using Get-CIStatus.ps1 and gh CLI (with MCP tools as optional enhancements if available). This skill provides MAUI-specific corrections and context on top of that.

Script Location

The ci-analysis skill and its Get-CIStatus.ps1 script are loaded automatically from the dotnet/arcade-skills plugin (configured in .github/copilot/settings.json via enabledPlugins). The CLI caches scripts to ~/.copilot/installed-plugins/dotnet-arcade-skills/. No manual download is needed.

MAUI CI Pipelines

⚠️ The ci-analysis skill's reference doc lists maui-public as the MAUI pipeline — this is outdated. The correct pipeline names are below.

Pipeline Name Definition ID Purpose
maui-pr 302 Main build — check this first
maui-pr-devicetests 314 Helix device tests (iOS, Android, Windows, MacCatalyst)
maui-pr-uitests 313 Appium-based UI tests

Organization: dnceng-public / project public

Investigation priority order: maui-prmaui-pr-devicetestsmaui-pr-uitests

Most failures are in maui-pr. Device test failures appear in maui-pr-devicetests. Focus on the first failing pipeline before checking others.

When CI hasn't run: Community PRs require a maintainer to trigger builds. Use /azp run maui-pr (or maui-pr-devicetests, maui-pr-uitests) in a PR comment, or trigger via Azure CLI. Not all pipelines run automatically — maui-pr-devicetests and maui-pr-uitests may need explicit triggers depending on the changed files.

Escalation: For deep Helix log analysis (recurring failures, machine-specific issues, comparing passing vs. failing runs), escalate to the helix-investigation skill.

MAUI-Specific Quirks

XHarness Exit-0 Blind Spot

XHarness (used for iOS/Android device tests in maui-pr-devicetests) exits with code 0 even when tests fail. This means:

  • The ADO job shows ✅ "Succeeded"
  • ci-analysis may report no failures
  • But actual test failures are hidden inside the Helix work items

How to detect hidden test failures: Query the ResultSummaryByBuild Helix API endpoint:

GET https://helix.dot.net/api/2019-06-17/jobs/{correlationId}/aggregated

Look for Failed > 0 in the response even when the ADO build job shows green.

When ci-analysis reports a maui-pr-devicetests build as passing but the PR has a s/agent-gate-failed label or the user suspects device test failures, always cross-check Helix ResultSummaryByBuild.

Container Artifact Binlogs

MAUI build artifacts are Container type, not PipelineArtifact. This means:

  • az pipelines runs artifact download does not work for binlogs
  • Artifact names are like Windows_NT_Build Windows (Debug)_Attempt1 (not binlog)
  • Download requires a Bearer token from az account get-access-token --resource 499b84ac-1321-427f-aa17-267ca6975798
  • Use the ADO File Container API: /_apis/resources/Containers/{id}?api-version=5.0-preview&$format=OctetStream

If available, use the mcp-binlog-tool MCP server to analyze downloaded .binlog files. This is optional — the core investigation workflow works without it via gh CLI and REST APIs.

Common MAUI Failure Patterns

Pattern Where Notes
error CS#### maui-pr C# compiler error — check file/line
error XA#### maui-pr Android build error
XamlC maui-pr XAML compiler — usually missing type or bad binding
error XAGRDL0000 / 401 / No local versions maui-pr or official build Gradle/Maven feed issue — see below
XHarness timeout maui-pr-devicetests Helix logs Test killed by infrastructure; may be transient
No test result files found maui-pr-devicetests Helix logs Tests never ran or app crashed on launch
UI test screenshot diff maui-pr-uitests Visual regression; check baseline images

Test Count Deduplication

When querying AzDO test results directly (e.g., via the /test/runs/{id}/results API), always deduplicate before reporting counts. MAUI UI tests produce multiple test runs per test because each test executes across:

  • Runtime variants: CoreCLR and Mono
  • Platform versions: e.g., iOS 18.5 and iOS latest, Android API 30 and API 36
  • Retry attempts: failed jobs are retried, each attempt publishes a new test run

A single failing test can appear in 4–8+ test runs. Summing raw totalTests - passedTests across all runs inflates failure counts dramatically.

How to deduplicate: Group by test name + OS platform (extract the OS token — ios, android, mac, win — from the run name as the grouping key). For example, "DatePicker_Format_D on iOS" vs "DatePicker_Format_D on Android" are distinct failures worth reporting separately. Collapse retries and runtime variants (coreclr/mono) of the same test on the same OS — if a test fails on both coreclr and mono for iOS, that's one issue, not two.

Gradle / Maven / CFSClean Failures

Error signatures:

error XAGRDL0000: Could not resolve com.android.tools.build:gradle:8.11.1
  > Received status code 401: Unauthorized - No local versions of package
error XAGRDL0000: Could not GET '...pkgs.dev.azure.com/.../maven/v1/...'
  > Unauthorized - Please provide authentication to save package from upstream

Fix: Tell the user to run ./eng/ingest-maven-deps.sh locally to pre-ingest packages into the feed.

Do NOT:

  • Remove CFSClean from ci-official.yml — security compliance requirement
  • Upgrade Gradle past 8.x — dotnet/android#10738
  • Add mavenCentral() or google() back — use the Azure Artifacts feed