mirror of
https://github.com/reactivecircus/android-emulator-runner.git
synced 2026-09-03 19:09:32 +00:00
Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 599839e428 | |||
| 751bef68f6 | |||
| bbf0887eb9 | |||
| 84b9418977 | |||
| a732f125bb | |||
| 5201a33a90 | |||
| cf46dc4c18 | |||
| f790770d0f | |||
| 505c899f12 | |||
| 0d47f0813d |
@@ -1,5 +1,11 @@
|
|||||||
# Change Log
|
# Change Log
|
||||||
|
|
||||||
|
## v2.16.0
|
||||||
|
|
||||||
|
* Avoid wrapping script code in quotes - [#134](https://github.com/ReactiveCircus/android-emulator-runner/pull/134) @hostilefork
|
||||||
|
* Add option to disable spellcheck - [#143](https://github.com/ReactiveCircus/android-emulator-runner/pull/143) @AfzalivE
|
||||||
|
* Add support for arm64-v8a for Apple Silicon Macs - [#146](https://github.com/ReactiveCircus/android-emulator-runner/pull/146) @Jeehut
|
||||||
|
|
||||||
## v2.15.0
|
## v2.15.0
|
||||||
|
|
||||||
* Added support for specifying the number of cores to use for the emulator - [#130](https://github.com/ReactiveCircus/android-emulator-runner/pull/130).
|
* Added support for specifying the number of cores to use for the emulator - [#130](https://github.com/ReactiveCircus/android-emulator-runner/pull/130).
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ A GitHub Action for installing, configuring and running hardware-accelerated And
|
|||||||
|
|
||||||
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).
|
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).
|
||||||
|
|
||||||
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
|
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
|
||||||
tests directly on the VM.
|
tests directly on the VM.
|
||||||
|
|
||||||
This action automates the process by doing the following:
|
This action automates the process by doing the following:
|
||||||
@@ -90,13 +90,14 @@ jobs:
|
|||||||
|-|-|-|-|
|
|-|-|-|-|
|
||||||
| `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**. |
|
| `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**. |
|
||||||
| `target` | Optional | `default` | Target of the system image - `default`, `google_apis` or `playstore`. |
|
| `target` | Optional | `default` | Target of the system image - `default`, `google_apis` or `playstore`. |
|
||||||
| `arch` | Optional | `x86` | CPU architecture of the system image - `x86` or `x86_64`. Note that `x86_64` image is only available for API 21+. |
|
| `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). |
|
||||||
| `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". |
|
| `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". |
|
||||||
| `cores` | Optional | 2 | Number of cores to use for the emulator (`hw.cpu.ncore` in config.ini). |
|
| `cores` | Optional | 2 | Number of cores to use for the emulator (`hw.cpu.ncore` in config.ini). |
|
||||||
| `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`. |
|
| `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`. |
|
||||||
| `avd-name` | Optional | `test` | Custom AVD name used for creating the Android Virtual Device. |
|
| `avd-name` | Optional | `test` | Custom AVD name used for creating the Android Virtual Device. |
|
||||||
| `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`. |
|
| `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`. |
|
||||||
| `disable-animations` | Optional | `true` | Whether to disable animations - `true` or `false`. |
|
| `disable-animations` | Optional | `true` | Whether to disable animations - `true` or `false`. |
|
||||||
|
| `disable-spellchecker` | Optional | `false` | Whether to disable spellchecker - `true` or `false`. |
|
||||||
| `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. |
|
| `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. |
|
||||||
| `working-directory` | Optional | `./` | A custom working directory - e.g. `./android` if your root Gradle project is under the `./android` sub-directory within your repository. |
|
| `working-directory` | Optional | `./` | A custom working directory - e.g. `./android` if your root Gradle project is under the `./android` sub-directory within your repository. |
|
||||||
| `ndk` | Optional | N/A | Version of NDK to install - e.g. `21.0.6113669` |
|
| `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
|
|||||||
- [square/leakcanary](https://github.com/square/leakcanary/tree/main/.github/workflows)
|
- [square/leakcanary](https://github.com/square/leakcanary/tree/main/.github/workflows)
|
||||||
- [hash-checker/hash-checker](https://github.com/hash-checker/hash-checker/tree/master/.github/workflows)
|
- [hash-checker/hash-checker](https://github.com/hash-checker/hash-checker/tree/master/.github/workflows)
|
||||||
- [hash-checker/hash-checker-lite](https://github.com/hash-checker/hash-checker-lite/tree/master/.github/workflows)
|
- [hash-checker/hash-checker-lite](https://github.com/hash-checker/hash-checker-lite/tree/master/.github/workflows)
|
||||||
|
- [Kiwix/kiwix-android](https://github.com/kiwix/kiwix-android/blob/develop/.github/workflows)
|
||||||
|
- [wikimedia/apps-android-wikipedia](https://github.com/wikimedia/apps-android-wikipedia/blob/master/.github/workflows)
|
||||||
|
- [google/android-fhir](https://github.com/google/android-fhir/tree/master/.github/workflows)
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|||||||
@@ -103,6 +103,27 @@ describe('disable-animations validator tests', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('disable-spellchecker validator tests', () => {
|
||||||
|
it('Throws if disable-spellchecker is not a boolean', () => {
|
||||||
|
const func = () => {
|
||||||
|
validator.checkDisableSpellchecker('yes');
|
||||||
|
};
|
||||||
|
expect(func).toThrowError(`Input for input.disable-spellchecker should be either 'true' or 'false'.`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Validates successfully if disable-spellchecker is either true or false', () => {
|
||||||
|
const func1 = () => {
|
||||||
|
validator.checkDisableSpellchecker('true');
|
||||||
|
};
|
||||||
|
expect(func1).not.toThrow();
|
||||||
|
|
||||||
|
const func2 = () => {
|
||||||
|
validator.checkDisableSpellchecker('false');
|
||||||
|
};
|
||||||
|
expect(func2).not.toThrow();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('emulator-build validator tests', () => {
|
describe('emulator-build validator tests', () => {
|
||||||
it('Throws if emulator-build is not a number', () => {
|
it('Throws if emulator-build is not a number', () => {
|
||||||
const func = () => {
|
const func = () => {
|
||||||
|
|||||||
+5
-2
@@ -2,7 +2,7 @@ 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 macOS virtual machines.'
|
||||||
author: 'Reactive Circus'
|
author: 'Reactive Circus'
|
||||||
branding:
|
branding:
|
||||||
icon: 'smartphone'
|
icon: 'smartphone'
|
||||||
color: 'green'
|
color: 'green'
|
||||||
inputs:
|
inputs:
|
||||||
api-level:
|
api-level:
|
||||||
@@ -12,7 +12,7 @@ inputs:
|
|||||||
description: 'target of the system image - default, google_apis or playstore'
|
description: 'target of the system image - default, google_apis or playstore'
|
||||||
default: 'default'
|
default: 'default'
|
||||||
arch:
|
arch:
|
||||||
description: 'CPU architecture of the system image - x86 or x86_64'
|
description: 'CPU architecture of the system image - x86, x86_64 or arm64-v8a'
|
||||||
default: 'x86'
|
default: 'x86'
|
||||||
profile:
|
profile:
|
||||||
description: 'hardware profile used for creating the AVD - e.g. `Nexus 6`'
|
description: 'hardware profile used for creating the AVD - e.g. `Nexus 6`'
|
||||||
@@ -30,6 +30,9 @@ inputs:
|
|||||||
disable-animations:
|
disable-animations:
|
||||||
description: 'whether to disable animations - true or false'
|
description: 'whether to disable animations - true or false'
|
||||||
default: 'true'
|
default: 'true'
|
||||||
|
disable-spellchecker:
|
||||||
|
description: Whether to disable spellchecker - `true` or `false`.
|
||||||
|
default: 'false'
|
||||||
emulator-build:
|
emulator-build:
|
||||||
description: 'build number of a specific version of the emulator binary to use - e.g. `6061023` for emulator v29.3.0.0'
|
description: 'build number of a specific version of the emulator binary to use - e.g. `6061023` for emulator v29.3.0.0'
|
||||||
working-directory:
|
working-directory:
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ const EMULATOR_BOOT_TIMEOUT_SECONDS = 600;
|
|||||||
/**
|
/**
|
||||||
* Creates and launches a new AVD instance with the specified configurations.
|
* Creates and launches a new AVD instance with the specified configurations.
|
||||||
*/
|
*/
|
||||||
function launchEmulator(apiLevel, target, arch, profile, cores, sdcardPathOrSize, avdName, emulatorOptions, disableAnimations) {
|
function launchEmulator(apiLevel, target, arch, profile, cores, sdcardPathOrSize, avdName, emulatorOptions, disableAnimations, disableSpellChecker) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
// create a new AVD
|
// create a new AVD
|
||||||
const profileOption = profile.trim() !== '' ? `--device '${profile}'` : '';
|
const profileOption = profile.trim() !== '' ? `--device '${profile}'` : '';
|
||||||
@@ -69,6 +69,9 @@ function launchEmulator(apiLevel, target, arch, profile, cores, sdcardPathOrSize
|
|||||||
yield exec.exec(`adb shell settings put global transition_animation_scale 0.0`);
|
yield exec.exec(`adb shell settings put global transition_animation_scale 0.0`);
|
||||||
yield exec.exec(`adb shell settings put global animator_duration_scale 0.0`);
|
yield exec.exec(`adb shell settings put global animator_duration_scale 0.0`);
|
||||||
}
|
}
|
||||||
|
if (disableSpellChecker) {
|
||||||
|
yield exec.exec(`adb shell settings put secure spell_checker_enabled 0`);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
exports.launchEmulator = launchEmulator;
|
exports.launchEmulator = launchEmulator;
|
||||||
|
|||||||
+12
-3
@@ -1,9 +1,9 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.checkEmulatorBuild = exports.checkDisableAnimations = exports.checkArch = exports.checkTarget = exports.checkApiLevel = exports.VALID_ARCHS = exports.VALID_TARGETS = exports.MIN_API_LEVEL = void 0;
|
exports.checkEmulatorBuild = exports.checkDisableSpellchecker = exports.checkDisableAnimations = exports.checkArch = exports.checkTarget = exports.checkApiLevel = exports.VALID_ARCHS = exports.VALID_TARGETS = exports.MIN_API_LEVEL = void 0;
|
||||||
exports.MIN_API_LEVEL = 15;
|
exports.MIN_API_LEVEL = 15;
|
||||||
exports.VALID_TARGETS = ['default', 'google_apis', 'google_apis_playstore'];
|
exports.VALID_TARGETS = ['default', 'google_apis', 'google_apis_playstore'];
|
||||||
exports.VALID_ARCHS = ['x86', 'x86_64'];
|
exports.VALID_ARCHS = ['x86', 'x86_64', 'arm64-v8a'];
|
||||||
function checkApiLevel(apiLevel) {
|
function checkApiLevel(apiLevel) {
|
||||||
if (isNaN(Number(apiLevel)) || !Number.isInteger(Number(apiLevel))) {
|
if (isNaN(Number(apiLevel)) || !Number.isInteger(Number(apiLevel))) {
|
||||||
throw new Error(`Unexpected API level: '${apiLevel}'.`);
|
throw new Error(`Unexpected API level: '${apiLevel}'.`);
|
||||||
@@ -26,14 +26,23 @@ function checkArch(arch) {
|
|||||||
}
|
}
|
||||||
exports.checkArch = checkArch;
|
exports.checkArch = checkArch;
|
||||||
function checkDisableAnimations(disableAnimations) {
|
function checkDisableAnimations(disableAnimations) {
|
||||||
if (disableAnimations !== 'true' && disableAnimations !== 'false') {
|
if (!isValidBoolean(disableAnimations)) {
|
||||||
throw new Error(`Input for input.disable-animations should be either 'true' or 'false'.`);
|
throw new Error(`Input for input.disable-animations should be either 'true' or 'false'.`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exports.checkDisableAnimations = checkDisableAnimations;
|
exports.checkDisableAnimations = checkDisableAnimations;
|
||||||
|
function checkDisableSpellchecker(disableSpellchecker) {
|
||||||
|
if (!isValidBoolean(disableSpellchecker)) {
|
||||||
|
throw new Error(`Input for input.disable-spellchecker should be either 'true' or 'false'.`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.checkDisableSpellchecker = checkDisableSpellchecker;
|
||||||
function checkEmulatorBuild(emulatorBuild) {
|
function checkEmulatorBuild(emulatorBuild) {
|
||||||
if (isNaN(Number(emulatorBuild)) || !Number.isInteger(Number(emulatorBuild))) {
|
if (isNaN(Number(emulatorBuild)) || !Number.isInteger(Number(emulatorBuild))) {
|
||||||
throw new Error(`Unexpected emulator build: '${emulatorBuild}'.`);
|
throw new Error(`Unexpected emulator build: '${emulatorBuild}'.`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exports.checkEmulatorBuild = checkEmulatorBuild;
|
exports.checkEmulatorBuild = checkEmulatorBuild;
|
||||||
|
function isValidBoolean(value) {
|
||||||
|
return value === 'true' || value === 'false';
|
||||||
|
}
|
||||||
|
|||||||
+9
-2
@@ -80,6 +80,11 @@ function run() {
|
|||||||
input_validator_1.checkDisableAnimations(disableAnimationsInput);
|
input_validator_1.checkDisableAnimations(disableAnimationsInput);
|
||||||
const disableAnimations = disableAnimationsInput === 'true';
|
const disableAnimations = disableAnimationsInput === 'true';
|
||||||
console.log(`disable animations: ${disableAnimations}`);
|
console.log(`disable animations: ${disableAnimations}`);
|
||||||
|
// disable spellchecker
|
||||||
|
const disableSpellcheckerInput = core.getInput('disable-spellchecker');
|
||||||
|
input_validator_1.checkDisableSpellchecker(disableSpellcheckerInput);
|
||||||
|
const disableSpellchecker = disableSpellcheckerInput === 'true';
|
||||||
|
console.log(`disable spellchecker: ${disableSpellchecker}`);
|
||||||
// emulator build
|
// emulator build
|
||||||
const emulatorBuildInput = core.getInput('emulator-build');
|
const emulatorBuildInput = core.getInput('emulator-build');
|
||||||
if (emulatorBuildInput) {
|
if (emulatorBuildInput) {
|
||||||
@@ -115,7 +120,7 @@ function run() {
|
|||||||
// install SDK
|
// install SDK
|
||||||
yield sdk_installer_1.installAndroidSdk(apiLevel, target, arch, emulatorBuild, ndkVersion, cmakeVersion);
|
yield sdk_installer_1.installAndroidSdk(apiLevel, target, arch, emulatorBuild, ndkVersion, cmakeVersion);
|
||||||
// launch an emulator
|
// launch an emulator
|
||||||
yield emulator_manager_1.launchEmulator(apiLevel, target, arch, profile, cores, sdcardPathOrSize, avdName, emulatorOptions, disableAnimations);
|
yield emulator_manager_1.launchEmulator(apiLevel, target, arch, profile, cores, sdcardPathOrSize, avdName, emulatorOptions, disableAnimations, disableSpellchecker);
|
||||||
// execute the custom script
|
// execute the custom script
|
||||||
try {
|
try {
|
||||||
// move to custom working directory if set
|
// move to custom working directory if set
|
||||||
@@ -123,7 +128,9 @@ function run() {
|
|||||||
process.chdir(workingDirectory);
|
process.chdir(workingDirectory);
|
||||||
}
|
}
|
||||||
for (const script of scripts) {
|
for (const script of scripts) {
|
||||||
yield exec.exec(`sh -c \\"${script}"`);
|
// use array form to avoid various quote escaping problems
|
||||||
|
// caused by exec(`sh -c "${script}"`)
|
||||||
|
yield exec.exec('sh', ['-c', script]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
|
|||||||
Generated
+3
-3
@@ -11309,9 +11309,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"y18n": {
|
"y18n": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz",
|
||||||
"integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
|
"integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"yallist": {
|
"yallist": {
|
||||||
|
|||||||
@@ -14,7 +14,8 @@ export async function launchEmulator(
|
|||||||
sdcardPathOrSize: string,
|
sdcardPathOrSize: string,
|
||||||
avdName: string,
|
avdName: string,
|
||||||
emulatorOptions: string,
|
emulatorOptions: string,
|
||||||
disableAnimations: boolean
|
disableAnimations: boolean,
|
||||||
|
disableSpellChecker: boolean
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
// create a new AVD
|
// create a new AVD
|
||||||
const profileOption = profile.trim() !== '' ? `--device '${profile}'` : '';
|
const profileOption = profile.trim() !== '' ? `--device '${profile}'` : '';
|
||||||
@@ -57,6 +58,9 @@ export async function launchEmulator(
|
|||||||
await exec.exec(`adb shell settings put global transition_animation_scale 0.0`);
|
await exec.exec(`adb shell settings put global transition_animation_scale 0.0`);
|
||||||
await exec.exec(`adb shell settings put global animator_duration_scale 0.0`);
|
await exec.exec(`adb shell settings put global animator_duration_scale 0.0`);
|
||||||
}
|
}
|
||||||
|
if (disableSpellChecker) {
|
||||||
|
await exec.exec(`adb shell settings put secure spell_checker_enabled 0`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+12
-2
@@ -1,6 +1,6 @@
|
|||||||
export const MIN_API_LEVEL = 15;
|
export const MIN_API_LEVEL = 15;
|
||||||
export const VALID_TARGETS: Array<string> = ['default', 'google_apis', 'google_apis_playstore'];
|
export const VALID_TARGETS: Array<string> = ['default', 'google_apis', 'google_apis_playstore'];
|
||||||
export const VALID_ARCHS: Array<string> = ['x86', 'x86_64'];
|
export const VALID_ARCHS: Array<string> = ['x86', 'x86_64', 'arm64-v8a'];
|
||||||
|
|
||||||
export function checkApiLevel(apiLevel: string): void {
|
export function checkApiLevel(apiLevel: string): void {
|
||||||
if (isNaN(Number(apiLevel)) || !Number.isInteger(Number(apiLevel))) {
|
if (isNaN(Number(apiLevel)) || !Number.isInteger(Number(apiLevel))) {
|
||||||
@@ -24,13 +24,23 @@ export function checkArch(arch: string): void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function checkDisableAnimations(disableAnimations: string): void {
|
export function checkDisableAnimations(disableAnimations: string): void {
|
||||||
if (disableAnimations !== 'true' && disableAnimations !== 'false') {
|
if (!isValidBoolean(disableAnimations)) {
|
||||||
throw new Error(`Input for input.disable-animations should be either 'true' or 'false'.`);
|
throw new Error(`Input for input.disable-animations should be either 'true' or 'false'.`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function checkDisableSpellchecker(disableSpellchecker: string): void {
|
||||||
|
if (!isValidBoolean(disableSpellchecker)) {
|
||||||
|
throw new Error(`Input for input.disable-spellchecker should be either 'true' or 'false'.`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function checkEmulatorBuild(emulatorBuild: string): void {
|
export function checkEmulatorBuild(emulatorBuild: string): void {
|
||||||
if (isNaN(Number(emulatorBuild)) || !Number.isInteger(Number(emulatorBuild))) {
|
if (isNaN(Number(emulatorBuild)) || !Number.isInteger(Number(emulatorBuild))) {
|
||||||
throw new Error(`Unexpected emulator build: '${emulatorBuild}'.`);
|
throw new Error(`Unexpected emulator build: '${emulatorBuild}'.`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isValidBoolean(value: string): boolean {
|
||||||
|
return value === 'true' || value === 'false';
|
||||||
|
}
|
||||||
|
|||||||
+11
-3
@@ -1,6 +1,6 @@
|
|||||||
import * as core from '@actions/core';
|
import * as core from '@actions/core';
|
||||||
import { installAndroidSdk } from './sdk-installer';
|
import { installAndroidSdk } from './sdk-installer';
|
||||||
import { checkApiLevel, checkTarget, checkArch, checkDisableAnimations, checkEmulatorBuild } from './input-validator';
|
import { checkApiLevel, checkTarget, checkArch, checkDisableAnimations, checkEmulatorBuild, checkDisableSpellchecker } from './input-validator';
|
||||||
import { launchEmulator, killEmulator } from './emulator-manager';
|
import { launchEmulator, killEmulator } from './emulator-manager';
|
||||||
import * as exec from '@actions/exec';
|
import * as exec from '@actions/exec';
|
||||||
import { parseScript } from './script-parser';
|
import { parseScript } from './script-parser';
|
||||||
@@ -61,6 +61,12 @@ async function run() {
|
|||||||
const disableAnimations = disableAnimationsInput === 'true';
|
const disableAnimations = disableAnimationsInput === 'true';
|
||||||
console.log(`disable animations: ${disableAnimations}`);
|
console.log(`disable animations: ${disableAnimations}`);
|
||||||
|
|
||||||
|
// disable spellchecker
|
||||||
|
const disableSpellcheckerInput = core.getInput('disable-spellchecker');
|
||||||
|
checkDisableSpellchecker(disableSpellcheckerInput);
|
||||||
|
const disableSpellchecker = disableSpellcheckerInput === 'true';
|
||||||
|
console.log(`disable spellchecker: ${disableSpellchecker}`);
|
||||||
|
|
||||||
// emulator build
|
// emulator build
|
||||||
const emulatorBuildInput = core.getInput('emulator-build');
|
const emulatorBuildInput = core.getInput('emulator-build');
|
||||||
if (emulatorBuildInput) {
|
if (emulatorBuildInput) {
|
||||||
@@ -102,7 +108,7 @@ async function run() {
|
|||||||
await installAndroidSdk(apiLevel, target, arch, emulatorBuild, ndkVersion, cmakeVersion);
|
await installAndroidSdk(apiLevel, target, arch, emulatorBuild, ndkVersion, cmakeVersion);
|
||||||
|
|
||||||
// launch an emulator
|
// launch an emulator
|
||||||
await launchEmulator(apiLevel, target, arch, profile, cores, sdcardPathOrSize, avdName, emulatorOptions, disableAnimations);
|
await launchEmulator(apiLevel, target, arch, profile, cores, sdcardPathOrSize, avdName, emulatorOptions, disableAnimations, disableSpellchecker);
|
||||||
|
|
||||||
// execute the custom script
|
// execute the custom script
|
||||||
try {
|
try {
|
||||||
@@ -111,7 +117,9 @@ async function run() {
|
|||||||
process.chdir(workingDirectory);
|
process.chdir(workingDirectory);
|
||||||
}
|
}
|
||||||
for (const script of scripts) {
|
for (const script of scripts) {
|
||||||
await exec.exec(`sh -c \\"${script}"`);
|
// use array form to avoid various quote escaping problems
|
||||||
|
// caused by exec(`sh -c "${script}"`)
|
||||||
|
await exec.exec('sh', ['-c', script]);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
core.setFailed(error.message);
|
core.setFailed(error.message);
|
||||||
|
|||||||
Reference in New Issue
Block a user