Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions eng/pipelines/arcade/setup-test-env.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ steps:
fetchDepth: 1
clean: true

- template: /eng/pipelines/common/enable-kvm.yml@self

- template: /eng/pipelines/common/provision.yml@self
parameters:
checkoutDirectory: '$(System.DefaultWorkingDirectory)'
Expand Down
14 changes: 9 additions & 5 deletions eng/pipelines/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,13 @@ parameters:
- ImageOverride -equals ACES_VM_SharedPool_Tahoe
label: macOS

- name: AndroidPoolLinux
type: object
default:
name: MAUI-DNCENG
demands:
- ImageOverride -equals 1ESPT-Ubuntu22.04


# Condition for MacOSPool comparison lanes (non-ARM64)
# Runs on: (non-PR on main/net*.0/release/*/inflight/*) OR (PR targeting net*.0/release/*/inflight/*)
Expand Down Expand Up @@ -277,12 +284,9 @@ stages:
# TODO: macOSTemplates and AOT template categories
- name: mac_runandroid_tests
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The stage name mac_runandroid_tests is now misleading since it runs on a Linux pool. Consider renaming it to something platform-neutral (e.g., runandroid_tests) or explicitly Linux-based (e.g., linux_runandroid_tests) to avoid confusion when diagnosing CI failures.

Suggested change
- name: mac_runandroid_tests
- name: linux_runandroid_tests

Copilot uses AI. Check for mistakes.
${{ if eq(variables['Build.DefinitionName'], 'maui-pr') }}:
pool:
name: AcesShared
demands:
- ImageOverride -equals ACES_arm64_Sequoia_Xcode
pool: ${{ parameters.AndroidPoolLinux }}
${{ else }}:
pool: ${{ parameters.MacOSPool.internal }}
pool: ${{ parameters.AndroidPoolLinux }}
timeout: 240
testCategory: RunOnAndroid

Expand Down
8 changes: 1 addition & 7 deletions eng/pipelines/common/device-tests-steps.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,8 @@ steps:
continueOnError: true
timeoutInMinutes: 60

# Enable KVM for Android builds on Linux
- ${{ if and(ne(parameters.buildType, 'buildOnly'), eq(parameters.platform, 'android')) }}:
- 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'))
- template: enable-kvm.yml

# Provision the various SDKs that are needed
- template: provision.yml
Expand Down
8 changes: 8 additions & 0 deletions eng/pipelines/common/enable-kvm.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Enable KVM for Android tests on Linux
steps:
- 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'))
8 changes: 1 addition & 7 deletions eng/pipelines/common/ui-tests-steps.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,8 @@ steps:
continueOnError: true
timeoutInMinutes: 60

# Enable KVM for Android builds on Linux
- ${{ if and(ne(parameters.buildType, 'buildOnly'), eq(parameters.platform, 'android')) }}:
- 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'))
- template: enable-kvm.yml

- ${{ if eq(parameters.platform, 'catalyst')}}:
- bash: |
Expand Down
4 changes: 3 additions & 1 deletion src/DotNet/DotNet.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,9 @@
<!-- Run 'dotnet workload install' for the current running 'dotnet' install -->
<ItemGroup>
<_WorkloadSource Include="$(NugetArtifactsPath)" />
<_LocalWorkloadIds Include="maui" />
<!-- 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'))" />

<_LocalWorkloadIds Include="tizen" Condition=" '$(IncludeTizenTargetFrameworks)' == 'true' " />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using Microsoft.Maui.IntegrationTests.Android;

namespace Microsoft.Maui.IntegrationTests
Expand Down Expand Up @@ -94,6 +95,12 @@ public void RunOnAndroid(string id, string framework, string config, string? tri
Assert.True(DotnetInternal.New(id, projectDir, framework, output: _output),
$"Unable to create template {id}. Check test output for errors.");

// On Linux, only the maui-android workload is installed. Previous .NET
// templates may still include iOS/macOS TFMs causing NETSDK1178 errors
// during restore. Strip them so only Android remains.
if (TestEnvironment.IsLinux)
StripNonAndroidTfms(projectFile, framework);

var buildProps = BuildProps;
if (!string.IsNullOrEmpty(trimMode))
{
Expand Down Expand Up @@ -128,5 +135,20 @@ void AddInstrumentation(string projectDir)
"MainLauncher = true, Name = \"com.microsoft.mauitemplate.MainActivity\"");
}

static void StripNonAndroidTfms(string projectFile, string framework)
{
var content = File.ReadAllText(projectFile);
var androidTfm = $"{framework}-android";
// Remove conditional TargetFrameworks lines (iOS/macOS/Windows additions)
content = Regex.Replace(content,
@"\s*<TargetFrameworks\s+Condition=""[^""]*"">[^<]*</TargetFrameworks>",
"");
// Set the base TargetFrameworks to Android only
content = Regex.Replace(content,
@"<TargetFrameworks>[^<]*</TargetFrameworks>",
$"<TargetFrameworks>{androidTfm}</TargetFrameworks>");
File.WriteAllText(projectFile, content);
}

}
}
Loading