mirror of
https://github.com/reactivecircus/android-emulator-runner.git
synced 2026-08-31 17:49:33 +00:00
Promote using ubuntu runner with KVM. (#366)
This commit is contained in:
@@ -18,15 +18,11 @@ jobs:
|
|||||||
timeout-minutes: 15
|
timeout-minutes: 15
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [macos-latest, ubuntu-latest]
|
os: [ubuntu-latest]
|
||||||
api-level: [23, 29]
|
api-level: [23, 29]
|
||||||
target: [default, google_apis]
|
target: [default, google_apis]
|
||||||
arch: [x86]
|
arch: [x86]
|
||||||
exclude:
|
exclude:
|
||||||
- os: ubuntu-latest
|
|
||||||
api-level: 23
|
|
||||||
- os: ubuntu-latest
|
|
||||||
api-level: 29
|
|
||||||
- target: google_apis
|
- target: google_apis
|
||||||
api-level: 16
|
api-level: 16
|
||||||
- target: google_apis
|
- target: google_apis
|
||||||
@@ -34,18 +30,22 @@ jobs:
|
|||||||
- target: google_apis
|
- target: google_apis
|
||||||
api-level: 29
|
api-level: 29
|
||||||
include:
|
include:
|
||||||
- os: macos-latest
|
- os: ubuntu-latest
|
||||||
api-level: 24
|
api-level: 24
|
||||||
target: playstore
|
target: playstore
|
||||||
arch: x86
|
arch: x86
|
||||||
- os: macos-latest
|
- os: ubuntu-latest
|
||||||
api-level: 30
|
api-level: 30
|
||||||
target: aosp_atd
|
target: aosp_atd
|
||||||
arch: x86
|
arch: x86
|
||||||
- os: macos-11
|
- os: macos-latest
|
||||||
api-level: 31
|
api-level: 31
|
||||||
target: google_apis
|
target: google_apis
|
||||||
arch: x86_64
|
arch: x86_64
|
||||||
|
- os: ubuntu-latest
|
||||||
|
api-level: 34
|
||||||
|
target: aosp_atd
|
||||||
|
arch: x86_64
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: checkout
|
- name: checkout
|
||||||
@@ -64,7 +64,7 @@ jobs:
|
|||||||
- uses: actions/setup-java@v3
|
- uses: actions/setup-java@v3
|
||||||
with:
|
with:
|
||||||
distribution: 'zulu'
|
distribution: 'zulu'
|
||||||
java-version: 19
|
java-version: 21
|
||||||
|
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v3
|
||||||
id: avd-cache
|
id: avd-cache
|
||||||
@@ -81,6 +81,13 @@ jobs:
|
|||||||
build-root-directory: test-fixture
|
build-root-directory: test-fixture
|
||||||
arguments: assembleAndroidTest
|
arguments: assembleAndroidTest
|
||||||
|
|
||||||
|
- name: enable KVM for linux runners
|
||||||
|
if: runner.os == 'Linux'
|
||||||
|
run: |
|
||||||
|
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
|
||||||
|
|
||||||
- name: run emulator to generate snapshot for caching
|
- name: run emulator to generate snapshot for caching
|
||||||
if: steps.avd-cache.outputs.cache-hit != 'true'
|
if: steps.avd-cache.outputs.cache-hit != 'true'
|
||||||
uses: ./
|
uses: ./
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ on:
|
|||||||
os:
|
os:
|
||||||
description: 'OS'
|
description: 'OS'
|
||||||
required: true
|
required: true
|
||||||
default: 'macos-latest'
|
default: 'ubuntu-latest'
|
||||||
api-level:
|
api-level:
|
||||||
description: 'API level of the platform and system image'
|
description: 'API level of the platform and system image'
|
||||||
required: true
|
required: true
|
||||||
@@ -54,12 +54,19 @@ jobs:
|
|||||||
- uses: actions/setup-java@v3
|
- uses: actions/setup-java@v3
|
||||||
with:
|
with:
|
||||||
distribution: 'zulu'
|
distribution: 'zulu'
|
||||||
java-version: 19
|
java-version: 21
|
||||||
|
|
||||||
- uses: gradle/gradle-build-action@v2
|
- uses: gradle/gradle-build-action@v2
|
||||||
with:
|
with:
|
||||||
gradle-home-cache-cleanup: true
|
gradle-home-cache-cleanup: true
|
||||||
|
|
||||||
|
- name: enable KVM for linux runners
|
||||||
|
if: runner.os == 'Linux'
|
||||||
|
run: |
|
||||||
|
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
|
||||||
|
|
||||||
- name: run action
|
- name: run action
|
||||||
uses: ./
|
uses: ./
|
||||||
with:
|
with:
|
||||||
|
|||||||
@@ -4,12 +4,24 @@
|
|||||||
<a href="https://github.com/ReactiveCircus/android-emulator-runner"><img alt="GitHub Actions status" src="https://github.com/ReactiveCircus/android-emulator-runner/workflows/Main%20workflow/badge.svg"></a>
|
<a href="https://github.com/ReactiveCircus/android-emulator-runner"><img alt="GitHub Actions status" src="https://github.com/ReactiveCircus/android-emulator-runner/workflows/Main%20workflow/badge.svg"></a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
A GitHub Action for installing, configuring and running hardware-accelerated Android Emulators on macOS virtual machines.
|
A GitHub Action for installing, configuring and running hardware-accelerated Android Emulators on Linux and macOS virtual machines.
|
||||||
|
|
||||||
The old ARM-based emulators were slow and are no longer supported by Google. The modern Intel Atom (x86 and x86_64) emulators can be fast, but rely on two forms of hardware acceleration to reach their peak potential: [Graphics Acceleration](https://developer.android.com/studio/run/emulator-acceleration#accel-graphics), e.g. `emulator -gpu host` and [Virtual Machine(VM) Acceleration](https://developer.android.com/studio/run/emulator-acceleration#accel-vm), e.g. `emulator -accel on`. **Note:** GPU and VM Acceleration are two different and non-mutually exclusive forms of Hardware Acceleration.
|
The old ARM-based emulators were slow and are no longer supported by Google. The modern Intel Atom (x86 and x86_64) emulators can be fast, but rely on two forms of hardware acceleration to reach their peak potential: [Graphics Acceleration](https://developer.android.com/studio/run/emulator-acceleration#accel-graphics), e.g. `emulator -gpu host` and [Virtual Machine(VM) Acceleration](https://developer.android.com/studio/run/emulator-acceleration#accel-vm), e.g. `emulator -accel on`. **Note:** GPU and VM Acceleration are two different and non-mutually exclusive forms of Hardware Acceleration.
|
||||||
|
|
||||||
This presents a challenge when running emulators on CI especially when running emulators within a docker container, because **Nested Virtualization** must be supported by the host VM which isn't the case for most cloud-based CI providers due to infrastructural limits. If you want to learn more about Emulators on CI, here's an article [Yang](https://github.com/ychescale9) wrote: [Running Android Instrumented Tests on CI](https://dev.to/ychescale9/running-android-emulators-on-ci-from-bitrise-io-to-github-actions-3j76).
|
This presents a challenge when running emulators on CI especially when running emulators within a docker container, because **Nested Virtualization** must be supported by the host VM which isn't the case for most cloud-based CI providers due to infrastructural limits. If you want to learn more about Emulators on CI, here's an article [Yang](https://github.com/ychescale9) wrote: [Running Android Instrumented Tests on CI](https://dev.to/ychescale9/running-android-emulators-on-ci-from-bitrise-io-to-github-actions-3j76).
|
||||||
|
|
||||||
|
## Running hardware accelerated emulators on Linux runners
|
||||||
|
|
||||||
|
GitHub's [larger Linux runners support running hardware accelerated emulators](https://github.blog/changelog/2023-02-23-hardware-accelerated-android-virtualization-on-actions-windows-and-linux-larger-hosted-runners/) which is [free for public GitHub repos](https://github.blog/2024-01-17-github-hosted-runners-double-the-power-for-open-source/). It is now recommended to use the **Ubuntu** (`ubuntu-latest`) runners which are 2-3 times faster than the **macOS** ones which are also a lot more expensive. Remember to enable KVM in your workflow before running this action:
|
||||||
|
|
||||||
|
```
|
||||||
|
- name: Enable KVM group perms
|
||||||
|
run: |
|
||||||
|
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
|
||||||
|
```
|
||||||
|
|
||||||
## A note on VM Acceleration and why we don't need HAXM anymore
|
## A note on VM Acceleration and why we don't need HAXM anymore
|
||||||
|
|
||||||
According to [this documentation](https://developer.android.com/studio/run/emulator-acceleration#vm-mac), "on Mac OS X v10.10 Yosemite and higher, the Android Emulator uses the built-in [Hypervisor.Framework](https://developer.apple.com/documentation/hypervisor) by default, and falls back to using Intel HAXM if Hypervisor.Framework fails to initialize." This means that **HAXM is only needed to achieve VM Acceleration if this default Hypervisor is not available on macOS machines.**
|
According to [this documentation](https://developer.android.com/studio/run/emulator-acceleration#vm-mac), "on Mac OS X v10.10 Yosemite and higher, the Android Emulator uses the built-in [Hypervisor.Framework](https://developer.apple.com/documentation/hypervisor) by default, and falls back to using Intel HAXM if Hypervisor.Framework fails to initialize." This means that **HAXM is only needed to achieve VM Acceleration if this default Hypervisor is not available on macOS machines.**
|
||||||
@@ -34,11 +46,17 @@ A workflow that uses **android-emulator-runner** to run your instrumented tests
|
|||||||
```yml
|
```yml
|
||||||
jobs:
|
jobs:
|
||||||
test:
|
test:
|
||||||
runs-on: macos-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: checkout
|
- name: checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Enable KVM
|
||||||
|
run: |
|
||||||
|
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
|
||||||
|
|
||||||
- name: run tests
|
- name: run tests
|
||||||
uses: reactivecircus/android-emulator-runner@v2
|
uses: reactivecircus/android-emulator-runner@v2
|
||||||
with:
|
with:
|
||||||
@@ -51,7 +69,7 @@ We can also leverage GitHub Actions's build matrix to test across multiple confi
|
|||||||
```yml
|
```yml
|
||||||
jobs:
|
jobs:
|
||||||
test:
|
test:
|
||||||
runs-on: macos-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
api-level: [21, 23, 29]
|
api-level: [21, 23, 29]
|
||||||
@@ -60,6 +78,12 @@ jobs:
|
|||||||
- name: checkout
|
- name: checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Enable KVM
|
||||||
|
run: |
|
||||||
|
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
|
||||||
|
|
||||||
- name: run tests
|
- name: run tests
|
||||||
uses: reactivecircus/android-emulator-runner@v2
|
uses: reactivecircus/android-emulator-runner@v2
|
||||||
with:
|
with:
|
||||||
@@ -75,11 +99,17 @@ If you need specific versions of **NDK** and **CMake** installed:
|
|||||||
```yml
|
```yml
|
||||||
jobs:
|
jobs:
|
||||||
test:
|
test:
|
||||||
runs-on: macos-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: checkout
|
- name: checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Enable KVM
|
||||||
|
run: |
|
||||||
|
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
|
||||||
|
|
||||||
- name: run tests
|
- name: run tests
|
||||||
uses: reactivecircus/android-emulator-runner@v2
|
uses: reactivecircus/android-emulator-runner@v2
|
||||||
with:
|
with:
|
||||||
@@ -99,7 +129,7 @@ We can significantly reduce emulator startup time by setting up AVD snapshot cac
|
|||||||
```yml
|
```yml
|
||||||
jobs:
|
jobs:
|
||||||
test:
|
test:
|
||||||
runs-on: macos-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
api-level: [21, 23, 29]
|
api-level: [21, 23, 29]
|
||||||
@@ -107,6 +137,12 @@ jobs:
|
|||||||
- name: checkout
|
- name: checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Enable KVM
|
||||||
|
run: |
|
||||||
|
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
|
||||||
|
|
||||||
- name: Gradle cache
|
- name: Gradle cache
|
||||||
uses: gradle/gradle-build-action@v2
|
uses: gradle/gradle-build-action@v2
|
||||||
|
|
||||||
@@ -170,12 +206,6 @@ jobs:
|
|||||||
|
|
||||||
Default `emulator-options`: `-no-window -gpu swiftshader_indirect -no-snapshot -noaudio -no-boot-anim`.
|
Default `emulator-options`: `-no-window -gpu swiftshader_indirect -no-snapshot -noaudio -no-boot-anim`.
|
||||||
|
|
||||||
## Can I use this action on Github Hosted Linux VMs?
|
|
||||||
|
|
||||||
The short answer is yes but on Github-hosted Linux runners it's expected to be a much worse experience (on some newer API levels it might not work at all) than running it on macOS, because of the current lack of hardware acceleration support. You can get it running much faster on self-hosted Linux runners but only if the underlying instances support KVM (which most don't). Things might be better on the newer Larger runners but they are still in Beta. It is possible to use this Action with hardware accelerated Linux VMs hosted by a third-party runner provider.
|
|
||||||
|
|
||||||
For a longer answer please refer to [this issue](https://github.com/ReactiveCircus/android-emulator-runner/issues/46).
|
|
||||||
|
|
||||||
## Who is using Android Emulator Runner?
|
## Who is using Android Emulator Runner?
|
||||||
|
|
||||||
These are some of the open-source projects using (or used) **Android Emulator Runner**:
|
These are some of the open-source projects using (or used) **Android Emulator Runner**:
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
name: 'Android Emulator Runner'
|
name: 'Android Emulator Runner'
|
||||||
description: 'Installs, configures and starts an Android Emulator directly on macOS virtual machines.'
|
description: 'Installs, configures and starts an Android Emulator directly on hardware-accelerated runners.'
|
||||||
author: 'Reactive Circus'
|
author: 'Reactive Circus'
|
||||||
branding:
|
branding:
|
||||||
icon: 'smartphone'
|
icon: 'smartphone'
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ function launchEmulator(apiLevel, target, arch, profile, cores, ramSize, heapSiz
|
|||||||
if (diskSize) {
|
if (diskSize) {
|
||||||
yield exec.exec(`sh -c \\"printf 'disk.dataPartition.size=${diskSize}\n' >> ${process.env.ANDROID_AVD_HOME}/"${avdName}".avd"/config.ini`);
|
yield exec.exec(`sh -c \\"printf 'disk.dataPartition.size=${diskSize}\n' >> ${process.env.ANDROID_AVD_HOME}/"${avdName}".avd"/config.ini`);
|
||||||
}
|
}
|
||||||
//turn off hardware acceleration on Linux
|
// turn off hardware acceleration on Linux
|
||||||
if (process.platform === 'linux' && disableLinuxHardwareAcceleration) {
|
if (process.platform === 'linux' && disableLinuxHardwareAcceleration) {
|
||||||
console.log('Disabling Linux hardware acceleration.');
|
console.log('Disabling Linux hardware acceleration.');
|
||||||
emulatorOptions += ' -accel off';
|
emulatorOptions += ' -accel off';
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
"name": "android-emulator-runner",
|
"name": "android-emulator-runner",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"description": "A GitHub Action for installing, configuring and running Android Emulators on macOS virtual machines.",
|
"description": "A GitHub Action for installing, configuring and running Android Emulators on hardware-accelerated runners.",
|
||||||
"main": "lib/main.js",
|
"main": "lib/main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc",
|
"build": "tsc",
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ export async function launchEmulator(
|
|||||||
await exec.exec(`sh -c \\"printf 'disk.dataPartition.size=${diskSize}\n' >> ${process.env.ANDROID_AVD_HOME}/"${avdName}".avd"/config.ini`);
|
await exec.exec(`sh -c \\"printf 'disk.dataPartition.size=${diskSize}\n' >> ${process.env.ANDROID_AVD_HOME}/"${avdName}".avd"/config.ini`);
|
||||||
}
|
}
|
||||||
|
|
||||||
//turn off hardware acceleration on Linux
|
// turn off hardware acceleration on Linux
|
||||||
if (process.platform === 'linux' && disableLinuxHardwareAcceleration) {
|
if (process.platform === 'linux' && disableLinuxHardwareAcceleration) {
|
||||||
console.log('Disabling Linux hardware acceleration.');
|
console.log('Disabling Linux hardware acceleration.');
|
||||||
emulatorOptions += ' -accel off';
|
emulatorOptions += ' -accel off';
|
||||||
|
|||||||
Reference in New Issue
Block a user