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-analysisskill — it handles the core investigation workflow usingGet-CIStatus.ps1andghCLI (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-analysisskill's reference doc listsmaui-publicas 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-pr → maui-pr-devicetests → maui-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-analysismay 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 downloaddoes not work for binlogs- Artifact names are like
Windows_NT_Build Windows (Debug)_Attempt1(notbinlog) - 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()orgoogle()back — use the Azure Artifacts feed