Skip to content

Commit 50986b1

Browse files
committed
Merge branch 'main' into release/v2
* main: Prepare for release 2.27.0. Clean up action description. Update dependencies (ReactiveCircus#282) Update Readme & Provide current context on Hardware Acceleration on Github (ReactiveCircus#279) Pre Emulator Launch Script (ReactiveCircus#247) Update to Node 16 (ReactiveCircus#276)
2 parents d7b53dd + 87e9722 commit 50986b1

File tree

153 files changed

+8012
-18205
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

153 files changed

+8012
-18205
lines changed

.eslintrc.json

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,6 @@
55
"es6": true
66
},
77
"extends": [
8-
"eslint:recommended",
9-
"plugin:@typescript-eslint/recommended",
10-
"prettier/@typescript-eslint",
118
"plugin:prettier/recommended"
129
],
1310
"globals": {

.github/workflows/main.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
name: Main workflow
22
on:
3+
workflow_call:
34
pull_request:
45
paths-ignore:
56
- '**.md'
@@ -114,6 +115,9 @@ jobs:
114115
disable-animations: true
115116
working-directory: ./test-fixture/
116117
channel: canary
118+
pre-emulator-launch-script: |
119+
echo "Running pre emulator launch script. Printing the working directory now:"
120+
pwd
117121
script: |
118122
echo $GITHUB_REPOSITORY
119123
adb devices

.github/workflows/pr-comment.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
name: Re-Run Tests on PR Comment Workflow
2+
on:
3+
issue_comment:
4+
types: [created]
5+
6+
jobs:
7+
rerun-tests-job:
8+
if: github.event.issue.pull_request && contains(github.event.comment.body, 'run tests') # if comment is created on a PR, can also use the syntax if: contains(github.event.comment.html_url, '/pull/')
9+
uses: ./.github/workflows/main.yml

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
# Change Log
22

3+
## v2.27.0
4+
5+
* Added `pre-emulator-launch-script` to support running script after creating the AVD and before launching the emulator. - [#247](https://github.com/ReactiveCircus/android-emulator-runner/pull/247) @nilsreichardt.
6+
* Update to Node 16. - [#276](https://github.com/ReactiveCircus/android-emulator-runner/pull/276) @mattjohnsonpint.
7+
* Update NPM dependencies. - [#282](https://github.com/ReactiveCircus/android-emulator-runner/pull/282) @mattjohnsonpint.
8+
* Update README with more context on hardware acceleration on GitHub hosted runners. - [#279](https://github.com/ReactiveCircus/android-emulator-runner/pull/279) @mrk-han.
9+
10+
311
## v2.26.0
412

513
* Support [github-actions-typing](https://github.com/krzema12/github-actions-typing). - [#257](https://github.com/ReactiveCircus/android-emulator-runner/pull/257) @LeoColman.

README.md

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,21 @@
66

77
A GitHub Action for installing, configuring and running hardware-accelerated Android Emulators on macOS virtual machines.
88

9-
The old ARM-based emulators were slow and are no longer supported by Google. The modern Intel Atom (x86 and x86_64) emulators require hardware acceleration (HAXM on Mac & Windows, QEMU on Linux) from the host to run fast. This presents a challenge on CI as to be able to run hardware accelerated emulators within a docker container, **KVM** must be supported by the host VM which isn't the case for cloud-based CI providers due to infrastructural limits. If you want to learn more about this, here's an article I wrote: [Running Android Instrumented Tests on CI](https://dev.to/ychescale9/running-android-emulators-on-ci-from-bitrise-io-to-github-actions-3j76).
9+
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.
1010

11-
The **macOS** VM provided by **GitHub Actions** has **HAXM** installed so we are able to create a new AVD instance, launch an emulator with hardware acceleration, and run our Android
12-
tests directly on the VM. You can also achieve this on a self-hosted Linux runner, but it will need to be on a compatible instance that allows you to enable KVM - for example AWS EC2 Bare Metal instances.
11+
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).
1312

14-
This action automates the process by doing the following:
13+
## HAXM support on Github's MacOS Runners
14+
15+
The 10.x **macOS** VM provided by **GitHub Actions** had **HAXM** [pre-installed](https://github.com/actions/runner-images/blob/main/images/macos/macos-10.15-Readme.md). However, Github's [macOS-11](https://github.com/actions/runner-images/blob/main/images/macos/macos-11-Readme.md) and [macOS-12](https://github.com/actions/runner-images/blob/main/images/macos/macos-12-Readme.md) VMs **no longer** come pre-installed with HAXM. See [here](https://github.com/actions/runner-images/issues/183#issuecomment-610723516) and [here](https://github.com/actions/runner-images/issues/6388) for more info.
16+
17+
**To run with HAXM on the macOS-11 and macOS-12 agents, you must install HAXM before starting your emulator**. See: [this snippet](https://gist.github.com/mrk-han/a0a11ed9bed966bb8b775ff55f2a87e9) for more info. This will enable VM acceleration, but as of right now running with GPU acceleration, e.g. `emulator -gpu host` is not possible with Github's standard runners.
18+
19+
For Linux, Nested virtualization is possible on a self-hosted or 3rd party runner, but the VM will need to be hosted on a compatible machine that allows you to [enable KVM](https://developer.android.com/studio/run/emulator-acceleration#vm-linux), or is already configured with - for example the AWS EC2 Bare Metal instances. **The Github-hosted Linux runners are not currently KVM compatible.**
20+
21+
## Purpose
22+
23+
This action helps automate and configure the process of setting up an emulator and running your tests by doing the following:
1524

1625
- Install / update the required **Android SDK** components including `build-tools`, `platform-tools`, `platform` (for the required API level), `emulator` and `system-images` (for the required API level).
1726
- Create a new instance of **AVD** with the provided [configurations](#configurations).
@@ -20,9 +29,7 @@ This action automates the process by doing the following:
2029
- Run a custom script provided by user once the Emulator is up and running - e.g. `./gradlew connectedCheck`.
2130
- Kill the Emulator and finish the action.
2231

23-
## Usage
24-
25-
It is recommended to run this action on a **macOS** VM, e.g. `macos-latest`, `macos-10.15` or `macos-11` to take advantage of hardware acceleration support provided by **HAXM**.
32+
## Usage & Examples
2633

2734
A workflow that uses **android-emulator-runner** to run your instrumented tests on **API 29**:
2835

@@ -146,7 +153,7 @@ jobs:
146153
| `ram-size` | Optional | N/A | Size of RAM to use for this AVD, in KB or MB, denoted with K or M. - e.g. `2048M` |
147154
| `heap-size` | Optional | N/A | Heap size to use for this AVD, in KB or MB, denoted with K or M. - e.g. `512M` |
148155
| `sdcard-path-or-size` | Optional | N/A | Path to the SD card image for this AVD or the size of a new SD card image to create for this AVD, in KB or MB, denoted with K or M. - e.g. `path/to/sdcard`, or `1000M`. |
149-
| `disk-size` | Optional | N/A | Disk size to use for this AVD. Either in bytes or KB, MB or GB, when denoted with K, M or G. - e.g. `2048M` |
156+
| `disk-size` | Optional | N/A | Disk size, or partition size to use for this AVD. Either in bytes or KB, MB or GB, when denoted with K, M or G. - e.g. `2048M` |
150157
| `avd-name` | Optional | `test` | Custom AVD name used for creating the Android Virtual Device. |
151158
| `force-avd-creation` | Optional | `true` | Whether to force create the AVD by overwriting an existing AVD with the same name as `avd-name` - `true` or `false`. |
152159
| `emulator-options` | Optional | See below | Command-line options used when launching the emulator (replacing all default options) - e.g. `-no-window -no-snapshot -camera-back emulated`. |
@@ -155,21 +162,21 @@ jobs:
155162
| `disable-linux-hw-accel` | Optional | `auto` | Whether to disable hardware acceleration on Linux machines - `true`, `false` or `auto`.|
156163
| `enable-hw-keyboard` | Optional | `false` | Whether to enable hardware keyboard - `true` or `false`. |
157164
| `emulator-build` | Optional | N/A | Build number of a specific version of the emulator binary to use e.g. `6061023` for emulator v29.3.0.0. |
158-
| `working-directory` | Optional | `./` | A custom working directory - e.g. `./android` if your root Gradle project is under the `./android` sub-directory within your repository. |
165+
| `working-directory` | Optional | `./` | A custom working directory - e.g. `./android` if your root Gradle project is under the `./android` sub-directory within your repository. Will be used for `script` & `pre-emulator-launch-script`. |
159166
| `ndk` | Optional | N/A | Version of NDK to install - e.g. `21.0.6113669` |
160167
| `cmake` | Optional | N/A | Version of CMake to install - e.g. `3.10.2.4988404` |
161168
| `channel` | Optional | stable | Channel to download the SDK components from - `stable`, `beta`, `dev`, `canary` |
162169
| `script` | Required | N/A | Custom script to run - e.g. to run Android instrumented tests on the emulator: `./gradlew connectedCheck` |
170+
| `pre-emulator-launch-script` | Optional | N/A | Custom script to run after creating the AVD and before launching the emulator - e.g. `./adjust-emulator-configs.sh` |
163171

164172
Default `emulator-options`: `-no-window -gpu swiftshader_indirect -no-snapshot -noaudio -no-boot-anim`.
165173

166-
## Can I use this action on Linux VMs?
174+
## Can I use this action on Github Hosted Linux VMs?
167175

168-
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. You can get it running much faster on self-hosted Linux runners but only if the underlying instances support KVM (which most don't).
176+
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.
169177

170178
For a longer answer please refer to [this issue](https://github.com/ReactiveCircus/android-emulator-runner/issues/46).
171179

172-
173180
## Who is using Android Emulator Runner?
174181

175182
These are some of the open-source projects using (or used) **Android Emulator Runner**:
@@ -204,4 +211,4 @@ These are some of the open-source projects using (or used) **Android Emulator Ru
204211
- [tinylog-org/tinylog](https://github.com/tinylog-org/tinylog/blob/v3.0/.github/workflows/build.yaml)
205212
- [hzi-braunschweig/SORMAS-Project](https://github.com/hzi-braunschweig/SORMAS-Project/blob/development/.github/workflows/sormas_app_ci.yml)
206213

207-
If you are using **Android Emulator Runner** and want your project included in the list, please feel free to create an issue or open a pull request.
214+
If you are using **Android Emulator Runner** and want your project included in the list, please feel free to open a pull request.

action-types.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,3 +62,5 @@ inputs:
6262
- canary
6363
script:
6464
type: string
65+
pre-emulator-launch-script:
66+
type: string

action.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ inputs:
4040
description: 'whether to disable animations - true or false'
4141
default: 'true'
4242
disable-spellchecker:
43-
description: 'whether to disable spellchecker - `true` or `false`'
43+
description: 'whether to disable the Android spell checker framework, a common source of flakiness in text fields - `true` or `false`'
4444
default: 'false'
4545
disable-linux-hw-accel:
4646
description: 'whether to disable hardware acceleration on Linux machines - `true` or `false` or `auto`'
@@ -62,6 +62,8 @@ inputs:
6262
script:
6363
description: 'custom script to run - e.g. `./gradlew connectedCheck`'
6464
required: true
65+
pre-emulator-launch-script:
66+
description: 'custom script to run after creating the AVD and before launching the emulator - e.g. `./adjust-emulator-configs.sh`'
6567
runs:
66-
using: 'node12'
68+
using: 'node16'
6769
main: 'lib/main.js'

lib/emulator-manager.js

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
"use strict";
22
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
33
if (k2 === undefined) k2 = k;
4-
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
4+
var desc = Object.getOwnPropertyDescriptor(m, k);
5+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6+
desc = { enumerable: true, get: function() { return m[k]; } };
7+
}
8+
Object.defineProperty(o, k2, desc);
59
}) : (function(o, m, k, k2) {
610
if (k2 === undefined) k2 = k;
711
o[k2] = m[k];
@@ -14,7 +18,7 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
1418
var __importStar = (this && this.__importStar) || function (mod) {
1519
if (mod && mod.__esModule) return mod;
1620
var result = {};
17-
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
21+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
1822
__setModuleDefault(result, mod);
1923
return result;
2024
};
@@ -75,8 +79,8 @@ function launchEmulator(apiLevel, target, arch, profile, cores, ramSize, heapSiz
7579
if (data.toString().includes('invalid command-line parameter')) {
7680
throw new Error(data.toString());
7781
}
78-
}
79-
}
82+
},
83+
},
8084
});
8185
// wait for emulator to complete booting
8286
yield waitForDevice();
@@ -110,7 +114,7 @@ function killEmulator() {
110114
yield exec.exec(`adb -s emulator-5554 emu kill`);
111115
}
112116
catch (error) {
113-
console.log(error.message);
117+
console.log(error instanceof Error ? error.message : error);
114118
}
115119
finally {
116120
console.log(`::endgroup::`);
@@ -134,8 +138,8 @@ function waitForDevice() {
134138
listeners: {
135139
stdout: (data) => {
136140
result += data.toString();
137-
}
138-
}
141+
},
142+
},
139143
});
140144
if (result.trim() === '1') {
141145
console.log('Emulator booted.');
@@ -144,7 +148,7 @@ function waitForDevice() {
144148
}
145149
}
146150
catch (error) {
147-
console.warn(error.message);
151+
console.warn(error instanceof Error ? error.message : error);
148152
}
149153
if (attempts < maxAttempts) {
150154
yield delay(retryInterval * 1000);
@@ -157,5 +161,5 @@ function waitForDevice() {
157161
});
158162
}
159163
function delay(ms) {
160-
return new Promise(resolve => setTimeout(resolve, ms));
164+
return new Promise((resolve) => setTimeout(resolve, ms));
161165
}

0 commit comments

Comments
 (0)