From c479bb6c0fb05202bee9d2725ad6ffae158bf815 Mon Sep 17 00:00:00 2001 From: Yang Date: Fri, 19 Jan 2024 17:38:35 +1100 Subject: [PATCH 1/4] Promote using ubuntu runner with KVM. (#366) --- .github/workflows/main.yml | 25 ++++++++++------ .github/workflows/manually.yml | 11 +++++-- README.md | 52 +++++++++++++++++++++++++++------- action.yml | 2 +- lib/emulator-manager.js | 2 +- package.json | 2 +- src/emulator-manager.ts | 2 +- 7 files changed, 70 insertions(+), 26 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 95072bd62..43170a6b6 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -18,15 +18,11 @@ jobs: timeout-minutes: 15 strategy: matrix: - os: [macos-latest, ubuntu-latest] + os: [ubuntu-latest] api-level: [23, 29] target: [default, google_apis] arch: [x86] exclude: - - os: ubuntu-latest - api-level: 23 - - os: ubuntu-latest - api-level: 29 - target: google_apis api-level: 16 - target: google_apis @@ -34,18 +30,22 @@ jobs: - target: google_apis api-level: 29 include: - - os: macos-latest + - os: ubuntu-latest api-level: 24 target: playstore arch: x86 - - os: macos-latest + - os: ubuntu-latest api-level: 30 target: aosp_atd arch: x86 - - os: macos-11 + - os: macos-latest api-level: 31 target: google_apis arch: x86_64 + - os: ubuntu-latest + api-level: 34 + target: aosp_atd + arch: x86_64 steps: - name: checkout @@ -64,7 +64,7 @@ jobs: - uses: actions/setup-java@v3 with: distribution: 'zulu' - java-version: 19 + java-version: 21 - uses: actions/cache@v3 id: avd-cache @@ -81,6 +81,13 @@ jobs: build-root-directory: test-fixture 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 if: steps.avd-cache.outputs.cache-hit != 'true' uses: ./ diff --git a/.github/workflows/manually.yml b/.github/workflows/manually.yml index 33d3b39e2..753b86a59 100644 --- a/.github/workflows/manually.yml +++ b/.github/workflows/manually.yml @@ -5,7 +5,7 @@ on: os: description: 'OS' required: true - default: 'macos-latest' + default: 'ubuntu-latest' api-level: description: 'API level of the platform and system image' required: true @@ -54,12 +54,19 @@ jobs: - uses: actions/setup-java@v3 with: distribution: 'zulu' - java-version: 19 + java-version: 21 - uses: gradle/gradle-build-action@v2 with: 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 uses: ./ with: diff --git a/README.md b/README.md index 2a4aab44b..5b0583da3 100644 --- a/README.md +++ b/README.md @@ -4,12 +4,24 @@ GitHub Actions status

-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. 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 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 jobs: test: - runs-on: macos-latest + runs-on: ubuntu-latest steps: - name: checkout 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 uses: reactivecircus/android-emulator-runner@v2 with: @@ -51,7 +69,7 @@ We can also leverage GitHub Actions's build matrix to test across multiple confi ```yml jobs: test: - runs-on: macos-latest + runs-on: ubuntu-latest strategy: matrix: api-level: [21, 23, 29] @@ -60,6 +78,12 @@ jobs: - name: checkout 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 uses: reactivecircus/android-emulator-runner@v2 with: @@ -75,11 +99,17 @@ If you need specific versions of **NDK** and **CMake** installed: ```yml jobs: test: - runs-on: macos-latest + runs-on: ubuntu-latest steps: - name: checkout 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 uses: reactivecircus/android-emulator-runner@v2 with: @@ -99,7 +129,7 @@ We can significantly reduce emulator startup time by setting up AVD snapshot cac ```yml jobs: test: - runs-on: macos-latest + runs-on: ubuntu-latest strategy: matrix: api-level: [21, 23, 29] @@ -107,6 +137,12 @@ jobs: - name: checkout 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 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`. -## 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? These are some of the open-source projects using (or used) **Android Emulator Runner**: diff --git a/action.yml b/action.yml index a988b3712..edb0a381b 100644 --- a/action.yml +++ b/action.yml @@ -1,5 +1,5 @@ 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' branding: icon: 'smartphone' diff --git a/lib/emulator-manager.js b/lib/emulator-manager.js index 97b4a435b..5225a189b 100644 --- a/lib/emulator-manager.js +++ b/lib/emulator-manager.js @@ -65,7 +65,7 @@ function launchEmulator(apiLevel, target, arch, profile, cores, ramSize, heapSiz if (diskSize) { 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) { console.log('Disabling Linux hardware acceleration.'); emulatorOptions += ' -accel off'; diff --git a/package.json b/package.json index 917f20943..3fa61c52b 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "android-emulator-runner", "version": "0.0.0", "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", "scripts": { "build": "tsc", diff --git a/src/emulator-manager.ts b/src/emulator-manager.ts index 4f6910472..d1fb364f8 100644 --- a/src/emulator-manager.ts +++ b/src/emulator-manager.ts @@ -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`); } - //turn off hardware acceleration on Linux + // turn off hardware acceleration on Linux if (process.platform === 'linux' && disableLinuxHardwareAcceleration) { console.log('Disabling Linux hardware acceleration.'); emulatorOptions += ' -accel off'; From 1e33853aad84a7bfdae06fdde14c08704833e7ef Mon Sep 17 00:00:00 2001 From: utzcoz <43091780+utzcoz@users.noreply.github.com> Date: Sat, 20 Jan 2024 13:43:05 +0800 Subject: [PATCH 2/4] Add another user: robolectric/robolectric (#352) Signed-off-by: utzcoz --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 5b0583da3..d1b1871f5 100644 --- a/README.md +++ b/README.md @@ -241,5 +241,6 @@ These are some of the open-source projects using (or used) **Android Emulator Ru - [hzi-braunschweig/SORMAS-Project](https://github.com/hzi-braunschweig/SORMAS-Project/blob/development/.github/workflows/sormas_app_ci.yml) - [ACRA/acra](https://github.com/ACRA/acra/blob/master/.github/workflows/test.yml) - [bitfireAT/davx5-ose](https://github.com/bitfireAT/davx5-ose/blob/dev-ose/.github/workflows/test-dev.yml) +- [robolectric/robolectric](https://github.com/robolectric/robolectric/blob/master/.github/workflows/tests.yml) If you are using **Android Emulator Runner** and want your project included in the list, please feel free to open a pull request. From e1bd48ca1d1d9244397d237f5cd315dcad66b482 Mon Sep 17 00:00:00 2001 From: Yang Date: Thu, 25 Jan 2024 23:10:17 +1100 Subject: [PATCH 3/4] Node 20. (#369) --- package-lock.json | 39 ++++++++++++++++++++++++++++++--------- package.json | 5 ++++- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index ca831d0bc..7e590dcbc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,7 +17,7 @@ }, "devDependencies": { "@types/jest": "^29.2.0", - "@types/node": "^16.18.2", + "@types/node": "^20.11.0", "@typescript-eslint/eslint-plugin": "^5.41.0", "@typescript-eslint/parser": "^5.41.0", "eslint": "^8.26.0", @@ -29,6 +29,9 @@ "prettier": "^2.7.1", "ts-jest": "^29.0.3", "typescript": "^4.8.4" + }, + "engines": { + "node": ">=20" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -1421,10 +1424,13 @@ "dev": true }, "node_modules/@types/node": { - "version": "16.18.43", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.43.tgz", - "integrity": "sha512-YFpgPKPRcwYbeNOimfu70B+TVJe6tr88WiW/TzEldkwGxQXrmabpU+lDjrFlNqdqIi3ON0o69EQBW62VH4MIxw==", - "dev": true + "version": "20.11.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.6.tgz", + "integrity": "sha512-+EOokTnksGVgip2PbYbr3xnR7kZigh4LbybAfBAw5BpnQ+FqBYUsvCEjYd70IXKlbohQ64mzEYmMtlWUY8q//Q==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } }, "node_modules/@types/semver": { "version": "7.5.0", @@ -5998,6 +6004,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, "node_modules/update-browserslist-db": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", @@ -7317,10 +7329,13 @@ "dev": true }, "@types/node": { - "version": "16.18.43", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.43.tgz", - "integrity": "sha512-YFpgPKPRcwYbeNOimfu70B+TVJe6tr88WiW/TzEldkwGxQXrmabpU+lDjrFlNqdqIi3ON0o69EQBW62VH4MIxw==", - "dev": true + "version": "20.11.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.6.tgz", + "integrity": "sha512-+EOokTnksGVgip2PbYbr3xnR7kZigh4LbybAfBAw5BpnQ+FqBYUsvCEjYd70IXKlbohQ64mzEYmMtlWUY8q//Q==", + "dev": true, + "requires": { + "undici-types": "~5.26.4" + } }, "@types/semver": { "version": "7.5.0", @@ -10606,6 +10621,12 @@ "which-boxed-primitive": "^1.0.2" } }, + "undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, "update-browserslist-db": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", diff --git a/package.json b/package.json index 3fa61c52b..aa3f392a9 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,9 @@ "node", "setup" ], + "engines": { + "node": ">=20" + }, "author": "Reactive Circus", "license": "MIT", "dependencies": { @@ -29,7 +32,7 @@ }, "devDependencies": { "@types/jest": "^29.2.0", - "@types/node": "^16.18.2", + "@types/node": "^20.11.0", "@typescript-eslint/eslint-plugin": "^5.41.0", "@typescript-eslint/parser": "^5.41.0", "eslint": "^8.26.0", From 426fbd28207a4699c31e2ebca40a78c7182c4968 Mon Sep 17 00:00:00 2001 From: Yang Date: Thu, 25 Jan 2024 23:14:27 +1100 Subject: [PATCH 4/4] Prepare for release 2.30.0. --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bcc80f5a1..0cceeafd6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Change Log +## v2.30.0 + +* Update to Node 20. - [#369](https://github.com/ReactiveCircus/android-emulator-runner/pull/369) + ## v2.29.0 * Fixed emulator download URL. - [#343](https://github.com/ReactiveCircus/android-emulator-runner/pull/343)