Skip to content

[ci] Enable Linux Android integration tests with workload and KVM support#34046

Merged
rmarinho merged 4 commits intofix-android-run-linuxfrom
copilot/sub-pr-33997
Feb 20, 2026
Merged

[ci] Enable Linux Android integration tests with workload and KVM support#34046
rmarinho merged 4 commits intofix-android-run-linuxfrom
copilot/sub-pr-33997

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Feb 13, 2026

The mac_runandroid_tests stage was moved to Linux pools but failed due to two issues: workload installation attempted to install the full maui workload (which includes iOS/macOS dependencies unavailable on Linux), and KVM was not enabled for Android emulator support.

Changes:

  • Modified src/DotNet/DotNet.csproj Install target to conditionally install maui-android on Linux, maui on other platforms
    • Aligns with existing pattern in _InstallWorkloadPacks target where iOS/macOS workloads are excluded on Linux
  • Added KVM enablement step to eng/pipelines/arcade/setup-test-env.yml for Android integration tests on Linux
    • Creates udev rules to allow KVM access for Android emulators
    • Matches pattern used in device-tests-steps.yml and ui-tests-steps.yml
<ItemGroup>
  <!-- On Linux, install maui-android instead of maui to avoid iOS/macOS dependencies -->
  <_LocalWorkloadIds Include="maui-android" Condition="$([MSBuild]::IsOSPlatform('linux'))" />
  <_LocalWorkloadIds Include="maui" Condition="!$([MSBuild]::IsOSPlatform('linux'))" />
</ItemGroup>

💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

On Linux, we should install the maui-android workload instead of the full maui workload to avoid iOS/macOS dependencies that cannot be installed on Linux. This matches the pattern used in _InstallWorkloadPacks target where iOS/macOS workloads are excluded on Linux.

Co-authored-by: rmarinho <1235097+rmarinho@users.noreply.github.com>
Copilot AI changed the title [WIP] Update CI pipeline to run Android tests on Linux [ci] Install maui-android workload on Linux for Android integration tests Feb 13, 2026
Copilot AI requested a review from rmarinho February 13, 2026 16:56
@rmarinho
Copy link
Copy Markdown
Member

/azp run maui-pr

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines could not run because the pipeline triggers exclude this branch/path.

@rmarinho
Copy link
Copy Markdown
Member

@copilot can you also check seems we need to enable KVM , we have a script for that somewhere

Android emulators require KVM to be enabled on Linux hosts. This adds the KVM enablement step to the setup-test-env.yml template, which is used by the integration tests stage.

The script creates udev rules to allow KVM access and reloads the udev rules. This matches the pattern used in device-tests-steps.yml and ui-tests-steps.yml.

Co-authored-by: rmarinho <1235097+rmarinho@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Feb 13, 2026

@copilot can you also check seems we need to enable KVM , we have a script for that somewhere

I've enabled KVM for Android integration tests on Linux by adding the KVM enablement step to setup-test-env.yml. This matches the pattern used in device-tests-steps.yml and ui-tests-steps.yml.

The script creates udev rules to allow KVM access and is conditionally executed only on Linux agents.

Commit: ba58555

Copilot AI changed the title [ci] Install maui-android workload on Linux for Android integration tests [ci] Enable Linux Android integration tests with workload and KVM support Feb 13, 2026
@rmarinho
Copy link
Copy Markdown
Member

rmarinho commented Feb 18, 2026

🤖 AI Summary

📊 Expand Full Review
🔍 Pre-Flight — Context & Validation
📝 Review SessionEnable KVM for Android integration tests on Linux · ba58555

PR: #34046 - [ci] Enable Linux Android integration tests with workload and KVM support
Parent Issue: #33997 - [ci] Run android on MAUI-Dnceng
Platforms Affected: CI infrastructure (Linux agents for Android integration tests)
Files Changed: 2 files (1 pipeline YAML, 1 MSBuild project)

Issue Summary

PR #33997 moved the mac_runandroid_tests stage from macOS pools to Linux pools (MAUI-DNCENG / 1ESPT-Ubuntu22.04). This failed due to two issues:

  1. The Install target in DotNet.csproj installed the full maui workload (which includes iOS/macOS dependencies unavailable on Linux)
  2. KVM (Kernel-based Virtual Machine) was not enabled on Linux, which is required for Android emulators

Key Findings

  • Workload issue: The Install target unconditionally installed maui workload. On Linux, this fails because it tries to install iOS/macOS dependencies. The fix conditionally installs maui-android on Linux and maui on other platforms.
  • KVM issue: Android emulators need KVM for hardware acceleration on Linux. This is already done in device-tests-steps.yml and ui-tests-steps.yml. The fix adds the same KVM enablement step to setup-test-env.yml (used by integration tests) with a Linux-only condition.
  • The fix aligns with the existing pattern in _InstallWorkloadPacks target which already excludes iOS/macOS workloads on Linux (lines 186-188, 245, 261, 277, 293 of DotNet.csproj).

PR Discussion Summary

Commenter Comment Action Taken
rmarinho Initial PR #33997 failure: "Can't install maui on linux" Spawned PR #34046 (Copilot)
rmarinho "@copilot can you also check seems we need to enable KVM" Copilot added KVM step in commit ba58555

No disagreements. rmarinho requested KVM enablement, which was added.

Files Changed

  • eng/pipelines/arcade/setup-test-env.yml (+10): Added KVM enablement step for Linux Android tests
  • src/DotNet/DotNet.csproj (+2, -1): Conditional workload installation (maui-android on Linux, maui elsewhere)

Fix Candidates

# Source Approach Test Result Files Changed Notes
PR PR #34046 Conditional maui-android workload on Linux + KVM enablement step ⏳ PENDING (Gate) DotNet.csproj (+2), setup-test-env.yml (+10) CI-only change, no functional code tests

Important Notes

  • This is a CI infrastructure-only change — no functional code, no UI tests, no integration test cases to run locally
  • The Gate phase will need to assess differently since there are no tests to verify fail/pass behavior
  • The fix follows established patterns in the codebase

🚦 Gate — Test Verification
📝 Review SessionEnable KVM for Android integration tests on Linux · ba58555

Result: ⏳ SKIPPED (CI Infrastructure Change)
Platform: N/A
Mode: N/A

Reason for Skip

This PR is a CI infrastructure-only change. It modifies:

  1. eng/pipelines/arcade/setup-test-env.yml — Azure DevOps pipeline YAML
  2. src/DotNet/DotNet.csproj — MSBuild workload installation target

There are no functional code changes and no UI/integration tests associated with this PR. The changes can only be verified by running the actual CI pipeline on Linux Azure DevOps agents, which is not possible locally.

Verification Notes

  • No test files exist matching this PR (*34046*, *33997*)
  • The fix is a CI pipeline/build system change that cannot be reproduced locally
  • Gate verification (fail-without-fix / pass-with-fix) is not applicable to CI infrastructure PRs
  • The correctness of the changes was assessed via code review only

Gate Result

Gate: ⚠️ SKIPPED — CI infrastructure change, no testable code paths locally


🔧 Fix — Analysis & Comparison
📝 Review SessionEnable KVM for Android integration tests on Linux · ba58555

Fix Candidates

Phase 3 (try-fix) SKIPPED — This is a CI infrastructure change with no functional code tests.

The PR modifies Azure DevOps pipeline YAML and MSBuild targets. There are no unit tests, UI tests, or integration tests that can be run locally to verify fail-without-fix / pass-with-fix behavior. The correctness can only be validated by running the actual CI pipeline on Linux agents.

# Source Approach Test Result Files Changed Notes
PR PR #34046 Conditional maui-android workload on Linux + KVM enablement step ⚠️ UNTESTABLE LOCALLY DotNet.csproj (+2), setup-test-env.yml (+10) CI infrastructure only

Exhausted: N/A (CI infrastructure change - try-fix not applicable)
Selected Fix: PR's fix — The approach is correct, follows established patterns in the codebase, and directly addresses both failure modes identified in issue #33997.


📋 Report — Final Recommendation
📝 Review SessionEnable KVM for Android integration tests on Linux · ba58555

✅ Final Recommendation: APPROVE

Summary

PR #34046 fixes two CI infrastructure issues that prevented Android integration tests from running on Linux agents (introduced by PR #33997 which moved the mac_runandroid_tests stage to Linux pools):

  1. Workload installation failure: On Linux, the Install target was trying to install the full maui workload (which includes iOS/macOS dependencies). Fixed by conditionally installing maui-android on Linux and maui on other platforms.

  2. Missing KVM support: Android emulators need KVM for hardware acceleration on Linux. The KVM enablement step was already present in device-tests-steps.yml and ui-tests-steps.yml, but was missing from setup-test-env.yml (used by integration tests). Added it with the same pattern.

Root Cause

The CI migration from macOS to Linux pools (PR #33997) didn't account for two Linux-specific requirements:

  • The maui workload includes iOS/macOS workloads that cannot be installed on Linux
  • Linux Android emulators require explicit KVM permission setup via udev rules

Code Review

src/DotNet/DotNet.csproj

  • Conditional uses $([MSBuild]::IsOSPlatform('linux')) — the same API used elsewhere in this file (lines 186-189, 245, 261, 277, 293) for identical iOS/macOS exclusions
  • Comment clearly explains the reason
  • Pattern is consistent with the existing _InstallWorkloadPacks target approach
  • No concerns

eng/pipelines/arcade/setup-test-env.yml

  • KVM step matches the exact same script used in device-tests-steps.yml and ui-tests-steps.yml
  • Uses runtime condition and(succeeded(), eq(variables['Agent.OS'], 'Linux')) rather than a template-time ${{ if }} guard — this is acceptable; it means the step appears in all job definitions but is a no-op on non-Linux agents
  • In the other files, the step uses ${{ if eq(parameters.platform, 'android') }} at template-time. That conditional isn't available in setup-test-env.yml (no platform parameter), but the runtime Linux condition is sufficient since the step is safe to run on Linux regardless
  • No concerns

Minor Observation (Non-blocking)

The mac_runandroid_tests stage in ci.yml (from PR #33997) has both branches of an ${{ if }} pointing to AndroidPoolLinux:

${{ if eq(variables['Build.DefinitionName'], 'maui-pr') }}:
  pool: ${{ parameters.AndroidPoolLinux }}
${{ else }}:  
  pool: ${{ parameters.AndroidPoolLinux }}

This is redundant but harmless. It could be simplified to just pool: ${{ parameters.AndroidPoolLinux }}, but this is from the parent PR #33997 and not in scope for PR #34046.

Fix Quality

The fix is minimal, correct, and follows established patterns. Both changes have clear precedent in the codebase. No alternative approaches were explored (not applicable for CI infrastructure changes).

PR Title Accuracy: ✅ Accurate — "Enable Linux Android integration tests with workload and KVM support" correctly describes both changes.

PR Description Accuracy: ✅ Accurate — Correctly explains the problem and solution, references the existing patterns.


📋 Expand PR Finalization Review
Title: ✅ Good

Current: [ci] Enable Linux Android integration tests with workload and KVM support

Description: ✅ Good

Description needs updates. See details below.

✨ Suggested PR Description

[!NOTE]
Are you waiting for the changes in this PR to be merged?
It would be very helpful if you could test the resulting artifacts from this PR and let us know in a comment if this change resolves your issue. Thank you!

The mac_runandroid_tests stage was moved to Linux pools but failed due to two issues: workload installation attempted to install the full maui workload (which includes iOS/macOS dependencies unavailable on Linux), and KVM was not enabled for Android emulator support.

Changes:

  • Modified src/DotNet/DotNet.csproj Install target to conditionally install maui-android on Linux, maui on other platforms
    • Aligns with existing pattern in _InstallWorkloadPacks target where iOS/macOS workloads are excluded on Linux
  • Added KVM enablement step to eng/pipelines/arcade/setup-test-env.yml for Android integration tests on Linux
    • Creates udev rules to allow KVM access for Android emulators
    • Matches pattern used in device-tests-steps.yml and ui-tests-steps.yml
<_LocalWorkloadIds Include="maui-android" Condition="$([MSBuild]::IsOSPlatform('linux'))" />
<_LocalWorkloadIds Include="maui" Condition="!$([MSBuild]::IsOSPlatform('linux'))" />

Issues Fixed

Fixes #33997

Code Review: ✅ Passed

Code Review — PR #34046

✅ No Critical Issues

The implementation is minimal, correct, and follows established patterns in the codebase.


File: src/DotNet/DotNet.csproj

✅ Conditional workload installation

<!-- On Linux, install maui-android instead of maui to avoid iOS/macOS dependencies -->
<_LocalWorkloadIds Include="maui-android" Condition="$([MSBuild]::IsOSPlatform('linux'))" />
<_LocalWorkloadIds Include="maui" Condition="!$([MSBuild]::IsOSPlatform('linux'))" />
  • Pattern consistency: ✅ Uses the exact same $([MSBuild]::IsOSPlatform('linux')) API already used at lines 186–189, 245, 261, 277, 293 of this file for identical iOS/macOS exclusions in _InstallWorkloadPacks.
  • Comment: ✅ Clear and explains the "why."
  • Correctness:maui-android is the correct workload ID for Linux-only Android support.

File: eng/pipelines/arcade/setup-test-env.yml

✅ KVM enablement step

- bash: |
    echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
    sudo udevadm control --reload-rules
    sudo udevadm trigger --name-match=kvm
  displayName: Enable KVM
  condition: and(succeeded(), eq(variables['Agent.OS'], 'Linux'))
  • Pattern consistency: ✅ Identical script to device-tests-steps.yml and ui-tests-steps.yml. Verified in codebase.
  • Condition style: ℹ️ Uses runtime condition eq(variables['Agent.OS'], 'Linux') rather than template-time ${{ if eq(parameters.platform, 'android') }} used in the other files. This is acceptable because:
    • setup-test-env.yml has no platform parameter to guard on at template-time
    • The runtime Linux condition is sufficient — the step is a no-op if not on Linux and is safe to run on any Linux agent
    • The step appears in the job definition for all agents but is skipped at runtime on non-Linux agents (minor cost)
  • No security concerns: The udev rules grant group-based KVM access, which is standard practice for Android emulator CI setups.

🟡 Minor Observations (Non-blocking)

  1. Condition style difference (noted above): Runtime vs. template-time Linux condition. Functionally correct but slightly less efficient than a template-time guard. Acceptable for this use case.

  2. maui-android workload completeness: Ensure maui-android includes everything needed for the integration tests being run. This appears to be correct based on existing patterns in _InstallWorkloadPacks, but can only be fully validated by running the actual CI pipeline on Linux.


✅ Looks Good

  • Minimal change, targeted fix
  • Both changes have direct precedent in the codebase
  • Follows the established Linux exclusion pattern throughout DotNet.csproj
  • KVM script is byte-for-byte identical to the working script in other pipeline files
  • No functional code changes — CI infrastructure only

@rmarinho rmarinho added s/agent-approved AI agent recommends approval - PR fix is correct and optimal s/agent-gate-failed AI could not verify tests catch the bug s/agent-fix-lose Author adopted the agent's fix and it turned out to be bad s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review) labels Feb 18, 2026
@rmarinho
Copy link
Copy Markdown
Member

rmarinho commented Feb 19, 2026

@copilot Also when "Install dotnet preview workloads from PackageArtifacts" we need to make sure if we are on linux to only install maui-android workload

@kubaflo kubaflo added s/agent-fix-pr-picked AI could not beat the PR fix - PR is the best among all candidates and removed s/agent-fix-lose Author adopted the agent's fix and it turned out to be bad labels Feb 20, 2026
@rmarinho
Copy link
Copy Markdown
Member

@copilot Also when "Install dotnet preview workloads from PackageArtifacts" we need to make sure if we are on linux to only install maui-android workload

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Feb 20, 2026

@copilot Also when "Install dotnet preview workloads from PackageArtifacts" we need to make sure if we are on linux to only install maui-android workload

This change was already implemented in commit 1c9bc98. The Install target in DotNet.csproj (which is called during "Install dotnet preview workloads from PackageArtifacts") now conditionally installs maui-android on Linux and maui on other platforms.

The logic uses Condition="$([MSBuild]::IsOSPlatform('linux'))" to detect the platform and select the appropriate workload.

@copilot Also when "Install dotnet preview workloads from PackageArtifacts" we need to make sure if we are on linux to only install maui-android workload

This change was already implemented in commit 1c9bc98. The Install target in DotNet.csproj (which is called during "Install dotnet preview workloads from PackageArtifacts") now conditionally installs maui-android on Linux and maui on other platforms.

The logic uses Condition="$([MSBuild]::IsOSPlatform('linux'))" to detect the platform and select the appropriate workload.

@rmarinho rmarinho marked this pull request as ready for review February 20, 2026 16:11
On Linux, only the maui-android workload is installed. Previous .NET
templates (e.g., net9.0) may not have the Linux OS condition to exclude
iOS/macOS target frameworks from the csproj. This causes NETSDK1178
errors during restore because the iOS workload packs are not available.

After template creation, strip non-Android TFMs from the generated
csproj when running on Linux so builds succeed.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@rmarinho rmarinho merged commit 0bc5342 into fix-android-run-linux Feb 20, 2026
23 of 27 checks passed
@rmarinho rmarinho deleted the copilot/sub-pr-33997 branch February 20, 2026 19:04
github-actions bot pushed a commit that referenced this pull request Feb 23, 2026
…port (#34046)

The `mac_runandroid_tests` stage was moved to Linux pools but failed due
to two issues: workload installation attempted to install the full
`maui` workload (which includes iOS/macOS dependencies unavailable on
Linux), and KVM was not enabled for Android emulator support.

**Changes:**
- Modified `src/DotNet/DotNet.csproj` `Install` target to conditionally
install `maui-android` on Linux, `maui` on other platforms
- Aligns with existing pattern in `_InstallWorkloadPacks` target where
iOS/macOS workloads are excluded on Linux
- Added KVM enablement step to `eng/pipelines/arcade/setup-test-env.yml`
for Android integration tests on Linux
  - Creates udev rules to allow KVM access for Android emulators
- Matches pattern used in `device-tests-steps.yml` and
`ui-tests-steps.yml`

```xml
<ItemGroup>
  <!-- On Linux, install maui-android instead of maui to avoid iOS/macOS dependencies -->
  <_LocalWorkloadIds Include="maui-android" Condition="$([MSBuild]::IsOSPlatform('linux'))" />
  <_LocalWorkloadIds Include="maui" Condition="!$([MSBuild]::IsOSPlatform('linux'))" />
</ItemGroup>
```

<!-- START COPILOT CODING AGENT TIPS -->
@kubaflo kubaflo removed the s/agent-gate-failed AI could not verify tests catch the bug label Feb 25, 2026
@github-actions github-actions bot locked and limited conversation to collaborators Mar 28, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

s/agent-approved AI agent recommends approval - PR fix is correct and optimal s/agent-fix-pr-picked AI could not beat the PR fix - PR is the best among all candidates s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants