Skip to content

Commit 599839e

Browse files
committed
Merge branch 'main' into release/v2
* main: Prepare for release 2.16.0. Add support for arm64-v8a for Apple Silicon Macs Add option to disable spellcheck Bump y18n from 4.0.0 to 4.0.1 Update README.md Add google/android-fhir to the list of projects that use android-emulator-runner (ReactiveCircus#132) Add Wikipedia app to list of projects. Add kiwix-android to the list of projects Avoid Wrapping Script Code In Quotes
2 parents d279995 + 751bef6 commit 599839e

File tree

11 files changed

+94
-19
lines changed

11 files changed

+94
-19
lines changed

CHANGELOG.md

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

3+
## v2.16.0
4+
5+
* Avoid wrapping script code in quotes - [#134](https://github.com/ReactiveCircus/android-emulator-runner/pull/134) @hostilefork
6+
* Add option to disable spellcheck - [#143](https://github.com/ReactiveCircus/android-emulator-runner/pull/143) @AfzalivE
7+
* Add support for arm64-v8a for Apple Silicon Macs - [#146](https://github.com/ReactiveCircus/android-emulator-runner/pull/146) @Jeehut
8+
39
## v2.15.0
410

511
* Added support for specifying the number of cores to use for the emulator - [#130](https://github.com/ReactiveCircus/android-emulator-runner/pull/130).

README.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ A GitHub Action for installing, configuring and running hardware-accelerated And
88

99
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).
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
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
1212
tests directly on the VM.
1313

1414
This action automates the process by doing the following:
@@ -90,13 +90,14 @@ jobs:
9090
|-|-|-|-|
9191
| `api-level` | Required | N/A | API level of the platform system image - e.g. 23 for Android Marshmallow, 29 for Android 10. **Minimum API level supported is 15**. |
9292
| `target` | Optional | `default` | Target of the system image - `default`, `google_apis` or `playstore`. |
93-
| `arch` | Optional | `x86` | CPU architecture of the system image - `x86` or `x86_64`. Note that `x86_64` image is only available for API 21+. |
93+
| `arch` | Optional | `x86` | CPU architecture of the system image - `x86`, `x86_64` or `arm64-v8a`. Note that `x86_64` image is only available for API 21+. `arm64-v8a` images require Android 4.2+ and are limited to fewer API levels (e.g. 30). |
9494
| `profile` | Optional | N/A | Hardware profile used for creating the AVD - e.g. `Nexus 6`. For a list of all profiles available, run `avdmanager list` and refer to the results under "Available Android Virtual Devices". |
9595
| `cores` | Optional | 2 | Number of cores to use for the emulator (`hw.cpu.ncore` in config.ini). |
9696
| `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`. |
9797
| `avd-name` | Optional | `test` | Custom AVD name used for creating the Android Virtual Device. |
9898
| `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`. |
9999
| `disable-animations` | Optional | `true` | Whether to disable animations - `true` or `false`. |
100+
| `disable-spellchecker` | Optional | `false` | Whether to disable spellchecker - `true` or `false`. |
100101
| `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. |
101102
| `working-directory` | Optional | `./` | A custom working directory - e.g. `./android` if your root Gradle project is under the `./android` sub-directory within your repository. |
102103
| `ndk` | Optional | N/A | Version of NDK to install - e.g. `21.0.6113669` |
@@ -138,5 +139,8 @@ These are some of the open-source projects using (or used) **Android Emulator Ru
138139
- [square/leakcanary](https://github.com/square/leakcanary/tree/main/.github/workflows)
139140
- [hash-checker/hash-checker](https://github.com/hash-checker/hash-checker/tree/master/.github/workflows)
140141
- [hash-checker/hash-checker-lite](https://github.com/hash-checker/hash-checker-lite/tree/master/.github/workflows)
142+
- [Kiwix/kiwix-android](https://github.com/kiwix/kiwix-android/blob/develop/.github/workflows)
143+
- [wikimedia/apps-android-wikipedia](https://github.com/wikimedia/apps-android-wikipedia/blob/master/.github/workflows)
144+
- [google/android-fhir](https://github.com/google/android-fhir/tree/master/.github/workflows)
141145

142146
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.

__tests__/input-validator.test.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,27 @@ describe('disable-animations validator tests', () => {
103103
});
104104
});
105105

106+
describe('disable-spellchecker validator tests', () => {
107+
it('Throws if disable-spellchecker is not a boolean', () => {
108+
const func = () => {
109+
validator.checkDisableSpellchecker('yes');
110+
};
111+
expect(func).toThrowError(`Input for input.disable-spellchecker should be either 'true' or 'false'.`);
112+
});
113+
114+
it('Validates successfully if disable-spellchecker is either true or false', () => {
115+
const func1 = () => {
116+
validator.checkDisableSpellchecker('true');
117+
};
118+
expect(func1).not.toThrow();
119+
120+
const func2 = () => {
121+
validator.checkDisableSpellchecker('false');
122+
};
123+
expect(func2).not.toThrow();
124+
});
125+
});
126+
106127
describe('emulator-build validator tests', () => {
107128
it('Throws if emulator-build is not a number', () => {
108129
const func = () => {

action.yml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: 'Android Emulator Runner'
22
description: 'Installs, configures and starts an Android Emulator directly on macOS virtual machines.'
33
author: 'Reactive Circus'
44
branding:
5-
icon: 'smartphone'
5+
icon: 'smartphone'
66
color: 'green'
77
inputs:
88
api-level:
@@ -12,7 +12,7 @@ inputs:
1212
description: 'target of the system image - default, google_apis or playstore'
1313
default: 'default'
1414
arch:
15-
description: 'CPU architecture of the system image - x86 or x86_64'
15+
description: 'CPU architecture of the system image - x86, x86_64 or arm64-v8a'
1616
default: 'x86'
1717
profile:
1818
description: 'hardware profile used for creating the AVD - e.g. `Nexus 6`'
@@ -30,6 +30,9 @@ inputs:
3030
disable-animations:
3131
description: 'whether to disable animations - true or false'
3232
default: 'true'
33+
disable-spellchecker:
34+
description: Whether to disable spellchecker - `true` or `false`.
35+
default: 'false'
3336
emulator-build:
3437
description: 'build number of a specific version of the emulator binary to use - e.g. `6061023` for emulator v29.3.0.0'
3538
working-directory:

lib/emulator-manager.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ const EMULATOR_BOOT_TIMEOUT_SECONDS = 600;
3434
/**
3535
* Creates and launches a new AVD instance with the specified configurations.
3636
*/
37-
function launchEmulator(apiLevel, target, arch, profile, cores, sdcardPathOrSize, avdName, emulatorOptions, disableAnimations) {
37+
function launchEmulator(apiLevel, target, arch, profile, cores, sdcardPathOrSize, avdName, emulatorOptions, disableAnimations, disableSpellChecker) {
3838
return __awaiter(this, void 0, void 0, function* () {
3939
// create a new AVD
4040
const profileOption = profile.trim() !== '' ? `--device '${profile}'` : '';
@@ -69,6 +69,9 @@ function launchEmulator(apiLevel, target, arch, profile, cores, sdcardPathOrSize
6969
yield exec.exec(`adb shell settings put global transition_animation_scale 0.0`);
7070
yield exec.exec(`adb shell settings put global animator_duration_scale 0.0`);
7171
}
72+
if (disableSpellChecker) {
73+
yield exec.exec(`adb shell settings put secure spell_checker_enabled 0`);
74+
}
7275
});
7376
}
7477
exports.launchEmulator = launchEmulator;

lib/input-validator.js

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
"use strict";
22
Object.defineProperty(exports, "__esModule", { value: true });
3-
exports.checkEmulatorBuild = exports.checkDisableAnimations = exports.checkArch = exports.checkTarget = exports.checkApiLevel = exports.VALID_ARCHS = exports.VALID_TARGETS = exports.MIN_API_LEVEL = void 0;
3+
exports.checkEmulatorBuild = exports.checkDisableSpellchecker = exports.checkDisableAnimations = exports.checkArch = exports.checkTarget = exports.checkApiLevel = exports.VALID_ARCHS = exports.VALID_TARGETS = exports.MIN_API_LEVEL = void 0;
44
exports.MIN_API_LEVEL = 15;
55
exports.VALID_TARGETS = ['default', 'google_apis', 'google_apis_playstore'];
6-
exports.VALID_ARCHS = ['x86', 'x86_64'];
6+
exports.VALID_ARCHS = ['x86', 'x86_64', 'arm64-v8a'];
77
function checkApiLevel(apiLevel) {
88
if (isNaN(Number(apiLevel)) || !Number.isInteger(Number(apiLevel))) {
99
throw new Error(`Unexpected API level: '${apiLevel}'.`);
@@ -26,14 +26,23 @@ function checkArch(arch) {
2626
}
2727
exports.checkArch = checkArch;
2828
function checkDisableAnimations(disableAnimations) {
29-
if (disableAnimations !== 'true' && disableAnimations !== 'false') {
29+
if (!isValidBoolean(disableAnimations)) {
3030
throw new Error(`Input for input.disable-animations should be either 'true' or 'false'.`);
3131
}
3232
}
3333
exports.checkDisableAnimations = checkDisableAnimations;
34+
function checkDisableSpellchecker(disableSpellchecker) {
35+
if (!isValidBoolean(disableSpellchecker)) {
36+
throw new Error(`Input for input.disable-spellchecker should be either 'true' or 'false'.`);
37+
}
38+
}
39+
exports.checkDisableSpellchecker = checkDisableSpellchecker;
3440
function checkEmulatorBuild(emulatorBuild) {
3541
if (isNaN(Number(emulatorBuild)) || !Number.isInteger(Number(emulatorBuild))) {
3642
throw new Error(`Unexpected emulator build: '${emulatorBuild}'.`);
3743
}
3844
}
3945
exports.checkEmulatorBuild = checkEmulatorBuild;
46+
function isValidBoolean(value) {
47+
return value === 'true' || value === 'false';
48+
}

lib/main.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,11 @@ function run() {
8080
input_validator_1.checkDisableAnimations(disableAnimationsInput);
8181
const disableAnimations = disableAnimationsInput === 'true';
8282
console.log(`disable animations: ${disableAnimations}`);
83+
// disable spellchecker
84+
const disableSpellcheckerInput = core.getInput('disable-spellchecker');
85+
input_validator_1.checkDisableSpellchecker(disableSpellcheckerInput);
86+
const disableSpellchecker = disableSpellcheckerInput === 'true';
87+
console.log(`disable spellchecker: ${disableSpellchecker}`);
8388
// emulator build
8489
const emulatorBuildInput = core.getInput('emulator-build');
8590
if (emulatorBuildInput) {
@@ -115,15 +120,17 @@ function run() {
115120
// install SDK
116121
yield sdk_installer_1.installAndroidSdk(apiLevel, target, arch, emulatorBuild, ndkVersion, cmakeVersion);
117122
// launch an emulator
118-
yield emulator_manager_1.launchEmulator(apiLevel, target, arch, profile, cores, sdcardPathOrSize, avdName, emulatorOptions, disableAnimations);
123+
yield emulator_manager_1.launchEmulator(apiLevel, target, arch, profile, cores, sdcardPathOrSize, avdName, emulatorOptions, disableAnimations, disableSpellchecker);
119124
// execute the custom script
120125
try {
121126
// move to custom working directory if set
122127
if (workingDirectory) {
123128
process.chdir(workingDirectory);
124129
}
125130
for (const script of scripts) {
126-
yield exec.exec(`sh -c \\"${script}"`);
131+
// use array form to avoid various quote escaping problems
132+
// caused by exec(`sh -c "${script}"`)
133+
yield exec.exec('sh', ['-c', script]);
127134
}
128135
}
129136
catch (error) {

package-lock.json

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/emulator-manager.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ export async function launchEmulator(
1414
sdcardPathOrSize: string,
1515
avdName: string,
1616
emulatorOptions: string,
17-
disableAnimations: boolean
17+
disableAnimations: boolean,
18+
disableSpellChecker: boolean
1819
): Promise<void> {
1920
// create a new AVD
2021
const profileOption = profile.trim() !== '' ? `--device '${profile}'` : '';
@@ -57,6 +58,9 @@ export async function launchEmulator(
5758
await exec.exec(`adb shell settings put global transition_animation_scale 0.0`);
5859
await exec.exec(`adb shell settings put global animator_duration_scale 0.0`);
5960
}
61+
if (disableSpellChecker) {
62+
await exec.exec(`adb shell settings put secure spell_checker_enabled 0`);
63+
}
6064
}
6165

6266
/**

src/input-validator.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
export const MIN_API_LEVEL = 15;
22
export const VALID_TARGETS: Array<string> = ['default', 'google_apis', 'google_apis_playstore'];
3-
export const VALID_ARCHS: Array<string> = ['x86', 'x86_64'];
3+
export const VALID_ARCHS: Array<string> = ['x86', 'x86_64', 'arm64-v8a'];
44

55
export function checkApiLevel(apiLevel: string): void {
66
if (isNaN(Number(apiLevel)) || !Number.isInteger(Number(apiLevel))) {
@@ -24,13 +24,23 @@ export function checkArch(arch: string): void {
2424
}
2525

2626
export function checkDisableAnimations(disableAnimations: string): void {
27-
if (disableAnimations !== 'true' && disableAnimations !== 'false') {
27+
if (!isValidBoolean(disableAnimations)) {
2828
throw new Error(`Input for input.disable-animations should be either 'true' or 'false'.`);
2929
}
3030
}
3131

32+
export function checkDisableSpellchecker(disableSpellchecker: string): void {
33+
if (!isValidBoolean(disableSpellchecker)) {
34+
throw new Error(`Input for input.disable-spellchecker should be either 'true' or 'false'.`);
35+
}
36+
}
37+
3238
export function checkEmulatorBuild(emulatorBuild: string): void {
3339
if (isNaN(Number(emulatorBuild)) || !Number.isInteger(Number(emulatorBuild))) {
3440
throw new Error(`Unexpected emulator build: '${emulatorBuild}'.`);
3541
}
3642
}
43+
44+
function isValidBoolean(value: string): boolean {
45+
return value === 'true' || value === 'false';
46+
}

0 commit comments

Comments
 (0)